bakery-ui 0.0.1 → 0.1.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/LICENSE +21 -0
- package/README.md +124 -33
- package/fesm2022/bakery-ui.mjs +1092 -13
- package/fesm2022/bakery-ui.mjs.map +1 -1
- package/index.d.ts +5 -17
- package/lib/bakery-ui.d.ts +5 -0
- package/lib/button/baguette-button.d.ts +22 -0
- package/lib/display/cupcake-card.d.ts +34 -0
- package/lib/feedback/toast-notification.d.ts +30 -0
- package/lib/inputs/bagel-input.d.ts +53 -0
- package/package.json +12 -5
- package/public-api.d.ts +5 -0
- package/bakery-ui-0.0.1.tgz +0 -0
package/fesm2022/bakery-ui.mjs
CHANGED
@@ -1,15 +1,26 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
|
-
import { Component, Input } from '@angular/core';
|
2
|
+
import { Component, EventEmitter, Output, Input, ChangeDetectionStrategy, forwardRef } from '@angular/core';
|
3
|
+
import { MatButtonModule } from '@angular/material/button';
|
4
|
+
import * as i2 from '@angular/material/core';
|
5
|
+
import { MatRippleModule } from '@angular/material/core';
|
6
|
+
import * as i1 from '@angular/common';
|
7
|
+
import { CommonModule } from '@angular/common';
|
8
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
9
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
10
|
+
import { MatInputModule } from '@angular/material/input';
|
11
|
+
import { MatCardModule } from '@angular/material/card';
|
12
|
+
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
13
|
+
import { trigger, state, transition, style, animate } from '@angular/animations';
|
3
14
|
|
4
15
|
class BakeryUi {
|
5
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
6
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
16
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BakeryUi, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
17
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: BakeryUi, isStandalone: true, selector: "lib-bakery-ui", ngImport: i0, template: `
|
7
18
|
<p>
|
8
19
|
bakery-ui works!
|
9
20
|
</p>
|
10
21
|
`, isInline: true, styles: [""] });
|
11
22
|
}
|
12
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BakeryUi, decorators: [{
|
13
24
|
type: Component,
|
14
25
|
args: [{ selector: 'lib-bakery-ui', imports: [], template: `
|
15
26
|
<p>
|
@@ -18,25 +29,1093 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImpor
|
|
18
29
|
` }]
|
19
30
|
}] });
|
20
31
|
|
21
|
-
class
|
22
|
-
label = 'Button';
|
32
|
+
class BaguetteButton {
|
23
33
|
variant = 'primary';
|
24
|
-
size = '
|
34
|
+
size = 'md';
|
25
35
|
disabled = false;
|
26
|
-
|
27
|
-
|
36
|
+
loading = false;
|
37
|
+
fullWidth = false;
|
38
|
+
leftIcon;
|
39
|
+
rightIcon;
|
40
|
+
ariaLabel;
|
41
|
+
ariaDescribedBy;
|
42
|
+
clicked = new EventEmitter();
|
43
|
+
handleClick(event) {
|
44
|
+
if (!this.disabled && !this.loading) {
|
45
|
+
this.clicked.emit(event);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
get buttonClasses() {
|
49
|
+
const baseClasses = [
|
50
|
+
'inline-flex items-center justify-center font-medium rounded-lg',
|
51
|
+
'transition-all duration-200 ease-in-out',
|
52
|
+
'focus:outline-none focus:ring-2 focus:ring-offset-2',
|
53
|
+
'disabled:opacity-50 disabled:cursor-not-allowed',
|
54
|
+
'transform hover:scale-105 active:scale-95',
|
55
|
+
'shadow-sm hover:shadow-md'
|
56
|
+
];
|
57
|
+
// Size classes - made more compact
|
58
|
+
const sizeClasses = {
|
59
|
+
sm: 'px-2 py-1 text-xs',
|
60
|
+
md: 'px-3 py-1.5 text-sm',
|
61
|
+
lg: 'px-4 py-2 text-base',
|
62
|
+
xl: 'px-5 py-2.5 text-lg'
|
63
|
+
};
|
64
|
+
// Variant classes with bakery theme
|
65
|
+
const variantClasses = {
|
66
|
+
primary: [
|
67
|
+
'bg-gradient-to-r from-amber-400 to-yellow-500',
|
68
|
+
'hover:from-amber-500 hover:to-yellow-600',
|
69
|
+
'text-amber-900 font-semibold',
|
70
|
+
'border border-amber-300',
|
71
|
+
'focus:ring-amber-500',
|
72
|
+
'shadow-amber-200'
|
73
|
+
],
|
74
|
+
secondary: [
|
75
|
+
'bg-gradient-to-r from-orange-100 to-amber-100',
|
76
|
+
'hover:from-orange-200 hover:to-amber-200',
|
77
|
+
'text-amber-800 font-medium',
|
78
|
+
'border border-amber-200',
|
79
|
+
'focus:ring-amber-400'
|
80
|
+
],
|
81
|
+
outline: [
|
82
|
+
'bg-transparent border-2 border-amber-400',
|
83
|
+
'hover:bg-amber-50 hover:border-amber-500',
|
84
|
+
'text-amber-700 font-medium',
|
85
|
+
'focus:ring-amber-400'
|
86
|
+
],
|
87
|
+
ghost: [
|
88
|
+
'bg-transparent hover:bg-amber-50',
|
89
|
+
'text-amber-700 font-medium',
|
90
|
+
'focus:ring-amber-400'
|
91
|
+
],
|
92
|
+
danger: [
|
93
|
+
'bg-gradient-to-r from-red-500 to-red-600',
|
94
|
+
'hover:from-red-600 hover:to-red-700',
|
95
|
+
'text-white font-medium',
|
96
|
+
'border border-red-400',
|
97
|
+
'focus:ring-red-500',
|
98
|
+
'shadow-red-200'
|
99
|
+
]
|
100
|
+
};
|
101
|
+
const classes = [
|
102
|
+
...baseClasses,
|
103
|
+
sizeClasses[this.size],
|
104
|
+
...variantClasses[this.variant]
|
105
|
+
];
|
106
|
+
if (this.fullWidth) {
|
107
|
+
classes.push('w-full');
|
108
|
+
}
|
109
|
+
return classes.join(' ');
|
110
|
+
}
|
111
|
+
get contentClasses() {
|
112
|
+
return this.loading ? 'opacity-70' : '';
|
113
|
+
}
|
114
|
+
get rippleColor() {
|
115
|
+
const rippleColors = {
|
116
|
+
primary: 'rgba(245, 158, 11, 0.3)',
|
117
|
+
secondary: 'rgba(217, 119, 6, 0.3)',
|
118
|
+
outline: 'rgba(245, 158, 11, 0.2)',
|
119
|
+
ghost: 'rgba(245, 158, 11, 0.1)',
|
120
|
+
danger: 'rgba(239, 68, 68, 0.3)'
|
121
|
+
};
|
122
|
+
return rippleColors[this.variant];
|
123
|
+
}
|
124
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaguetteButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
125
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: BaguetteButton, isStandalone: true, selector: "baguette-button", inputs: { variant: "variant", size: "size", disabled: "disabled", loading: "loading", fullWidth: "fullWidth", leftIcon: "leftIcon", rightIcon: "rightIcon", ariaLabel: "ariaLabel", ariaDescribedBy: "ariaDescribedBy" }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
|
126
|
+
<button
|
127
|
+
[class]="buttonClasses"
|
128
|
+
[disabled]="disabled || loading"
|
129
|
+
[attr.aria-label]="ariaLabel"
|
130
|
+
[attr.aria-describedby]="ariaDescribedBy"
|
131
|
+
(click)="handleClick($event)"
|
132
|
+
matRipple
|
133
|
+
[matRippleDisabled]="disabled || loading"
|
134
|
+
[matRippleColor]="rippleColor">
|
135
|
+
|
136
|
+
<!-- Loading spinner -->
|
137
|
+
<svg
|
138
|
+
*ngIf="loading"
|
139
|
+
class="animate-spin -ml-1 mr-2 h-4 w-4"
|
140
|
+
xmlns="http://www.w3.org/2000/svg"
|
141
|
+
fill="none"
|
142
|
+
viewBox="0 0 24 24">
|
143
|
+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
144
|
+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
145
|
+
</svg>
|
146
|
+
|
147
|
+
<!-- Left icon -->
|
148
|
+
<span *ngIf="leftIcon && !loading" [innerHTML]="leftIcon" class="mr-2"></span>
|
149
|
+
|
150
|
+
<!-- Button content -->
|
151
|
+
<span [class]="contentClasses">
|
152
|
+
<ng-content></ng-content>
|
153
|
+
</span>
|
154
|
+
|
155
|
+
<!-- Right icon -->
|
156
|
+
<span *ngIf="rightIcon" [innerHTML]="rightIcon" class="ml-2"></span>
|
157
|
+
</button>
|
158
|
+
`, isInline: true, styles: [":host{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i2.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
28
159
|
}
|
29
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaguetteButton, decorators: [{
|
30
161
|
type: Component,
|
31
|
-
args: [{ selector: '
|
162
|
+
args: [{ selector: 'baguette-button', standalone: true, imports: [CommonModule, MatButtonModule, MatRippleModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
163
|
+
<button
|
164
|
+
[class]="buttonClasses"
|
165
|
+
[disabled]="disabled || loading"
|
166
|
+
[attr.aria-label]="ariaLabel"
|
167
|
+
[attr.aria-describedby]="ariaDescribedBy"
|
168
|
+
(click)="handleClick($event)"
|
169
|
+
matRipple
|
170
|
+
[matRippleDisabled]="disabled || loading"
|
171
|
+
[matRippleColor]="rippleColor">
|
172
|
+
|
173
|
+
<!-- Loading spinner -->
|
174
|
+
<svg
|
175
|
+
*ngIf="loading"
|
176
|
+
class="animate-spin -ml-1 mr-2 h-4 w-4"
|
177
|
+
xmlns="http://www.w3.org/2000/svg"
|
178
|
+
fill="none"
|
179
|
+
viewBox="0 0 24 24">
|
180
|
+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
181
|
+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
182
|
+
</svg>
|
183
|
+
|
184
|
+
<!-- Left icon -->
|
185
|
+
<span *ngIf="leftIcon && !loading" [innerHTML]="leftIcon" class="mr-2"></span>
|
186
|
+
|
187
|
+
<!-- Button content -->
|
188
|
+
<span [class]="contentClasses">
|
189
|
+
<ng-content></ng-content>
|
190
|
+
</span>
|
191
|
+
|
192
|
+
<!-- Right icon -->
|
193
|
+
<span *ngIf="rightIcon" [innerHTML]="rightIcon" class="ml-2"></span>
|
194
|
+
</button>
|
195
|
+
`, styles: [":host{display:inline-block}\n"] }]
|
196
|
+
}], propDecorators: { variant: [{
|
197
|
+
type: Input
|
198
|
+
}], size: [{
|
199
|
+
type: Input
|
200
|
+
}], disabled: [{
|
201
|
+
type: Input
|
202
|
+
}], loading: [{
|
203
|
+
type: Input
|
204
|
+
}], fullWidth: [{
|
205
|
+
type: Input
|
206
|
+
}], leftIcon: [{
|
207
|
+
type: Input
|
208
|
+
}], rightIcon: [{
|
209
|
+
type: Input
|
210
|
+
}], ariaLabel: [{
|
211
|
+
type: Input
|
212
|
+
}], ariaDescribedBy: [{
|
213
|
+
type: Input
|
214
|
+
}], clicked: [{
|
215
|
+
type: Output
|
216
|
+
}] } });
|
217
|
+
|
218
|
+
class BagelInput {
|
219
|
+
label;
|
220
|
+
placeholder;
|
221
|
+
type = 'text';
|
222
|
+
size = 'md';
|
223
|
+
disabled = false;
|
224
|
+
readonly = false;
|
225
|
+
required = false;
|
226
|
+
clearable = false;
|
227
|
+
leftIcon;
|
228
|
+
rightIcon;
|
229
|
+
helperText;
|
230
|
+
error;
|
231
|
+
ariaLabel;
|
232
|
+
ariaDescribedBy;
|
233
|
+
autocomplete;
|
234
|
+
maxLength;
|
235
|
+
minLength;
|
236
|
+
min;
|
237
|
+
max;
|
238
|
+
step;
|
239
|
+
showCharCount = false;
|
240
|
+
inputId = `bagel-input-${Math.random().toString(36).substring(2, 9)}`;
|
241
|
+
valueChange = new EventEmitter();
|
242
|
+
inputFocus = new EventEmitter();
|
243
|
+
inputBlur = new EventEmitter();
|
244
|
+
enterPressed = new EventEmitter();
|
245
|
+
value = '';
|
246
|
+
onChange = (value) => { };
|
247
|
+
onTouched = () => { };
|
248
|
+
// ControlValueAccessor implementation
|
249
|
+
writeValue(value) {
|
250
|
+
this.value = value || '';
|
251
|
+
}
|
252
|
+
registerOnChange(fn) {
|
253
|
+
this.onChange = fn;
|
254
|
+
}
|
255
|
+
registerOnTouched(fn) {
|
256
|
+
this.onTouched = fn;
|
257
|
+
}
|
258
|
+
setDisabledState(isDisabled) {
|
259
|
+
this.disabled = isDisabled;
|
260
|
+
}
|
261
|
+
onInput(event) {
|
262
|
+
const target = event.target;
|
263
|
+
this.value = target.value;
|
264
|
+
this.onChange(this.value);
|
265
|
+
this.valueChange.emit(this.value);
|
266
|
+
}
|
267
|
+
onBlur() {
|
268
|
+
this.onTouched();
|
269
|
+
this.inputBlur.emit();
|
270
|
+
}
|
271
|
+
onFocus() {
|
272
|
+
this.inputFocus.emit();
|
273
|
+
}
|
274
|
+
onEnter() {
|
275
|
+
this.enterPressed.emit();
|
276
|
+
}
|
277
|
+
clearValue() {
|
278
|
+
this.value = '';
|
279
|
+
this.onChange(this.value);
|
280
|
+
this.valueChange.emit(this.value);
|
281
|
+
}
|
282
|
+
get labelClasses() {
|
283
|
+
return [
|
284
|
+
'block text-xs font-medium mb-1',
|
285
|
+
this.error ? 'text-red-700' : 'text-amber-800'
|
286
|
+
].join(' ');
|
287
|
+
}
|
288
|
+
get containerClasses() {
|
289
|
+
return 'relative';
|
290
|
+
}
|
291
|
+
get inputClasses() {
|
292
|
+
const baseClasses = [
|
293
|
+
'block w-full rounded-lg border-2 transition-all duration-200',
|
294
|
+
'focus:outline-none focus:ring-2 focus:ring-offset-1',
|
295
|
+
'disabled:opacity-50 disabled:cursor-not-allowed',
|
296
|
+
'placeholder-amber-400'
|
297
|
+
];
|
298
|
+
const sizeClasses = {
|
299
|
+
sm: 'px-2 py-1 text-xs',
|
300
|
+
md: 'px-3 py-1.5 text-sm',
|
301
|
+
lg: 'px-4 py-2 text-base'
|
302
|
+
};
|
303
|
+
const stateClasses = this.error
|
304
|
+
? [
|
305
|
+
'border-red-300 bg-red-50',
|
306
|
+
'focus:border-red-500 focus:ring-red-200',
|
307
|
+
'text-red-900'
|
308
|
+
]
|
309
|
+
: [
|
310
|
+
'border-amber-300 bg-amber-50',
|
311
|
+
'focus:border-amber-500 focus:ring-amber-200',
|
312
|
+
'text-amber-900',
|
313
|
+
'hover:border-amber-400'
|
314
|
+
];
|
315
|
+
const paddingAdjustment = [];
|
316
|
+
if (this.leftIcon)
|
317
|
+
paddingAdjustment.push('pl-10');
|
318
|
+
if (this.rightIcon || this.clearable)
|
319
|
+
paddingAdjustment.push('pr-10');
|
320
|
+
return [
|
321
|
+
...baseClasses,
|
322
|
+
sizeClasses[this.size],
|
323
|
+
...stateClasses,
|
324
|
+
...paddingAdjustment
|
325
|
+
].join(' ');
|
326
|
+
}
|
327
|
+
get helperClasses() {
|
328
|
+
return 'mt-0.5 text-xs text-amber-600';
|
329
|
+
}
|
330
|
+
get errorClasses() {
|
331
|
+
return 'mt-0.5 text-xs text-red-600 flex items-center';
|
332
|
+
}
|
333
|
+
get charCountClasses() {
|
334
|
+
const isNearLimit = this.maxLength && this.value?.length > this.maxLength * 0.8;
|
335
|
+
return [
|
336
|
+
'mt-1 text-xs text-right',
|
337
|
+
isNearLimit ? 'text-red-500' : 'text-amber-500'
|
338
|
+
].join(' ');
|
339
|
+
}
|
340
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BagelInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
341
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: BagelInput, isStandalone: true, selector: "bagel-input", inputs: { label: "label", placeholder: "placeholder", type: "type", size: "size", disabled: "disabled", readonly: "readonly", required: "required", clearable: "clearable", leftIcon: "leftIcon", rightIcon: "rightIcon", helperText: "helperText", error: "error", ariaLabel: "ariaLabel", ariaDescribedBy: "ariaDescribedBy", autocomplete: "autocomplete", maxLength: "maxLength", minLength: "minLength", min: "min", max: "max", step: "step", showCharCount: "showCharCount", inputId: "inputId" }, outputs: { valueChange: "valueChange", inputFocus: "inputFocus", inputBlur: "inputBlur", enterPressed: "enterPressed" }, providers: [
|
342
|
+
{
|
343
|
+
provide: NG_VALUE_ACCESSOR,
|
344
|
+
useExisting: forwardRef(() => BagelInput),
|
345
|
+
multi: true
|
346
|
+
}
|
347
|
+
], ngImport: i0, template: `
|
348
|
+
<div class="w-full">
|
349
|
+
<!-- Label -->
|
350
|
+
<label
|
351
|
+
*ngIf="label"
|
352
|
+
[for]="inputId"
|
353
|
+
[class]="labelClasses">
|
354
|
+
{{ label }}
|
355
|
+
<span *ngIf="required" class="text-red-500 ml-1">*</span>
|
356
|
+
</label>
|
357
|
+
|
358
|
+
<!-- Input Container -->
|
359
|
+
<div [class]="containerClasses">
|
360
|
+
<!-- Left Icon -->
|
361
|
+
<div *ngIf="leftIcon" class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
362
|
+
<span [innerHTML]="leftIcon" class="text-amber-600"></span>
|
363
|
+
</div>
|
364
|
+
|
365
|
+
<!-- Input Field -->
|
366
|
+
<input
|
367
|
+
[id]="inputId"
|
368
|
+
[type]="type"
|
369
|
+
[value]="value"
|
370
|
+
[placeholder]="placeholder"
|
371
|
+
[disabled]="disabled"
|
372
|
+
[readonly]="readonly"
|
373
|
+
[class]="inputClasses"
|
374
|
+
[attr.aria-label]="ariaLabel"
|
375
|
+
[attr.aria-describedby]="ariaDescribedBy"
|
376
|
+
[attr.autocomplete]="autocomplete"
|
377
|
+
[attr.maxlength]="maxLength"
|
378
|
+
[attr.minlength]="minLength"
|
379
|
+
[attr.min]="min"
|
380
|
+
[attr.max]="max"
|
381
|
+
[attr.step]="step"
|
382
|
+
(input)="onInput($event)"
|
383
|
+
(blur)="onBlur()"
|
384
|
+
(focus)="onFocus()"
|
385
|
+
(keyup.enter)="onEnter()"
|
386
|
+
/>
|
387
|
+
|
388
|
+
<!-- Right Icon / Clear Button -->
|
389
|
+
<div *ngIf="rightIcon || (clearable && value)" class="absolute inset-y-0 right-0 flex items-center">
|
390
|
+
<button
|
391
|
+
*ngIf="clearable && value && !disabled"
|
392
|
+
type="button"
|
393
|
+
class="pr-3 text-amber-600 hover:text-amber-700 focus:outline-none"
|
394
|
+
(click)="clearValue()"
|
395
|
+
[attr.aria-label]="'Clear ' + (label || 'input')">
|
396
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
397
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
398
|
+
</svg>
|
399
|
+
</button>
|
400
|
+
<span
|
401
|
+
*ngIf="rightIcon"
|
402
|
+
[innerHTML]="rightIcon"
|
403
|
+
class="pr-3 text-amber-600"></span>
|
404
|
+
</div>
|
405
|
+
</div>
|
406
|
+
|
407
|
+
<!-- Helper Text -->
|
408
|
+
<p *ngIf="helperText && !error" [class]="helperClasses">
|
409
|
+
{{ helperText }}
|
410
|
+
</p>
|
411
|
+
|
412
|
+
<!-- Error Message -->
|
413
|
+
<p *ngIf="error" [class]="errorClasses">
|
414
|
+
{{ error }}
|
415
|
+
</p>
|
416
|
+
|
417
|
+
<!-- Character Count -->
|
418
|
+
<p *ngIf="maxLength && showCharCount" [class]="charCountClasses">
|
419
|
+
{{ value?.length || 0 }}/{{ maxLength }}
|
420
|
+
</p>
|
421
|
+
</div>
|
422
|
+
`, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
423
|
+
}
|
424
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BagelInput, decorators: [{
|
425
|
+
type: Component,
|
426
|
+
args: [{ selector: 'bagel-input', standalone: true, imports: [CommonModule, MatFormFieldModule, MatInputModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
427
|
+
{
|
428
|
+
provide: NG_VALUE_ACCESSOR,
|
429
|
+
useExisting: forwardRef(() => BagelInput),
|
430
|
+
multi: true
|
431
|
+
}
|
432
|
+
], template: `
|
433
|
+
<div class="w-full">
|
434
|
+
<!-- Label -->
|
435
|
+
<label
|
436
|
+
*ngIf="label"
|
437
|
+
[for]="inputId"
|
438
|
+
[class]="labelClasses">
|
439
|
+
{{ label }}
|
440
|
+
<span *ngIf="required" class="text-red-500 ml-1">*</span>
|
441
|
+
</label>
|
442
|
+
|
443
|
+
<!-- Input Container -->
|
444
|
+
<div [class]="containerClasses">
|
445
|
+
<!-- Left Icon -->
|
446
|
+
<div *ngIf="leftIcon" class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
447
|
+
<span [innerHTML]="leftIcon" class="text-amber-600"></span>
|
448
|
+
</div>
|
449
|
+
|
450
|
+
<!-- Input Field -->
|
451
|
+
<input
|
452
|
+
[id]="inputId"
|
453
|
+
[type]="type"
|
454
|
+
[value]="value"
|
455
|
+
[placeholder]="placeholder"
|
456
|
+
[disabled]="disabled"
|
457
|
+
[readonly]="readonly"
|
458
|
+
[class]="inputClasses"
|
459
|
+
[attr.aria-label]="ariaLabel"
|
460
|
+
[attr.aria-describedby]="ariaDescribedBy"
|
461
|
+
[attr.autocomplete]="autocomplete"
|
462
|
+
[attr.maxlength]="maxLength"
|
463
|
+
[attr.minlength]="minLength"
|
464
|
+
[attr.min]="min"
|
465
|
+
[attr.max]="max"
|
466
|
+
[attr.step]="step"
|
467
|
+
(input)="onInput($event)"
|
468
|
+
(blur)="onBlur()"
|
469
|
+
(focus)="onFocus()"
|
470
|
+
(keyup.enter)="onEnter()"
|
471
|
+
/>
|
472
|
+
|
473
|
+
<!-- Right Icon / Clear Button -->
|
474
|
+
<div *ngIf="rightIcon || (clearable && value)" class="absolute inset-y-0 right-0 flex items-center">
|
475
|
+
<button
|
476
|
+
*ngIf="clearable && value && !disabled"
|
477
|
+
type="button"
|
478
|
+
class="pr-3 text-amber-600 hover:text-amber-700 focus:outline-none"
|
479
|
+
(click)="clearValue()"
|
480
|
+
[attr.aria-label]="'Clear ' + (label || 'input')">
|
481
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
482
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
483
|
+
</svg>
|
484
|
+
</button>
|
485
|
+
<span
|
486
|
+
*ngIf="rightIcon"
|
487
|
+
[innerHTML]="rightIcon"
|
488
|
+
class="pr-3 text-amber-600"></span>
|
489
|
+
</div>
|
490
|
+
</div>
|
491
|
+
|
492
|
+
<!-- Helper Text -->
|
493
|
+
<p *ngIf="helperText && !error" [class]="helperClasses">
|
494
|
+
{{ helperText }}
|
495
|
+
</p>
|
496
|
+
|
497
|
+
<!-- Error Message -->
|
498
|
+
<p *ngIf="error" [class]="errorClasses">
|
499
|
+
{{ error }}
|
500
|
+
</p>
|
501
|
+
|
502
|
+
<!-- Character Count -->
|
503
|
+
<p *ngIf="maxLength && showCharCount" [class]="charCountClasses">
|
504
|
+
{{ value?.length || 0 }}/{{ maxLength }}
|
505
|
+
</p>
|
506
|
+
</div>
|
507
|
+
`, styles: [":host{display:block;width:100%}\n"] }]
|
32
508
|
}], propDecorators: { label: [{
|
33
509
|
type: Input
|
34
|
-
}],
|
510
|
+
}], placeholder: [{
|
511
|
+
type: Input
|
512
|
+
}], type: [{
|
513
|
+
type: Input
|
514
|
+
}], size: [{
|
515
|
+
type: Input
|
516
|
+
}], disabled: [{
|
517
|
+
type: Input
|
518
|
+
}], readonly: [{
|
519
|
+
type: Input
|
520
|
+
}], required: [{
|
521
|
+
type: Input
|
522
|
+
}], clearable: [{
|
523
|
+
type: Input
|
524
|
+
}], leftIcon: [{
|
525
|
+
type: Input
|
526
|
+
}], rightIcon: [{
|
527
|
+
type: Input
|
528
|
+
}], helperText: [{
|
529
|
+
type: Input
|
530
|
+
}], error: [{
|
531
|
+
type: Input
|
532
|
+
}], ariaLabel: [{
|
533
|
+
type: Input
|
534
|
+
}], ariaDescribedBy: [{
|
535
|
+
type: Input
|
536
|
+
}], autocomplete: [{
|
537
|
+
type: Input
|
538
|
+
}], maxLength: [{
|
539
|
+
type: Input
|
540
|
+
}], minLength: [{
|
541
|
+
type: Input
|
542
|
+
}], min: [{
|
543
|
+
type: Input
|
544
|
+
}], max: [{
|
545
|
+
type: Input
|
546
|
+
}], step: [{
|
547
|
+
type: Input
|
548
|
+
}], showCharCount: [{
|
549
|
+
type: Input
|
550
|
+
}], inputId: [{
|
551
|
+
type: Input
|
552
|
+
}], valueChange: [{
|
553
|
+
type: Output
|
554
|
+
}], inputFocus: [{
|
555
|
+
type: Output
|
556
|
+
}], inputBlur: [{
|
557
|
+
type: Output
|
558
|
+
}], enterPressed: [{
|
559
|
+
type: Output
|
560
|
+
}] } });
|
561
|
+
|
562
|
+
class CupcakeCard {
|
563
|
+
variant = 'default';
|
564
|
+
size = 'md';
|
565
|
+
title;
|
566
|
+
subtitle;
|
567
|
+
image;
|
568
|
+
imageAlt;
|
569
|
+
imageLoading = 'lazy';
|
570
|
+
imageBadge;
|
571
|
+
avatar;
|
572
|
+
avatarAlt;
|
573
|
+
clickable = false;
|
574
|
+
disabled = false;
|
575
|
+
loading = false;
|
576
|
+
headerAction = false;
|
577
|
+
hasHeader = false;
|
578
|
+
hasFooter = false;
|
579
|
+
ariaLabel;
|
580
|
+
fullWidth = false;
|
581
|
+
cardClick = new EventEmitter();
|
582
|
+
handleClick(event) {
|
583
|
+
if (this.clickable && !this.disabled && !this.loading) {
|
584
|
+
this.cardClick.emit(event);
|
585
|
+
}
|
586
|
+
}
|
587
|
+
get cardClasses() {
|
588
|
+
const baseClasses = [
|
589
|
+
'rounded-xl overflow-hidden transition-all duration-200',
|
590
|
+
'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-amber-500'
|
591
|
+
];
|
592
|
+
const sizeClasses = {
|
593
|
+
sm: 'max-w-xs',
|
594
|
+
md: 'max-w-sm',
|
595
|
+
lg: 'max-w-md'
|
596
|
+
};
|
597
|
+
const variantClasses = {
|
598
|
+
default: [
|
599
|
+
'bg-white border border-amber-200',
|
600
|
+
'hover:border-amber-300 hover:shadow-md'
|
601
|
+
],
|
602
|
+
outlined: [
|
603
|
+
'bg-transparent border-2 border-amber-300',
|
604
|
+
'hover:border-amber-400 hover:bg-amber-50'
|
605
|
+
],
|
606
|
+
elevated: [
|
607
|
+
'bg-white shadow-lg shadow-amber-100',
|
608
|
+
'hover:shadow-xl hover:shadow-amber-200',
|
609
|
+
'border border-amber-100'
|
610
|
+
],
|
611
|
+
filled: [
|
612
|
+
'bg-gradient-to-br from-amber-50 to-orange-50',
|
613
|
+
'border border-amber-200',
|
614
|
+
'hover:from-amber-100 hover:to-orange-100'
|
615
|
+
]
|
616
|
+
};
|
617
|
+
const interactionClasses = [];
|
618
|
+
if (this.clickable) {
|
619
|
+
interactionClasses.push('cursor-pointer', 'hover:transform hover:scale-105', 'active:scale-95');
|
620
|
+
}
|
621
|
+
if (this.disabled) {
|
622
|
+
interactionClasses.push('opacity-50 cursor-not-allowed');
|
623
|
+
}
|
624
|
+
if (this.loading) {
|
625
|
+
interactionClasses.push('opacity-70 cursor-wait');
|
626
|
+
}
|
627
|
+
const classes = [
|
628
|
+
...baseClasses,
|
629
|
+
...variantClasses[this.variant],
|
630
|
+
...interactionClasses
|
631
|
+
];
|
632
|
+
if (!this.fullWidth) {
|
633
|
+
classes.push(sizeClasses[this.size]);
|
634
|
+
}
|
635
|
+
return classes.join(' ');
|
636
|
+
}
|
637
|
+
get headerClasses() {
|
638
|
+
const sizeClasses = {
|
639
|
+
sm: 'p-2 pb-1',
|
640
|
+
md: 'p-3 pb-2',
|
641
|
+
lg: 'p-4 pb-2'
|
642
|
+
};
|
643
|
+
return [
|
644
|
+
'border-b border-amber-100',
|
645
|
+
sizeClasses[this.size]
|
646
|
+
].join(' ');
|
647
|
+
}
|
648
|
+
get contentClasses() {
|
649
|
+
const sizeClasses = {
|
650
|
+
sm: 'p-2',
|
651
|
+
md: 'p-3',
|
652
|
+
lg: 'p-4'
|
653
|
+
};
|
654
|
+
const spacingClasses = [];
|
655
|
+
if (this.hasHeader && !this.image)
|
656
|
+
spacingClasses.push('pt-2');
|
657
|
+
if (this.hasFooter)
|
658
|
+
spacingClasses.push('pb-2');
|
659
|
+
if (this.image && !this.hasHeader)
|
660
|
+
spacingClasses.push('pt-0');
|
661
|
+
return [
|
662
|
+
sizeClasses[this.size],
|
663
|
+
...spacingClasses
|
664
|
+
].join(' ');
|
665
|
+
}
|
666
|
+
get footerClasses() {
|
667
|
+
const sizeClasses = {
|
668
|
+
sm: 'p-2 pt-1',
|
669
|
+
md: 'p-3 pt-2',
|
670
|
+
lg: 'p-4 pt-2'
|
671
|
+
};
|
672
|
+
return [
|
673
|
+
'border-t border-amber-100',
|
674
|
+
sizeClasses[this.size]
|
675
|
+
].join(' ');
|
676
|
+
}
|
677
|
+
get imageClasses() {
|
678
|
+
return [
|
679
|
+
'w-full h-32 object-cover',
|
680
|
+
'transition-transform duration-200',
|
681
|
+
this.clickable ? 'hover:scale-105' : ''
|
682
|
+
].join(' ');
|
683
|
+
}
|
684
|
+
get rippleColor() {
|
685
|
+
return 'rgba(245, 158, 11, 0.2)';
|
686
|
+
}
|
687
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CupcakeCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
688
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: CupcakeCard, isStandalone: true, selector: "cupcake-card", inputs: { variant: "variant", size: "size", title: "title", subtitle: "subtitle", image: "image", imageAlt: "imageAlt", imageLoading: "imageLoading", imageBadge: "imageBadge", avatar: "avatar", avatarAlt: "avatarAlt", clickable: "clickable", disabled: "disabled", loading: "loading", headerAction: "headerAction", hasHeader: "hasHeader", hasFooter: "hasFooter", ariaLabel: "ariaLabel", fullWidth: "fullWidth" }, outputs: { cardClick: "cardClick" }, ngImport: i0, template: `
|
689
|
+
<div
|
690
|
+
[class]="cardClasses"
|
691
|
+
[attr.role]="clickable ? 'button' : null"
|
692
|
+
[attr.tabindex]="clickable ? 0 : null"
|
693
|
+
[attr.aria-label]="ariaLabel"
|
694
|
+
(click)="handleClick($event)"
|
695
|
+
(keyup.enter)="handleClick($event)"
|
696
|
+
(keyup.space)="handleClick($event)"
|
697
|
+
matRipple
|
698
|
+
[matRippleDisabled]="!clickable"
|
699
|
+
[matRippleColor]="rippleColor">
|
700
|
+
|
701
|
+
<!-- Header -->
|
702
|
+
<div *ngIf="hasHeader" [class]="headerClasses">
|
703
|
+
<div class="flex items-center justify-between">
|
704
|
+
<div class="flex items-center space-x-3">
|
705
|
+
<div *ngIf="avatar" class="flex-shrink-0">
|
706
|
+
<img [src]="avatar" [alt]="avatarAlt" class="w-10 h-10 rounded-full object-cover">
|
707
|
+
</div>
|
708
|
+
<div>
|
709
|
+
<h3 *ngIf="title" class="text-lg font-semibold text-amber-900">{{ title }}</h3>
|
710
|
+
<p *ngIf="subtitle" class="text-sm text-amber-600">{{ subtitle }}</p>
|
711
|
+
</div>
|
712
|
+
</div>
|
713
|
+
<div *ngIf="headerAction" class="flex-shrink-0">
|
714
|
+
<ng-content select="[slot=header-action]"></ng-content>
|
715
|
+
</div>
|
716
|
+
</div>
|
717
|
+
</div>
|
718
|
+
|
719
|
+
<!-- Image -->
|
720
|
+
<div *ngIf="image" class="relative overflow-hidden">
|
721
|
+
<img
|
722
|
+
[src]="image"
|
723
|
+
[alt]="imageAlt"
|
724
|
+
[class]="imageClasses"
|
725
|
+
[loading]="imageLoading">
|
726
|
+
<div *ngIf="imageBadge" class="absolute top-2 right-2">
|
727
|
+
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800">
|
728
|
+
{{ imageBadge }}
|
729
|
+
</span>
|
730
|
+
</div>
|
731
|
+
</div>
|
732
|
+
|
733
|
+
<!-- Content -->
|
734
|
+
<div [class]="contentClasses">
|
735
|
+
<ng-content></ng-content>
|
736
|
+
</div>
|
737
|
+
|
738
|
+
<!-- Footer -->
|
739
|
+
<div *ngIf="hasFooter" [class]="footerClasses">
|
740
|
+
<ng-content select="[slot=footer]"></ng-content>
|
741
|
+
</div>
|
742
|
+
</div>
|
743
|
+
`, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i2.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
744
|
+
}
|
745
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CupcakeCard, decorators: [{
|
746
|
+
type: Component,
|
747
|
+
args: [{ selector: 'cupcake-card', standalone: true, imports: [CommonModule, MatCardModule, MatRippleModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
748
|
+
<div
|
749
|
+
[class]="cardClasses"
|
750
|
+
[attr.role]="clickable ? 'button' : null"
|
751
|
+
[attr.tabindex]="clickable ? 0 : null"
|
752
|
+
[attr.aria-label]="ariaLabel"
|
753
|
+
(click)="handleClick($event)"
|
754
|
+
(keyup.enter)="handleClick($event)"
|
755
|
+
(keyup.space)="handleClick($event)"
|
756
|
+
matRipple
|
757
|
+
[matRippleDisabled]="!clickable"
|
758
|
+
[matRippleColor]="rippleColor">
|
759
|
+
|
760
|
+
<!-- Header -->
|
761
|
+
<div *ngIf="hasHeader" [class]="headerClasses">
|
762
|
+
<div class="flex items-center justify-between">
|
763
|
+
<div class="flex items-center space-x-3">
|
764
|
+
<div *ngIf="avatar" class="flex-shrink-0">
|
765
|
+
<img [src]="avatar" [alt]="avatarAlt" class="w-10 h-10 rounded-full object-cover">
|
766
|
+
</div>
|
767
|
+
<div>
|
768
|
+
<h3 *ngIf="title" class="text-lg font-semibold text-amber-900">{{ title }}</h3>
|
769
|
+
<p *ngIf="subtitle" class="text-sm text-amber-600">{{ subtitle }}</p>
|
770
|
+
</div>
|
771
|
+
</div>
|
772
|
+
<div *ngIf="headerAction" class="flex-shrink-0">
|
773
|
+
<ng-content select="[slot=header-action]"></ng-content>
|
774
|
+
</div>
|
775
|
+
</div>
|
776
|
+
</div>
|
777
|
+
|
778
|
+
<!-- Image -->
|
779
|
+
<div *ngIf="image" class="relative overflow-hidden">
|
780
|
+
<img
|
781
|
+
[src]="image"
|
782
|
+
[alt]="imageAlt"
|
783
|
+
[class]="imageClasses"
|
784
|
+
[loading]="imageLoading">
|
785
|
+
<div *ngIf="imageBadge" class="absolute top-2 right-2">
|
786
|
+
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800">
|
787
|
+
{{ imageBadge }}
|
788
|
+
</span>
|
789
|
+
</div>
|
790
|
+
</div>
|
791
|
+
|
792
|
+
<!-- Content -->
|
793
|
+
<div [class]="contentClasses">
|
794
|
+
<ng-content></ng-content>
|
795
|
+
</div>
|
796
|
+
|
797
|
+
<!-- Footer -->
|
798
|
+
<div *ngIf="hasFooter" [class]="footerClasses">
|
799
|
+
<ng-content select="[slot=footer]"></ng-content>
|
800
|
+
</div>
|
801
|
+
</div>
|
802
|
+
`, styles: [":host{display:block;width:100%}\n"] }]
|
803
|
+
}], propDecorators: { variant: [{
|
35
804
|
type: Input
|
36
805
|
}], size: [{
|
37
806
|
type: Input
|
807
|
+
}], title: [{
|
808
|
+
type: Input
|
809
|
+
}], subtitle: [{
|
810
|
+
type: Input
|
811
|
+
}], image: [{
|
812
|
+
type: Input
|
813
|
+
}], imageAlt: [{
|
814
|
+
type: Input
|
815
|
+
}], imageLoading: [{
|
816
|
+
type: Input
|
817
|
+
}], imageBadge: [{
|
818
|
+
type: Input
|
819
|
+
}], avatar: [{
|
820
|
+
type: Input
|
821
|
+
}], avatarAlt: [{
|
822
|
+
type: Input
|
823
|
+
}], clickable: [{
|
824
|
+
type: Input
|
38
825
|
}], disabled: [{
|
39
826
|
type: Input
|
827
|
+
}], loading: [{
|
828
|
+
type: Input
|
829
|
+
}], headerAction: [{
|
830
|
+
type: Input
|
831
|
+
}], hasHeader: [{
|
832
|
+
type: Input
|
833
|
+
}], hasFooter: [{
|
834
|
+
type: Input
|
835
|
+
}], ariaLabel: [{
|
836
|
+
type: Input
|
837
|
+
}], fullWidth: [{
|
838
|
+
type: Input
|
839
|
+
}], cardClick: [{
|
840
|
+
type: Output
|
841
|
+
}] } });
|
842
|
+
|
843
|
+
class ToastNotification {
|
844
|
+
type = 'info';
|
845
|
+
title;
|
846
|
+
message = '';
|
847
|
+
duration = 5000; // 5 seconds
|
848
|
+
closable = true;
|
849
|
+
actionText;
|
850
|
+
position = 'top-right';
|
851
|
+
persistent = false; // Don't auto-hide
|
852
|
+
visible = true;
|
853
|
+
closed = new EventEmitter();
|
854
|
+
action = new EventEmitter();
|
855
|
+
timeoutId;
|
856
|
+
ngOnInit() {
|
857
|
+
if (!this.persistent && this.duration > 0) {
|
858
|
+
this.timeoutId = window.setTimeout(() => {
|
859
|
+
this.onClose();
|
860
|
+
}, this.duration);
|
861
|
+
}
|
862
|
+
}
|
863
|
+
ngOnDestroy() {
|
864
|
+
if (this.timeoutId) {
|
865
|
+
clearTimeout(this.timeoutId);
|
866
|
+
}
|
867
|
+
}
|
868
|
+
onClose() {
|
869
|
+
this.visible = false;
|
870
|
+
this.closed.emit();
|
871
|
+
}
|
872
|
+
onAction() {
|
873
|
+
this.action.emit();
|
874
|
+
}
|
875
|
+
get toastClasses() {
|
876
|
+
const baseClasses = [
|
877
|
+
'max-w-xs w-full bg-white shadow-md rounded-md pointer-events-auto',
|
878
|
+
'ring-1 ring-black ring-opacity-5 overflow-hidden',
|
879
|
+
'transition-all duration-300 ease-in-out'
|
880
|
+
];
|
881
|
+
const typeClasses = {
|
882
|
+
success: 'border-l-2 border-green-400',
|
883
|
+
error: 'border-l-2 border-red-400',
|
884
|
+
warning: 'border-l-2 border-yellow-400',
|
885
|
+
info: 'border-l-2 border-blue-400'
|
886
|
+
};
|
887
|
+
return [
|
888
|
+
...baseClasses,
|
889
|
+
typeClasses[this.type],
|
890
|
+
'p-2'
|
891
|
+
].join(' ');
|
892
|
+
}
|
893
|
+
get iconClasses() {
|
894
|
+
const baseClasses = 'h-4 w-4';
|
895
|
+
const typeClasses = {
|
896
|
+
success: 'text-green-400',
|
897
|
+
error: 'text-red-400',
|
898
|
+
warning: 'text-yellow-400',
|
899
|
+
info: 'text-blue-400'
|
900
|
+
};
|
901
|
+
return [baseClasses, typeClasses[this.type]].join(' ');
|
902
|
+
}
|
903
|
+
get titleClasses() {
|
904
|
+
return 'text-xs font-medium text-gray-900';
|
905
|
+
}
|
906
|
+
get messageClasses() {
|
907
|
+
return this.title ? 'mt-0.5 text-xs text-gray-500' : 'text-xs text-gray-900';
|
908
|
+
}
|
909
|
+
get actionButtonClasses() {
|
910
|
+
const typeClasses = {
|
911
|
+
success: 'text-green-600 hover:text-green-500 focus:ring-green-500',
|
912
|
+
error: 'text-red-600 hover:text-red-500 focus:ring-red-500',
|
913
|
+
warning: 'text-yellow-600 hover:text-yellow-500 focus:ring-yellow-500',
|
914
|
+
info: 'text-blue-600 hover:text-blue-500 focus:ring-blue-500'
|
915
|
+
};
|
916
|
+
return [
|
917
|
+
'text-sm font-medium rounded-md',
|
918
|
+
'focus:outline-none focus:ring-2 focus:ring-offset-2',
|
919
|
+
'transition-colors duration-200',
|
920
|
+
typeClasses[this.type]
|
921
|
+
].join(' ');
|
922
|
+
}
|
923
|
+
get closeButtonClasses() {
|
924
|
+
return [
|
925
|
+
'bg-white rounded-md inline-flex text-gray-400',
|
926
|
+
'hover:text-gray-500 focus:outline-none',
|
927
|
+
'focus:ring-2 focus:ring-offset-2 focus:ring-amber-500',
|
928
|
+
'transition-colors duration-200'
|
929
|
+
].join(' ');
|
930
|
+
}
|
931
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ToastNotification, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
932
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ToastNotification, isStandalone: true, selector: "toast-notification", inputs: { type: "type", title: "title", message: "message", duration: "duration", closable: "closable", actionText: "actionText", position: "position", persistent: "persistent", visible: "visible" }, outputs: { closed: "closed", action: "action" }, ngImport: i0, template: `
|
933
|
+
<div
|
934
|
+
*ngIf="visible"
|
935
|
+
[@slideIn]
|
936
|
+
[class]="toastClasses"
|
937
|
+
[attr.role]="'alert'"
|
938
|
+
[attr.aria-live]="'polite'"
|
939
|
+
[attr.aria-atomic]="'true'">
|
940
|
+
|
941
|
+
<!-- Icon -->
|
942
|
+
<div class="flex-shrink-0">
|
943
|
+
<svg [class]="iconClasses" fill="currentColor" viewBox="0 0 20 20">
|
944
|
+
<!-- Success Icon -->
|
945
|
+
<path *ngIf="type === 'success'"
|
946
|
+
fill-rule="evenodd"
|
947
|
+
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
|
948
|
+
clip-rule="evenodd" />
|
949
|
+
|
950
|
+
<!-- Error Icon -->
|
951
|
+
<path *ngIf="type === 'error'"
|
952
|
+
fill-rule="evenodd"
|
953
|
+
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
954
|
+
clip-rule="evenodd" />
|
955
|
+
|
956
|
+
<!-- Warning Icon -->
|
957
|
+
<path *ngIf="type === 'warning'"
|
958
|
+
fill-rule="evenodd"
|
959
|
+
d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
|
960
|
+
clip-rule="evenodd" />
|
961
|
+
|
962
|
+
<!-- Info Icon -->
|
963
|
+
<path *ngIf="type === 'info'"
|
964
|
+
fill-rule="evenodd"
|
965
|
+
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
|
966
|
+
clip-rule="evenodd" />
|
967
|
+
</svg>
|
968
|
+
</div>
|
969
|
+
|
970
|
+
<!-- Content -->
|
971
|
+
<div class="ml-2 flex-1">
|
972
|
+
<h4 *ngIf="title" [class]="titleClasses">{{ title }}</h4>
|
973
|
+
<p [class]="messageClasses">{{ message }}</p>
|
974
|
+
|
975
|
+
<!-- Action Button -->
|
976
|
+
<div *ngIf="actionText" class="mt-1">
|
977
|
+
<button
|
978
|
+
type="button"
|
979
|
+
[class]="actionButtonClasses"
|
980
|
+
(click)="onAction()">
|
981
|
+
{{ actionText }}
|
982
|
+
</button>
|
983
|
+
</div>
|
984
|
+
</div>
|
985
|
+
|
986
|
+
<!-- Close Button -->
|
987
|
+
<div *ngIf="closable" class="ml-2 flex-shrink-0 flex">
|
988
|
+
<button
|
989
|
+
type="button"
|
990
|
+
[class]="closeButtonClasses"
|
991
|
+
(click)="onClose()"
|
992
|
+
[attr.aria-label]="'Close notification'">
|
993
|
+
<svg class="h-3 w-3" viewBox="0 0 20 20" fill="currentColor">
|
994
|
+
<path fill-rule="evenodd"
|
995
|
+
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
996
|
+
clip-rule="evenodd" />
|
997
|
+
</svg>
|
998
|
+
</button>
|
999
|
+
</div>
|
1000
|
+
</div>
|
1001
|
+
`, isInline: true, styles: [":host{display:block;position:fixed;z-index:1000}:host(.top-right){top:1rem;right:1rem}:host(.top-left){top:1rem;left:1rem}:host(.bottom-right){bottom:1rem;right:1rem}:host(.bottom-left){bottom:1rem;left:1rem}:host(.top-center){top:1rem;left:50%;transform:translate(-50%)}:host(.bottom-center){bottom:1rem;left:50%;transform:translate(-50%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatSnackBarModule }], animations: [
|
1002
|
+
trigger('slideIn', [
|
1003
|
+
state('in', style({ transform: 'translateX(0)', opacity: 1 })),
|
1004
|
+
transition('void => *', [
|
1005
|
+
style({ transform: 'translateX(100%)', opacity: 0 }),
|
1006
|
+
animate('300ms ease-in-out')
|
1007
|
+
]),
|
1008
|
+
transition('* => void', [
|
1009
|
+
animate('300ms ease-in-out', style({ transform: 'translateX(100%)', opacity: 0 }))
|
1010
|
+
])
|
1011
|
+
])
|
1012
|
+
], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
1013
|
+
}
|
1014
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ToastNotification, decorators: [{
|
1015
|
+
type: Component,
|
1016
|
+
args: [{ selector: 'toast-notification', standalone: true, imports: [CommonModule, MatSnackBarModule], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
|
1017
|
+
trigger('slideIn', [
|
1018
|
+
state('in', style({ transform: 'translateX(0)', opacity: 1 })),
|
1019
|
+
transition('void => *', [
|
1020
|
+
style({ transform: 'translateX(100%)', opacity: 0 }),
|
1021
|
+
animate('300ms ease-in-out')
|
1022
|
+
]),
|
1023
|
+
transition('* => void', [
|
1024
|
+
animate('300ms ease-in-out', style({ transform: 'translateX(100%)', opacity: 0 }))
|
1025
|
+
])
|
1026
|
+
])
|
1027
|
+
], template: `
|
1028
|
+
<div
|
1029
|
+
*ngIf="visible"
|
1030
|
+
[@slideIn]
|
1031
|
+
[class]="toastClasses"
|
1032
|
+
[attr.role]="'alert'"
|
1033
|
+
[attr.aria-live]="'polite'"
|
1034
|
+
[attr.aria-atomic]="'true'">
|
1035
|
+
|
1036
|
+
<!-- Icon -->
|
1037
|
+
<div class="flex-shrink-0">
|
1038
|
+
<svg [class]="iconClasses" fill="currentColor" viewBox="0 0 20 20">
|
1039
|
+
<!-- Success Icon -->
|
1040
|
+
<path *ngIf="type === 'success'"
|
1041
|
+
fill-rule="evenodd"
|
1042
|
+
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
|
1043
|
+
clip-rule="evenodd" />
|
1044
|
+
|
1045
|
+
<!-- Error Icon -->
|
1046
|
+
<path *ngIf="type === 'error'"
|
1047
|
+
fill-rule="evenodd"
|
1048
|
+
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
1049
|
+
clip-rule="evenodd" />
|
1050
|
+
|
1051
|
+
<!-- Warning Icon -->
|
1052
|
+
<path *ngIf="type === 'warning'"
|
1053
|
+
fill-rule="evenodd"
|
1054
|
+
d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
|
1055
|
+
clip-rule="evenodd" />
|
1056
|
+
|
1057
|
+
<!-- Info Icon -->
|
1058
|
+
<path *ngIf="type === 'info'"
|
1059
|
+
fill-rule="evenodd"
|
1060
|
+
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
|
1061
|
+
clip-rule="evenodd" />
|
1062
|
+
</svg>
|
1063
|
+
</div>
|
1064
|
+
|
1065
|
+
<!-- Content -->
|
1066
|
+
<div class="ml-2 flex-1">
|
1067
|
+
<h4 *ngIf="title" [class]="titleClasses">{{ title }}</h4>
|
1068
|
+
<p [class]="messageClasses">{{ message }}</p>
|
1069
|
+
|
1070
|
+
<!-- Action Button -->
|
1071
|
+
<div *ngIf="actionText" class="mt-1">
|
1072
|
+
<button
|
1073
|
+
type="button"
|
1074
|
+
[class]="actionButtonClasses"
|
1075
|
+
(click)="onAction()">
|
1076
|
+
{{ actionText }}
|
1077
|
+
</button>
|
1078
|
+
</div>
|
1079
|
+
</div>
|
1080
|
+
|
1081
|
+
<!-- Close Button -->
|
1082
|
+
<div *ngIf="closable" class="ml-2 flex-shrink-0 flex">
|
1083
|
+
<button
|
1084
|
+
type="button"
|
1085
|
+
[class]="closeButtonClasses"
|
1086
|
+
(click)="onClose()"
|
1087
|
+
[attr.aria-label]="'Close notification'">
|
1088
|
+
<svg class="h-3 w-3" viewBox="0 0 20 20" fill="currentColor">
|
1089
|
+
<path fill-rule="evenodd"
|
1090
|
+
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
1091
|
+
clip-rule="evenodd" />
|
1092
|
+
</svg>
|
1093
|
+
</button>
|
1094
|
+
</div>
|
1095
|
+
</div>
|
1096
|
+
`, styles: [":host{display:block;position:fixed;z-index:1000}:host(.top-right){top:1rem;right:1rem}:host(.top-left){top:1rem;left:1rem}:host(.bottom-right){bottom:1rem;right:1rem}:host(.bottom-left){bottom:1rem;left:1rem}:host(.top-center){top:1rem;left:50%;transform:translate(-50%)}:host(.bottom-center){bottom:1rem;left:50%;transform:translate(-50%)}\n"] }]
|
1097
|
+
}], propDecorators: { type: [{
|
1098
|
+
type: Input
|
1099
|
+
}], title: [{
|
1100
|
+
type: Input
|
1101
|
+
}], message: [{
|
1102
|
+
type: Input
|
1103
|
+
}], duration: [{
|
1104
|
+
type: Input
|
1105
|
+
}], closable: [{
|
1106
|
+
type: Input
|
1107
|
+
}], actionText: [{
|
1108
|
+
type: Input
|
1109
|
+
}], position: [{
|
1110
|
+
type: Input
|
1111
|
+
}], persistent: [{
|
1112
|
+
type: Input
|
1113
|
+
}], visible: [{
|
1114
|
+
type: Input
|
1115
|
+
}], closed: [{
|
1116
|
+
type: Output
|
1117
|
+
}], action: [{
|
1118
|
+
type: Output
|
40
1119
|
}] } });
|
41
1120
|
|
42
1121
|
/*
|
@@ -47,5 +1126,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImpor
|
|
47
1126
|
* Generated bundle index. Do not edit.
|
48
1127
|
*/
|
49
1128
|
|
50
|
-
export { BakeryUi,
|
1129
|
+
export { BagelInput, BaguetteButton, BakeryUi, CupcakeCard, ToastNotification };
|
51
1130
|
//# sourceMappingURL=bakery-ui.mjs.map
|