@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,101 @@
1
+ <div class="drawer-host-wrapper">
2
+ <a href="/" class="h-[60px] p-4">
3
+ @if (logo) {
4
+ <img
5
+ [src]="logo"
6
+ class="h-[20px] w-auto transition-all duration-300 ease-in-out"
7
+ [ngClass]="{ 'scale-90 ml-2': !isExpanded, 'ml-5': isExpanded }"
8
+ />
9
+ } @else {
10
+ <div class="h-[30px] w-auto transition-all duration-300 ease-in-out"></div>
11
+ }
12
+ </a>
13
+ <div class="drawer-container" [@drawerExpand]="getDrawerState()">
14
+ <!-- Navigation Items -->
15
+ <nav class="drawer-nav">
16
+ <ng-container *ngFor="let item of items">
17
+ <ng-container
18
+ *ngTemplateOutlet="drawerItem; context: { $implicit: item, level: 0 }"
19
+ ></ng-container>
20
+ </ng-container>
21
+ </nav>
22
+ </div>
23
+
24
+ <!-- Floating Toggle Button on right border -->
25
+ <button
26
+ type="button"
27
+ class="toggle-btn"
28
+ (click)="toggleDrawer()"
29
+ [matTooltip]="isExpanded ? 'Collapse' : 'Expand'"
30
+ matTooltipClass="text-text-primary text-xs font-semibold"
31
+ matTooltipPosition="right"
32
+ >
33
+ <fx-ui-hero-icon
34
+ [icon]="isExpanded ? 'chevron-left' : 'chevron-right'"
35
+ [size]="16"
36
+ class="text-text-primary"
37
+ ></fx-ui-hero-icon>
38
+ </button>
39
+ </div>
40
+
41
+ <!-- Recursive Template for Drawer Items -->
42
+ <ng-template #drawerItem let-item let-level="level">
43
+ <div class="drawer-item-wrapper">
44
+ <!-- Item Button/Link -->
45
+ <a
46
+ *ngIf="item.route && !item.children"
47
+ [routerLink]="item.route"
48
+ class="drawer-item"
49
+ [class.active]="isActiveRoute(item.route)"
50
+ [class.has-children]="item.children && item.children.length > 0"
51
+ [style.paddingLeft.px]="isExpanded ? 16 + level * 16 : 16"
52
+ [matTooltip]="!isExpanded ? item.label : ''"
53
+ matTooltipPosition="right"
54
+ matTooltipClass="text-text-primary text-xs font-semibold"
55
+ (click)="onItemClick(item, $event)"
56
+ >
57
+ <div class="item-content">
58
+ <fx-ui-hero-icon [icon]="item.icon" [size]="20" class="item-icon"></fx-ui-hero-icon>
59
+ <span *ngIf="isExpanded" class="item-label">{{ item.label }}</span>
60
+ </div>
61
+ </a>
62
+
63
+ <button
64
+ *ngIf="!item.route || item.children"
65
+ type="button"
66
+ class="drawer-item"
67
+ [class.active]="isActiveRoute(item.route)"
68
+ [class.has-children]="item.children && item.children.length > 0"
69
+ [style.paddingLeft.px]="isExpanded ? 16 + level * 16 : 16"
70
+ [matTooltip]="!isExpanded ? item.label : ''"
71
+ matTooltipPosition="right"
72
+ matTooltipClass="text-text-primary text-sm font-semibold"
73
+ (click)="onItemClick(item, $event)"
74
+ >
75
+ <div class="item-content">
76
+ <fx-ui-hero-icon [icon]="item.icon" [size]="20" class="item-icon"></fx-ui-hero-icon>
77
+ <span *ngIf="isExpanded" class="item-label">{{ item.label }}</span>
78
+ <fx-ui-hero-icon
79
+ *ngIf="isExpanded && item.children && item.children.length > 0"
80
+ [icon]="'chevron-down'"
81
+ [size]="16"
82
+ class="chevron-icon"
83
+ [class.rotated]="isAccordionExpanded(item.id)"
84
+ ></fx-ui-hero-icon>
85
+ </div>
86
+ </button>
87
+
88
+ <!-- Accordion Children -->
89
+ <div
90
+ *ngIf="item.children && item.children.length > 0"
91
+ class="accordion-children"
92
+ [@accordionExpand]="getAccordionState(item.id)"
93
+ >
94
+ <ng-container *ngFor="let child of item.children">
95
+ <ng-container
96
+ *ngTemplateOutlet="drawerItem; context: { $implicit: child, level: level + 1 }"
97
+ ></ng-container>
98
+ </ng-container>
99
+ </div>
100
+ </div>
101
+ </ng-template>
@@ -0,0 +1,10 @@
1
+ <vflow
2
+ [background]="{
3
+ type: 'solid',
4
+ color: `rgba(var(${backgroundColor})`
5
+ }"
6
+ [nodes]="nodes"
7
+ [edges]="edges"
8
+ (onConnect)="handleConnection($event)"
9
+ [view]="view"
10
+ />
@@ -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,48 @@
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
+ appTrimOnBlur
11
+ [appTrimOnBlurCollapse]="true"
12
+ [type]="displayType"
13
+ [placeholder]="placeholder"
14
+ [disabled]="disabled"
15
+ [value]="value"
16
+ (input)="onInput($event)"
17
+ (blur)="onBlur()"
18
+ (focus)="onFocus()"
19
+ [attr.maxlength]="maxlength"
20
+ [class]="type === 'otp' ? 'input-otp' : 'input-default'"
21
+ [ngClass]="{
22
+ 'input-invalid': invalid,
23
+ 'pr-8': type === 'password' || suffixIcon,
24
+ 'txt-otp-input': type === 'otp'
25
+ }"
26
+ />
27
+ <button
28
+ type="button"
29
+ class="absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary"
30
+ (click)="onSuffixClick()"
31
+ [disabled]="disabled"
32
+ >
33
+ @if (type === 'password') {
34
+ <i class="material-symbols-outlined text-lg select-none">{{
35
+ showPassword ? 'visibility_off' : 'visibility'
36
+ }}</i>
37
+ } @else if (suffixIcon) {
38
+ <i [class]="iconClass" class="text-lg select-none">{{ suffixIcon }}</i>
39
+ }
40
+ </button>
41
+ </div>
42
+
43
+ @if (invalid){
44
+ <div class="txt-invalid">
45
+ {{ getErrorMessage(label) }}
46
+ </div>
47
+ }
48
+ </div>
@@ -0,0 +1,43 @@
1
+ <div class="kanban-board">
2
+ <div class="kanban-columns">
3
+ @for (column of columns; track column.id) {
4
+ <div class="kanban-column">
5
+ <div class="kanban-column-header">
6
+ <h3 class="kanban-column-title">{{ column.title }}</h3>
7
+ <span class="kanban-column-count">{{ column.items.length }}</span>
8
+ </div>
9
+
10
+ <div
11
+ class="kanban-column-content"
12
+ cdkDropList
13
+ [id]="column.id"
14
+ [cdkDropListData]="column.items"
15
+ [cdkDropListConnectedTo]="getColumnIds()"
16
+ (cdkDropListDropped)="onDrop($event, column.id)"
17
+ >
18
+ @for (item of column.items; track $index) {
19
+ <div class="kanban-item" cdkDrag>
20
+ <div class="kanban-item-placeholder" *cdkDragPlaceholder></div>
21
+
22
+ @if (itemTemplate) {
23
+ <ng-container
24
+ *ngTemplateOutlet="itemTemplate; context: { $implicit: item, index: $index }"
25
+ ></ng-container>
26
+ } @else {
27
+ <div class="kanban-item-default">
28
+ {{ item }}
29
+ </div>
30
+ }
31
+ </div>
32
+ }
33
+
34
+ @if (column.items.length === 0) {
35
+ <div class="kanban-column-empty">
36
+ Drop items here
37
+ </div>
38
+ }
39
+ </div>
40
+ </div>
41
+ }
42
+ </div>
43
+ </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,3 @@
1
+ <div class="w-full rounded-2xl shadow-sm p-1 bg-bg-primary">
2
+ <div #editorContainer class="min-h-[200px] text-base"></div>
3
+ </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>
@@ -0,0 +1,102 @@
1
+ ::ng-deep .fx-select-field {
2
+ display: block !important;
3
+ width: 100% !important;
4
+ margin: 0 !important;
5
+ padding: 0 !important;
6
+ border-radius: 0.75rem;
7
+ box-shadow: 0 1px 1px rgb(var(--border-default));
8
+ }
9
+
10
+ ::ng-deep .fx-select-field .mat-mdc-form-field-wrapper,
11
+ ::ng-deep .fx-select-field .mat-mdc-text-field-wrapper {
12
+ padding: 0 !important;
13
+ margin: 0 !important;
14
+ width: 100% !important;
15
+ }
16
+
17
+ ::ng-deep .fx-select-field .mdc-text-field {
18
+ width: 100% !important;
19
+ margin: 0 !important;
20
+ padding: 0 !important;
21
+ --mdc-shape-small: 0 !important;
22
+ }
23
+
24
+ ::ng-deep .fx-select-field .mat-mdc-form-field-flex {
25
+ width: 100% !important;
26
+ margin: 0 !important;
27
+ padding: 0 0.75rem !important;
28
+ border: 1px solid rgb(var(--border-default));
29
+ border-radius: 0.5rem;
30
+ height: 36px !important;
31
+ align-items: center;
32
+ background-color: rgb(var(--bg-primary));
33
+ }
34
+
35
+ ::ng-deep .fx-select-field .mdc-notched-outline,
36
+ ::ng-deep .fx-select-field .mat-mdc-form-field-subscript-wrapper {
37
+ display: none !important;
38
+ }
39
+
40
+ ::ng-deep .fx-select-field.mat-focused .mat-mdc-form-field-flex {
41
+ border: 2px solid rgb(var(--border-interactive)) !important;
42
+ outline: none !important;
43
+ border-radius: 0.5rem;
44
+ }
45
+
46
+ ::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex {
47
+ border-color: #ef4444 !important;
48
+ box-shadow: none !important;
49
+ }
50
+
51
+ ::ng-deep .fx-select-field .mat-mdc-select-trigger {
52
+ padding: 0 !important;
53
+ margin: 0 !important;
54
+ }
55
+
56
+ ::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper {
57
+ margin-right: 0 !important;
58
+ }
59
+
60
+ ::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper {
61
+ color: rgb(var(--text-primary));
62
+ }
63
+
64
+ ::ng-deep .mat-mdc-select-panel {
65
+ background-color: rgb(var(--bg-primary)) !important;
66
+ border: 1px solid rgb(var(--border-default)) !important;
67
+ border-radius: 0.5rem !important;
68
+ box-shadow: 0 2px 4px rgb(0 0 0 / 0.1) !important;
69
+ }
70
+
71
+ ::ng-deep .fx-select-field .mat-mdc-select-placeholder {
72
+ color: rgb(var(--text-placeholder)) !important;
73
+ font-size: 14px;
74
+ }
75
+
76
+ ::ng-deep .fx-select-field .mat-mdc-select-value {
77
+ color: rgb(var(--text-primary)) !important;
78
+ font-size: 14px;
79
+ font-weight: 400;
80
+ }
81
+
82
+ .mat-select-panel .search-option-full-width {
83
+ /* Remove default padding to allow the input to stretch */
84
+ padding-left: 0 !important;
85
+ padding-right: 0 !important;
86
+ /* Ensure it is a block element to take up full width */
87
+ display: block;
88
+ /* Prevent the option from being highlighted on hover/focus */
89
+ pointer-events: none;
90
+ /* Optional: Adjust height if needed */
91
+ line-height: initial;
92
+ height: auto;
93
+ }
94
+
95
+ .mat-select-panel .search-option-full-width .search-bar {
96
+ width: 100%;
97
+ padding: 8px 16px; /* Add visual padding back to the input */
98
+ border: none;
99
+ /* Optional: Add a subtle border to separate it from the options */
100
+ border-bottom: 1px solid #ddd;
101
+ box-sizing: border-box; /* Include padding in the element's total width */
102
+ }
@@ -0,0 +1,42 @@
1
+ <div class="mb-4 text-left w-full" [class]="class">
2
+ @if (label) {
3
+ <label class="block txt-field-label">
4
+ {{ label }}
5
+ @if(required) {<span class="txt-required">*</span>}
6
+ </label>
7
+ }
8
+
9
+ <mat-form-field class="fx-select-field w-full shadow-sm" appearance="fill">
10
+ <mat-select
11
+ [placeholder]="placeholder"
12
+ [disabled]="disabled"
13
+ [multiple]="multiple"
14
+ [value]="value"
15
+ (selectionChange)="onSelectionChange($event.value)"
16
+ (openedChange)="onOpened($event)"
17
+ (blur)="onTouched()"
18
+ >
19
+ @if(enableSearch){
20
+ <div class="px-semi w-full">
21
+ <input
22
+ type="text"
23
+ [placeholder]="'Search'"
24
+ [(ngModel)]="searchTerm"
25
+ (ngModelChange)="onSearchChange($event)"
26
+ (click)="$event.stopPropagation()"
27
+ class="text-text-primary placeholder:text-text-placeholder w-full bg-bg-primary border-b px-semi py-normal border-border-default focus:outline-none focus:border-border-interactive text-sm text-text-primary tracking-normal ring-0 transition-colors duration-500 ease-in-out"
28
+ />
29
+ </div>
30
+ }
31
+ <mat-option *ngFor="let option of filteredOptions" [value]="option.value">
32
+ <span class="txt-default">{{ option.label }}</span>
33
+ </mat-option>
34
+ </mat-select>
35
+ </mat-form-field>
36
+
37
+ @if(invalid) {
38
+ <div class="txt-invalid text-left">
39
+ {{ getErrorMessage(label) }}
40
+ </div>
41
+ }
42
+ </div>
@@ -0,0 +1,21 @@
1
+ <div class="w-full animate-pulse space-y-normal">
2
+ <div
3
+ class="grid gap-small"
4
+ [ngStyle]="{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }"
5
+ >
6
+ @for(col of [].constructor(columns); track col) {
7
+ <div class="h-6 bg-bg-hover rounded"></div>
8
+ }
9
+ </div>
10
+
11
+ @for(row of [].constructor(rows); track row) {
12
+ <div
13
+ class="grid gap-small"
14
+ [ngStyle]="{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }"
15
+ >
16
+ @for(col of [].constructor(columns); track col) {
17
+ <div class="h-7 bg-bg-hover rounded"></div>
18
+ }
19
+ </div>
20
+ }
21
+ </div>
@@ -0,0 +1,54 @@
1
+ <div
2
+ class="w-full select-none"
3
+ [class.cursor-not-allowed]="disabled"
4
+ [class.opacity-60]="disabled"
5
+ role="group"
6
+ >
7
+ <div
8
+ #track
9
+ class="relative touch-none py-4"
10
+ (click)="onTrackClick($event)"
11
+ [attr.aria-disabled]="disabled"
12
+ [attr.aria-orientation]="vertical ? 'vertical' : 'horizontal'"
13
+ >
14
+ <div
15
+ class="relative flex items-center"
16
+ [ngClass]="{ 'flex-col h-48': vertical }"
17
+ >
18
+ <div
19
+ class="relative flex-1 rounded-full bg-gray-600 h-2"
20
+ [ngClass]="{ 'w-1 rotate-0 h-full w-auto bg-border-gray-700': vertical }"
21
+ >
22
+ <div
23
+ class="absolute left-0 top-0 h-full rounded-full bg-primary"
24
+ *ngIf="!vertical"
25
+ [style.width.%]="percent"
26
+ ></div>
27
+
28
+ <div
29
+ class="absolute bottom-0 left-0 w-full rounded-full bg-primary"
30
+ *ngIf="vertical"
31
+ [style.height.%]="percent"
32
+ style="transform-origin: bottom;"
33
+ ></div>
34
+
35
+ <button
36
+ #thumb
37
+ type="button"
38
+ class="absolute -mt-1 -ml-1.5 w-4 h-4 rounded-full shadow focus:ring-primary bg-primary border-2 border-text-primary"
39
+ [ngStyle]="thumbStyle()"
40
+ role="slider"
41
+ [attr.aria-valuemin]="min"
42
+ [attr.aria-valuemax]="max"
43
+ [attr.aria-valuenow]="value"
44
+ [attr.aria-disabled]="disabled"
45
+ tabindex="0"
46
+ (pointerdown)="onPointerDown($event)"
47
+ (pointermove)="onPointerMove($event)"
48
+ (pointerup)="onPointerUp($event)"
49
+ [disabled]="disabled"
50
+ ></button>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </div>
@@ -0,0 +1,21 @@
1
+ <div
2
+ class="relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer"
3
+ [ngClass]="{
4
+ 'bg-success': value && !disabled,
5
+ 'bg-button-default': !value && !disabled,
6
+ 'bg-bg-hover': disabled
7
+ }"
8
+ (click)="toggle()"
9
+ >
10
+ @if(value) {
11
+ <i style="font-size: 20px;" class="material-symbols-outlined absolute left-0.5 top-0 text-text-inverse">check</i>
12
+
13
+ }
14
+ @if(!value) {
15
+ <i style="font-size: 20px;" class="material-symbols-outlined absolute right-0.5 top-0 text-text-inverse">close</i>
16
+ }
17
+ <div
18
+ class="absolute top-0.5 left-0.5 w-4 h-4 bg-text-inverse rounded-full shadow-md transform transition-transform duration-300"
19
+ [ngClass]="{ 'translate-x-5': value }"
20
+ ></div>
21
+ </div>
@@ -0,0 +1 @@
1
+ <ng-template><ng-content></ng-content></ng-template>