@fxlt/common-ui 0.0.1
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/BeVietnamPro-Regular.ttf +0 -0
- package/README.md +63 -0
- package/SpaceMono-Regular.ttf +0 -0
- package/animations.css +115 -0
- package/components.css +383 -0
- package/dialogs.css +116 -0
- package/fesm2022/fxlt-common-ui.mjs +2439 -0
- package/fesm2022/fxlt-common-ui.mjs.map +1 -0
- package/fonts.css +13 -0
- package/index.d.ts +739 -0
- package/package.json +53 -0
- package/src/lib/styles/animations.css +115 -0
- package/src/lib/styles/components.css +383 -0
- package/src/lib/styles/dialogs.css +116 -0
- package/src/lib/styles/fonts.css +13 -0
- package/src/lib/styles/tailwind.css +18 -0
- package/src/lib/styles/theme.css +63 -0
- package/src/lib/ui/components/button/button.component.html +223 -0
- package/src/lib/ui/components/chart/chart.component.html +13 -0
- package/src/lib/ui/components/checkbox/checkbox.component.html +43 -0
- package/src/lib/ui/components/datetime-picker/datetime-picker.component.html +25 -0
- package/src/lib/ui/components/dnd-upload/dnd-upload.component.html +34 -0
- package/src/lib/ui/components/hero-icon/hero-icon.component.html +8 -0
- package/src/lib/ui/components/input/input.component.css +0 -0
- package/src/lib/ui/components/input/input.component.html +46 -0
- package/src/lib/ui/components/loading-panel/loading-panel.component.html +51 -0
- package/src/lib/ui/components/radio-button/radio-button.component.css +0 -0
- package/src/lib/ui/components/radio-button/radio-button.component.html +35 -0
- package/src/lib/ui/components/radio-button-toggle/radio-button-toggle.component.html +34 -0
- package/src/lib/ui/components/search-bar/search-bar.component.html +22 -0
- package/src/lib/ui/components/select/select.component.css +80 -0
- package/src/lib/ui/components/select/select.component.html +25 -0
- package/src/lib/ui/components/slider/slider.component.html +54 -0
- package/src/lib/ui/components/switch/switch.component.html +21 -0
- package/src/lib/ui/components/tab-component/tab.component.html +1 -0
- package/src/lib/ui/components/tab-group/tab-group.component.html +75 -0
- package/src/lib/ui/components/tag/tag.component.html +43 -0
- package/src/lib/ui/components/toast/toast.component.html +48 -0
- package/src/lib/ui/components/toast-container/toast-container.component.html +12 -0
- package/src/lib/ui/dialogs/confirmation/confirmation.component.html +10 -0
- package/tailwind-config.d.ts +4 -0
- package/tailwind.config.js +69 -0
- package/tailwind.css +18 -0
- package/theme.css +63 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.light_theme {
|
|
2
|
+
--bg-primary: 255 255 255;
|
|
3
|
+
--primary: 236 25 56;
|
|
4
|
+
--success: 15 140 96;
|
|
5
|
+
--warning: 255 188 59;
|
|
6
|
+
--critical: 236 25 56;
|
|
7
|
+
--danger: 249 133 7;
|
|
8
|
+
--discovery: 119 113 227;
|
|
9
|
+
--information: 62 175 240;
|
|
10
|
+
--text-primary: 12 14 18;
|
|
11
|
+
--text-secondary: 97 101 108;
|
|
12
|
+
--border-default: 236 236 236;
|
|
13
|
+
--text-placeholder:148 151 156;
|
|
14
|
+
--step-bg: 12 14 18;
|
|
15
|
+
--text-link-primary: 29 122 252;
|
|
16
|
+
--bg-primary-hover: 247 247 247;
|
|
17
|
+
--text-focus: 255 255 255;
|
|
18
|
+
--bg-primary-neutral: 12 14 18;
|
|
19
|
+
--text-selected-primary: 199 14 41;
|
|
20
|
+
--button-default: 34 38 47;
|
|
21
|
+
--text-inverse: 255 255 255;
|
|
22
|
+
--bg-error-bold: 215 0 68;
|
|
23
|
+
--text-error: 215 0 68;
|
|
24
|
+
--border-interactive: 236 25 56;
|
|
25
|
+
--border-selected: 254 53 83;
|
|
26
|
+
--button-primary: 236 25 56;
|
|
27
|
+
--border-strong: 206 207 210;
|
|
28
|
+
--border-secondary-hover: 0 199 205;
|
|
29
|
+
--bg-secondary-hover: 6 59 70;
|
|
30
|
+
--shadow-color: 0 0 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
:root {
|
|
34
|
+
--bg-primary: 12 14 18;
|
|
35
|
+
--primary: 236 25 56;
|
|
36
|
+
--success: 76 175 80;
|
|
37
|
+
--warning: 255 188 59;
|
|
38
|
+
--critical: 236 25 56;
|
|
39
|
+
--danger: 249 133 7;
|
|
40
|
+
--discovery: 119 113 227;
|
|
41
|
+
--information: 62 175 240;
|
|
42
|
+
--text-primary: 247 247 247;
|
|
43
|
+
--text-secondary: 148 151 156;
|
|
44
|
+
--border-default: 55 58 65;
|
|
45
|
+
--text-placeholder: 133 136 142;
|
|
46
|
+
--step-bg: 255 255 255;
|
|
47
|
+
--text-link-primary: 87 157 255;
|
|
48
|
+
--bg-primary-hover: 34 38 47;
|
|
49
|
+
--text-focus: 255 255 255;
|
|
50
|
+
--bg-primary-neutral: 12 14 18;
|
|
51
|
+
--text-selected-primary: 254 53 83;
|
|
52
|
+
--button-default: 236 236 236;
|
|
53
|
+
--text-inverse: 12 14 18;
|
|
54
|
+
--bg-error-bold: 215 0 68;
|
|
55
|
+
--text-error: 255 0 81;
|
|
56
|
+
--border-interactive: 236 25 56;
|
|
57
|
+
--border-selected: 254 53 83;
|
|
58
|
+
--button-primary: 236 25 56;
|
|
59
|
+
--border-strong: 97 101 108;
|
|
60
|
+
--border-secondary-hover: 0 199 205;
|
|
61
|
+
--bg-secondary-hover: 6 59 70;
|
|
62
|
+
--shadow-color: 255 255 255;
|
|
63
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<button
|
|
2
|
+
[class]="class"
|
|
3
|
+
[ngClass]="{
|
|
4
|
+
'btn-default': buttonVariant === 'default',
|
|
5
|
+
'btn-primary': buttonVariant === 'primary',
|
|
6
|
+
'btn-alternative': buttonVariant === 'alternative',
|
|
7
|
+
}"
|
|
8
|
+
[disabled]="disabled || loading"
|
|
9
|
+
(click)="onClick()"
|
|
10
|
+
>
|
|
11
|
+
@if (loading) {
|
|
12
|
+
<div class="flex w-full items-center justify-center">
|
|
13
|
+
<svg
|
|
14
|
+
[attr.fill]="
|
|
15
|
+
buttonVariant !== 'alternative' ? 'rgb(var(--text-primary))' : 'rgb(var(--primary))'
|
|
16
|
+
"
|
|
17
|
+
width="20"
|
|
18
|
+
height="20"
|
|
19
|
+
viewBox="0 0 24 24"
|
|
20
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
21
|
+
>
|
|
22
|
+
<circle cx="4" cy="12" r="0">
|
|
23
|
+
<animate
|
|
24
|
+
begin="0;spinner_z0Or.end"
|
|
25
|
+
attributeName="r"
|
|
26
|
+
calcMode="spline"
|
|
27
|
+
dur="0.5s"
|
|
28
|
+
keySplines=".36,.6,.31,1"
|
|
29
|
+
values="0;3"
|
|
30
|
+
fill="freeze"
|
|
31
|
+
/>
|
|
32
|
+
<animate
|
|
33
|
+
begin="spinner_OLMs.end"
|
|
34
|
+
attributeName="cx"
|
|
35
|
+
calcMode="spline"
|
|
36
|
+
dur="0.5s"
|
|
37
|
+
keySplines=".36,.6,.31,1"
|
|
38
|
+
values="4;12"
|
|
39
|
+
fill="freeze"
|
|
40
|
+
/>
|
|
41
|
+
<animate
|
|
42
|
+
begin="spinner_UHR2.end"
|
|
43
|
+
attributeName="cx"
|
|
44
|
+
calcMode="spline"
|
|
45
|
+
dur="0.5s"
|
|
46
|
+
keySplines=".36,.6,.31,1"
|
|
47
|
+
values="12;20"
|
|
48
|
+
fill="freeze"
|
|
49
|
+
/>
|
|
50
|
+
<animate
|
|
51
|
+
id="spinner_lo66"
|
|
52
|
+
begin="spinner_Aguh.end"
|
|
53
|
+
attributeName="r"
|
|
54
|
+
calcMode="spline"
|
|
55
|
+
dur="0.5s"
|
|
56
|
+
keySplines=".36,.6,.31,1"
|
|
57
|
+
values="3;0"
|
|
58
|
+
fill="freeze"
|
|
59
|
+
/>
|
|
60
|
+
<animate
|
|
61
|
+
id="spinner_z0Or"
|
|
62
|
+
begin="spinner_lo66.end"
|
|
63
|
+
attributeName="cx"
|
|
64
|
+
dur="0.001s"
|
|
65
|
+
values="20;4"
|
|
66
|
+
fill="freeze"
|
|
67
|
+
/>
|
|
68
|
+
</circle>
|
|
69
|
+
<circle cx="4" cy="12" r="3">
|
|
70
|
+
<animate
|
|
71
|
+
begin="0;spinner_z0Or.end"
|
|
72
|
+
attributeName="cx"
|
|
73
|
+
calcMode="spline"
|
|
74
|
+
dur="0.5s"
|
|
75
|
+
keySplines=".36,.6,.31,1"
|
|
76
|
+
values="4;12"
|
|
77
|
+
fill="freeze"
|
|
78
|
+
/>
|
|
79
|
+
<animate
|
|
80
|
+
begin="spinner_OLMs.end"
|
|
81
|
+
attributeName="cx"
|
|
82
|
+
calcMode="spline"
|
|
83
|
+
dur="0.5s"
|
|
84
|
+
keySplines=".36,.6,.31,1"
|
|
85
|
+
values="12;20"
|
|
86
|
+
fill="freeze"
|
|
87
|
+
/>
|
|
88
|
+
<animate
|
|
89
|
+
id="spinner_JsnR"
|
|
90
|
+
begin="spinner_UHR2.end"
|
|
91
|
+
attributeName="r"
|
|
92
|
+
calcMode="spline"
|
|
93
|
+
dur="0.5s"
|
|
94
|
+
keySplines=".36,.6,.31,1"
|
|
95
|
+
values="3;0"
|
|
96
|
+
fill="freeze"
|
|
97
|
+
/>
|
|
98
|
+
<animate
|
|
99
|
+
id="spinner_Aguh"
|
|
100
|
+
begin="spinner_JsnR.end"
|
|
101
|
+
attributeName="cx"
|
|
102
|
+
dur="0.001s"
|
|
103
|
+
values="20;4"
|
|
104
|
+
fill="freeze"
|
|
105
|
+
/>
|
|
106
|
+
<animate
|
|
107
|
+
begin="spinner_Aguh.end"
|
|
108
|
+
attributeName="r"
|
|
109
|
+
calcMode="spline"
|
|
110
|
+
dur="0.5s"
|
|
111
|
+
keySplines=".36,.6,.31,1"
|
|
112
|
+
values="0;3"
|
|
113
|
+
fill="freeze"
|
|
114
|
+
/>
|
|
115
|
+
</circle>
|
|
116
|
+
<circle cx="12" cy="12" r="3">
|
|
117
|
+
<animate
|
|
118
|
+
begin="0;spinner_z0Or.end"
|
|
119
|
+
attributeName="cx"
|
|
120
|
+
calcMode="spline"
|
|
121
|
+
dur="0.5s"
|
|
122
|
+
keySplines=".36,.6,.31,1"
|
|
123
|
+
values="12;20"
|
|
124
|
+
fill="freeze"
|
|
125
|
+
/>
|
|
126
|
+
<animate
|
|
127
|
+
id="spinner_hSjk"
|
|
128
|
+
begin="spinner_OLMs.end"
|
|
129
|
+
attributeName="r"
|
|
130
|
+
calcMode="spline"
|
|
131
|
+
dur="0.5s"
|
|
132
|
+
keySplines=".36,.6,.31,1"
|
|
133
|
+
values="3;0"
|
|
134
|
+
fill="freeze"
|
|
135
|
+
/>
|
|
136
|
+
<animate
|
|
137
|
+
id="spinner_UHR2"
|
|
138
|
+
begin="spinner_hSjk.end"
|
|
139
|
+
attributeName="cx"
|
|
140
|
+
dur="0.001s"
|
|
141
|
+
values="20;4"
|
|
142
|
+
fill="freeze"
|
|
143
|
+
/>
|
|
144
|
+
<animate
|
|
145
|
+
begin="spinner_UHR2.end"
|
|
146
|
+
attributeName="r"
|
|
147
|
+
calcMode="spline"
|
|
148
|
+
dur="0.5s"
|
|
149
|
+
keySplines=".36,.6,.31,1"
|
|
150
|
+
values="0;3"
|
|
151
|
+
fill="freeze"
|
|
152
|
+
/>
|
|
153
|
+
<animate
|
|
154
|
+
begin="spinner_Aguh.end"
|
|
155
|
+
attributeName="cx"
|
|
156
|
+
calcMode="spline"
|
|
157
|
+
dur="0.5s"
|
|
158
|
+
keySplines=".36,.6,.31,1"
|
|
159
|
+
values="4;12"
|
|
160
|
+
fill="freeze"
|
|
161
|
+
/>
|
|
162
|
+
</circle>
|
|
163
|
+
<circle cx="20" cy="12" r="3">
|
|
164
|
+
<animate
|
|
165
|
+
id="spinner_4v5M"
|
|
166
|
+
begin="0;spinner_z0Or.end"
|
|
167
|
+
attributeName="r"
|
|
168
|
+
calcMode="spline"
|
|
169
|
+
dur="0.5s"
|
|
170
|
+
keySplines=".36,.6,.31,1"
|
|
171
|
+
values="3;0"
|
|
172
|
+
fill="freeze"
|
|
173
|
+
/>
|
|
174
|
+
<animate
|
|
175
|
+
id="spinner_OLMs"
|
|
176
|
+
begin="spinner_4v5M.end"
|
|
177
|
+
attributeName="cx"
|
|
178
|
+
dur="0.001s"
|
|
179
|
+
values="20;4"
|
|
180
|
+
fill="freeze"
|
|
181
|
+
/>
|
|
182
|
+
<animate
|
|
183
|
+
begin="spinner_OLMs.end"
|
|
184
|
+
attributeName="r"
|
|
185
|
+
calcMode="spline"
|
|
186
|
+
dur="0.5s"
|
|
187
|
+
keySplines=".36,.6,.31,1"
|
|
188
|
+
values="0;3"
|
|
189
|
+
fill="freeze"
|
|
190
|
+
/>
|
|
191
|
+
<animate
|
|
192
|
+
begin="spinner_UHR2.end"
|
|
193
|
+
attributeName="cx"
|
|
194
|
+
calcMode="spline"
|
|
195
|
+
dur="0.5s"
|
|
196
|
+
keySplines=".36,.6,.31,1"
|
|
197
|
+
values="4;12"
|
|
198
|
+
fill="freeze"
|
|
199
|
+
/>
|
|
200
|
+
<animate
|
|
201
|
+
begin="spinner_Aguh.end"
|
|
202
|
+
attributeName="cx"
|
|
203
|
+
calcMode="spline"
|
|
204
|
+
dur="0.5s"
|
|
205
|
+
keySplines=".36,.6,.31,1"
|
|
206
|
+
values="12;20"
|
|
207
|
+
fill="freeze"
|
|
208
|
+
/>
|
|
209
|
+
</circle>
|
|
210
|
+
</svg>
|
|
211
|
+
</div>
|
|
212
|
+
} @else {
|
|
213
|
+
<ng-container>
|
|
214
|
+
<div class="flex items-center justify-center gap-small">
|
|
215
|
+
@if(icon) {<fx-ui-hero-icon [icon]="icon" [size]="20" class="flex" [ngClass]="{
|
|
216
|
+
'text-text-inverse': buttonVariant !== 'default',
|
|
217
|
+
'text-text-primary': buttonVariant === 'alternative'
|
|
218
|
+
}"></fx-ui-hero-icon>}
|
|
219
|
+
<div>{{ label }}</div>
|
|
220
|
+
</div>
|
|
221
|
+
</ng-container>
|
|
222
|
+
}
|
|
223
|
+
</button>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<div class="chart-wrapper" [style.height]="height" [class.loading]="loading">
|
|
2
|
+
<div
|
|
3
|
+
echarts
|
|
4
|
+
[options]="chartOptions"
|
|
5
|
+
(chartInit)="onChartInit($event)"
|
|
6
|
+
(chartClick)="onChartClick($event)"
|
|
7
|
+
class="w-full h-full">
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="chart-loader" *ngIf="loading">
|
|
11
|
+
<span class="txt-default">Loading...</span>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<label
|
|
2
|
+
class="inline-flex items-center gap-normal cursor-pointer select-none"
|
|
3
|
+
[class.opacity-50]="disabled"
|
|
4
|
+
[class.cursor-not-allowed]="disabled"
|
|
5
|
+
>
|
|
6
|
+
<input
|
|
7
|
+
type="checkbox"
|
|
8
|
+
class="hidden"
|
|
9
|
+
[checked]="value"
|
|
10
|
+
[disabled]="disabled"
|
|
11
|
+
(change)="onInputChange($event)"
|
|
12
|
+
(blur)="onTouched()"
|
|
13
|
+
/>
|
|
14
|
+
<span
|
|
15
|
+
class="relative flex items-center justify-center border rounded-full transition-colors duration-150 shrink-0"
|
|
16
|
+
[class]="rounded ? 'rounded-full' : 'rounded-sm'"
|
|
17
|
+
[class]="size === 'large' ? 'w-6 h-6' : 'w-4 h-4'"
|
|
18
|
+
[ngClass]="{
|
|
19
|
+
'border-border-strong bg-transparent': !value,
|
|
20
|
+
'border-border-selected bg-border-selected': value
|
|
21
|
+
}"
|
|
22
|
+
>
|
|
23
|
+
<!-- Keep SVG space reserved always -->
|
|
24
|
+
<span class="absolute inset-0 flex items-center justify-center">
|
|
25
|
+
<svg
|
|
26
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
27
|
+
class="text-bg-primary transition-opacity duration-150"
|
|
28
|
+
[class]="size === 'large' ? 'w-4.5 h-4.5' : 'w-3 h-3'"
|
|
29
|
+
viewBox="0 0 24 24"
|
|
30
|
+
fill="none"
|
|
31
|
+
stroke="currentColor"
|
|
32
|
+
stroke-width="3"
|
|
33
|
+
stroke-linecap="round"
|
|
34
|
+
stroke-linejoin="round"
|
|
35
|
+
[style.opacity]="value ? 1 : 0"
|
|
36
|
+
>
|
|
37
|
+
<path d="M5 13l4 4L19 7" />
|
|
38
|
+
</svg>
|
|
39
|
+
</span>
|
|
40
|
+
</span>
|
|
41
|
+
|
|
42
|
+
<span class="mb-0 txt-field-label">{{ label }}</span>
|
|
43
|
+
</label>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="flex flex-col mb-4 w-full text-left">
|
|
2
|
+
<label *ngIf="label" class="txt-field-label">
|
|
3
|
+
{{ label }}
|
|
4
|
+
<span *ngIf="required" class="txt-required">*</span>
|
|
5
|
+
</label>
|
|
6
|
+
|
|
7
|
+
<div class="relative">
|
|
8
|
+
<input
|
|
9
|
+
[owlDateTimeTrigger]="picker"
|
|
10
|
+
[owlDateTime]="picker"
|
|
11
|
+
[placeholder]="placeholder"
|
|
12
|
+
[disabled]="disabled"
|
|
13
|
+
(blur)="onBlur()"
|
|
14
|
+
[value]="value"
|
|
15
|
+
readonly
|
|
16
|
+
class="input-default"
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
<owl-date-time
|
|
20
|
+
#picker
|
|
21
|
+
[pickerType]="showTime ? 'both' : 'calendar'"
|
|
22
|
+
(afterPickerClosed)="onValueChange($event)"
|
|
23
|
+
></owl-date-time>
|
|
24
|
+
<div *ngIf="invalid" class="txt-invalid">{{ getErrorMessage(label) }}</div>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<div
|
|
2
|
+
class="block w-full"
|
|
3
|
+
(dragover)="onDragOver($event)"
|
|
4
|
+
(dragleave)="onDragLeave($event)"
|
|
5
|
+
(drop)="onDrop($event)"
|
|
6
|
+
>
|
|
7
|
+
<div
|
|
8
|
+
role="button"
|
|
9
|
+
tabindex="0"
|
|
10
|
+
class="flex flex-col items-center justify-center gap-1 border-2 border-dashed rounded-md p-4 cursor-pointer select-none outline-none focus:ring-2 focus:ring-primary"
|
|
11
|
+
[ngClass]="{
|
|
12
|
+
'border-border-default bg-bg-hover': !isDragOver,
|
|
13
|
+
'border-border-interactive bg-secondary': isDragOver
|
|
14
|
+
}"
|
|
15
|
+
(click)="onAreaClick(fileInput, $event)"
|
|
16
|
+
(keydown.enter)="onAreaClick(fileInput, $event)"
|
|
17
|
+
>
|
|
18
|
+
<div class="text-sm text-text-link font-medium">
|
|
19
|
+
Click to upload <span class="text-text-secondary opacity-50">or drag and drop</span>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="text-xs text-text-secondary">
|
|
22
|
+
Allowed: {{ accept || 'any file type' }} (max {{ maxSizeMB }} MB)
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<input
|
|
26
|
+
#fileInput
|
|
27
|
+
type="file"
|
|
28
|
+
class="hidden"
|
|
29
|
+
[attr.multiple]="multiple ? '' : null"
|
|
30
|
+
[attr.accept]="accept"
|
|
31
|
+
(change)="onFileSelected($event)"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<div class="mb-4 text-left w-full text-text-primary" [class]="class">
|
|
2
|
+
@if(label){<label class="block txt-field-label">
|
|
3
|
+
{{ label }}
|
|
4
|
+
@if (required) {<span class="txt-required">*</span>}
|
|
5
|
+
</label>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
<div class="relative">
|
|
9
|
+
<input
|
|
10
|
+
[type]="displayType"
|
|
11
|
+
[placeholder]="placeholder"
|
|
12
|
+
[disabled]="disabled"
|
|
13
|
+
[value]="value"
|
|
14
|
+
(input)="onInput($event)"
|
|
15
|
+
(blur)="onBlur()"
|
|
16
|
+
(focus)="onFocus()"
|
|
17
|
+
[attr.maxlength]="maxlength"
|
|
18
|
+
[class]="type === 'otp' ? 'input-otp' : 'input-default'"
|
|
19
|
+
[ngClass]="{
|
|
20
|
+
'input-invalid': invalid,
|
|
21
|
+
'pr-8': type === 'password' || suffixIcon,
|
|
22
|
+
'txt-otp-input': type === 'otp'
|
|
23
|
+
}"
|
|
24
|
+
/>
|
|
25
|
+
<button
|
|
26
|
+
type="button"
|
|
27
|
+
class="absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary"
|
|
28
|
+
(click)="onSuffixClick()"
|
|
29
|
+
[disabled]="disabled"
|
|
30
|
+
>
|
|
31
|
+
@if (type === 'password') {
|
|
32
|
+
<i class="material-symbols-outlined text-lg select-none">{{
|
|
33
|
+
showPassword ? 'visibility_off' : 'visibility'
|
|
34
|
+
}}</i>
|
|
35
|
+
} @else if (suffixIcon) {
|
|
36
|
+
<i [class]="iconClass" class="text-lg select-none">{{ suffixIcon }}</i>
|
|
37
|
+
}
|
|
38
|
+
</button>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
@if (invalid){
|
|
42
|
+
<div class="txt-invalid">
|
|
43
|
+
{{ getErrorMessage(label) }}
|
|
44
|
+
</div>
|
|
45
|
+
}
|
|
46
|
+
</div>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<!-- Full-screen glass overlay -->
|
|
2
|
+
<div
|
|
3
|
+
*ngIf="show"
|
|
4
|
+
class="fixed inset-0 z-50 flex items-center justify-center"
|
|
5
|
+
aria-hidden="false"
|
|
6
|
+
role="alert"
|
|
7
|
+
aria-busy="true"
|
|
8
|
+
>
|
|
9
|
+
<div class="absolute inset-0 bg-bg-primary/30 backdrop-blur-xl" aria-hidden="true"></div>
|
|
10
|
+
|
|
11
|
+
<div
|
|
12
|
+
class="relative z-10 flex flex-col items-center gap-4 p-6 rounded-2xl shadow-xl bg-bg-primary/70 border border-border-strong backdrop-bg-primary/70"
|
|
13
|
+
style="min-width: 220px; max-width: 90%"
|
|
14
|
+
>
|
|
15
|
+
<svg fill="rgb(var(--primary))" width="50" height="50" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
16
|
+
<circle cx="4" cy="12" r="0">
|
|
17
|
+
<animate begin="0;spinner_z0Or.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="0;3" fill="freeze"/>
|
|
18
|
+
<animate begin="spinner_OLMs.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="4;12" fill="freeze"/>
|
|
19
|
+
<animate begin="spinner_UHR2.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="12;20" fill="freeze"/>
|
|
20
|
+
<animate id="spinner_lo66" begin="spinner_Aguh.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="3;0" fill="freeze"/>
|
|
21
|
+
<animate id="spinner_z0Or" begin="spinner_lo66.end" attributeName="cx" dur="0.001s" values="20;4" fill="freeze"/>
|
|
22
|
+
</circle>
|
|
23
|
+
<circle cx="4" cy="12" r="3">
|
|
24
|
+
<animate begin="0;spinner_z0Or.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="4;12" fill="freeze"/>
|
|
25
|
+
<animate begin="spinner_OLMs.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="12;20" fill="freeze"/>
|
|
26
|
+
<animate id="spinner_JsnR" begin="spinner_UHR2.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="3;0" fill="freeze"/>
|
|
27
|
+
<animate id="spinner_Aguh" begin="spinner_JsnR.end" attributeName="cx" dur="0.001s" values="20;4" fill="freeze"/>
|
|
28
|
+
<animate begin="spinner_Aguh.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="0;3" fill="freeze"/>
|
|
29
|
+
</circle>
|
|
30
|
+
<circle cx="12" cy="12" r="3">
|
|
31
|
+
<animate begin="0;spinner_z0Or.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="12;20" fill="freeze"/>
|
|
32
|
+
<animate id="spinner_hSjk" begin="spinner_OLMs.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="3;0" fill="freeze"/>
|
|
33
|
+
<animate id="spinner_UHR2" begin="spinner_hSjk.end" attributeName="cx" dur="0.001s" values="20;4" fill="freeze"/>
|
|
34
|
+
<animate begin="spinner_UHR2.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="0;3" fill="freeze"/>
|
|
35
|
+
<animate begin="spinner_Aguh.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="4;12" fill="freeze"/>
|
|
36
|
+
</circle>
|
|
37
|
+
<circle cx="20" cy="12" r="3">
|
|
38
|
+
<animate id="spinner_4v5M" begin="0;spinner_z0Or.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="3;0" fill="freeze"/>
|
|
39
|
+
<animate id="spinner_OLMs" begin="spinner_4v5M.end" attributeName="cx" dur="0.001s" values="20;4" fill="freeze"/>
|
|
40
|
+
<animate begin="spinner_OLMs.end" attributeName="r" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="0;3" fill="freeze"/>
|
|
41
|
+
<animate begin="spinner_UHR2.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="4;12" fill="freeze"/>
|
|
42
|
+
<animate begin="spinner_Aguh.end" attributeName="cx" calcMode="spline" dur="0.5s" keySplines=".36,.6,.31,1" values="12;20" fill="freeze"/>
|
|
43
|
+
</circle>
|
|
44
|
+
</svg>
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
<div *ngIf="message" class="text-sm text-text-primary text-center">
|
|
48
|
+
{{ message }}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<div class="w-full rounded-lg overflow-hidden" [class]="class" role="radiogroup">
|
|
2
|
+
@if (label){
|
|
3
|
+
<label class="txt-field-label">
|
|
4
|
+
{{ label }}
|
|
5
|
+
@if(required){<span class="txt-required">*</span>} </label
|
|
6
|
+
>}
|
|
7
|
+
|
|
8
|
+
<button
|
|
9
|
+
*ngFor="let opt of options"
|
|
10
|
+
type="button"
|
|
11
|
+
role="radio"
|
|
12
|
+
[attr.aria-checked]="value === opt.value"
|
|
13
|
+
(click)="onSelectValue(opt.value)"
|
|
14
|
+
[disabled]="disabled"
|
|
15
|
+
[class.text-gray-900]="value !== opt.value"
|
|
16
|
+
class="flex-1 px-normal w-full flex items-center gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed"
|
|
17
|
+
>
|
|
18
|
+
<span
|
|
19
|
+
[ngClass]="{
|
|
20
|
+
'radio-checked': value === opt.value,
|
|
21
|
+
'radio-uncheck': value !== opt.value
|
|
22
|
+
}"
|
|
23
|
+
class="radio-container"
|
|
24
|
+
>
|
|
25
|
+
@if(value === opt.value) {<span class="radio-dot"></span>}
|
|
26
|
+
</span>
|
|
27
|
+
|
|
28
|
+
<span class="txt-default mb-0">{{ opt.label }}</span>
|
|
29
|
+
</button>
|
|
30
|
+
@if (invalid){
|
|
31
|
+
<div class="txt-invalid">
|
|
32
|
+
{{ getErrorMessage(label) }}
|
|
33
|
+
</div>
|
|
34
|
+
}
|
|
35
|
+
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<div class="flex flex-col text-left mb-4 w-full" [class]="class">
|
|
2
|
+
@if(label){<label class="txt-field-label">
|
|
3
|
+
{{ label }}
|
|
4
|
+
@if(required) {<span class="txt-required">*</span>} </label
|
|
5
|
+
>}
|
|
6
|
+
|
|
7
|
+
<div class="inline-flex w-full rounded-lg overflow-hidden" role="radiogroup">
|
|
8
|
+
@for(opt of options; track opt){<button
|
|
9
|
+
type="button"
|
|
10
|
+
role="radio"
|
|
11
|
+
[attr.aria-checked]="value === opt.value"
|
|
12
|
+
(click)="onSelectValue(opt.value)"
|
|
13
|
+
[disabled]="disabled"
|
|
14
|
+
[class.text-gray-900]="value !== opt.value"
|
|
15
|
+
class="flex-1 bg-bg-primary flex items-center pl-normal gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed"
|
|
16
|
+
>
|
|
17
|
+
<span
|
|
18
|
+
[ngClass]="{
|
|
19
|
+
'radio-checked': value === opt.value,
|
|
20
|
+
'radio-uncheck': value !== opt.value
|
|
21
|
+
}"
|
|
22
|
+
class="radio-container"
|
|
23
|
+
>
|
|
24
|
+
@if(value === opt.value) {<span class="radio-dot"></span>}
|
|
25
|
+
</span>
|
|
26
|
+
|
|
27
|
+
<span class="txt-field-label mb-0">{{ opt.label }}</span></button
|
|
28
|
+
>}
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
@if(invalid){
|
|
32
|
+
<div class="txt-invalid">{{ getErrorMessage(label) }}</div>
|
|
33
|
+
}
|
|
34
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="relative">
|
|
2
|
+
<fx-ui-hero-icon icon="magnifying-glass" [size]="18" class="absolute left-1 top-[3px] text-text-primary"></fx-ui-hero-icon>
|
|
3
|
+
<input
|
|
4
|
+
type="text"
|
|
5
|
+
class="input-default px-9"
|
|
6
|
+
[attr.placeholder]="placeholder"
|
|
7
|
+
[disabled]="disabled"
|
|
8
|
+
[value]="value"
|
|
9
|
+
(input)="onValueChange($any($event.target).value)"
|
|
10
|
+
(keydown.enter)="onEnterKey()"
|
|
11
|
+
/>
|
|
12
|
+
|
|
13
|
+
<button
|
|
14
|
+
*ngIf="value && !disabled"
|
|
15
|
+
type="button"
|
|
16
|
+
class="absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary"
|
|
17
|
+
(click)="clear()"
|
|
18
|
+
aria-label="Clear"
|
|
19
|
+
>
|
|
20
|
+
<i class="material-symbols-outlined text-lg select-none">close</i>
|
|
21
|
+
</button>
|
|
22
|
+
</div>
|