@foxeltech/angular-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 (68) hide show
  1. package/BeVietnamPro/BeVietnamPro-Bold.ttf +0 -0
  2. package/BeVietnamPro/BeVietnamPro-ExtraLight.ttf +0 -0
  3. package/BeVietnamPro/BeVietnamPro-Light.ttf +0 -0
  4. package/BeVietnamPro/BeVietnamPro-Medium.ttf +0 -0
  5. package/BeVietnamPro/BeVietnamPro-Regular.ttf +0 -0
  6. package/BeVietnamPro/BeVietnamPro-SemiBold.ttf +0 -0
  7. package/BeVietnamPro/BeVietnamPro-Thin.ttf +0 -0
  8. package/README.md +3 -0
  9. package/SpaceMono-Regular.ttf +0 -0
  10. package/animations.css +130 -0
  11. package/components.css +480 -0
  12. package/dialogs.css +70 -0
  13. package/dm-sans/DMSans-Bold.ttf +0 -0
  14. package/dm-sans/DMSans-Light.ttf +0 -0
  15. package/dm-sans/DMSans-Medium.ttf +0 -0
  16. package/dm-sans/DMSans-Regular.ttf +0 -0
  17. package/dm-sans/DMSans-SemiBold.ttf +0 -0
  18. package/dm-sans/DMSans-Thin.ttf +0 -0
  19. package/fesm2022/foxeltech-angular-ui.mjs +3450 -0
  20. package/fesm2022/foxeltech-angular-ui.mjs.map +1 -0
  21. package/fonts.css +125 -0
  22. package/index.d.ts +1022 -0
  23. package/orbitron/Orbitron-Bold.ttf +0 -0
  24. package/orbitron/Orbitron-Medium.ttf +0 -0
  25. package/orbitron/Orbitron-Regular.ttf +0 -0
  26. package/orbitron/Orbitron-SemiBold.ttf +0 -0
  27. package/package.json +56 -0
  28. package/src/lib/styles/animations.css +130 -0
  29. package/src/lib/styles/components.css +480 -0
  30. package/src/lib/styles/dialogs.css +70 -0
  31. package/src/lib/styles/fonts.css +125 -0
  32. package/src/lib/styles/tailwind.css +18 -0
  33. package/src/lib/styles/theme.css +67 -0
  34. package/src/lib/ui/components/button/button.component.html +223 -0
  35. package/src/lib/ui/components/chart/chart.component.html +11 -0
  36. package/src/lib/ui/components/checkbox/checkbox.component.html +42 -0
  37. package/src/lib/ui/components/circle-progress-bar/circle-progress-bar.component.html +44 -0
  38. package/src/lib/ui/components/datetime-picker/datetime-picker.component.html +36 -0
  39. package/src/lib/ui/components/dnd-upload/dnd-upload.component.html +34 -0
  40. package/src/lib/ui/components/drawer/drawer.component.html +101 -0
  41. package/src/lib/ui/components/flow-connection/flow-connection.component.html +10 -0
  42. package/src/lib/ui/components/hero-icon/hero-icon.component.html +8 -0
  43. package/src/lib/ui/components/input/input.component.css +0 -0
  44. package/src/lib/ui/components/input/input.component.html +48 -0
  45. package/src/lib/ui/components/kanban-board/kanban-board.component.html +43 -0
  46. package/src/lib/ui/components/loading-panel/loading-panel.component.html +51 -0
  47. package/src/lib/ui/components/radio-button/radio-button.component.css +0 -0
  48. package/src/lib/ui/components/radio-button/radio-button.component.html +35 -0
  49. package/src/lib/ui/components/radio-button-toggle/radio-button-toggle.component.html +34 -0
  50. package/src/lib/ui/components/rich-text-area/rich-text-area.component.html +3 -0
  51. package/src/lib/ui/components/search-bar/search-bar.component.html +22 -0
  52. package/src/lib/ui/components/select/select.component.css +102 -0
  53. package/src/lib/ui/components/select/select.component.html +42 -0
  54. package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.html +21 -0
  55. package/src/lib/ui/components/slider/slider.component.html +54 -0
  56. package/src/lib/ui/components/switch/switch.component.html +21 -0
  57. package/src/lib/ui/components/tab-component/tab.component.html +1 -0
  58. package/src/lib/ui/components/tab-group/tab-group.component.html +75 -0
  59. package/src/lib/ui/components/table-cell/table-cell.component.html +7 -0
  60. package/src/lib/ui/components/tag/tag.component.html +15 -0
  61. package/src/lib/ui/components/toast/toast.component.html +48 -0
  62. package/src/lib/ui/components/toast-container/toast-container.component.html +12 -0
  63. package/src/lib/ui/components/tree-diagram/tree-diagram.component.html +40 -0
  64. package/src/lib/ui/dialogs/confirmation/confirmation.component.html +17 -0
  65. package/tailwind-config.d.ts +4 -0
  66. package/tailwind.config.js +88 -0
  67. package/tailwind.css +18 -0
  68. package/theme.css +67 -0
