@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.
Files changed (44) hide show
  1. package/BeVietnamPro-Regular.ttf +0 -0
  2. package/README.md +63 -0
  3. package/SpaceMono-Regular.ttf +0 -0
  4. package/animations.css +115 -0
  5. package/components.css +383 -0
  6. package/dialogs.css +116 -0
  7. package/fesm2022/fxlt-common-ui.mjs +2439 -0
  8. package/fesm2022/fxlt-common-ui.mjs.map +1 -0
  9. package/fonts.css +13 -0
  10. package/index.d.ts +739 -0
  11. package/package.json +53 -0
  12. package/src/lib/styles/animations.css +115 -0
  13. package/src/lib/styles/components.css +383 -0
  14. package/src/lib/styles/dialogs.css +116 -0
  15. package/src/lib/styles/fonts.css +13 -0
  16. package/src/lib/styles/tailwind.css +18 -0
  17. package/src/lib/styles/theme.css +63 -0
  18. package/src/lib/ui/components/button/button.component.html +223 -0
  19. package/src/lib/ui/components/chart/chart.component.html +13 -0
  20. package/src/lib/ui/components/checkbox/checkbox.component.html +43 -0
  21. package/src/lib/ui/components/datetime-picker/datetime-picker.component.html +25 -0
  22. package/src/lib/ui/components/dnd-upload/dnd-upload.component.html +34 -0
  23. package/src/lib/ui/components/hero-icon/hero-icon.component.html +8 -0
  24. package/src/lib/ui/components/input/input.component.css +0 -0
  25. package/src/lib/ui/components/input/input.component.html +46 -0
  26. package/src/lib/ui/components/loading-panel/loading-panel.component.html +51 -0
  27. package/src/lib/ui/components/radio-button/radio-button.component.css +0 -0
  28. package/src/lib/ui/components/radio-button/radio-button.component.html +35 -0
  29. package/src/lib/ui/components/radio-button-toggle/radio-button-toggle.component.html +34 -0
  30. package/src/lib/ui/components/search-bar/search-bar.component.html +22 -0
  31. package/src/lib/ui/components/select/select.component.css +80 -0
  32. package/src/lib/ui/components/select/select.component.html +25 -0
  33. package/src/lib/ui/components/slider/slider.component.html +54 -0
  34. package/src/lib/ui/components/switch/switch.component.html +21 -0
  35. package/src/lib/ui/components/tab-component/tab.component.html +1 -0
  36. package/src/lib/ui/components/tab-group/tab-group.component.html +75 -0
  37. package/src/lib/ui/components/tag/tag.component.html +43 -0
  38. package/src/lib/ui/components/toast/toast.component.html +48 -0
  39. package/src/lib/ui/components/toast-container/toast-container.component.html +12 -0
  40. package/src/lib/ui/dialogs/confirmation/confirmation.component.html +10 -0
  41. package/tailwind-config.d.ts +4 -0
  42. package/tailwind.config.js +69 -0
  43. package/tailwind.css +18 -0
  44. 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>
@@ -0,0 +1,8 @@
1
+ <ng-heroicons
2
+ [icon]="icon"
3
+ [size]="size"
4
+ [solid]="solid"
5
+ [outline]="outline"
6
+ [color]="color"
7
+ [class]="class"
8
+ />
@@ -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>
@@ -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>