@tolle_/tolle-ui 0.0.18-beta → 0.0.21-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/alert.component.mjs +116 -0
- package/esm2022/lib/avatar-fallback.component.mjs +19 -0
- package/esm2022/lib/avatar.component.mjs +86 -0
- package/esm2022/lib/badge.component.mjs +4 -4
- package/esm2022/lib/breadcrumb-item.component.mjs +19 -0
- package/esm2022/lib/breadcrumb-link.component.mjs +60 -0
- package/esm2022/lib/breadcrumb-separator.component.mjs +23 -0
- package/esm2022/lib/breadcrumb.component.mjs +28 -0
- package/esm2022/lib/button.component.mjs +20 -24
- package/esm2022/lib/card.component.mjs +3 -3
- package/esm2022/lib/data-table.component.mjs +1 -1
- package/esm2022/lib/date-picker.component.mjs +2 -2
- package/esm2022/lib/date-range-picker.component.mjs +1 -1
- package/esm2022/lib/empty-state.component.mjs +111 -0
- package/esm2022/lib/input.component.mjs +125 -32
- package/esm2022/lib/masked-input.component.mjs +210 -46
- package/esm2022/lib/multi-select.component.mjs +1 -1
- package/esm2022/lib/otp-group.component.mjs +15 -0
- package/esm2022/lib/otp-slot.component.mjs +74 -0
- package/esm2022/lib/otp.component.mjs +127 -0
- package/esm2022/lib/popover-content.component.mjs +44 -0
- package/esm2022/lib/popover.component.mjs +105 -0
- package/esm2022/lib/radio-group.component.mjs +78 -0
- package/esm2022/lib/radio-item.component.mjs +112 -0
- package/esm2022/lib/radio-service.mjs +23 -0
- package/esm2022/lib/select.component.mjs +38 -9
- package/esm2022/lib/textarea.component.mjs +130 -26
- package/esm2022/lib/theme.service.mjs +227 -56
- package/esm2022/public-api.mjs +16 -1
- package/esm2022/tolle-ui.mjs +5 -0
- package/fesm2022/{tolle_-tolle-ui.mjs → tolle-ui.mjs} +1730 -201
- package/fesm2022/tolle-ui.mjs.map +1 -0
- package/lib/alert.component.d.ts +25 -0
- package/lib/avatar-fallback.component.d.ts +5 -0
- package/lib/avatar.component.d.ts +17 -0
- package/lib/breadcrumb-item.component.d.ts +5 -0
- package/lib/breadcrumb-link.component.d.ts +6 -0
- package/lib/breadcrumb-separator.component.d.ts +5 -0
- package/lib/breadcrumb.component.d.ts +8 -0
- package/lib/button.component.d.ts +1 -4
- package/lib/empty-state.component.d.ts +20 -0
- package/lib/input.component.d.ts +11 -3
- package/lib/masked-input.component.d.ts +14 -1
- package/lib/otp-group.component.d.ts +5 -0
- package/lib/otp-slot.component.d.ts +13 -0
- package/lib/otp.component.d.ts +21 -0
- package/lib/popover-content.component.d.ts +8 -0
- package/lib/popover.component.d.ts +19 -0
- package/lib/radio-group.component.d.ts +23 -0
- package/lib/radio-item.component.d.ts +22 -0
- package/lib/radio-service.d.ts +11 -0
- package/lib/select.component.d.ts +1 -0
- package/lib/textarea.component.d.ts +8 -1
- package/lib/theme.service.d.ts +37 -3
- package/package.json +7 -6
- package/preset.js +47 -33
- package/public-api.d.ts +15 -0
- package/theme.css +208 -163
- package/esm2022/tolle_-tolle-ui.mjs +0 -5
- package/fesm2022/tolle_-tolle-ui.mjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { Component, Input, forwardRef, Injectable, Optional, HostListener,
|
|
4
|
+
import { Component, Input, forwardRef, ViewChild, Injectable, Optional, HostListener, ContentChildren, EventEmitter, Output, Directive, inject, PLATFORM_ID, Inject, InjectionToken, APP_INITIALIZER, ChangeDetectorRef, ChangeDetectionStrategy, TemplateRef, Injector, HostBinding } from '@angular/core';
|
|
5
5
|
import * as i1 from '@angular/common';
|
|
6
|
-
import { CommonModule, isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
6
|
+
import { CommonModule, isPlatformBrowser, DOCUMENT, NgIf, NgTemplateOutlet } from '@angular/common';
|
|
7
7
|
import { cva } from 'class-variance-authority';
|
|
8
8
|
import * as i2 from '@angular/forms';
|
|
9
9
|
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
@@ -18,56 +18,48 @@ function cn(...inputs) {
|
|
|
18
18
|
return twMerge(clsx(inputs));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const buttonVariants = cva("inline-flex items-center justify-center rounded-md text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background active:scale-[0.98]", {
|
|
21
|
+
const buttonVariants = cva("tolle-button-base inline-flex items-center justify-center rounded-md text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background active:scale-[0.98]", {
|
|
22
22
|
variants: {
|
|
23
23
|
variant: {
|
|
24
24
|
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
25
25
|
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
26
|
-
outline: "border border-input hover:bg-accent hover:text-accent-foreground",
|
|
26
|
+
outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
|
|
27
27
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
28
28
|
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
29
|
-
link: "underline-offset-4 hover:underline
|
|
29
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
30
30
|
},
|
|
31
31
|
size: {
|
|
32
32
|
default: "h-10 px-4 py-2",
|
|
33
33
|
xs: "h-8 px-2 py-1 text-xs",
|
|
34
34
|
sm: "h-9 rounded-md px-3",
|
|
35
35
|
lg: "h-11 rounded-md px-8",
|
|
36
|
-
// RESTORED: Square icon button variants
|
|
37
36
|
"icon-xs": "h-8 w-8",
|
|
38
37
|
"icon-sm": "h-9 w-9",
|
|
39
38
|
icon: "h-10 w-10",
|
|
40
39
|
"icon-lg": "h-11 w-11",
|
|
41
40
|
},
|
|
42
|
-
|
|
43
|
-
busy: { true: "relative !cursor-wait !pointer-events-none" }
|
|
41
|
+
busy: { true: "tolle-button--busy relative !cursor-wait !pointer-events-none" }
|
|
44
42
|
},
|
|
45
43
|
defaultVariants: {
|
|
46
44
|
variant: "default",
|
|
47
45
|
size: "default",
|
|
48
|
-
block: false,
|
|
49
46
|
},
|
|
50
47
|
});
|
|
51
48
|
class ButtonComponent {
|
|
52
49
|
class = '';
|
|
53
50
|
variant = 'default';
|
|
54
51
|
size = 'default';
|
|
55
|
-
block = false;
|
|
56
52
|
disabled = false;
|
|
57
53
|
busy = false;
|
|
58
|
-
readonly = false;
|
|
59
54
|
get computedClass() {
|
|
60
55
|
return cn(buttonVariants({
|
|
61
56
|
variant: this.variant,
|
|
62
57
|
size: this.size,
|
|
63
|
-
block: this.block,
|
|
64
58
|
busy: this.busy
|
|
65
|
-
}),
|
|
66
|
-
// Adds 'size-icon-sm', 'size-xs', etc. for the CSS selectors to work
|
|
67
|
-
'size-' + this.size, this.class);
|
|
59
|
+
}), this.class);
|
|
68
60
|
}
|
|
69
61
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
70
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ButtonComponent, isStandalone: true, selector: "tolle-button", inputs: { class: "class", variant: "variant", size: "size",
|
|
62
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ButtonComponent, isStandalone: true, selector: "tolle-button", inputs: { class: "class", variant: "variant", size: "size", disabled: "disabled", busy: "busy" }, host: { classAttribute: "tolle-button-wrapper inline-block align-middle" }, ngImport: i0, template: `
|
|
71
63
|
<button
|
|
72
64
|
[class]="computedClass"
|
|
73
65
|
[disabled]="disabled || busy"
|
|
@@ -80,15 +72,19 @@ class ButtonComponent {
|
|
|
80
72
|
</svg>
|
|
81
73
|
</div>
|
|
82
74
|
|
|
83
|
-
<span class="flex items-center justify-center w-full h-full" [class.invisible]="busy">
|
|
75
|
+
<span class="flex items-center justify-center w-full h-full pointer-events-none" [class.invisible]="busy">
|
|
84
76
|
<ng-content></ng-content>
|
|
85
77
|
</span>
|
|
86
78
|
</button>
|
|
87
|
-
`, isInline: true,
|
|
79
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
88
80
|
}
|
|
89
81
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
90
82
|
type: Component,
|
|
91
|
-
args: [{
|
|
83
|
+
args: [{
|
|
84
|
+
selector: 'tolle-button',
|
|
85
|
+
standalone: true,
|
|
86
|
+
imports: [CommonModule],
|
|
87
|
+
template: `
|
|
92
88
|
<button
|
|
93
89
|
[class]="computedClass"
|
|
94
90
|
[disabled]="disabled || busy"
|
|
@@ -101,29 +97,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
101
97
|
</svg>
|
|
102
98
|
</div>
|
|
103
99
|
|
|
104
|
-
<span class="flex items-center justify-center w-full h-full" [class.invisible]="busy">
|
|
100
|
+
<span class="flex items-center justify-center w-full h-full pointer-events-none" [class.invisible]="busy">
|
|
105
101
|
<ng-content></ng-content>
|
|
106
102
|
</span>
|
|
107
103
|
</button>
|
|
108
|
-
`,
|
|
104
|
+
`,
|
|
105
|
+
host: {
|
|
106
|
+
'class': 'tolle-button-wrapper inline-block align-middle'
|
|
107
|
+
}
|
|
108
|
+
}]
|
|
109
109
|
}], propDecorators: { class: [{
|
|
110
110
|
type: Input
|
|
111
111
|
}], variant: [{
|
|
112
112
|
type: Input
|
|
113
113
|
}], size: [{
|
|
114
114
|
type: Input
|
|
115
|
-
}], block: [{
|
|
116
|
-
type: Input
|
|
117
115
|
}], disabled: [{
|
|
118
116
|
type: Input
|
|
119
117
|
}], busy: [{
|
|
120
118
|
type: Input
|
|
121
|
-
}], readonly: [{
|
|
122
|
-
type: Input
|
|
123
119
|
}] } });
|
|
124
120
|
|
|
125
121
|
class InputComponent {
|
|
126
122
|
cdr;
|
|
123
|
+
inputElement;
|
|
127
124
|
id = `input-${Math.random().toString(36).substr(2, 9)}`;
|
|
128
125
|
label = '';
|
|
129
126
|
hint = '';
|
|
@@ -137,12 +134,20 @@ class InputComponent {
|
|
|
137
134
|
disabled = false;
|
|
138
135
|
readonly = false;
|
|
139
136
|
error = false;
|
|
137
|
+
// Focus behavior
|
|
138
|
+
hideHintOnFocus = true;
|
|
140
139
|
value = '';
|
|
141
140
|
onChange = () => { };
|
|
142
141
|
onTouched = () => { };
|
|
142
|
+
isFocused = false;
|
|
143
143
|
constructor(cdr) {
|
|
144
144
|
this.cdr = cdr;
|
|
145
145
|
}
|
|
146
|
+
ngAfterViewInit() {
|
|
147
|
+
if (this.inputElement?.nativeElement.hasAttribute('autofocus')) {
|
|
148
|
+
setTimeout(() => this.inputElement.nativeElement.focus());
|
|
149
|
+
}
|
|
150
|
+
}
|
|
146
151
|
writeValue(value) {
|
|
147
152
|
this.value = value;
|
|
148
153
|
this.cdr.markForCheck();
|
|
@@ -160,66 +165,132 @@ class InputComponent {
|
|
|
160
165
|
this.value = val;
|
|
161
166
|
this.onChange(val);
|
|
162
167
|
}
|
|
168
|
+
onFocus() {
|
|
169
|
+
this.isFocused = true;
|
|
170
|
+
}
|
|
171
|
+
onBlur() {
|
|
172
|
+
this.isFocused = false;
|
|
173
|
+
this.onTouched();
|
|
174
|
+
}
|
|
175
|
+
focusInput() {
|
|
176
|
+
if (!this.disabled && this.inputElement) {
|
|
177
|
+
this.inputElement.nativeElement.focus();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
163
180
|
cn = cn;
|
|
181
|
+
get computedLabelClass() {
|
|
182
|
+
return cn("text-sm font-medium text-foreground leading-none transition-opacity duration-200", this.disabled && "opacity-50");
|
|
183
|
+
}
|
|
164
184
|
get computedContainerClass() {
|
|
165
|
-
return cn(
|
|
185
|
+
return cn(
|
|
186
|
+
// Base styles
|
|
187
|
+
"group relative flex items-center w-full rounded-md border transition-all duration-200", "bg-background",
|
|
188
|
+
// Border and shadow
|
|
189
|
+
"border-input shadow-sm",
|
|
166
190
|
// Sizing
|
|
167
|
-
this.size === 'xs' && "h-8 px-2 gap-1.5", this.size === 'sm' && "h-9 px-3 gap-2", this.size === 'default' && "h-10 px-3 gap-2", this.size === 'lg' && "h-11 px-4 gap-3",
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
191
|
+
this.size === 'xs' && "h-8 px-2 gap-1.5 text-xs", this.size === 'sm' && "h-9 px-3 gap-2 text-sm", this.size === 'default' && "h-10 px-3 gap-2 text-sm", this.size === 'lg' && "h-11 px-4 gap-3 text-base",
|
|
192
|
+
// Focus state - SIMPLE AND ELEGANT LIKE ZARDUI
|
|
193
|
+
// The magic happens in CSS: border darkens automatically on focus
|
|
194
|
+
!(this.readonly || this.disabled) && [
|
|
195
|
+
"focus-within:border-primary/80",
|
|
196
|
+
"focus-within:ring-4",
|
|
197
|
+
"focus-within:ring-ring/30",
|
|
198
|
+
"focus-within:ring-offset-0",
|
|
199
|
+
"focus-within:shadow-none",
|
|
200
|
+
],
|
|
201
|
+
// Error state
|
|
202
|
+
this.error && [
|
|
203
|
+
"border-destructive",
|
|
204
|
+
!(this.readonly || this.disabled) && [
|
|
205
|
+
"focus-within:border-destructive/80",
|
|
206
|
+
"focus-within:ring-destructive/30"
|
|
207
|
+
]
|
|
208
|
+
],
|
|
209
|
+
// Disabled state
|
|
210
|
+
this.disabled && [
|
|
211
|
+
"cursor-not-allowed opacity-50",
|
|
212
|
+
"border-opacity-50"
|
|
213
|
+
],
|
|
214
|
+
// Readonly state
|
|
215
|
+
this.readonly && [
|
|
216
|
+
"cursor-default",
|
|
217
|
+
"border-dashed",
|
|
218
|
+
!this.disabled && "focus-within:ring-0 focus-within:border-opacity-100"
|
|
219
|
+
], this.containerClass);
|
|
174
220
|
}
|
|
175
221
|
get computedInputClass() {
|
|
176
|
-
return cn(
|
|
222
|
+
return cn(
|
|
223
|
+
// Base styles
|
|
224
|
+
"flex-1 bg-transparent border-none p-0", "placeholder:text-muted-foreground",
|
|
225
|
+
// Remove all default focus styles
|
|
226
|
+
"focus:outline-none focus:ring-0 focus:shadow-none",
|
|
227
|
+
// Text sizing
|
|
228
|
+
this.size === 'xs' && "text-xs", this.size === 'sm' && "text-sm", this.size === 'default' && "text-sm", this.size === 'lg' && "text-base",
|
|
229
|
+
// Cursor states
|
|
230
|
+
this.disabled && "cursor-not-allowed", this.readonly && "cursor-default",
|
|
231
|
+
// Text color
|
|
232
|
+
"text-foreground",
|
|
233
|
+
// Selection color
|
|
234
|
+
"selection:bg-primary/20 selection:text-foreground", this.class);
|
|
177
235
|
}
|
|
178
236
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: InputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
179
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: InputComponent, isStandalone: true, selector: "tolle-input", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", type: "type", placeholder: "placeholder", size: "size", containerClass: "containerClass", class: "class", disabled: "disabled", readonly: "readonly", error: "error" }, providers: [
|
|
237
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: InputComponent, isStandalone: true, selector: "tolle-input", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", type: "type", placeholder: "placeholder", size: "size", containerClass: "containerClass", class: "class", disabled: "disabled", readonly: "readonly", error: "error", hideHintOnFocus: "hideHintOnFocus" }, providers: [
|
|
180
238
|
{
|
|
181
239
|
provide: NG_VALUE_ACCESSOR,
|
|
182
240
|
useExisting: forwardRef(() => InputComponent),
|
|
183
241
|
multi: true
|
|
184
242
|
}
|
|
185
|
-
], ngImport: i0, template: `
|
|
243
|
+
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], ngImport: i0, template: `
|
|
186
244
|
<div class="flex flex-col gap-1.5 w-full">
|
|
187
245
|
<label
|
|
188
246
|
*ngIf="label"
|
|
189
247
|
[for]="id"
|
|
190
|
-
[class
|
|
191
|
-
class="text-sm font-medium text-foreground leading-none transition-opacity"
|
|
192
|
-
>
|
|
248
|
+
[class]="computedLabelClass">
|
|
193
249
|
{{ label }}
|
|
194
250
|
</label>
|
|
195
251
|
|
|
196
|
-
<div
|
|
197
|
-
|
|
252
|
+
<div
|
|
253
|
+
[class]="computedContainerClass"
|
|
254
|
+
(click)="focusInput()"
|
|
255
|
+
>
|
|
256
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
198
257
|
<ng-content select="[prefix]"></ng-content>
|
|
199
258
|
</div>
|
|
200
259
|
|
|
201
260
|
<input
|
|
261
|
+
#inputElement
|
|
202
262
|
[id]="id"
|
|
203
263
|
[type]="type"
|
|
204
264
|
[placeholder]="placeholder"
|
|
205
265
|
[disabled]="disabled"
|
|
206
266
|
[readOnly]="readonly"
|
|
207
267
|
[(ngModel)]="value"
|
|
208
|
-
(blur)="
|
|
268
|
+
(blur)="onBlur()"
|
|
269
|
+
(focus)="onFocus()"
|
|
209
270
|
(input)="onInputChange($event)"
|
|
210
271
|
[class]="computedInputClass"
|
|
272
|
+
[attr.aria-invalid]="error"
|
|
273
|
+
[attr.aria-describedby]="error && errorMessage ? id + '-error' : null"
|
|
211
274
|
/>
|
|
212
275
|
|
|
213
|
-
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors">
|
|
276
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
214
277
|
<ng-content select="[suffix]"></ng-content>
|
|
215
278
|
</div>
|
|
216
279
|
</div>
|
|
217
280
|
|
|
218
281
|
<ng-container *ngIf="!disabled">
|
|
219
|
-
<p
|
|
282
|
+
<p
|
|
283
|
+
*ngIf="hint && !error"
|
|
284
|
+
class="text-xs text-muted-foreground px-1 transition-opacity duration-200"
|
|
285
|
+
[class.opacity-0]="isFocused && hideHintOnFocus"
|
|
286
|
+
>
|
|
220
287
|
{{ hint }}
|
|
221
288
|
</p>
|
|
222
|
-
<p
|
|
289
|
+
<p
|
|
290
|
+
*ngIf="error && errorMessage"
|
|
291
|
+
[id]="id + '-error'"
|
|
292
|
+
class="text-xs text-destructive px-1"
|
|
293
|
+
>
|
|
223
294
|
{{ errorMessage }}
|
|
224
295
|
</p>
|
|
225
296
|
</ng-container>
|
|
@@ -244,46 +315,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
244
315
|
<label
|
|
245
316
|
*ngIf="label"
|
|
246
317
|
[for]="id"
|
|
247
|
-
[class
|
|
248
|
-
class="text-sm font-medium text-foreground leading-none transition-opacity"
|
|
249
|
-
>
|
|
318
|
+
[class]="computedLabelClass">
|
|
250
319
|
{{ label }}
|
|
251
320
|
</label>
|
|
252
321
|
|
|
253
|
-
<div
|
|
254
|
-
|
|
322
|
+
<div
|
|
323
|
+
[class]="computedContainerClass"
|
|
324
|
+
(click)="focusInput()"
|
|
325
|
+
>
|
|
326
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
255
327
|
<ng-content select="[prefix]"></ng-content>
|
|
256
328
|
</div>
|
|
257
329
|
|
|
258
330
|
<input
|
|
331
|
+
#inputElement
|
|
259
332
|
[id]="id"
|
|
260
333
|
[type]="type"
|
|
261
334
|
[placeholder]="placeholder"
|
|
262
335
|
[disabled]="disabled"
|
|
263
336
|
[readOnly]="readonly"
|
|
264
337
|
[(ngModel)]="value"
|
|
265
|
-
(blur)="
|
|
338
|
+
(blur)="onBlur()"
|
|
339
|
+
(focus)="onFocus()"
|
|
266
340
|
(input)="onInputChange($event)"
|
|
267
341
|
[class]="computedInputClass"
|
|
342
|
+
[attr.aria-invalid]="error"
|
|
343
|
+
[attr.aria-describedby]="error && errorMessage ? id + '-error' : null"
|
|
268
344
|
/>
|
|
269
345
|
|
|
270
|
-
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors">
|
|
346
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
271
347
|
<ng-content select="[suffix]"></ng-content>
|
|
272
348
|
</div>
|
|
273
349
|
</div>
|
|
274
350
|
|
|
275
351
|
<ng-container *ngIf="!disabled">
|
|
276
|
-
<p
|
|
352
|
+
<p
|
|
353
|
+
*ngIf="hint && !error"
|
|
354
|
+
class="text-xs text-muted-foreground px-1 transition-opacity duration-200"
|
|
355
|
+
[class.opacity-0]="isFocused && hideHintOnFocus"
|
|
356
|
+
>
|
|
277
357
|
{{ hint }}
|
|
278
358
|
</p>
|
|
279
|
-
<p
|
|
359
|
+
<p
|
|
360
|
+
*ngIf="error && errorMessage"
|
|
361
|
+
[id]="id + '-error'"
|
|
362
|
+
class="text-xs text-destructive px-1"
|
|
363
|
+
>
|
|
280
364
|
{{ errorMessage }}
|
|
281
365
|
</p>
|
|
282
366
|
</ng-container>
|
|
283
367
|
</div>
|
|
284
368
|
`,
|
|
285
369
|
}]
|
|
286
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: {
|
|
370
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { inputElement: [{
|
|
371
|
+
type: ViewChild,
|
|
372
|
+
args: ['inputElement']
|
|
373
|
+
}], id: [{
|
|
287
374
|
type: Input
|
|
288
375
|
}], label: [{
|
|
289
376
|
type: Input
|
|
@@ -307,6 +394,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
307
394
|
type: Input
|
|
308
395
|
}], error: [{
|
|
309
396
|
type: Input
|
|
397
|
+
}], hideHintOnFocus: [{
|
|
398
|
+
type: Input
|
|
310
399
|
}] } });
|
|
311
400
|
|
|
312
401
|
class CardComponent {
|
|
@@ -314,7 +403,7 @@ class CardComponent {
|
|
|
314
403
|
cn = cn;
|
|
315
404
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
316
405
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CardComponent, isStandalone: true, selector: "tolle-card", inputs: { class: "class" }, ngImport: i0, template: `
|
|
317
|
-
<div [class]="cn('rounded-
|
|
406
|
+
<div [class]="cn('rounded-md border border-border bg-card text-card-foreground shadow', class)">
|
|
318
407
|
<ng-content></ng-content>
|
|
319
408
|
</div>
|
|
320
409
|
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
@@ -326,7 +415,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
326
415
|
standalone: true,
|
|
327
416
|
imports: [CommonModule],
|
|
328
417
|
template: `
|
|
329
|
-
<div [class]="cn('rounded-
|
|
418
|
+
<div [class]="cn('rounded-md border border-border bg-card text-card-foreground shadow', class)">
|
|
330
419
|
<ng-content></ng-content>
|
|
331
420
|
</div>
|
|
332
421
|
`,
|
|
@@ -505,6 +594,7 @@ class SelectComponent {
|
|
|
505
594
|
readonly = false;
|
|
506
595
|
trigger;
|
|
507
596
|
popover;
|
|
597
|
+
container;
|
|
508
598
|
items;
|
|
509
599
|
sub = new Subscription();
|
|
510
600
|
searchQuery = '';
|
|
@@ -528,15 +618,38 @@ class SelectComponent {
|
|
|
528
618
|
this.close();
|
|
529
619
|
}));
|
|
530
620
|
}
|
|
531
|
-
//
|
|
621
|
+
// SIMPLIFIED: Zardui-inspired trigger styling
|
|
532
622
|
get computedTriggerClass() {
|
|
533
|
-
return cn(
|
|
623
|
+
return cn(
|
|
624
|
+
// Base styles
|
|
625
|
+
'flex w-full items-center justify-between rounded-md border transition-all duration-200', 'bg-background text-foreground',
|
|
626
|
+
// Border and shadow
|
|
627
|
+
'border-input shadow-sm',
|
|
534
628
|
// Sizing
|
|
535
629
|
this.size === 'xs' && 'h-8 px-2 text-xs', this.size === 'sm' && 'h-9 px-3 text-sm', this.size === 'default' && 'h-10 px-3 text-sm', this.size === 'lg' && 'h-11 px-4 text-base',
|
|
536
|
-
//
|
|
537
|
-
!(this.readonly || this.disabled) &&
|
|
538
|
-
|
|
539
|
-
|
|
630
|
+
// Focus state - SIMPLE LIKE ZARDUI
|
|
631
|
+
!(this.readonly || this.disabled) && [
|
|
632
|
+
'focus:outline-none',
|
|
633
|
+
'focus:ring-4',
|
|
634
|
+
'focus:ring-ring/30',
|
|
635
|
+
'focus:ring-offset-0',
|
|
636
|
+
'focus:shadow-none',
|
|
637
|
+
// Border darkens on focus automatically
|
|
638
|
+
'focus:border-primary/80'
|
|
639
|
+
],
|
|
640
|
+
// Hover state
|
|
641
|
+
!(this.readonly || this.disabled) && 'hover:border-accent',
|
|
642
|
+
// Disabled state
|
|
643
|
+
this.disabled && [
|
|
644
|
+
'cursor-not-allowed opacity-50',
|
|
645
|
+
'border-opacity-50'
|
|
646
|
+
],
|
|
647
|
+
// Readonly state
|
|
648
|
+
this.readonly && [
|
|
649
|
+
'cursor-default',
|
|
650
|
+
'border-dashed',
|
|
651
|
+
!this.disabled && 'focus:ring-0 focus:border-opacity-100'
|
|
652
|
+
], this.class);
|
|
540
653
|
}
|
|
541
654
|
// UPDATED: Dynamic icon sizing relative to the trigger size
|
|
542
655
|
get iconClass() {
|
|
@@ -562,6 +675,8 @@ class SelectComponent {
|
|
|
562
675
|
}
|
|
563
676
|
open() {
|
|
564
677
|
this.isOpen = true;
|
|
678
|
+
// Trigger focus on the button for focus styling
|
|
679
|
+
this.trigger.nativeElement.focus();
|
|
565
680
|
// Tick to ensure DOM is rendered before positioning
|
|
566
681
|
setTimeout(() => this.updatePosition());
|
|
567
682
|
}
|
|
@@ -630,7 +745,7 @@ class SelectComponent {
|
|
|
630
745
|
useExisting: forwardRef(() => SelectComponent),
|
|
631
746
|
multi: true
|
|
632
747
|
}
|
|
633
|
-
], queries: [{ propertyName: "items", predicate: SelectItemComponent, descendants: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "popover", first: true, predicate: ["popover"], descendants: true }], ngImport: i0, template: `
|
|
748
|
+
], queries: [{ propertyName: "items", predicate: SelectItemComponent, descendants: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "popover", first: true, predicate: ["popover"], descendants: true }, { propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: `
|
|
634
749
|
<div [class]="cn('w-full', 'size-' + size)" #container>
|
|
635
750
|
<button
|
|
636
751
|
type="button"
|
|
@@ -670,7 +785,7 @@ class SelectComponent {
|
|
|
670
785
|
</div>
|
|
671
786
|
</div>
|
|
672
787
|
</div>
|
|
673
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error"] }] });
|
|
788
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error", "hideHintOnFocus"] }] });
|
|
674
789
|
}
|
|
675
790
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectComponent, decorators: [{
|
|
676
791
|
type: Component,
|
|
@@ -746,6 +861,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
746
861
|
}], popover: [{
|
|
747
862
|
type: ViewChild,
|
|
748
863
|
args: ['popover']
|
|
864
|
+
}], container: [{
|
|
865
|
+
type: ViewChild,
|
|
866
|
+
args: ['container']
|
|
749
867
|
}], items: [{
|
|
750
868
|
type: ContentChildren,
|
|
751
869
|
args: [SelectItemComponent, { descendants: true }]
|
|
@@ -938,7 +1056,7 @@ class BadgeComponent {
|
|
|
938
1056
|
get computedClass() {
|
|
939
1057
|
return cn(
|
|
940
1058
|
// Base styles - Pills are always rounded-full
|
|
941
|
-
'inline-flex items-center justify-center rounded-
|
|
1059
|
+
'inline-flex items-center justify-center rounded-md border px-2 py-0.5 font-medium transition-colors gap-1',
|
|
942
1060
|
// Variants (Google Dark Mode theme)
|
|
943
1061
|
this.variant === 'default' && 'border-transparent bg-primary text-primary-foreground', this.variant === 'secondary' && 'border-transparent bg-secondary text-secondary-foreground', this.variant === 'outline' && 'text-foreground border-border bg-transparent', this.variant === 'destructive' && 'border-transparent bg-destructive text-destructive-foreground',
|
|
944
1062
|
// Sizing
|
|
@@ -956,7 +1074,7 @@ class BadgeComponent {
|
|
|
956
1074
|
<button
|
|
957
1075
|
*ngIf="removable"
|
|
958
1076
|
(click)="onRemove.emit($event)"
|
|
959
|
-
class="ml-1 -mr-1 rounded-
|
|
1077
|
+
class="ml-1 -mr-1 rounded-md p-0.5 hover:bg-foreground/20 transition-colors outline-none focus:ring-1 focus:ring-ring"
|
|
960
1078
|
>
|
|
961
1079
|
<i class="ri-close-line text-[1.1em]"></i>
|
|
962
1080
|
</button>
|
|
@@ -980,7 +1098,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
980
1098
|
<button
|
|
981
1099
|
*ngIf="removable"
|
|
982
1100
|
(click)="onRemove.emit($event)"
|
|
983
|
-
class="ml-1 -mr-1 rounded-
|
|
1101
|
+
class="ml-1 -mr-1 rounded-md p-0.5 hover:bg-foreground/20 transition-colors outline-none focus:ring-1 focus:ring-ring"
|
|
984
1102
|
>
|
|
985
1103
|
<i class="ri-close-line text-[1.1em]"></i>
|
|
986
1104
|
</button>
|
|
@@ -1365,93 +1483,212 @@ class ThemeService {
|
|
|
1365
1483
|
else {
|
|
1366
1484
|
this.disableDarkMode();
|
|
1367
1485
|
}
|
|
1368
|
-
|
|
1369
|
-
if (
|
|
1370
|
-
this.
|
|
1486
|
+
const savedPrimary = localStorage.getItem('tolle-primary-color');
|
|
1487
|
+
if (savedPrimary) {
|
|
1488
|
+
this.setPrimaryColor(savedPrimary, false);
|
|
1489
|
+
}
|
|
1490
|
+
else if (this.config?.primaryColor) {
|
|
1491
|
+
this.setPrimaryColor(this.config.primaryColor, false);
|
|
1492
|
+
}
|
|
1493
|
+
// Set radius from config
|
|
1494
|
+
if (this.config?.radius) {
|
|
1495
|
+
this.setRadius(this.config.radius, false);
|
|
1371
1496
|
}
|
|
1372
1497
|
}
|
|
1373
1498
|
/**
|
|
1374
|
-
*
|
|
1499
|
+
* Sets the border radius for all components
|
|
1375
1500
|
*/
|
|
1376
|
-
|
|
1501
|
+
setRadius(radius, persist = true) {
|
|
1377
1502
|
if (!isPlatformBrowser(this.platformId))
|
|
1378
1503
|
return;
|
|
1379
1504
|
const root = this.document.documentElement;
|
|
1380
|
-
// Set
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1505
|
+
// Set the CSS variable
|
|
1506
|
+
this.renderer.setStyle(root, '--radius', radius);
|
|
1507
|
+
// Also update the dynamic styles to include radius calculations
|
|
1508
|
+
this.updateRadiusInDynamicStyles(radius);
|
|
1509
|
+
// Persist if needed
|
|
1510
|
+
if (persist) {
|
|
1511
|
+
localStorage.setItem('tolle-radius', radius);
|
|
1384
1512
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Updates the radius calculations in dynamic styles
|
|
1516
|
+
*/
|
|
1517
|
+
updateRadiusInDynamicStyles(radius) {
|
|
1518
|
+
const existingStyle = this.document.getElementById(this.styleId);
|
|
1519
|
+
if (existingStyle) {
|
|
1520
|
+
let css = existingStyle.textContent || '';
|
|
1521
|
+
// Update or add radius calculations
|
|
1522
|
+
if (css.includes('--radius:')) {
|
|
1523
|
+
// Replace existing radius declarations
|
|
1524
|
+
css = css.replace(/--radius:[^;]+;/g, `--radius: ${radius};`);
|
|
1525
|
+
}
|
|
1526
|
+
else {
|
|
1527
|
+
// Add radius to the beginning of :root
|
|
1528
|
+
css = css.replace(/:root\s*{/, `:root {\n --radius: ${radius};`);
|
|
1529
|
+
}
|
|
1530
|
+
// Update the calculated radius values in the CSS
|
|
1531
|
+
const radiusCalcRegex = /calc\(var\(--radius[^)]+\)/g;
|
|
1532
|
+
css = css.replace(radiusCalcRegex, (match) => {
|
|
1533
|
+
if (match.includes('- 2px')) {
|
|
1534
|
+
return `calc(${radius} - 2px)`;
|
|
1535
|
+
}
|
|
1536
|
+
else if (match.includes('- 4px')) {
|
|
1537
|
+
return `calc(${radius} - 4px)`;
|
|
1538
|
+
}
|
|
1539
|
+
return match;
|
|
1540
|
+
});
|
|
1541
|
+
existingStyle.textContent = css;
|
|
1388
1542
|
}
|
|
1389
1543
|
}
|
|
1390
1544
|
/**
|
|
1391
1545
|
* Generates full primary color palette (50-900) based on base color
|
|
1392
|
-
* Uses color-mix() for consistency with your existing approach
|
|
1393
1546
|
*/
|
|
1394
1547
|
generatePrimaryShades(baseColor) {
|
|
1548
|
+
// Convert hex to RGB
|
|
1549
|
+
const rgb = this.hexToRgb(baseColor);
|
|
1550
|
+
const rgbString = rgb ? `${rgb.r} ${rgb.g} ${rgb.b}` : '37 99 235';
|
|
1551
|
+
// Create lighter ring colors in RGB
|
|
1552
|
+
const ringLight = this.lightenColor(baseColor, 40);
|
|
1553
|
+
const ringLightRgb = this.hexToRgb(ringLight);
|
|
1554
|
+
const ringLightRgbString = ringLightRgb ? `${ringLightRgb.r} ${ringLightRgb.g} ${ringLightRgb.b}` : '96 165 250';
|
|
1555
|
+
const ringDark = this.lightenColor(baseColor, 20);
|
|
1556
|
+
const ringDarkRgb = this.hexToRgb(ringDark);
|
|
1557
|
+
const ringDarkRgbString = ringDarkRgb ? `${ringDarkRgb.r} ${ringDarkRgb.g} ${ringDarkRgb.b}` : '147 197 253';
|
|
1558
|
+
// Get current radius or use default
|
|
1559
|
+
const root = this.document.documentElement;
|
|
1560
|
+
const currentRadius = getComputedStyle(root).getPropertyValue('--radius').trim() || '0.5rem';
|
|
1395
1561
|
const css = `
|
|
1562
|
+
/* Override primary colors - this needs to come AFTER your main CSS */
|
|
1396
1563
|
:root {
|
|
1397
|
-
/* Primary
|
|
1398
|
-
--primary
|
|
1399
|
-
--primary-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
--
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
--primary-
|
|
1406
|
-
--primary-
|
|
1407
|
-
--primary-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
--primary-
|
|
1411
|
-
--
|
|
1412
|
-
--
|
|
1413
|
-
--
|
|
1414
|
-
--
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
--ring:
|
|
1564
|
+
/* Primary in RGB format for Tailwind opacity support */
|
|
1565
|
+
--primary: ${rgbString};
|
|
1566
|
+
--primary-foreground: ${this.getContrastColorRgb(baseColor)};
|
|
1567
|
+
|
|
1568
|
+
/* Radius */
|
|
1569
|
+
--radius: ${currentRadius};
|
|
1570
|
+
|
|
1571
|
+
/* Primary shades for light mode */
|
|
1572
|
+
--primary-50: ${this.hexToRgbString(this.lightenColor(baseColor, 90))};
|
|
1573
|
+
--primary-100: ${this.hexToRgbString(this.lightenColor(baseColor, 80))};
|
|
1574
|
+
--primary-200: ${this.hexToRgbString(this.lightenColor(baseColor, 60))};
|
|
1575
|
+
--primary-300: ${this.hexToRgbString(this.lightenColor(baseColor, 40))};
|
|
1576
|
+
--primary-400: ${this.hexToRgbString(this.lightenColor(baseColor, 20))};
|
|
1577
|
+
--primary-500: ${rgbString};
|
|
1578
|
+
--primary-600: ${this.hexToRgbString(this.darkenColor(baseColor, 20))};
|
|
1579
|
+
--primary-700: ${this.hexToRgbString(this.darkenColor(baseColor, 40))};
|
|
1580
|
+
--primary-800: ${this.hexToRgbString(this.darkenColor(baseColor, 60))};
|
|
1581
|
+
--primary-900: ${this.hexToRgbString(this.darkenColor(baseColor, 80))};
|
|
1582
|
+
|
|
1583
|
+
/* Update ring color to be lighter */
|
|
1584
|
+
--ring: ${ringLightRgbString};
|
|
1418
1585
|
}
|
|
1419
1586
|
|
|
1420
1587
|
.dark {
|
|
1421
|
-
/*
|
|
1422
|
-
--primary
|
|
1423
|
-
--primary-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
--primary-
|
|
1427
|
-
--primary-
|
|
1428
|
-
--primary-
|
|
1429
|
-
--primary-
|
|
1430
|
-
--primary-
|
|
1431
|
-
--primary-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
--primary-
|
|
1435
|
-
--
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
--
|
|
1439
|
-
--accent: color-mix(in srgb, var(--primary-800), transparent 80%);
|
|
1440
|
-
--accent-foreground: var(--primary-200);
|
|
1441
|
-
--ring: color-mix(in srgb, var(--primary-600), transparent 60%);
|
|
1588
|
+
/* For dark mode, we keep the primary color but adjust shades */
|
|
1589
|
+
--primary: ${rgbString};
|
|
1590
|
+
--primary-foreground: ${this.getContrastColorRgb(baseColor)};
|
|
1591
|
+
|
|
1592
|
+
/* Dark mode shades */
|
|
1593
|
+
--primary-50: ${this.hexToRgbString(this.darkenColor(baseColor, 85))};
|
|
1594
|
+
--primary-100: ${this.hexToRgbString(this.darkenColor(baseColor, 75))};
|
|
1595
|
+
--primary-200: ${this.hexToRgbString(this.darkenColor(baseColor, 65))};
|
|
1596
|
+
--primary-300: ${this.hexToRgbString(this.darkenColor(baseColor, 55))};
|
|
1597
|
+
--primary-400: ${this.hexToRgbString(this.darkenColor(baseColor, 45))};
|
|
1598
|
+
--primary-500: ${rgbString};
|
|
1599
|
+
--primary-600: ${this.hexToRgbString(this.lightenColor(baseColor, 20))};
|
|
1600
|
+
--primary-700: ${this.hexToRgbString(this.lightenColor(baseColor, 35))};
|
|
1601
|
+
--primary-800: ${this.hexToRgbString(this.lightenColor(baseColor, 50))};
|
|
1602
|
+
--primary-900: ${this.hexToRgbString(this.lightenColor(baseColor, 65))};
|
|
1603
|
+
|
|
1604
|
+
/* Update ring color for dark mode - lighter variant */
|
|
1605
|
+
--ring: ${ringDarkRgbString};
|
|
1442
1606
|
}
|
|
1443
1607
|
`;
|
|
1444
1608
|
this.injectDynamicStyles(css);
|
|
1445
1609
|
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Convert hex color to RGB object
|
|
1612
|
+
*/
|
|
1613
|
+
hexToRgb(hex) {
|
|
1614
|
+
// Remove # if present
|
|
1615
|
+
const cleanedHex = hex.replace('#', '');
|
|
1616
|
+
let r = 0, g = 0, b = 0;
|
|
1617
|
+
if (cleanedHex.length === 3) {
|
|
1618
|
+
r = parseInt(cleanedHex[0] + cleanedHex[0], 16);
|
|
1619
|
+
g = parseInt(cleanedHex[1] + cleanedHex[1], 16);
|
|
1620
|
+
b = parseInt(cleanedHex[2] + cleanedHex[2], 16);
|
|
1621
|
+
return { r, g, b };
|
|
1622
|
+
}
|
|
1623
|
+
if (cleanedHex.length === 6) {
|
|
1624
|
+
r = parseInt(cleanedHex.substring(0, 2), 16);
|
|
1625
|
+
g = parseInt(cleanedHex.substring(2, 4), 16);
|
|
1626
|
+
b = parseInt(cleanedHex.substring(4, 6), 16);
|
|
1627
|
+
return { r, g, b };
|
|
1628
|
+
}
|
|
1629
|
+
return null;
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Convert hex to RGB string format for CSS (space-separated)
|
|
1633
|
+
*/
|
|
1634
|
+
hexToRgbString(hexColor) {
|
|
1635
|
+
const rgb = this.hexToRgb(hexColor);
|
|
1636
|
+
return rgb ? `${rgb.r} ${rgb.g} ${rgb.b}` : '37 99 235';
|
|
1637
|
+
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Get contrast color in RGB format
|
|
1640
|
+
*/
|
|
1641
|
+
getContrastColorRgb(hexColor) {
|
|
1642
|
+
const contrast = this.getContrastColor(hexColor);
|
|
1643
|
+
const rgb = this.hexToRgb(contrast);
|
|
1644
|
+
return rgb ? `${rgb.r} ${rgb.g} ${rgb.b}` : '255 255 255';
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
|
+
* Lighten a hex color by a percentage
|
|
1648
|
+
*/
|
|
1649
|
+
lightenColor(color, percent) {
|
|
1650
|
+
const rgb = this.hexToRgb(color);
|
|
1651
|
+
if (!rgb)
|
|
1652
|
+
return color;
|
|
1653
|
+
// Lighten by percentage
|
|
1654
|
+
const r = Math.min(255, Math.floor(rgb.r + (255 - rgb.r) * (percent / 100)));
|
|
1655
|
+
const g = Math.min(255, Math.floor(rgb.g + (255 - rgb.g) * (percent / 100)));
|
|
1656
|
+
const b = Math.min(255, Math.floor(rgb.b + (255 - rgb.b) * (percent / 100)));
|
|
1657
|
+
// Convert back to hex
|
|
1658
|
+
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Darken a hex color by a percentage
|
|
1662
|
+
*/
|
|
1663
|
+
darkenColor(color, percent) {
|
|
1664
|
+
const rgb = this.hexToRgb(color);
|
|
1665
|
+
if (!rgb)
|
|
1666
|
+
return color;
|
|
1667
|
+
const factor = 1 - (percent / 100);
|
|
1668
|
+
const r = Math.max(0, Math.floor(rgb.r * factor));
|
|
1669
|
+
const g = Math.max(0, Math.floor(rgb.g * factor));
|
|
1670
|
+
const b = Math.max(0, Math.floor(rgb.b * factor));
|
|
1671
|
+
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
1672
|
+
}
|
|
1673
|
+
/**
|
|
1674
|
+
* Calculate contrast color (black or white) based on background color
|
|
1675
|
+
*/
|
|
1676
|
+
getContrastColor(hexColor) {
|
|
1677
|
+
const rgb = this.hexToRgb(hexColor);
|
|
1678
|
+
if (!rgb)
|
|
1679
|
+
return '#ffffff';
|
|
1680
|
+
// Calculate relative luminance
|
|
1681
|
+
const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
|
|
1682
|
+
// Return black for light colors, white for dark colors
|
|
1683
|
+
return luminance > 0.5 ? '#000000' : '#ffffff';
|
|
1684
|
+
}
|
|
1446
1685
|
injectDynamicStyles(css) {
|
|
1447
1686
|
if (!isPlatformBrowser(this.platformId))
|
|
1448
1687
|
return;
|
|
1449
|
-
// Remove existing dynamic styles
|
|
1450
1688
|
const existingStyle = this.document.getElementById(this.styleId);
|
|
1451
1689
|
if (existingStyle) {
|
|
1452
1690
|
existingStyle.remove();
|
|
1453
1691
|
}
|
|
1454
|
-
// Create and inject new styles
|
|
1455
1692
|
const styleElement = this.document.createElement('style');
|
|
1456
1693
|
styleElement.id = this.styleId;
|
|
1457
1694
|
styleElement.textContent = css;
|
|
@@ -1471,9 +1708,61 @@ class ThemeService {
|
|
|
1471
1708
|
localStorage.setItem('tolle-theme', 'light');
|
|
1472
1709
|
this.isDarkSubject.next(false);
|
|
1473
1710
|
}
|
|
1711
|
+
setPrimaryColor(color, persist = true) {
|
|
1712
|
+
if (!isPlatformBrowser(this.platformId))
|
|
1713
|
+
return;
|
|
1714
|
+
this.generatePrimaryShades(color);
|
|
1715
|
+
// Also set inline for immediate update
|
|
1716
|
+
const rgb = this.hexToRgb(color);
|
|
1717
|
+
if (rgb) {
|
|
1718
|
+
this.renderer.setStyle(this.document.documentElement, '--primary', `${rgb.r} ${rgb.g} ${rgb.b}`);
|
|
1719
|
+
}
|
|
1720
|
+
if (persist) {
|
|
1721
|
+
localStorage.setItem('tolle-primary-color', color);
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1474
1724
|
get currentTheme() {
|
|
1475
1725
|
return this.isDarkSubject.value ? 'dark' : 'light';
|
|
1476
1726
|
}
|
|
1727
|
+
get primaryColor() {
|
|
1728
|
+
if (!isPlatformBrowser(this.platformId))
|
|
1729
|
+
return null;
|
|
1730
|
+
const root = this.document.documentElement;
|
|
1731
|
+
const cssValue = getComputedStyle(root).getPropertyValue('--primary').trim();
|
|
1732
|
+
if (cssValue && cssValue !== '') {
|
|
1733
|
+
// Convert RGB string back to hex for external use
|
|
1734
|
+
const rgbParts = cssValue.split(' ').map(Number);
|
|
1735
|
+
if (rgbParts.length === 3) {
|
|
1736
|
+
return `#${rgbParts[0].toString(16).padStart(2, '0')}${rgbParts[1].toString(16).padStart(2, '0')}${rgbParts[2].toString(16).padStart(2, '0')}`;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
return localStorage.getItem('tolle-primary-color');
|
|
1740
|
+
}
|
|
1741
|
+
get radius() {
|
|
1742
|
+
if (!isPlatformBrowser(this.platformId))
|
|
1743
|
+
return null;
|
|
1744
|
+
const root = this.document.documentElement;
|
|
1745
|
+
const cssValue = getComputedStyle(root).getPropertyValue('--radius').trim();
|
|
1746
|
+
if (cssValue && cssValue !== '') {
|
|
1747
|
+
return cssValue;
|
|
1748
|
+
}
|
|
1749
|
+
return localStorage.getItem('tolle-radius') || '0.5rem';
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Applies the brand identity variables with full shade palette
|
|
1753
|
+
*/
|
|
1754
|
+
applyBrandConfig(config) {
|
|
1755
|
+
if (!isPlatformBrowser(this.platformId))
|
|
1756
|
+
return;
|
|
1757
|
+
// Set primary color if provided
|
|
1758
|
+
if (config.primaryColor) {
|
|
1759
|
+
this.setPrimaryColor(config.primaryColor, false);
|
|
1760
|
+
}
|
|
1761
|
+
// Set border radius if provided
|
|
1762
|
+
if (config.radius) {
|
|
1763
|
+
this.setRadius(config.radius, false);
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1477
1766
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThemeService, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: TOLLE_CONFIG, optional: true }, { token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1478
1767
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThemeService, providedIn: 'root' });
|
|
1479
1768
|
}
|
|
@@ -1655,7 +1944,7 @@ class MultiSelectComponent {
|
|
|
1655
1944
|
</div>
|
|
1656
1945
|
</div>
|
|
1657
1946
|
</div>
|
|
1658
|
-
`, isInline: true, 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: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BadgeComponent, selector: "tolle-badge", inputs: ["variant", "size", "removable", "class"], outputs: ["onRemove"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error"] }] });
|
|
1947
|
+
`, isInline: true, 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: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BadgeComponent, selector: "tolle-badge", inputs: ["variant", "size", "removable", "class"], outputs: ["onRemove"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error", "hideHintOnFocus"] }] });
|
|
1659
1948
|
}
|
|
1660
1949
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectComponent, decorators: [{
|
|
1661
1950
|
type: Component,
|
|
@@ -2038,18 +2327,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2038
2327
|
class MaskedInputComponent {
|
|
2039
2328
|
el;
|
|
2040
2329
|
cdr;
|
|
2330
|
+
id = `masked-input-${Math.random().toString(36).substr(2, 9)}`;
|
|
2331
|
+
label = '';
|
|
2332
|
+
hint = '';
|
|
2333
|
+
errorMessage = '';
|
|
2041
2334
|
mask = '';
|
|
2042
2335
|
placeholder = '';
|
|
2043
2336
|
type = 'text';
|
|
2044
2337
|
disabled = false;
|
|
2338
|
+
readonly = false;
|
|
2045
2339
|
class = '';
|
|
2340
|
+
containerClass = '';
|
|
2046
2341
|
error = false;
|
|
2047
2342
|
size = 'default';
|
|
2048
2343
|
returnRaw = false;
|
|
2344
|
+
hideHintOnFocus = true;
|
|
2049
2345
|
inputEl;
|
|
2050
2346
|
hasPrefix = false;
|
|
2051
2347
|
hasSuffix = false;
|
|
2052
2348
|
displayValue = '';
|
|
2349
|
+
isFocused = false;
|
|
2053
2350
|
tokens = {
|
|
2054
2351
|
'0': /\d/, '9': /\d/, 'a': /[a-z]/i, 'A': /[a-z]/i, '*': /[a-z0-9]/i
|
|
2055
2352
|
};
|
|
@@ -2059,7 +2356,6 @@ class MaskedInputComponent {
|
|
|
2059
2356
|
this.el = el;
|
|
2060
2357
|
this.cdr = cdr;
|
|
2061
2358
|
}
|
|
2062
|
-
// FIXED DETECTION: Check the actual DOM nodes projected into the component
|
|
2063
2359
|
ngAfterContentChecked() {
|
|
2064
2360
|
const prefix = this.el.nativeElement.querySelector('[prefix]');
|
|
2065
2361
|
const suffix = this.el.nativeElement.querySelector('[suffix]');
|
|
@@ -2069,11 +2365,76 @@ class MaskedInputComponent {
|
|
|
2069
2365
|
this.cdr.detectChanges();
|
|
2070
2366
|
}
|
|
2071
2367
|
}
|
|
2368
|
+
get computedLabelClass() {
|
|
2369
|
+
return cn("text-sm font-medium text-foreground leading-none transition-opacity duration-200", this.disabled && "opacity-50");
|
|
2370
|
+
}
|
|
2371
|
+
get computedContainerClass() {
|
|
2372
|
+
return cn(
|
|
2373
|
+
// Base styles
|
|
2374
|
+
"group relative flex items-center w-full rounded-md border transition-all duration-200", "bg-background",
|
|
2375
|
+
// Border and shadow
|
|
2376
|
+
"border-input shadow-sm",
|
|
2377
|
+
// Sizing
|
|
2378
|
+
this.size === 'xs' && "h-8 px-2 gap-1.5 text-xs", this.size === 'sm' && "h-9 px-3 gap-2 text-sm", this.size === 'default' && "h-10 px-3 gap-2 text-sm", this.size === 'lg' && "h-11 px-4 gap-3 text-base",
|
|
2379
|
+
// Focus state - SIMPLE LIKE ZARDUI
|
|
2380
|
+
!(this.readonly || this.disabled) && [
|
|
2381
|
+
"focus-within:border-primary/80",
|
|
2382
|
+
"focus-within:ring-4",
|
|
2383
|
+
"focus-within:ring-ring/30",
|
|
2384
|
+
"focus-within:ring-offset-0",
|
|
2385
|
+
"focus-within:shadow-none",
|
|
2386
|
+
],
|
|
2387
|
+
// Error state
|
|
2388
|
+
this.error && [
|
|
2389
|
+
"border-destructive",
|
|
2390
|
+
!(this.readonly || this.disabled) && [
|
|
2391
|
+
"focus-within:border-destructive/80",
|
|
2392
|
+
"focus-within:ring-destructive/30"
|
|
2393
|
+
]
|
|
2394
|
+
],
|
|
2395
|
+
// Disabled state
|
|
2396
|
+
this.disabled && [
|
|
2397
|
+
"cursor-not-allowed opacity-50",
|
|
2398
|
+
"border-opacity-50"
|
|
2399
|
+
],
|
|
2400
|
+
// Readonly state
|
|
2401
|
+
this.readonly && [
|
|
2402
|
+
"cursor-default",
|
|
2403
|
+
"border-dashed",
|
|
2404
|
+
!this.disabled && "focus-within:ring-0 focus-within:border-opacity-100"
|
|
2405
|
+
], this.containerClass);
|
|
2406
|
+
}
|
|
2072
2407
|
get computedInputClass() {
|
|
2073
|
-
return cn(
|
|
2408
|
+
return cn(
|
|
2409
|
+
// Base styles
|
|
2410
|
+
"flex-1 bg-transparent border-none p-0", "placeholder:text-muted-foreground",
|
|
2411
|
+
// Remove all default focus styles
|
|
2412
|
+
"focus:outline-none focus:ring-0 focus:shadow-none",
|
|
2413
|
+
// Text sizing
|
|
2414
|
+
this.size === 'xs' && "text-xs", this.size === 'sm' && "text-sm", this.size === 'default' && "text-sm", this.size === 'lg' && "text-base",
|
|
2415
|
+
// Cursor states
|
|
2416
|
+
this.disabled && "cursor-not-allowed", this.readonly && "cursor-default",
|
|
2417
|
+
// Text color
|
|
2418
|
+
"text-foreground",
|
|
2419
|
+
// Selection color
|
|
2420
|
+
"selection:bg-primary/20 selection:text-foreground", this.class);
|
|
2421
|
+
}
|
|
2422
|
+
focusInput() {
|
|
2423
|
+
if (!this.disabled && this.inputEl) {
|
|
2424
|
+
this.inputEl.nativeElement.focus();
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
onFocus() {
|
|
2428
|
+
this.isFocused = true;
|
|
2429
|
+
}
|
|
2430
|
+
onBlur() {
|
|
2431
|
+
this.isFocused = false;
|
|
2432
|
+
this.onTouched();
|
|
2074
2433
|
}
|
|
2075
2434
|
// --- Masking Logic ---
|
|
2076
2435
|
onInput(event) {
|
|
2436
|
+
if (this.readonly || this.disabled)
|
|
2437
|
+
return;
|
|
2077
2438
|
const input = event.target;
|
|
2078
2439
|
const raw = this.unmask(input.value);
|
|
2079
2440
|
const masked = this.applyMask(raw);
|
|
@@ -2107,47 +2468,90 @@ class MaskedInputComponent {
|
|
|
2107
2468
|
}
|
|
2108
2469
|
return formatted;
|
|
2109
2470
|
}
|
|
2110
|
-
unmask(val) {
|
|
2471
|
+
unmask(val) {
|
|
2472
|
+
return val.replace(/[^a-zA-Z0-9]/g, '');
|
|
2473
|
+
}
|
|
2111
2474
|
writeValue(value) {
|
|
2112
2475
|
this.displayValue = value ? this.applyMask(this.unmask(value.toString())) : '';
|
|
2113
2476
|
this.cdr.markForCheck();
|
|
2114
2477
|
}
|
|
2115
|
-
registerOnChange(fn) {
|
|
2116
|
-
|
|
2117
|
-
|
|
2478
|
+
registerOnChange(fn) {
|
|
2479
|
+
this.onChange = fn;
|
|
2480
|
+
}
|
|
2481
|
+
registerOnTouched(fn) {
|
|
2482
|
+
this.onTouched = fn;
|
|
2483
|
+
}
|
|
2484
|
+
setDisabledState(isDisabled) {
|
|
2485
|
+
this.disabled = isDisabled;
|
|
2486
|
+
this.cdr.markForCheck();
|
|
2487
|
+
}
|
|
2118
2488
|
cn = cn;
|
|
2119
2489
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MaskedInputComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2120
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MaskedInputComponent, isStandalone: true, selector: "tolle-masked-input", inputs: { mask: "mask", placeholder: "placeholder", type: "type", disabled: "disabled", class: "class", error: "error", size: "size", returnRaw: "returnRaw" }, providers: [
|
|
2490
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MaskedInputComponent, isStandalone: true, selector: "tolle-masked-input", inputs: { id: "id", label: "label", hint: "hint", errorMessage: "errorMessage", mask: "mask", placeholder: "placeholder", type: "type", disabled: "disabled", readonly: "readonly", class: "class", containerClass: "containerClass", error: "error", size: "size", returnRaw: "returnRaw", hideHintOnFocus: "hideHintOnFocus" }, providers: [
|
|
2121
2491
|
{
|
|
2122
2492
|
provide: NG_VALUE_ACCESSOR,
|
|
2123
2493
|
useExisting: forwardRef(() => MaskedInputComponent),
|
|
2124
2494
|
multi: true
|
|
2125
2495
|
}
|
|
2126
2496
|
], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, static: true }], ngImport: i0, template: `
|
|
2127
|
-
<div
|
|
2497
|
+
<div class="flex flex-col gap-1.5 w-full">
|
|
2498
|
+
<label
|
|
2499
|
+
*ngIf="label"
|
|
2500
|
+
[for]="id"
|
|
2501
|
+
[class]="computedLabelClass"
|
|
2502
|
+
>
|
|
2503
|
+
{{ label }}
|
|
2504
|
+
</label>
|
|
2128
2505
|
|
|
2129
|
-
<div
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2506
|
+
<div
|
|
2507
|
+
[class]="computedContainerClass"
|
|
2508
|
+
(click)="focusInput()"
|
|
2509
|
+
>
|
|
2510
|
+
<!-- Prefix Icon -->
|
|
2511
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
2512
|
+
<ng-content select="[prefix]"></ng-content>
|
|
2513
|
+
</div>
|
|
2133
2514
|
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2515
|
+
<input
|
|
2516
|
+
#inputEl
|
|
2517
|
+
[id]="id"
|
|
2518
|
+
[type]="type"
|
|
2519
|
+
[placeholder]="placeholder"
|
|
2520
|
+
[disabled]="disabled"
|
|
2521
|
+
[readOnly]="readonly"
|
|
2522
|
+
[value]="displayValue"
|
|
2523
|
+
(input)="onInput($event)"
|
|
2524
|
+
(blur)="onBlur()"
|
|
2525
|
+
(focus)="onFocus()"
|
|
2526
|
+
[class]="computedInputClass"
|
|
2527
|
+
[attr.aria-invalid]="error"
|
|
2528
|
+
[attr.aria-describedby]="error && errorMessage ? id + '-error' : null"
|
|
2529
|
+
/>
|
|
2144
2530
|
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2531
|
+
<!-- Suffix Icon -->
|
|
2532
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
2533
|
+
<ng-content select="[suffix]"></ng-content>
|
|
2534
|
+
</div>
|
|
2148
2535
|
</div>
|
|
2536
|
+
|
|
2537
|
+
<ng-container *ngIf="!disabled">
|
|
2538
|
+
<p
|
|
2539
|
+
*ngIf="hint && !error"
|
|
2540
|
+
class="text-xs text-muted-foreground px-1 transition-opacity duration-200"
|
|
2541
|
+
[class.opacity-0]="isFocused && hideHintOnFocus"
|
|
2542
|
+
>
|
|
2543
|
+
{{ hint }}
|
|
2544
|
+
</p>
|
|
2545
|
+
<p
|
|
2546
|
+
*ngIf="error && errorMessage"
|
|
2547
|
+
[id]="id + '-error'"
|
|
2548
|
+
class="text-xs text-destructive px-1"
|
|
2549
|
+
>
|
|
2550
|
+
{{ errorMessage }}
|
|
2551
|
+
</p>
|
|
2552
|
+
</ng-container>
|
|
2149
2553
|
</div>
|
|
2150
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
|
|
2554
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }] });
|
|
2151
2555
|
}
|
|
2152
2556
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MaskedInputComponent, decorators: [{
|
|
2153
2557
|
type: Component,
|
|
@@ -2163,32 +2567,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2163
2567
|
}
|
|
2164
2568
|
],
|
|
2165
2569
|
template: `
|
|
2166
|
-
<div
|
|
2570
|
+
<div class="flex flex-col gap-1.5 w-full">
|
|
2571
|
+
<label
|
|
2572
|
+
*ngIf="label"
|
|
2573
|
+
[for]="id"
|
|
2574
|
+
[class]="computedLabelClass"
|
|
2575
|
+
>
|
|
2576
|
+
{{ label }}
|
|
2577
|
+
</label>
|
|
2167
2578
|
|
|
2168
|
-
<div
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2579
|
+
<div
|
|
2580
|
+
[class]="computedContainerClass"
|
|
2581
|
+
(click)="focusInput()"
|
|
2582
|
+
>
|
|
2583
|
+
<!-- Prefix Icon -->
|
|
2584
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
2585
|
+
<ng-content select="[prefix]"></ng-content>
|
|
2586
|
+
</div>
|
|
2172
2587
|
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2588
|
+
<input
|
|
2589
|
+
#inputEl
|
|
2590
|
+
[id]="id"
|
|
2591
|
+
[type]="type"
|
|
2592
|
+
[placeholder]="placeholder"
|
|
2593
|
+
[disabled]="disabled"
|
|
2594
|
+
[readOnly]="readonly"
|
|
2595
|
+
[value]="displayValue"
|
|
2596
|
+
(input)="onInput($event)"
|
|
2597
|
+
(blur)="onBlur()"
|
|
2598
|
+
(focus)="onFocus()"
|
|
2599
|
+
[class]="computedInputClass"
|
|
2600
|
+
[attr.aria-invalid]="error"
|
|
2601
|
+
[attr.aria-describedby]="error && errorMessage ? id + '-error' : null"
|
|
2602
|
+
/>
|
|
2183
2603
|
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2604
|
+
<!-- Suffix Icon -->
|
|
2605
|
+
<div class="flex items-center text-muted-foreground group-focus-within:text-primary transition-colors duration-200">
|
|
2606
|
+
<ng-content select="[suffix]"></ng-content>
|
|
2607
|
+
</div>
|
|
2187
2608
|
</div>
|
|
2609
|
+
|
|
2610
|
+
<ng-container *ngIf="!disabled">
|
|
2611
|
+
<p
|
|
2612
|
+
*ngIf="hint && !error"
|
|
2613
|
+
class="text-xs text-muted-foreground px-1 transition-opacity duration-200"
|
|
2614
|
+
[class.opacity-0]="isFocused && hideHintOnFocus"
|
|
2615
|
+
>
|
|
2616
|
+
{{ hint }}
|
|
2617
|
+
</p>
|
|
2618
|
+
<p
|
|
2619
|
+
*ngIf="error && errorMessage"
|
|
2620
|
+
[id]="id + '-error'"
|
|
2621
|
+
class="text-xs text-destructive px-1"
|
|
2622
|
+
>
|
|
2623
|
+
{{ errorMessage }}
|
|
2624
|
+
</p>
|
|
2625
|
+
</ng-container>
|
|
2188
2626
|
</div>
|
|
2189
2627
|
`
|
|
2190
2628
|
}]
|
|
2191
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: {
|
|
2629
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { id: [{
|
|
2630
|
+
type: Input
|
|
2631
|
+
}], label: [{
|
|
2632
|
+
type: Input
|
|
2633
|
+
}], hint: [{
|
|
2634
|
+
type: Input
|
|
2635
|
+
}], errorMessage: [{
|
|
2636
|
+
type: Input
|
|
2637
|
+
}], mask: [{
|
|
2192
2638
|
type: Input
|
|
2193
2639
|
}], placeholder: [{
|
|
2194
2640
|
type: Input
|
|
@@ -2196,14 +2642,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2196
2642
|
type: Input
|
|
2197
2643
|
}], disabled: [{
|
|
2198
2644
|
type: Input
|
|
2645
|
+
}], readonly: [{
|
|
2646
|
+
type: Input
|
|
2199
2647
|
}], class: [{
|
|
2200
2648
|
type: Input
|
|
2649
|
+
}], containerClass: [{
|
|
2650
|
+
type: Input
|
|
2201
2651
|
}], error: [{
|
|
2202
2652
|
type: Input
|
|
2203
2653
|
}], size: [{
|
|
2204
2654
|
type: Input
|
|
2205
2655
|
}], returnRaw: [{
|
|
2206
2656
|
type: Input
|
|
2657
|
+
}], hideHintOnFocus: [{
|
|
2658
|
+
type: Input
|
|
2207
2659
|
}], inputEl: [{
|
|
2208
2660
|
type: ViewChild,
|
|
2209
2661
|
args: ['inputEl', { static: true }]
|
|
@@ -2356,7 +2808,7 @@ class DatePickerComponent {
|
|
|
2356
2808
|
></tolle-calendar>
|
|
2357
2809
|
</div>
|
|
2358
2810
|
</div>
|
|
2359
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MaskedInputComponent, selector: "tolle-masked-input", inputs: ["mask", "placeholder", "type", "disabled", "class", "error", "size", "returnRaw"] }, { kind: "component", type: CalendarComponent, selector: "tolle-calendar", inputs: ["class", "disablePastDates"] }] });
|
|
2811
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MaskedInputComponent, selector: "tolle-masked-input", inputs: ["id", "label", "hint", "errorMessage", "mask", "placeholder", "type", "disabled", "readonly", "class", "containerClass", "error", "size", "returnRaw", "hideHintOnFocus"] }, { kind: "component", type: CalendarComponent, selector: "tolle-calendar", inputs: ["class", "disablePastDates"] }] });
|
|
2360
2812
|
}
|
|
2361
2813
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatePickerComponent, decorators: [{
|
|
2362
2814
|
type: Component,
|
|
@@ -2948,7 +3400,7 @@ class DataTableComponent {
|
|
|
2948
3400
|
(onPageSizeChange)="updatePage()"
|
|
2949
3401
|
></tolle-pagination>
|
|
2950
3402
|
</div>
|
|
2951
|
-
`, isInline: true, 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"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PaginationComponent, selector: "tolle-pagination", inputs: ["class", "showPageLinks", "showPageOptions", "showCurrentPageInfo", "currentPageInfoTemplate", "totalRecords", "currentPageSize", "currentPage", "pageSizeOptions"], outputs: ["onPageNumberChange", "onPageSizeChange"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error"] }] });
|
|
3403
|
+
`, isInline: true, 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"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PaginationComponent, selector: "tolle-pagination", inputs: ["class", "showPageLinks", "showPageOptions", "showCurrentPageInfo", "currentPageInfoTemplate", "totalRecords", "currentPageSize", "currentPage", "pageSizeOptions"], outputs: ["onPageNumberChange", "onPageSizeChange"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error", "hideHintOnFocus"] }] });
|
|
2952
3404
|
}
|
|
2953
3405
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DataTableComponent, decorators: [{
|
|
2954
3406
|
type: Component,
|
|
@@ -3858,7 +4310,7 @@ class DateRangePickerComponent {
|
|
|
3858
4310
|
></tolle-range-calendar>
|
|
3859
4311
|
</div>
|
|
3860
4312
|
</div>
|
|
3861
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: RangeCalendarComponent, selector: "tolle-range-calendar", inputs: ["class", "disablePastDates"], outputs: ["rangeSelect"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error"] }] });
|
|
4313
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: RangeCalendarComponent, selector: "tolle-range-calendar", inputs: ["class", "disablePastDates"], outputs: ["rangeSelect"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["id", "label", "hint", "errorMessage", "type", "placeholder", "size", "containerClass", "class", "disabled", "readonly", "error", "hideHintOnFocus"] }] });
|
|
3862
4314
|
}
|
|
3863
4315
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateRangePickerComponent, decorators: [{
|
|
3864
4316
|
type: Component,
|
|
@@ -4076,30 +4528,69 @@ class TextareaComponent {
|
|
|
4076
4528
|
label = '';
|
|
4077
4529
|
placeholder = '';
|
|
4078
4530
|
hint = '';
|
|
4531
|
+
errorMessage = '';
|
|
4079
4532
|
rows = 3;
|
|
4080
4533
|
maxLength;
|
|
4081
4534
|
showCharacterCount = false;
|
|
4082
4535
|
autoGrow = false;
|
|
4083
4536
|
error = false;
|
|
4084
4537
|
className = '';
|
|
4538
|
+
// Focus behavior
|
|
4539
|
+
hideHintOnFocus = true;
|
|
4540
|
+
hideCharacterCountOnFocus = false;
|
|
4085
4541
|
// New States
|
|
4086
4542
|
disabled = false;
|
|
4087
4543
|
readonly = false;
|
|
4088
4544
|
value = '';
|
|
4545
|
+
isFocused = false;
|
|
4089
4546
|
onChange = () => { };
|
|
4090
4547
|
onTouched = () => { };
|
|
4091
4548
|
ngAfterViewInit() {
|
|
4092
4549
|
if (this.autoGrow)
|
|
4093
4550
|
this.resize();
|
|
4094
4551
|
}
|
|
4552
|
+
get computedLabelClass() {
|
|
4553
|
+
return cn("text-sm font-medium text-foreground leading-none transition-opacity duration-200", this.disabled && "opacity-50");
|
|
4554
|
+
}
|
|
4095
4555
|
get textareaClasses() {
|
|
4096
|
-
return cn(
|
|
4097
|
-
//
|
|
4098
|
-
|
|
4099
|
-
// Border
|
|
4100
|
-
|
|
4101
|
-
//
|
|
4102
|
-
|
|
4556
|
+
return cn(
|
|
4557
|
+
// Base styles
|
|
4558
|
+
'flex w-full rounded-md border bg-background px-3 py-2 text-sm', 'ring-offset-background transition-all duration-200', 'placeholder:text-muted-foreground',
|
|
4559
|
+
// Border and shadow
|
|
4560
|
+
'border-input shadow-sm',
|
|
4561
|
+
// Minimum height
|
|
4562
|
+
'min-h-[80px]',
|
|
4563
|
+
// Focus state - SIMPLE LIKE ZARDUI
|
|
4564
|
+
!(this.readonly || this.disabled) && [
|
|
4565
|
+
'focus:outline-none',
|
|
4566
|
+
'focus:ring-4',
|
|
4567
|
+
'focus:ring-ring/30',
|
|
4568
|
+
'focus:ring-offset-0',
|
|
4569
|
+
'focus:shadow-none',
|
|
4570
|
+
// Border darkens on focus automatically
|
|
4571
|
+
'focus:border-primary/80'
|
|
4572
|
+
],
|
|
4573
|
+
// Error state
|
|
4574
|
+
this.error && [
|
|
4575
|
+
'border-destructive',
|
|
4576
|
+
!(this.readonly || this.disabled) && [
|
|
4577
|
+
'focus:border-destructive/80',
|
|
4578
|
+
'focus:ring-destructive/30'
|
|
4579
|
+
]
|
|
4580
|
+
],
|
|
4581
|
+
// Disabled state
|
|
4582
|
+
this.disabled && [
|
|
4583
|
+
'cursor-not-allowed opacity-50',
|
|
4584
|
+
'border-opacity-50'
|
|
4585
|
+
],
|
|
4586
|
+
// Readonly state
|
|
4587
|
+
this.readonly && [
|
|
4588
|
+
'cursor-default',
|
|
4589
|
+
'border-dashed',
|
|
4590
|
+
!this.disabled && 'focus:ring-0 focus:border-opacity-100'
|
|
4591
|
+
],
|
|
4592
|
+
// Scrollbar styling
|
|
4593
|
+
'scrollbar-thin scrollbar-thumb-muted scrollbar-track-transparent', this.className);
|
|
4103
4594
|
}
|
|
4104
4595
|
handleInput(event) {
|
|
4105
4596
|
if (this.readonly || this.disabled)
|
|
@@ -4110,6 +4601,13 @@ class TextareaComponent {
|
|
|
4110
4601
|
if (this.autoGrow)
|
|
4111
4602
|
this.resize();
|
|
4112
4603
|
}
|
|
4604
|
+
onFocus() {
|
|
4605
|
+
this.isFocused = true;
|
|
4606
|
+
}
|
|
4607
|
+
onBlur() {
|
|
4608
|
+
this.isFocused = false;
|
|
4609
|
+
this.onTouched();
|
|
4610
|
+
}
|
|
4113
4611
|
resize() {
|
|
4114
4612
|
const textarea = this.textareaElement.nativeElement;
|
|
4115
4613
|
textarea.style.height = 'auto';
|
|
@@ -4120,11 +4618,17 @@ class TextareaComponent {
|
|
|
4120
4618
|
if (this.autoGrow)
|
|
4121
4619
|
setTimeout(() => this.resize());
|
|
4122
4620
|
}
|
|
4123
|
-
registerOnChange(fn) {
|
|
4124
|
-
|
|
4125
|
-
|
|
4621
|
+
registerOnChange(fn) {
|
|
4622
|
+
this.onChange = fn;
|
|
4623
|
+
}
|
|
4624
|
+
registerOnTouched(fn) {
|
|
4625
|
+
this.onTouched = fn;
|
|
4626
|
+
}
|
|
4627
|
+
setDisabledState(isDisabled) {
|
|
4628
|
+
this.disabled = isDisabled;
|
|
4629
|
+
}
|
|
4126
4630
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4127
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TextareaComponent, isStandalone: true, selector: "tolle-textarea", inputs: { id: "id", label: "label", placeholder: "placeholder", hint: "hint", rows: "rows", maxLength: "maxLength", showCharacterCount: "showCharacterCount", autoGrow: "autoGrow", error: "error", className: "className", disabled: "disabled", readonly: "readonly" }, providers: [
|
|
4631
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TextareaComponent, isStandalone: true, selector: "tolle-textarea", inputs: { id: "id", label: "label", placeholder: "placeholder", hint: "hint", errorMessage: "errorMessage", rows: "rows", maxLength: "maxLength", showCharacterCount: "showCharacterCount", autoGrow: "autoGrow", error: "error", className: "className", hideHintOnFocus: "hideHintOnFocus", hideCharacterCountOnFocus: "hideCharacterCountOnFocus", disabled: "disabled", readonly: "readonly" }, providers: [
|
|
4128
4632
|
{
|
|
4129
4633
|
provide: NG_VALUE_ACCESSOR,
|
|
4130
4634
|
useExisting: forwardRef(() => TextareaComponent),
|
|
@@ -4132,9 +4636,11 @@ class TextareaComponent {
|
|
|
4132
4636
|
}
|
|
4133
4637
|
], viewQueries: [{ propertyName: "textareaElement", first: true, predicate: ["textareaElement"], descendants: true }], ngImport: i0, template: `
|
|
4134
4638
|
<div class="flex flex-col gap-1.5 w-full">
|
|
4135
|
-
<label
|
|
4136
|
-
|
|
4137
|
-
|
|
4639
|
+
<label
|
|
4640
|
+
*ngIf="label"
|
|
4641
|
+
[for]="id"
|
|
4642
|
+
[class]="computedLabelClass"
|
|
4643
|
+
>
|
|
4138
4644
|
{{ label }}
|
|
4139
4645
|
</label>
|
|
4140
4646
|
|
|
@@ -4148,16 +4654,37 @@ class TextareaComponent {
|
|
|
4148
4654
|
[rows]="rows"
|
|
4149
4655
|
[(ngModel)]="value"
|
|
4150
4656
|
(input)="handleInput($event)"
|
|
4151
|
-
(blur)="
|
|
4657
|
+
(blur)="onBlur()"
|
|
4658
|
+
(focus)="onFocus()"
|
|
4152
4659
|
[class]="textareaClasses"
|
|
4153
4660
|
[style.resize]="(autoGrow || readonly || disabled) ? 'none' : 'vertical'"
|
|
4154
4661
|
[style.overflow]="autoGrow ? 'hidden' : 'auto'"
|
|
4662
|
+
[attr.aria-invalid]="error"
|
|
4663
|
+
[attr.aria-describedby]="error && errorMessage ? id + '-error' : null"
|
|
4664
|
+
[attr.maxlength]="maxLength"
|
|
4155
4665
|
></textarea>
|
|
4156
4666
|
</div>
|
|
4157
4667
|
|
|
4158
|
-
<div *ngIf="(showCharacterCount || hint) && !disabled" class="flex justify-between items-center px-1">
|
|
4159
|
-
<p
|
|
4160
|
-
|
|
4668
|
+
<div *ngIf="(showCharacterCount || hint || errorMessage) && !disabled" class="flex justify-between items-center px-1">
|
|
4669
|
+
<p
|
|
4670
|
+
*ngIf="hint && !error"
|
|
4671
|
+
class="text-xs text-muted-foreground transition-opacity duration-200"
|
|
4672
|
+
[class.opacity-0]="isFocused && hideHintOnFocus"
|
|
4673
|
+
>
|
|
4674
|
+
{{ hint }}
|
|
4675
|
+
</p>
|
|
4676
|
+
<p
|
|
4677
|
+
*ngIf="error && errorMessage"
|
|
4678
|
+
[id]="id + '-error'"
|
|
4679
|
+
class="text-xs text-destructive"
|
|
4680
|
+
>
|
|
4681
|
+
{{ errorMessage }}
|
|
4682
|
+
</p>
|
|
4683
|
+
<p
|
|
4684
|
+
*ngIf="showCharacterCount"
|
|
4685
|
+
class="text-[10px] uppercase tracking-wider text-muted-foreground ml-auto font-medium transition-opacity duration-200"
|
|
4686
|
+
[class.opacity-0]="isFocused && hideCharacterCountOnFocus"
|
|
4687
|
+
>
|
|
4161
4688
|
{{ value.length || 0 }}{{ maxLength ? ' / ' + maxLength : '' }}
|
|
4162
4689
|
</p>
|
|
4163
4690
|
</div>
|
|
@@ -4179,9 +4706,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4179
4706
|
],
|
|
4180
4707
|
template: `
|
|
4181
4708
|
<div class="flex flex-col gap-1.5 w-full">
|
|
4182
|
-
<label
|
|
4183
|
-
|
|
4184
|
-
|
|
4709
|
+
<label
|
|
4710
|
+
*ngIf="label"
|
|
4711
|
+
[for]="id"
|
|
4712
|
+
[class]="computedLabelClass"
|
|
4713
|
+
>
|
|
4185
4714
|
{{ label }}
|
|
4186
4715
|
</label>
|
|
4187
4716
|
|
|
@@ -4195,16 +4724,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4195
4724
|
[rows]="rows"
|
|
4196
4725
|
[(ngModel)]="value"
|
|
4197
4726
|
(input)="handleInput($event)"
|
|
4198
|
-
(blur)="
|
|
4727
|
+
(blur)="onBlur()"
|
|
4728
|
+
(focus)="onFocus()"
|
|
4199
4729
|
[class]="textareaClasses"
|
|
4200
4730
|
[style.resize]="(autoGrow || readonly || disabled) ? 'none' : 'vertical'"
|
|
4201
4731
|
[style.overflow]="autoGrow ? 'hidden' : 'auto'"
|
|
4732
|
+
[attr.aria-invalid]="error"
|
|
4733
|
+
[attr.aria-describedby]="error && errorMessage ? id + '-error' : null"
|
|
4734
|
+
[attr.maxlength]="maxLength"
|
|
4202
4735
|
></textarea>
|
|
4203
4736
|
</div>
|
|
4204
4737
|
|
|
4205
|
-
<div *ngIf="(showCharacterCount || hint) && !disabled" class="flex justify-between items-center px-1">
|
|
4206
|
-
<p
|
|
4207
|
-
|
|
4738
|
+
<div *ngIf="(showCharacterCount || hint || errorMessage) && !disabled" class="flex justify-between items-center px-1">
|
|
4739
|
+
<p
|
|
4740
|
+
*ngIf="hint && !error"
|
|
4741
|
+
class="text-xs text-muted-foreground transition-opacity duration-200"
|
|
4742
|
+
[class.opacity-0]="isFocused && hideHintOnFocus"
|
|
4743
|
+
>
|
|
4744
|
+
{{ hint }}
|
|
4745
|
+
</p>
|
|
4746
|
+
<p
|
|
4747
|
+
*ngIf="error && errorMessage"
|
|
4748
|
+
[id]="id + '-error'"
|
|
4749
|
+
class="text-xs text-destructive"
|
|
4750
|
+
>
|
|
4751
|
+
{{ errorMessage }}
|
|
4752
|
+
</p>
|
|
4753
|
+
<p
|
|
4754
|
+
*ngIf="showCharacterCount"
|
|
4755
|
+
class="text-[10px] uppercase tracking-wider text-muted-foreground ml-auto font-medium transition-opacity duration-200"
|
|
4756
|
+
[class.opacity-0]="isFocused && hideCharacterCountOnFocus"
|
|
4757
|
+
>
|
|
4208
4758
|
{{ value.length || 0 }}{{ maxLength ? ' / ' + maxLength : '' }}
|
|
4209
4759
|
</p>
|
|
4210
4760
|
</div>
|
|
@@ -4222,6 +4772,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4222
4772
|
type: Input
|
|
4223
4773
|
}], hint: [{
|
|
4224
4774
|
type: Input
|
|
4775
|
+
}], errorMessage: [{
|
|
4776
|
+
type: Input
|
|
4225
4777
|
}], rows: [{
|
|
4226
4778
|
type: Input
|
|
4227
4779
|
}], maxLength: [{
|
|
@@ -4234,12 +4786,989 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4234
4786
|
type: Input
|
|
4235
4787
|
}], className: [{
|
|
4236
4788
|
type: Input
|
|
4789
|
+
}], hideHintOnFocus: [{
|
|
4790
|
+
type: Input
|
|
4791
|
+
}], hideCharacterCountOnFocus: [{
|
|
4792
|
+
type: Input
|
|
4237
4793
|
}], disabled: [{
|
|
4238
4794
|
type: Input
|
|
4239
4795
|
}], readonly: [{
|
|
4240
4796
|
type: Input
|
|
4241
4797
|
}] } });
|
|
4242
4798
|
|
|
4799
|
+
const alertVariants = cva("relative w-full rounded-lg border p-4 transition-all duration-300 [&>i~div]:pl-7 [&>i]:absolute [&>i]:left-4 [&>i]:top-4 [&>i]:text-foreground", {
|
|
4800
|
+
variants: {
|
|
4801
|
+
variant: {
|
|
4802
|
+
default: "bg-background text-foreground",
|
|
4803
|
+
destructive: "border-destructive/50 text-destructive dark:border-destructive [&>i]:text-destructive",
|
|
4804
|
+
success: "border-emerald-500/50 text-emerald-700 dark:text-emerald-400 [&>i]:text-emerald-600",
|
|
4805
|
+
warning: "border-amber-500/50 text-amber-700 dark:text-amber-400 [&>i]:text-amber-600",
|
|
4806
|
+
},
|
|
4807
|
+
},
|
|
4808
|
+
defaultVariants: {
|
|
4809
|
+
variant: "default",
|
|
4810
|
+
},
|
|
4811
|
+
});
|
|
4812
|
+
class AlertComponent {
|
|
4813
|
+
variant = 'default';
|
|
4814
|
+
title;
|
|
4815
|
+
class = '';
|
|
4816
|
+
dismissible = false;
|
|
4817
|
+
onClose = new EventEmitter();
|
|
4818
|
+
dismissed = false;
|
|
4819
|
+
isDismissing = false;
|
|
4820
|
+
alertVariants = alertVariants;
|
|
4821
|
+
cn = cn;
|
|
4822
|
+
dismiss() {
|
|
4823
|
+
this.isDismissing = true;
|
|
4824
|
+
// Wait for animation to finish before removing from DOM
|
|
4825
|
+
setTimeout(() => {
|
|
4826
|
+
this.dismissed = true;
|
|
4827
|
+
this.onClose.emit();
|
|
4828
|
+
}, 300);
|
|
4829
|
+
}
|
|
4830
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4831
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AlertComponent, isStandalone: true, selector: "tolle-alert", inputs: { variant: "variant", title: "title", class: "class", dismissible: "dismissible" }, outputs: { onClose: "onClose" }, ngImport: i0, template: `
|
|
4832
|
+
<div
|
|
4833
|
+
*ngIf="!dismissed"
|
|
4834
|
+
[class]="cn(alertVariants({ variant }), class)"
|
|
4835
|
+
[class.opacity-0]="isDismissing"
|
|
4836
|
+
[class.scale-95]="isDismissing"
|
|
4837
|
+
role="alert"
|
|
4838
|
+
>
|
|
4839
|
+
<ng-content select="[icon]"></ng-content>
|
|
4840
|
+
|
|
4841
|
+
<button
|
|
4842
|
+
*ngIf="dismissible"
|
|
4843
|
+
(click)="dismiss()"
|
|
4844
|
+
class="absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 group-hover:opacity-100"
|
|
4845
|
+
[class.opacity-100]="dismissible"
|
|
4846
|
+
>
|
|
4847
|
+
<i class="ri-close-line text-lg"></i>
|
|
4848
|
+
</button>
|
|
4849
|
+
|
|
4850
|
+
<div>
|
|
4851
|
+
<h5 *ngIf="title" class="mb-1 font-medium leading-none tracking-tight">
|
|
4852
|
+
{{ title }}
|
|
4853
|
+
</h5>
|
|
4854
|
+
<div class="text-sm [&_p]:leading-relaxed">
|
|
4855
|
+
<ng-content></ng-content>
|
|
4856
|
+
</div>
|
|
4857
|
+
</div>
|
|
4858
|
+
</div>
|
|
4859
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
4860
|
+
}
|
|
4861
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AlertComponent, decorators: [{
|
|
4862
|
+
type: Component,
|
|
4863
|
+
args: [{
|
|
4864
|
+
selector: 'tolle-alert',
|
|
4865
|
+
standalone: true,
|
|
4866
|
+
imports: [CommonModule],
|
|
4867
|
+
template: `
|
|
4868
|
+
<div
|
|
4869
|
+
*ngIf="!dismissed"
|
|
4870
|
+
[class]="cn(alertVariants({ variant }), class)"
|
|
4871
|
+
[class.opacity-0]="isDismissing"
|
|
4872
|
+
[class.scale-95]="isDismissing"
|
|
4873
|
+
role="alert"
|
|
4874
|
+
>
|
|
4875
|
+
<ng-content select="[icon]"></ng-content>
|
|
4876
|
+
|
|
4877
|
+
<button
|
|
4878
|
+
*ngIf="dismissible"
|
|
4879
|
+
(click)="dismiss()"
|
|
4880
|
+
class="absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 group-hover:opacity-100"
|
|
4881
|
+
[class.opacity-100]="dismissible"
|
|
4882
|
+
>
|
|
4883
|
+
<i class="ri-close-line text-lg"></i>
|
|
4884
|
+
</button>
|
|
4885
|
+
|
|
4886
|
+
<div>
|
|
4887
|
+
<h5 *ngIf="title" class="mb-1 font-medium leading-none tracking-tight">
|
|
4888
|
+
{{ title }}
|
|
4889
|
+
</h5>
|
|
4890
|
+
<div class="text-sm [&_p]:leading-relaxed">
|
|
4891
|
+
<ng-content></ng-content>
|
|
4892
|
+
</div>
|
|
4893
|
+
</div>
|
|
4894
|
+
</div>
|
|
4895
|
+
`,
|
|
4896
|
+
}]
|
|
4897
|
+
}], propDecorators: { variant: [{
|
|
4898
|
+
type: Input
|
|
4899
|
+
}], title: [{
|
|
4900
|
+
type: Input
|
|
4901
|
+
}], class: [{
|
|
4902
|
+
type: Input
|
|
4903
|
+
}], dismissible: [{
|
|
4904
|
+
type: Input
|
|
4905
|
+
}], onClose: [{
|
|
4906
|
+
type: Output
|
|
4907
|
+
}] } });
|
|
4908
|
+
|
|
4909
|
+
class AvatarComponent {
|
|
4910
|
+
cdr;
|
|
4911
|
+
src;
|
|
4912
|
+
alt = '';
|
|
4913
|
+
size = 'default';
|
|
4914
|
+
shape = 'circle';
|
|
4915
|
+
// We remove @Input() class because standard class="" attributes
|
|
4916
|
+
// on the tag will now work automatically with the host bindings.
|
|
4917
|
+
isLoading = true;
|
|
4918
|
+
hasError = false;
|
|
4919
|
+
constructor(cdr) {
|
|
4920
|
+
this.cdr = cdr;
|
|
4921
|
+
}
|
|
4922
|
+
onLoad() {
|
|
4923
|
+
this.isLoading = false;
|
|
4924
|
+
this.cdr.detectChanges();
|
|
4925
|
+
}
|
|
4926
|
+
onError() {
|
|
4927
|
+
this.isLoading = false;
|
|
4928
|
+
this.hasError = true;
|
|
4929
|
+
this.cdr.detectChanges();
|
|
4930
|
+
}
|
|
4931
|
+
// Apply styles directly to the <tolle-avatar> tag
|
|
4932
|
+
get hostClasses() {
|
|
4933
|
+
return cn(
|
|
4934
|
+
// Layout & Shape
|
|
4935
|
+
"relative flex shrink-0 overflow-hidden bg-muted", this.shape === 'circle' ? 'rounded-full' : 'rounded-md',
|
|
4936
|
+
// Sizes
|
|
4937
|
+
this.size === 'sm' && "h-8 w-8 text-xs", this.size === 'default' && "h-10 w-10", this.size === 'lg' && "h-16 w-16 text-lg", this.size === 'xl' && "h-24 w-24 text-xl");
|
|
4938
|
+
}
|
|
4939
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AvatarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4940
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AvatarComponent, isStandalone: true, selector: "tolle-avatar", inputs: { src: "src", alt: "alt", size: "size", shape: "shape" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: `
|
|
4941
|
+
<!-- Image Layer -->
|
|
4942
|
+
<img *ngIf="src && !hasError"
|
|
4943
|
+
[src]="src"
|
|
4944
|
+
[alt]="alt"
|
|
4945
|
+
(load)="onLoad()"
|
|
4946
|
+
(error)="onError()"
|
|
4947
|
+
[class.opacity-0]="isLoading"
|
|
4948
|
+
class="h-full w-full object-cover transition-opacity duration-300" />
|
|
4949
|
+
|
|
4950
|
+
<!-- Fallback Layer -->
|
|
4951
|
+
<div *ngIf="hasError || !src || isLoading" class="flex h-full w-full items-center justify-center bg-muted">
|
|
4952
|
+
<ng-content></ng-content>
|
|
4953
|
+
</div>
|
|
4954
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
4955
|
+
}
|
|
4956
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AvatarComponent, decorators: [{
|
|
4957
|
+
type: Component,
|
|
4958
|
+
args: [{
|
|
4959
|
+
selector: 'tolle-avatar',
|
|
4960
|
+
standalone: true,
|
|
4961
|
+
imports: [NgIf],
|
|
4962
|
+
template: `
|
|
4963
|
+
<!-- Image Layer -->
|
|
4964
|
+
<img *ngIf="src && !hasError"
|
|
4965
|
+
[src]="src"
|
|
4966
|
+
[alt]="alt"
|
|
4967
|
+
(load)="onLoad()"
|
|
4968
|
+
(error)="onError()"
|
|
4969
|
+
[class.opacity-0]="isLoading"
|
|
4970
|
+
class="h-full w-full object-cover transition-opacity duration-300" />
|
|
4971
|
+
|
|
4972
|
+
<!-- Fallback Layer -->
|
|
4973
|
+
<div *ngIf="hasError || !src || isLoading" class="flex h-full w-full items-center justify-center bg-muted">
|
|
4974
|
+
<ng-content></ng-content>
|
|
4975
|
+
</div>
|
|
4976
|
+
`
|
|
4977
|
+
}]
|
|
4978
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { src: [{
|
|
4979
|
+
type: Input
|
|
4980
|
+
}], alt: [{
|
|
4981
|
+
type: Input
|
|
4982
|
+
}], size: [{
|
|
4983
|
+
type: Input
|
|
4984
|
+
}], shape: [{
|
|
4985
|
+
type: Input
|
|
4986
|
+
}], hostClasses: [{
|
|
4987
|
+
type: HostBinding,
|
|
4988
|
+
args: ['class']
|
|
4989
|
+
}] } });
|
|
4990
|
+
|
|
4991
|
+
class AvatarFallbackComponent {
|
|
4992
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AvatarFallbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4993
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AvatarFallbackComponent, isStandalone: true, selector: "tolle-avatar-fallback", ngImport: i0, template: `
|
|
4994
|
+
<div class="flex h-full w-full items-center justify-center bg-muted text-muted-foreground font-medium uppercase">
|
|
4995
|
+
<ng-content></ng-content>
|
|
4996
|
+
</div>
|
|
4997
|
+
`, isInline: true, styles: [""] });
|
|
4998
|
+
}
|
|
4999
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AvatarFallbackComponent, decorators: [{
|
|
5000
|
+
type: Component,
|
|
5001
|
+
args: [{ selector: 'tolle-avatar-fallback', standalone: true, imports: [], template: `
|
|
5002
|
+
<div class="flex h-full w-full items-center justify-center bg-muted text-muted-foreground font-medium uppercase">
|
|
5003
|
+
<ng-content></ng-content>
|
|
5004
|
+
</div>
|
|
5005
|
+
` }]
|
|
5006
|
+
}] });
|
|
5007
|
+
|
|
5008
|
+
class BreadcrumbComponent {
|
|
5009
|
+
class = '';
|
|
5010
|
+
cn = cn;
|
|
5011
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5012
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BreadcrumbComponent, isStandalone: true, selector: "tolle-breadcrumb", inputs: { class: "class" }, ngImport: i0, template: `
|
|
5013
|
+
<nav aria-label="breadcrumb" [class]="cn('flex flex-wrap items-center break-words text-sm text-muted-foreground', class)">
|
|
5014
|
+
<ol class="flex flex-wrap items-center gap-1.5 break-words">
|
|
5015
|
+
<ng-content></ng-content>
|
|
5016
|
+
</ol>
|
|
5017
|
+
</nav>
|
|
5018
|
+
`, isInline: true, styles: [""] });
|
|
5019
|
+
}
|
|
5020
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbComponent, decorators: [{
|
|
5021
|
+
type: Component,
|
|
5022
|
+
args: [{ selector: 'tolle-breadcrumb', standalone: true, imports: [], template: `
|
|
5023
|
+
<nav aria-label="breadcrumb" [class]="cn('flex flex-wrap items-center break-words text-sm text-muted-foreground', class)">
|
|
5024
|
+
<ol class="flex flex-wrap items-center gap-1.5 break-words">
|
|
5025
|
+
<ng-content></ng-content>
|
|
5026
|
+
</ol>
|
|
5027
|
+
</nav>
|
|
5028
|
+
` }]
|
|
5029
|
+
}], propDecorators: { class: [{
|
|
5030
|
+
type: Input
|
|
5031
|
+
}] } });
|
|
5032
|
+
|
|
5033
|
+
class BreadcrumbLinkComponent {
|
|
5034
|
+
active = false;
|
|
5035
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5036
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BreadcrumbLinkComponent, isStandalone: true, selector: "tolle-breadcrumb-link", inputs: { active: "active" }, ngImport: i0, template: `
|
|
5037
|
+
<ng-template #content>
|
|
5038
|
+
<ng-content></ng-content>
|
|
5039
|
+
</ng-template>
|
|
5040
|
+
|
|
5041
|
+
<ng-container *ngIf="active; else linkTemplate">
|
|
5042
|
+
<span
|
|
5043
|
+
role="link"
|
|
5044
|
+
aria-disabled="true"
|
|
5045
|
+
aria-current="page"
|
|
5046
|
+
class="font-normal text-foreground"
|
|
5047
|
+
>
|
|
5048
|
+
<ng-container *ngTemplateOutlet="content"></ng-container>
|
|
5049
|
+
</span>
|
|
5050
|
+
</ng-container>
|
|
5051
|
+
|
|
5052
|
+
<ng-template #linkTemplate>
|
|
5053
|
+
<div class="transition-colors hover:text-foreground cursor-pointer">
|
|
5054
|
+
<ng-container *ngTemplateOutlet="content"></ng-container>
|
|
5055
|
+
</div>
|
|
5056
|
+
</ng-template>
|
|
5057
|
+
`, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
5058
|
+
}
|
|
5059
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbLinkComponent, decorators: [{
|
|
5060
|
+
type: Component,
|
|
5061
|
+
args: [{ selector: 'tolle-breadcrumb-link', standalone: true, imports: [
|
|
5062
|
+
NgIf,
|
|
5063
|
+
NgTemplateOutlet
|
|
5064
|
+
], template: `
|
|
5065
|
+
<ng-template #content>
|
|
5066
|
+
<ng-content></ng-content>
|
|
5067
|
+
</ng-template>
|
|
5068
|
+
|
|
5069
|
+
<ng-container *ngIf="active; else linkTemplate">
|
|
5070
|
+
<span
|
|
5071
|
+
role="link"
|
|
5072
|
+
aria-disabled="true"
|
|
5073
|
+
aria-current="page"
|
|
5074
|
+
class="font-normal text-foreground"
|
|
5075
|
+
>
|
|
5076
|
+
<ng-container *ngTemplateOutlet="content"></ng-container>
|
|
5077
|
+
</span>
|
|
5078
|
+
</ng-container>
|
|
5079
|
+
|
|
5080
|
+
<ng-template #linkTemplate>
|
|
5081
|
+
<div class="transition-colors hover:text-foreground cursor-pointer">
|
|
5082
|
+
<ng-container *ngTemplateOutlet="content"></ng-container>
|
|
5083
|
+
</div>
|
|
5084
|
+
</ng-template>
|
|
5085
|
+
` }]
|
|
5086
|
+
}], propDecorators: { active: [{
|
|
5087
|
+
type: Input
|
|
5088
|
+
}] } });
|
|
5089
|
+
|
|
5090
|
+
class BreadcrumbSeparatorComponent {
|
|
5091
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbSeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5092
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BreadcrumbSeparatorComponent, isStandalone: true, selector: "tolle-breadcrumb-separator", ngImport: i0, template: `
|
|
5093
|
+
<li role="presentation" aria-hidden="true" class="[&>i]:size-3.5">
|
|
5094
|
+
<ng-content>
|
|
5095
|
+
<i class="ri-arrow-right-s-line"></i>
|
|
5096
|
+
</ng-content>
|
|
5097
|
+
</li>
|
|
5098
|
+
`, isInline: true, styles: [""] });
|
|
5099
|
+
}
|
|
5100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbSeparatorComponent, decorators: [{
|
|
5101
|
+
type: Component,
|
|
5102
|
+
args: [{ selector: 'tolle-breadcrumb-separator', standalone: true, imports: [], template: `
|
|
5103
|
+
<li role="presentation" aria-hidden="true" class="[&>i]:size-3.5">
|
|
5104
|
+
<ng-content>
|
|
5105
|
+
<i class="ri-arrow-right-s-line"></i>
|
|
5106
|
+
</ng-content>
|
|
5107
|
+
</li>
|
|
5108
|
+
` }]
|
|
5109
|
+
}] });
|
|
5110
|
+
|
|
5111
|
+
class BreadcrumbItemComponent {
|
|
5112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BreadcrumbItemComponent, isStandalone: true, selector: "tolle-breadcrumb-item", ngImport: i0, template: `
|
|
5114
|
+
<li class="inline-flex items-center gap-1.5">
|
|
5115
|
+
<ng-content></ng-content>
|
|
5116
|
+
</li>
|
|
5117
|
+
`, isInline: true, styles: [""] });
|
|
5118
|
+
}
|
|
5119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbItemComponent, decorators: [{
|
|
5120
|
+
type: Component,
|
|
5121
|
+
args: [{ selector: 'tolle-breadcrumb-item', standalone: true, imports: [], template: `
|
|
5122
|
+
<li class="inline-flex items-center gap-1.5">
|
|
5123
|
+
<ng-content></ng-content>
|
|
5124
|
+
</li>
|
|
5125
|
+
` }]
|
|
5126
|
+
}] });
|
|
5127
|
+
|
|
5128
|
+
const emptyStateVariants = cva("flex flex-col items-center justify-center text-center animate-in fade-in duration-500", {
|
|
5129
|
+
variants: {
|
|
5130
|
+
variant: {
|
|
5131
|
+
default: "min-h-[400px] rounded-md border border-dashed border-border p-8 bg-background/50",
|
|
5132
|
+
minimal: "p-4 min-h-[200px]",
|
|
5133
|
+
},
|
|
5134
|
+
},
|
|
5135
|
+
defaultVariants: {
|
|
5136
|
+
variant: "default",
|
|
5137
|
+
},
|
|
5138
|
+
});
|
|
5139
|
+
class EmptyStateComponent {
|
|
5140
|
+
variant = 'default';
|
|
5141
|
+
title = 'No items found';
|
|
5142
|
+
description;
|
|
5143
|
+
class = '';
|
|
5144
|
+
emptyStateVariants = emptyStateVariants;
|
|
5145
|
+
cn = cn;
|
|
5146
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5147
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: EmptyStateComponent, isStandalone: true, selector: "tolle-empty-state", inputs: { variant: "variant", title: "title", description: "description", class: "class" }, ngImport: i0, template: `
|
|
5148
|
+
<div [class]="cn(emptyStateVariants({ variant }), class)">
|
|
5149
|
+
|
|
5150
|
+
<div [class]="cn(
|
|
5151
|
+
'flex items-center justify-center rounded-full bg-muted',
|
|
5152
|
+
variant === 'minimal' ? 'h-12 w-12' : 'h-20 w-20'
|
|
5153
|
+
)">
|
|
5154
|
+
<ng-content select="[icon]">
|
|
5155
|
+
<i [class]="cn(
|
|
5156
|
+
'ri-inbox-line text-muted-foreground/60',
|
|
5157
|
+
variant === 'minimal' ? 'text-xl' : 'text-3xl'
|
|
5158
|
+
)"></i>
|
|
5159
|
+
</ng-content>
|
|
5160
|
+
</div>
|
|
5161
|
+
|
|
5162
|
+
<h3 [class]="cn(
|
|
5163
|
+
'font-semibold text-foreground',
|
|
5164
|
+
variant === 'minimal' ? 'mt-2 text-sm' : 'mt-4 text-lg'
|
|
5165
|
+
)">
|
|
5166
|
+
{{ title }}
|
|
5167
|
+
</h3>
|
|
5168
|
+
|
|
5169
|
+
<p *ngIf="description" [class]="cn(
|
|
5170
|
+
'text-muted-foreground',
|
|
5171
|
+
variant === 'minimal' ? 'mt-1 text-xs' : 'mb-6 mt-2 max-w-sm text-sm'
|
|
5172
|
+
)">
|
|
5173
|
+
{{ description }}
|
|
5174
|
+
</p>
|
|
5175
|
+
|
|
5176
|
+
<div *ngIf="variant !== 'minimal'" class="flex items-center justify-center gap-3">
|
|
5177
|
+
<ng-content select="[actions]"></ng-content>
|
|
5178
|
+
</div>
|
|
5179
|
+
</div>
|
|
5180
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
5181
|
+
}
|
|
5182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EmptyStateComponent, decorators: [{
|
|
5183
|
+
type: Component,
|
|
5184
|
+
args: [{
|
|
5185
|
+
selector: 'tolle-empty-state',
|
|
5186
|
+
standalone: true,
|
|
5187
|
+
imports: [CommonModule],
|
|
5188
|
+
template: `
|
|
5189
|
+
<div [class]="cn(emptyStateVariants({ variant }), class)">
|
|
5190
|
+
|
|
5191
|
+
<div [class]="cn(
|
|
5192
|
+
'flex items-center justify-center rounded-full bg-muted',
|
|
5193
|
+
variant === 'minimal' ? 'h-12 w-12' : 'h-20 w-20'
|
|
5194
|
+
)">
|
|
5195
|
+
<ng-content select="[icon]">
|
|
5196
|
+
<i [class]="cn(
|
|
5197
|
+
'ri-inbox-line text-muted-foreground/60',
|
|
5198
|
+
variant === 'minimal' ? 'text-xl' : 'text-3xl'
|
|
5199
|
+
)"></i>
|
|
5200
|
+
</ng-content>
|
|
5201
|
+
</div>
|
|
5202
|
+
|
|
5203
|
+
<h3 [class]="cn(
|
|
5204
|
+
'font-semibold text-foreground',
|
|
5205
|
+
variant === 'minimal' ? 'mt-2 text-sm' : 'mt-4 text-lg'
|
|
5206
|
+
)">
|
|
5207
|
+
{{ title }}
|
|
5208
|
+
</h3>
|
|
5209
|
+
|
|
5210
|
+
<p *ngIf="description" [class]="cn(
|
|
5211
|
+
'text-muted-foreground',
|
|
5212
|
+
variant === 'minimal' ? 'mt-1 text-xs' : 'mb-6 mt-2 max-w-sm text-sm'
|
|
5213
|
+
)">
|
|
5214
|
+
{{ description }}
|
|
5215
|
+
</p>
|
|
5216
|
+
|
|
5217
|
+
<div *ngIf="variant !== 'minimal'" class="flex items-center justify-center gap-3">
|
|
5218
|
+
<ng-content select="[actions]"></ng-content>
|
|
5219
|
+
</div>
|
|
5220
|
+
</div>
|
|
5221
|
+
`
|
|
5222
|
+
}]
|
|
5223
|
+
}], propDecorators: { variant: [{
|
|
5224
|
+
type: Input
|
|
5225
|
+
}], title: [{
|
|
5226
|
+
type: Input
|
|
5227
|
+
}], description: [{
|
|
5228
|
+
type: Input
|
|
5229
|
+
}], class: [{
|
|
5230
|
+
type: Input
|
|
5231
|
+
}] } });
|
|
5232
|
+
|
|
5233
|
+
class OtpComponent {
|
|
5234
|
+
cdr;
|
|
5235
|
+
length = 6;
|
|
5236
|
+
disabled = false;
|
|
5237
|
+
auto = false; // The toggle for automatic slot generation
|
|
5238
|
+
value = '';
|
|
5239
|
+
isFocused = false;
|
|
5240
|
+
onChange = () => { };
|
|
5241
|
+
onTouched = () => { };
|
|
5242
|
+
constructor(cdr) {
|
|
5243
|
+
this.cdr = cdr;
|
|
5244
|
+
}
|
|
5245
|
+
onInputChange(event) {
|
|
5246
|
+
const val = event.target.value.replace(/\D/g, '');
|
|
5247
|
+
this.value = val;
|
|
5248
|
+
this.onChange(val);
|
|
5249
|
+
this.cdr.markForCheck();
|
|
5250
|
+
}
|
|
5251
|
+
// Visual logic for the automated slots
|
|
5252
|
+
getSlotClass(index) {
|
|
5253
|
+
const isActive = this.isFocused && this.value.length === index;
|
|
5254
|
+
return cn('relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all bg-background', index === 0 && 'rounded-l-md border-l', index === this.length - 1 && 'rounded-r-md', isActive && 'z-30 ring-2 ring-ring ring-offset-background');
|
|
5255
|
+
}
|
|
5256
|
+
writeValue(value) { this.value = value || ''; this.cdr.markForCheck(); }
|
|
5257
|
+
registerOnChange(fn) { this.onChange = fn; }
|
|
5258
|
+
registerOnTouched(fn) { this.onTouched = fn; }
|
|
5259
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OtpComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5260
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: OtpComponent, isStandalone: true, selector: "tolle-otp", inputs: { length: "length", disabled: "disabled", auto: "auto" }, providers: [{
|
|
5261
|
+
provide: NG_VALUE_ACCESSOR,
|
|
5262
|
+
useExisting: forwardRef(() => OtpComponent),
|
|
5263
|
+
multi: true
|
|
5264
|
+
}], ngImport: i0, template: `
|
|
5265
|
+
<div class="relative flex items-center gap-2">
|
|
5266
|
+
<input
|
|
5267
|
+
#hiddenInput
|
|
5268
|
+
type="text"
|
|
5269
|
+
inputmode="numeric"
|
|
5270
|
+
autocomplete="one-time-code"
|
|
5271
|
+
[maxLength]="length"
|
|
5272
|
+
class="absolute inset-0 opacity-0 cursor-default z-20"
|
|
5273
|
+
[(ngModel)]="value"
|
|
5274
|
+
(input)="onInputChange($event)"
|
|
5275
|
+
(focus)="isFocused = true"
|
|
5276
|
+
(blur)="isFocused = false"
|
|
5277
|
+
[disabled]="disabled"
|
|
5278
|
+
/>
|
|
5279
|
+
|
|
5280
|
+
<div *ngIf="auto" class="flex items-center gap-2 pointer-events-none">
|
|
5281
|
+
<div class="flex items-center">
|
|
5282
|
+
<div *ngFor="let _ of [].constructor(length); let i = index"
|
|
5283
|
+
[class]="getSlotClass(i)"
|
|
5284
|
+
>
|
|
5285
|
+
{{ value[i] || '' }}
|
|
5286
|
+
<div *ngIf="isFocused && value.length === i" class="absolute inset-0 flex items-center justify-center">
|
|
5287
|
+
<div class="h-4 w-px animate-caret-blink bg-foreground duration-1000"></div>
|
|
5288
|
+
</div>
|
|
5289
|
+
</div>
|
|
5290
|
+
</div>
|
|
5291
|
+
</div>
|
|
5292
|
+
|
|
5293
|
+
<div *ngIf="!auto" class="flex items-center gap-2 pointer-events-none">
|
|
5294
|
+
<ng-content></ng-content>
|
|
5295
|
+
</div>
|
|
5296
|
+
</div>
|
|
5297
|
+
`, isInline: true, 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: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
5298
|
+
}
|
|
5299
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OtpComponent, decorators: [{
|
|
5300
|
+
type: Component,
|
|
5301
|
+
args: [{
|
|
5302
|
+
selector: 'tolle-otp',
|
|
5303
|
+
standalone: true,
|
|
5304
|
+
imports: [CommonModule, FormsModule],
|
|
5305
|
+
providers: [{
|
|
5306
|
+
provide: NG_VALUE_ACCESSOR,
|
|
5307
|
+
useExisting: forwardRef(() => OtpComponent),
|
|
5308
|
+
multi: true
|
|
5309
|
+
}],
|
|
5310
|
+
template: `
|
|
5311
|
+
<div class="relative flex items-center gap-2">
|
|
5312
|
+
<input
|
|
5313
|
+
#hiddenInput
|
|
5314
|
+
type="text"
|
|
5315
|
+
inputmode="numeric"
|
|
5316
|
+
autocomplete="one-time-code"
|
|
5317
|
+
[maxLength]="length"
|
|
5318
|
+
class="absolute inset-0 opacity-0 cursor-default z-20"
|
|
5319
|
+
[(ngModel)]="value"
|
|
5320
|
+
(input)="onInputChange($event)"
|
|
5321
|
+
(focus)="isFocused = true"
|
|
5322
|
+
(blur)="isFocused = false"
|
|
5323
|
+
[disabled]="disabled"
|
|
5324
|
+
/>
|
|
5325
|
+
|
|
5326
|
+
<div *ngIf="auto" class="flex items-center gap-2 pointer-events-none">
|
|
5327
|
+
<div class="flex items-center">
|
|
5328
|
+
<div *ngFor="let _ of [].constructor(length); let i = index"
|
|
5329
|
+
[class]="getSlotClass(i)"
|
|
5330
|
+
>
|
|
5331
|
+
{{ value[i] || '' }}
|
|
5332
|
+
<div *ngIf="isFocused && value.length === i" class="absolute inset-0 flex items-center justify-center">
|
|
5333
|
+
<div class="h-4 w-px animate-caret-blink bg-foreground duration-1000"></div>
|
|
5334
|
+
</div>
|
|
5335
|
+
</div>
|
|
5336
|
+
</div>
|
|
5337
|
+
</div>
|
|
5338
|
+
|
|
5339
|
+
<div *ngIf="!auto" class="flex items-center gap-2 pointer-events-none">
|
|
5340
|
+
<ng-content></ng-content>
|
|
5341
|
+
</div>
|
|
5342
|
+
</div>
|
|
5343
|
+
`
|
|
5344
|
+
}]
|
|
5345
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { length: [{
|
|
5346
|
+
type: Input
|
|
5347
|
+
}], disabled: [{
|
|
5348
|
+
type: Input
|
|
5349
|
+
}], auto: [{
|
|
5350
|
+
type: Input
|
|
5351
|
+
}] } });
|
|
5352
|
+
|
|
5353
|
+
class OtpSlotComponent {
|
|
5354
|
+
char = '';
|
|
5355
|
+
isActive = false;
|
|
5356
|
+
isFirst = false;
|
|
5357
|
+
isLast = false;
|
|
5358
|
+
class = '';
|
|
5359
|
+
cn = cn;
|
|
5360
|
+
get computedClass() {
|
|
5361
|
+
return cn(
|
|
5362
|
+
// Base styles (matching input container)
|
|
5363
|
+
'relative flex h-10 w-10 items-center justify-center', 'transition-all duration-200', 'text-center font-medium select-none',
|
|
5364
|
+
// Border styling - exactly like input
|
|
5365
|
+
'border border-input shadow-sm bg-background',
|
|
5366
|
+
// FOCUS STYLING - EXACTLY LIKE INPUT COMPONENT
|
|
5367
|
+
this.isActive && [
|
|
5368
|
+
// Darker border on focus
|
|
5369
|
+
'border-primary/80',
|
|
5370
|
+
// Remove shadow on focus
|
|
5371
|
+
'shadow-none',
|
|
5372
|
+
// Focus ring with same styling as input
|
|
5373
|
+
'ring-4',
|
|
5374
|
+
'ring-ring/30',
|
|
5375
|
+
'ring-offset-0',
|
|
5376
|
+
// Ensure it's above other slots
|
|
5377
|
+
'z-10'
|
|
5378
|
+
],
|
|
5379
|
+
// Filled state
|
|
5380
|
+
this.char && !this.isActive && 'border-primary/60',
|
|
5381
|
+
// Border radius
|
|
5382
|
+
this.isFirst && 'rounded-l-md', this.isLast && 'rounded-r-md',
|
|
5383
|
+
// Remove left border for all but first slot
|
|
5384
|
+
!this.isFirst && '-ml-px', this.class);
|
|
5385
|
+
}
|
|
5386
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OtpSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5387
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: OtpSlotComponent, isStandalone: true, selector: "tolle-otp-slot", inputs: { char: "char", isActive: "isActive", isFirst: "isFirst", isLast: "isLast", class: "class" }, ngImport: i0, template: `
|
|
5388
|
+
<div [class]="computedClass">
|
|
5389
|
+
<span class="text-lg font-medium">{{ char || '' }}</span>
|
|
5390
|
+
<div *ngIf="isActive && !char" class="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
5391
|
+
<div class="h-6 w-0.5 animate-caret-blink bg-foreground"></div>
|
|
5392
|
+
</div>
|
|
5393
|
+
</div>
|
|
5394
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
5395
|
+
}
|
|
5396
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OtpSlotComponent, decorators: [{
|
|
5397
|
+
type: Component,
|
|
5398
|
+
args: [{
|
|
5399
|
+
selector: 'tolle-otp-slot',
|
|
5400
|
+
standalone: true,
|
|
5401
|
+
imports: [NgIf],
|
|
5402
|
+
template: `
|
|
5403
|
+
<div [class]="computedClass">
|
|
5404
|
+
<span class="text-lg font-medium">{{ char || '' }}</span>
|
|
5405
|
+
<div *ngIf="isActive && !char" class="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
5406
|
+
<div class="h-6 w-0.5 animate-caret-blink bg-foreground"></div>
|
|
5407
|
+
</div>
|
|
5408
|
+
</div>
|
|
5409
|
+
`
|
|
5410
|
+
}]
|
|
5411
|
+
}], propDecorators: { char: [{
|
|
5412
|
+
type: Input
|
|
5413
|
+
}], isActive: [{
|
|
5414
|
+
type: Input
|
|
5415
|
+
}], isFirst: [{
|
|
5416
|
+
type: Input
|
|
5417
|
+
}], isLast: [{
|
|
5418
|
+
type: Input
|
|
5419
|
+
}], class: [{
|
|
5420
|
+
type: Input
|
|
5421
|
+
}] } });
|
|
5422
|
+
|
|
5423
|
+
class OtpGroupComponent {
|
|
5424
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OtpGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5425
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: OtpGroupComponent, isStandalone: true, selector: "tolle-otp-group", ngImport: i0, template: `
|
|
5426
|
+
<div class="flex items-center"><ng-content></ng-content></div>
|
|
5427
|
+
`, isInline: true, styles: [""] });
|
|
5428
|
+
}
|
|
5429
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OtpGroupComponent, decorators: [{
|
|
5430
|
+
type: Component,
|
|
5431
|
+
args: [{ selector: 'tolle-otp-group', standalone: true, imports: [], template: `
|
|
5432
|
+
<div class="flex items-center"><ng-content></ng-content></div>
|
|
5433
|
+
` }]
|
|
5434
|
+
}] });
|
|
5435
|
+
|
|
5436
|
+
class PopoverComponent {
|
|
5437
|
+
placement = 'bottom';
|
|
5438
|
+
onOpen = new EventEmitter();
|
|
5439
|
+
onClose = new EventEmitter();
|
|
5440
|
+
triggerEl;
|
|
5441
|
+
popoverEl;
|
|
5442
|
+
isOpen = false;
|
|
5443
|
+
cleanup;
|
|
5444
|
+
toggle() {
|
|
5445
|
+
this.isOpen ? this.close() : this.open();
|
|
5446
|
+
}
|
|
5447
|
+
open() {
|
|
5448
|
+
this.isOpen = true;
|
|
5449
|
+
this.onOpen.emit();
|
|
5450
|
+
setTimeout(() => this.updatePosition());
|
|
5451
|
+
}
|
|
5452
|
+
close() {
|
|
5453
|
+
this.isOpen = false;
|
|
5454
|
+
this.onClose.emit();
|
|
5455
|
+
if (this.cleanup)
|
|
5456
|
+
this.cleanup();
|
|
5457
|
+
}
|
|
5458
|
+
updatePosition() {
|
|
5459
|
+
if (!this.triggerEl || !this.popoverEl)
|
|
5460
|
+
return;
|
|
5461
|
+
this.cleanup = autoUpdate(this.triggerEl.nativeElement, this.popoverEl.nativeElement, () => {
|
|
5462
|
+
computePosition(this.triggerEl.nativeElement, this.popoverEl.nativeElement, {
|
|
5463
|
+
placement: this.placement,
|
|
5464
|
+
middleware: [offset(8), flip(), shift({ padding: 8 })],
|
|
5465
|
+
}).then(({ x, y }) => {
|
|
5466
|
+
Object.assign(this.popoverEl.nativeElement.style, {
|
|
5467
|
+
left: `${x}px`,
|
|
5468
|
+
top: `${y}px`,
|
|
5469
|
+
});
|
|
5470
|
+
});
|
|
5471
|
+
});
|
|
5472
|
+
}
|
|
5473
|
+
onClickOutside(event) {
|
|
5474
|
+
if (this.isOpen &&
|
|
5475
|
+
!this.triggerEl.nativeElement.contains(event.target) &&
|
|
5476
|
+
!this.popoverEl?.nativeElement.contains(event.target)) {
|
|
5477
|
+
this.close();
|
|
5478
|
+
}
|
|
5479
|
+
}
|
|
5480
|
+
ngOnDestroy() {
|
|
5481
|
+
if (this.cleanup)
|
|
5482
|
+
this.cleanup();
|
|
5483
|
+
}
|
|
5484
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5485
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PopoverComponent, isStandalone: true, selector: "tolle-popover", inputs: { placement: "placement" }, outputs: { onOpen: "onOpen", onClose: "onClose" }, host: { listeners: { "document:mousedown": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "popoverEl", first: true, predicate: ["popover"], descendants: true }], ngImport: i0, template: `
|
|
5486
|
+
<div class="inline-block" #trigger (click)="toggle()">
|
|
5487
|
+
<ng-content select="[trigger]"></ng-content>
|
|
5488
|
+
</div>
|
|
5489
|
+
|
|
5490
|
+
<div
|
|
5491
|
+
*ngIf="isOpen"
|
|
5492
|
+
#popover
|
|
5493
|
+
class="absolute top-0 left-0 w-max z-[9999]"
|
|
5494
|
+
>
|
|
5495
|
+
<ng-content></ng-content>
|
|
5496
|
+
</div>
|
|
5497
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
5498
|
+
}
|
|
5499
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
5500
|
+
type: Component,
|
|
5501
|
+
args: [{
|
|
5502
|
+
selector: 'tolle-popover',
|
|
5503
|
+
standalone: true,
|
|
5504
|
+
imports: [CommonModule],
|
|
5505
|
+
template: `
|
|
5506
|
+
<div class="inline-block" #trigger (click)="toggle()">
|
|
5507
|
+
<ng-content select="[trigger]"></ng-content>
|
|
5508
|
+
</div>
|
|
5509
|
+
|
|
5510
|
+
<div
|
|
5511
|
+
*ngIf="isOpen"
|
|
5512
|
+
#popover
|
|
5513
|
+
class="absolute top-0 left-0 w-max z-[9999]"
|
|
5514
|
+
>
|
|
5515
|
+
<ng-content></ng-content>
|
|
5516
|
+
</div>
|
|
5517
|
+
`,
|
|
5518
|
+
}]
|
|
5519
|
+
}], propDecorators: { placement: [{
|
|
5520
|
+
type: Input
|
|
5521
|
+
}], onOpen: [{
|
|
5522
|
+
type: Output
|
|
5523
|
+
}], onClose: [{
|
|
5524
|
+
type: Output
|
|
5525
|
+
}], triggerEl: [{
|
|
5526
|
+
type: ViewChild,
|
|
5527
|
+
args: ['trigger']
|
|
5528
|
+
}], popoverEl: [{
|
|
5529
|
+
type: ViewChild,
|
|
5530
|
+
args: ['popover']
|
|
5531
|
+
}], onClickOutside: [{
|
|
5532
|
+
type: HostListener,
|
|
5533
|
+
args: ['document:mousedown', ['$event']]
|
|
5534
|
+
}] } });
|
|
5535
|
+
|
|
5536
|
+
class PopoverContentComponent {
|
|
5537
|
+
class = '';
|
|
5538
|
+
cn = cn;
|
|
5539
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PopoverContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5540
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PopoverContentComponent, isStandalone: true, selector: "tolle-popover-content", inputs: { class: "class" }, ngImport: i0, template: `
|
|
5541
|
+
<div
|
|
5542
|
+
[class]="cn(
|
|
5543
|
+
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none',
|
|
5544
|
+
'animate-in fade-in zoom-in-95 duration-200',
|
|
5545
|
+
class
|
|
5546
|
+
)"
|
|
5547
|
+
role="dialog"
|
|
5548
|
+
>
|
|
5549
|
+
<ng-content></ng-content>
|
|
5550
|
+
</div>
|
|
5551
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
5552
|
+
}
|
|
5553
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PopoverContentComponent, decorators: [{
|
|
5554
|
+
type: Component,
|
|
5555
|
+
args: [{
|
|
5556
|
+
selector: 'tolle-popover-content',
|
|
5557
|
+
standalone: true,
|
|
5558
|
+
imports: [CommonModule],
|
|
5559
|
+
template: `
|
|
5560
|
+
<div
|
|
5561
|
+
[class]="cn(
|
|
5562
|
+
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none',
|
|
5563
|
+
'animate-in fade-in zoom-in-95 duration-200',
|
|
5564
|
+
class
|
|
5565
|
+
)"
|
|
5566
|
+
role="dialog"
|
|
5567
|
+
>
|
|
5568
|
+
<ng-content></ng-content>
|
|
5569
|
+
</div>
|
|
5570
|
+
`
|
|
5571
|
+
}]
|
|
5572
|
+
}], propDecorators: { class: [{
|
|
5573
|
+
type: Input
|
|
5574
|
+
}] } });
|
|
5575
|
+
|
|
5576
|
+
class RadioService {
|
|
5577
|
+
selectedValueSource = new BehaviorSubject(null);
|
|
5578
|
+
selectedValue$ = this.selectedValueSource.asObservable();
|
|
5579
|
+
disabledSource = new BehaviorSubject(false);
|
|
5580
|
+
disabled$ = this.disabledSource.asObservable();
|
|
5581
|
+
select(value) {
|
|
5582
|
+
if (!this.disabledSource.value) {
|
|
5583
|
+
this.selectedValueSource.next(value);
|
|
5584
|
+
}
|
|
5585
|
+
}
|
|
5586
|
+
setDisabled(isDisabled) {
|
|
5587
|
+
this.disabledSource.next(isDisabled);
|
|
5588
|
+
}
|
|
5589
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5590
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioService });
|
|
5591
|
+
}
|
|
5592
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioService, decorators: [{
|
|
5593
|
+
type: Injectable
|
|
5594
|
+
}] });
|
|
5595
|
+
|
|
5596
|
+
class RadioGroupComponent {
|
|
5597
|
+
radioService;
|
|
5598
|
+
class = '';
|
|
5599
|
+
disabled = false;
|
|
5600
|
+
name = `radio-group-${Math.random().toString(36).substring(2, 9)}`;
|
|
5601
|
+
value;
|
|
5602
|
+
onChange = () => { };
|
|
5603
|
+
onTouched = () => { };
|
|
5604
|
+
constructor(radioService) {
|
|
5605
|
+
this.radioService = radioService;
|
|
5606
|
+
this.radioService.selectedValue$.subscribe(val => {
|
|
5607
|
+
this.value = val;
|
|
5608
|
+
this.onChange(val);
|
|
5609
|
+
});
|
|
5610
|
+
}
|
|
5611
|
+
setDisabledState(isDisabled) {
|
|
5612
|
+
this.disabled = isDisabled;
|
|
5613
|
+
this.radioService.setDisabled(isDisabled);
|
|
5614
|
+
}
|
|
5615
|
+
ngOnChanges() {
|
|
5616
|
+
this.radioService.setDisabled(this.disabled);
|
|
5617
|
+
}
|
|
5618
|
+
writeValue(value) {
|
|
5619
|
+
this.value = value;
|
|
5620
|
+
this.radioService.select(value);
|
|
5621
|
+
}
|
|
5622
|
+
registerOnChange(fn) { this.onChange = fn; }
|
|
5623
|
+
registerOnTouched(fn) { this.onTouched = fn; }
|
|
5624
|
+
cn = cn;
|
|
5625
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioGroupComponent, deps: [{ token: RadioService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5626
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: RadioGroupComponent, isStandalone: true, selector: "tolle-radio-group", inputs: { class: "class", disabled: "disabled", name: "name" }, providers: [
|
|
5627
|
+
RadioService,
|
|
5628
|
+
{
|
|
5629
|
+
provide: NG_VALUE_ACCESSOR,
|
|
5630
|
+
useExisting: forwardRef(() => RadioGroupComponent),
|
|
5631
|
+
multi: true
|
|
5632
|
+
}
|
|
5633
|
+
], usesOnChanges: true, ngImport: i0, template: `
|
|
5634
|
+
<div [class]="cn('grid gap-2', class)" role="radiogroup">
|
|
5635
|
+
<ng-content></ng-content>
|
|
5636
|
+
</div>
|
|
5637
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
5638
|
+
}
|
|
5639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioGroupComponent, decorators: [{
|
|
5640
|
+
type: Component,
|
|
5641
|
+
args: [{
|
|
5642
|
+
selector: 'tolle-radio-group',
|
|
5643
|
+
standalone: true,
|
|
5644
|
+
imports: [CommonModule],
|
|
5645
|
+
providers: [
|
|
5646
|
+
RadioService,
|
|
5647
|
+
{
|
|
5648
|
+
provide: NG_VALUE_ACCESSOR,
|
|
5649
|
+
useExisting: forwardRef(() => RadioGroupComponent),
|
|
5650
|
+
multi: true
|
|
5651
|
+
}
|
|
5652
|
+
],
|
|
5653
|
+
template: `
|
|
5654
|
+
<div [class]="cn('grid gap-2', class)" role="radiogroup">
|
|
5655
|
+
<ng-content></ng-content>
|
|
5656
|
+
</div>
|
|
5657
|
+
`
|
|
5658
|
+
}]
|
|
5659
|
+
}], ctorParameters: () => [{ type: RadioService }], propDecorators: { class: [{
|
|
5660
|
+
type: Input
|
|
5661
|
+
}], disabled: [{
|
|
5662
|
+
type: Input
|
|
5663
|
+
}], name: [{
|
|
5664
|
+
type: Input
|
|
5665
|
+
}] } });
|
|
5666
|
+
|
|
5667
|
+
class RadioItemComponent {
|
|
5668
|
+
radioService;
|
|
5669
|
+
cdr;
|
|
5670
|
+
value;
|
|
5671
|
+
disabled = false;
|
|
5672
|
+
class = '';
|
|
5673
|
+
isSelected = false;
|
|
5674
|
+
groupDisabled = false;
|
|
5675
|
+
sub = new Subscription();
|
|
5676
|
+
get isEffectiveDisabled() {
|
|
5677
|
+
return this.disabled || this.groupDisabled;
|
|
5678
|
+
}
|
|
5679
|
+
// Inject ChangeDetectorRef to ensure UI updates when service emits
|
|
5680
|
+
constructor(radioService, cdr) {
|
|
5681
|
+
this.radioService = radioService;
|
|
5682
|
+
this.cdr = cdr;
|
|
5683
|
+
}
|
|
5684
|
+
ngOnInit() {
|
|
5685
|
+
// Listen for selection changes
|
|
5686
|
+
this.sub.add(this.radioService.selectedValue$.subscribe(val => {
|
|
5687
|
+
this.isSelected = (val === this.value);
|
|
5688
|
+
this.cdr.markForCheck(); // Trigger UI refresh
|
|
5689
|
+
}));
|
|
5690
|
+
// Listen for group-level disabled state
|
|
5691
|
+
this.sub.add(this.radioService.disabled$.subscribe(dis => {
|
|
5692
|
+
this.groupDisabled = dis;
|
|
5693
|
+
this.cdr.markForCheck(); // Trigger UI refresh
|
|
5694
|
+
}));
|
|
5695
|
+
}
|
|
5696
|
+
select() {
|
|
5697
|
+
this.radioService.select(this.value);
|
|
5698
|
+
}
|
|
5699
|
+
ngOnDestroy() {
|
|
5700
|
+
this.sub.unsubscribe(); // Clean up subscriptions
|
|
5701
|
+
}
|
|
5702
|
+
cn = cn;
|
|
5703
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioItemComponent, deps: [{ token: RadioService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5704
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: RadioItemComponent, isStandalone: true, selector: "tolle-radio-item", inputs: { value: "value", disabled: "disabled", class: "class" }, ngImport: i0, template: `
|
|
5705
|
+
<div
|
|
5706
|
+
(click)="!isEffectiveDisabled && select()"
|
|
5707
|
+
[class]="cn(
|
|
5708
|
+
'flex items-center space-x-2 group py-1',
|
|
5709
|
+
isEffectiveDisabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'
|
|
5710
|
+
)"
|
|
5711
|
+
>
|
|
5712
|
+
<div [class]="cn(
|
|
5713
|
+
'aspect-square h-4 w-4 rounded-full border border-primary text-primary transition-all flex items-center justify-center',
|
|
5714
|
+
'ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
5715
|
+
!isEffectiveDisabled && 'group-hover:border-primary/70',
|
|
5716
|
+
isSelected ? 'bg-background' : 'bg-transparent',
|
|
5717
|
+
class
|
|
5718
|
+
)">
|
|
5719
|
+
<div
|
|
5720
|
+
*ngIf="isSelected"
|
|
5721
|
+
class="h-2.5 w-2.5 rounded-full bg-primary animate-in zoom-in-50 duration-200"
|
|
5722
|
+
></div>
|
|
5723
|
+
</div>
|
|
5724
|
+
|
|
5725
|
+
<label class="text-sm font-medium leading-none select-none" [class.cursor-pointer]="!isEffectiveDisabled">
|
|
5726
|
+
<ng-content></ng-content>
|
|
5727
|
+
</label>
|
|
5728
|
+
</div>
|
|
5729
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
5730
|
+
}
|
|
5731
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioItemComponent, decorators: [{
|
|
5732
|
+
type: Component,
|
|
5733
|
+
args: [{
|
|
5734
|
+
selector: 'tolle-radio-item',
|
|
5735
|
+
standalone: true,
|
|
5736
|
+
imports: [CommonModule],
|
|
5737
|
+
template: `
|
|
5738
|
+
<div
|
|
5739
|
+
(click)="!isEffectiveDisabled && select()"
|
|
5740
|
+
[class]="cn(
|
|
5741
|
+
'flex items-center space-x-2 group py-1',
|
|
5742
|
+
isEffectiveDisabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'
|
|
5743
|
+
)"
|
|
5744
|
+
>
|
|
5745
|
+
<div [class]="cn(
|
|
5746
|
+
'aspect-square h-4 w-4 rounded-full border border-primary text-primary transition-all flex items-center justify-center',
|
|
5747
|
+
'ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
5748
|
+
!isEffectiveDisabled && 'group-hover:border-primary/70',
|
|
5749
|
+
isSelected ? 'bg-background' : 'bg-transparent',
|
|
5750
|
+
class
|
|
5751
|
+
)">
|
|
5752
|
+
<div
|
|
5753
|
+
*ngIf="isSelected"
|
|
5754
|
+
class="h-2.5 w-2.5 rounded-full bg-primary animate-in zoom-in-50 duration-200"
|
|
5755
|
+
></div>
|
|
5756
|
+
</div>
|
|
5757
|
+
|
|
5758
|
+
<label class="text-sm font-medium leading-none select-none" [class.cursor-pointer]="!isEffectiveDisabled">
|
|
5759
|
+
<ng-content></ng-content>
|
|
5760
|
+
</label>
|
|
5761
|
+
</div>
|
|
5762
|
+
`
|
|
5763
|
+
}]
|
|
5764
|
+
}], ctorParameters: () => [{ type: RadioService }, { type: i0.ChangeDetectorRef }], propDecorators: { value: [{
|
|
5765
|
+
type: Input
|
|
5766
|
+
}], disabled: [{
|
|
5767
|
+
type: Input
|
|
5768
|
+
}], class: [{
|
|
5769
|
+
type: Input
|
|
5770
|
+
}] } });
|
|
5771
|
+
|
|
4243
5772
|
/*
|
|
4244
5773
|
* Public API Surface of tolle
|
|
4245
5774
|
*/
|
|
@@ -4248,5 +5777,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4248
5777
|
* Generated bundle index. Do not edit.
|
|
4249
5778
|
*/
|
|
4250
5779
|
|
|
4251
|
-
export { AccordionComponent, AccordionItemComponent, BadgeComponent, ButtonComponent, ButtonGroupComponent, CalendarComponent, CardComponent, CardContentComponent, CardFooterComponent, CardHeaderComponent, CardTitleComponent, CheckboxComponent, DataTableComponent, DatePickerComponent, DateRangePickerComponent, DropdownItemComponent, DropdownLabelComponent, DropdownMenuComponent, DropdownSeparatorComponent, DropdownTriggerDirective, InputComponent, MaskedInputComponent, Modal, ModalComponent, ModalRef, ModalService, ModalStackService, MultiSelectComponent, PaginationComponent, RangeCalendarComponent, SelectComponent, SelectGroupComponent, SelectItemComponent, SelectSeparatorComponent, SkeletonComponent, SwitchComponent, TOLLE_CONFIG, TextareaComponent, ThemeService, ToastContainerComponent, ToastService, TolleCellDirective, TooltipDirective, cn, provideTolleConfig };
|
|
4252
|
-
//# sourceMappingURL=
|
|
5780
|
+
export { AccordionComponent, AccordionItemComponent, AlertComponent, AvatarComponent, AvatarFallbackComponent, BadgeComponent, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbLinkComponent, BreadcrumbSeparatorComponent, ButtonComponent, ButtonGroupComponent, CalendarComponent, CardComponent, CardContentComponent, CardFooterComponent, CardHeaderComponent, CardTitleComponent, CheckboxComponent, DataTableComponent, DatePickerComponent, DateRangePickerComponent, DropdownItemComponent, DropdownLabelComponent, DropdownMenuComponent, DropdownSeparatorComponent, DropdownTriggerDirective, EmptyStateComponent, InputComponent, MaskedInputComponent, Modal, ModalComponent, ModalRef, ModalService, ModalStackService, MultiSelectComponent, OtpComponent, OtpGroupComponent, OtpSlotComponent, PaginationComponent, PopoverComponent, PopoverContentComponent, RadioGroupComponent, RadioItemComponent, RangeCalendarComponent, SelectComponent, SelectGroupComponent, SelectItemComponent, SelectSeparatorComponent, SkeletonComponent, SwitchComponent, TOLLE_CONFIG, TextareaComponent, ThemeService, ToastContainerComponent, ToastService, TolleCellDirective, TooltipDirective, cn, provideTolleConfig };
|
|
5781
|
+
//# sourceMappingURL=tolle-ui.mjs.map
|