@@ -0,0 +1,70 @@
1
+ .fx-dialog {
2
+ max-width: unset !important;
3
+ border-radius: 8px !important;
4
+ .mat-dialog-actions {
5
+ border-top: 1px solid rgb(var(--border-default)) !important;
6
+ margin-left: -24px;
7
+ margin-right: -24px;
8
+ padding: 12px 24px 10px 10px;
9
+ }
10
+
11
+ .mat-dialog-title {
12
+ margin-left: -24px;
13
+ margin-right: -24px;
14
+ padding-right: 24px;
15
+ padding-left: 24px;
16
+ border-bottom: 1px solid rgb(var(--border-default));
17
+ padding-bottom: 20px;
18
+ letter-spacing: 0 !important;
19
+ }
20
+
21
+ .mat-dialog-content {
22
+ min-height: 110px;
23
+ letter-spacing: 0 !important;
24
+ }
25
+ }
26
+
27
+ .fx-fullsize-dialog {
28
+ max-width: 100vw !important;
29
+ height: 100%;
30
+
31
+ mat-dialog-container {
32
+ padding: 0;
33
+
34
+ form.wrapped-form {
35
+ display: flex;
36
+ flex-direction: column;
37
+ height: 100%;
38
+ justify-content: space-between;
39
+ }
40
+
41
+ .mat-dialog-title {
42
+ background-color: rgb(var(--bg-primary));
43
+ box-shadow: 0px 4px 8px rgba(26, 28, 38, 0.15);
44
+ color: rgb(var(--text-primary));
45
+ padding: 12px 20px;
46
+ min-height: 24px;
47
+
48
+ h2 {
49
+ font-weight: 500;
50
+ font-size: 18px;
51
+ line-height: 24px;
52
+ }
53
+ }
54
+
55
+ .mat-dialog-content {
56
+ background: rgb(var(--bg-primary));
57
+ padding: 16px 20px;
58
+ margin: unset;
59
+ height: 100%;
60
+ max-height: unset;
61
+ letter-spacing: 0 !important;
62
+ }
63
+
64
+ .mat-dialog-actions {
65
+ background-color: rgb(var(--bg-primary));
66
+ padding: 12px 20px;
67
+ margin-bottom: unset;
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,125 @@
1
+ @font-face {
2
+ font-family: 'BeVietnamPro';
3
+ src: url('./BeVietnamPro/BeVietnamPro-Thin.ttf') format('truetype');
4
+ font-weight: 100;
5
+ font-style: normal;
6
+ }
7
+
8
+ @font-face {
9
+ font-family: 'BeVietnamPro';
10
+ src: url('./BeVietnamPro/BeVietnamPro-ExtraLight.ttf') format('truetype');
11
+ font-weight: 200;
12
+ font-style: normal;
13
+ }
14
+
15
+ @font-face {
16
+ font-family: 'BeVietnamPro';
17
+ src: url('./BeVietnamPro/BeVietnamPro-Light.ttf') format('truetype');
18
+ font-weight: 300;
19
+ font-style: normal;
20
+ }
21
+
22
+ @font-face {
23
+ font-family: 'BeVietnamPro';
24
+ src: url('./BeVietnamPro/BeVietnamPro-Regular.ttf') format('truetype');
25
+ font-weight: 400;
26
+ font-style: normal;
27
+ }
28
+
29
+ @font-face {
30
+ font-family: 'BeVietnamPro';
31
+ src: url('./BeVietnamPro/BeVietnamPro-Medium.ttf') format('truetype');
32
+ font-weight: 500;
33
+ font-style: normal;
34
+ }
35
+
36
+ @font-face {
37
+ font-family: 'BeVietnamPro';
38
+ src: url('./BeVietnamPro/BeVietnamPro-SemiBold.ttf') format('truetype');
39
+ font-weight: 600;
40
+ font-style: normal;
41
+ }
42
+
43
+ @font-face {
44
+ font-family: 'BeVietnamPro';
45
+ src: url('./BeVietnamPro/BeVietnamPro-Bold.ttf') format('truetype');
46
+ font-weight: 700;
47
+ font-style: normal;
48
+ }
49
+
50
+ @font-face {
51
+ font-family: 'DMSans';
52
+ src: url('./dm-sans/DMSans-Thin.ttf') format('truetype');
53
+ font-weight: 200;
54
+ font-style: normal;
55
+ }
56
+
57
+ @font-face {
58
+ font-family: 'DMSans';
59
+ src: url('./dm-sans/DMSans-Light.ttf') format('truetype');
60
+ font-weight: 300;
61
+ font-style: normal;
62
+ }
63
+
64
+ @font-face {
65
+ font-family: 'DMSans';
66
+ src: url('./dm-sans/DMSans-Regular.ttf') format('truetype');
67
+ font-weight: 400;
68
+ font-style: normal;
69
+ }
70
+
71
+ @font-face {
72
+ font-family: 'DMSans';
73
+ src: url('./dm-sans/DMSans-Medium.ttf') format('truetype');
74
+ font-weight: 500;
75
+ font-style: normal;
76
+ }
77
+
78
+ @font-face {
79
+ font-family: 'DMSans';
80
+ src: url('./dm-sans/DMSans-SemiBold.ttf') format('truetype');
81
+ font-weight: 600;
82
+ font-style: normal;
83
+ }
84
+
85
+ @font-face {
86
+ font-family: 'DMSans';
87
+ src: url('./dm-sans/DMSans-Bold.ttf') format('truetype');
88
+ font-weight: 700;
89
+ font-style: normal;
90
+ }
91
+
92
+ @font-face {
93
+ font-family: 'Orbitron';
94
+ src: url('./orbitron/Orbitron-Regular.ttf') format('truetype');
95
+ font-weight: 400;
96
+ font-style: normal;
97
+ }
98
+
99
+ @font-face {
100
+ font-family: 'Orbitron';
101
+ src: url('./orbitron/Orbitron-Medium.ttf') format('truetype');
102
+ font-weight: 500;
103
+ font-style: normal;
104
+ }
105
+
106
+ @font-face {
107
+ font-family: 'Orbitron';
108
+ src: url('./orbitron/Orbitron-SemiBold.ttf') format('truetype');
109
+ font-weight: 600;
110
+ font-style: normal;
111
+ }
112
+
113
+ @font-face {
114
+ font-family: 'Orbitron';
115
+ src: url('./orbitron/Orbitron-Bold.ttf') format('truetype');
116
+ font-weight: 700;
117
+ font-style: normal;
118
+ }
119
+
120
+ @font-face {
121
+ font-family: 'SpaceMonoRegular';
122
+ src: url('./SpaceMono-Regular.ttf') format('truetype');
123
+ font-weight: normal;
124
+ font-style: normal;
125
+ }
@@ -0,0 +1,18 @@
1
+ @import './theme.css';
2
+ @import './components.css';
3
+ @import './dialogs.css';
4
+ @import './fonts.css';
5
+ @import './animations.css';
6
+ @import '@danielmoncada/angular-datetime-picker/assets/style/picker.min.css';
7
+ @tailwind base;
8
+ @tailwind component;
9
+ @tailwind utilities;
10
+
11
+ html, body {
12
+ font-family: 'BeVietnamPro';
13
+ margin: 0;
14
+ padding: 0;
15
+ height: 100%;
16
+ width: 100%;
17
+ background: rgb(var(--bg-primary));
18
+ }
@@ -0,0 +1,67 @@
1
+ .light_theme {
2
+ --gradient-primary-start: 156 129 255;
3
+ --gradient-primary-end: 4 255 135;
4
+ --bg-primary: 255 255 255;
5
+ --primary: 236 25 56;
6
+ --success: 15 140 96;
7
+ --warning: 255 188 59;
8
+ --critical: 236 25 56;
9
+ --danger: 249 133 7;
10
+ --discovery: 119 113 227;
11
+ --information: 62 175 240;
12
+ --text-primary: 36 45 66;
13
+ --text-secondary: 97 101 108;
14
+ --border-default: 236 236 236;
15
+ --text-placeholder:148 151 156;
16
+ --step-bg: 12 14 18;
17
+ --text-link-primary: 29 122 252;
18
+ --bg-primary-hover: 247 247 247;
19
+ --text-focus: 255 255 255;
20
+ --bg-primary-neutral: 12 14 18;
21
+ --text-selected-primary: 199 14 41;
22
+ --button-default: 34 38 47;
23
+ --text-inverse: 255 255 255;
24
+ --bg-error-bold: 215 0 68;
25
+ --text-error: 215 0 68;
26
+ --border-interactive: 236 25 56;
27
+ --border-selected: 254 53 83;
28
+ --button-primary: 236 25 56;
29
+ --border-strong: 206 207 210;
30
+ --border-secondary-hover: 0 199 205;
31
+ --bg-secondary-hover: 6 59 70;
32
+ --shadow-color: 0 0 0;
33
+ }
34
+
35
+ :root {
36
+ --gradient-primary-start: 156 129 255;
37
+ --gradient-primary-end: 4 255 135;
38
+ --bg-primary: 12 14 18;
39
+ --primary: 236 25 56;
40
+ --success: 76 175 80;
41
+ --warning: 255 188 59;
42
+ --critical: 236 25 56;
43
+ --danger: 249 133 7;
44
+ --discovery: 119 113 227;
45
+ --information: 62 175 240;
46
+ --text-primary: 247 247 247;
47
+ --text-secondary: 97 101 108;
48
+ --border-default: 55 58 65;
49
+ --text-placeholder: 133 136 142;
50
+ --step-bg: 255 255 255;
51
+ --text-link-primary: 87 157 255;
52
+ --bg-primary-hover: 34 38 47;
53
+ --text-focus: 255 255 255;
54
+ --bg-primary-neutral: 12 14 18;
55
+ --text-selected-primary: 254 53 83;
56
+ --button-default: 236 236 236;
57
+ --text-inverse: 12 14 18;
58
+ --bg-error-bold: 215 0 68;
59
+ --text-error: 255 0 81;
60
+ --border-interactive: 236 25 56;
61
+ --border-selected: 254 53 83;
62
+ --button-primary: 236 25 56;
63
+ --border-strong: 97 101 108;
64
+ --border-secondary-hover: 0 199 205;
65
+ --bg-secondary-hover: 6 59 70;
66
+ --shadow-color: 255 255 255;
67
+ }
@@ -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
+ @if(label){<div>{{ label }}</div>}
220
+ </div>
221
+ </ng-container>
222
+ }
223
+ </button>
@@ -0,0 +1,11 @@
1
+ <div class="chart-wrapper" [style.height]="height">
2
+ <div
3
+ echarts
4
+ [options]="chartOptions"
5
+ [loading]="loading"
6
+ (chartInit)="onChartInit($event)"
7
+ (chartClick)="onChartClick($event)"
8
+ class="fx-chart"
9
+ [style.height]="height"
10
+ ></div>
11
+ </div>
@@ -0,0 +1,42 @@
1
+ <label
2
+ class="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 w-4 h-4 border rounded-full transition-colors duration-150 shrink-0"
16
+ [ngClass]="{
17
+ 'rounded-full': rounded,
18
+ 'rounded-sm': !rounded,
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 w-4 h-4 transition-opacity duration-150"
28
+ viewBox="0 0 24 24"
29
+ fill="none"
30
+ stroke="currentColor"
31
+ stroke-width="3"
32
+ stroke-linecap="round"
33
+ stroke-linejoin="round"
34
+ [style.opacity]="value ? 1 : 0"
35
+ >
36
+ <path d="M5 13l4 4L19 7" />
37
+ </svg>
38
+ </span>
39
+ </span>
40
+
41
+ @if(label){<span class="mb-0 txt-field-label">{{ label }}</span>}
42
+ </label>
@@ -0,0 +1,44 @@
1
+ <div class="flex items-center justify-center w-full h-full">
2
+ <svg
3
+ class="transform -rotate-90 block"
4
+ [attr.viewBox]="'0 0 ' + radius * 2 + ' ' + radius * 2"
5
+ width="100%"
6
+ height="100%"
7
+ >
8
+ <circle
9
+ class="opacity-20"
10
+ [attr.cx]="radius"
11
+ [attr.cy]="radius"
12
+ [attr.r]="normalizedRadius"
13
+ [attr.stroke-width]="stroke"
14
+ fill="transparent"
15
+ stroke="currentColor"
16
+ ></circle>
17
+
18
+ <circle
19
+ class="stroke-current"
20
+ [attr.cx]="radius"
21
+ [attr.cy]="radius"
22
+ [attr.r]="normalizedRadius"
23
+ [attr.stroke-width]="stroke"
24
+ fill="transparent"
25
+ stroke-linecap="round"
26
+ [attr.stroke-dasharray]="circumference"
27
+ [attr.stroke-dashoffset]="dashOffset"
28
+ style="transition: stroke-dashoffset 300ms linear"
29
+ ></circle>
30
+
31
+ @if(showPercent){
32
+ <text
33
+ [attr.x]="radius"
34
+ [attr.y]="radius"
35
+ dominant-baseline="central"
36
+ text-anchor="middle"
37
+ class="text-xs font-medium"
38
+ fill="currentColor"
39
+ >
40
+ {{ percent }}%
41
+ </text>
42
+ }
43
+ </svg>
44
+ </div>
@@ -0,0 +1,36 @@
1
+ <div class="flex flex-col mb-4 w-full text-left">
2
+ @if (label) {
3
+ <label class="txt-field-label">
4
+ {{ label }}
5
+ <span *ngIf="required" class="txt-required">*</span>
6
+ </label>
7
+ }
8
+
9
+ <div class="relative">
10
+ <input
11
+ [owlDateTimeTrigger]="picker"
12
+ [owlDateTime]="picker"
13
+ [placeholder]="placeholder"
14
+ [disabled]="disabled"
15
+ [min]="minDate"
16
+ [max]="maxDate"
17
+ (blur)="onBlur()"
18
+ [value]="value"
19
+ readonly
20
+ class="input-default pr-9"
21
+ />
22
+ <span
23
+ [owlDateTimeTrigger]="picker"
24
+ class="absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors"
25
+ >
26
+ <fx-ui-hero-icon icon="calendar" [size]="20" class="text-text-primary"></fx-ui-hero-icon>
27
+ </span>
28
+ </div>
29
+ <owl-date-time
30
+ #picker
31
+ [startAt]="startAt"
32
+ [pickerType]="type"
33
+ (afterPickerClosed)="onValueChange($event)"
34
+ ></owl-date-time>
35
+ <div *ngIf="invalid" class="txt-invalid">{{ getErrorMessage(label) }}</div>
36
+ </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>