tailjng 0.1.6 → 0.1.8

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 (175) hide show
  1. package/README.md +27 -5
  2. package/cli/execute/init-app.js +5 -2
  3. package/cli/execute/sync-app.js +14 -2
  4. package/cli/settings/colors-config-utils.js +69 -11
  5. package/cli/settings/icons-config-utils.js +62 -0
  6. package/cli/settings/path-utils.js +32 -2
  7. package/cli/settings/project-utils.js +7 -1
  8. package/cli/templates/app.generator.js +8 -5
  9. package/fesm2022/tailjng.mjs +247 -80
  10. package/fesm2022/tailjng.mjs.map +1 -1
  11. package/lib/services/static/theme.service.d.ts +39 -1
  12. package/lib/utils/theme/theme-variables.util.d.ts +31 -0
  13. package/package.json +1 -1
  14. package/public-api.d.ts +2 -1
  15. package/registry/components.json +41 -18
  16. package/src/colors.safelist.css +2 -2
  17. package/src/lib/components/.config/README.md +11 -0
  18. package/src/lib/components/.config/colors/README.md +40 -0
  19. package/src/lib/components/{colors-config → .config/colors}/colors.config.ts +5 -5
  20. package/src/lib/components/{colors-config → .config/colors}/colors.safelist.css +2 -2
  21. package/src/lib/components/.config/icons/README.md +26 -0
  22. package/src/lib/components/.config/icons/icons.lucide.ts +134 -0
  23. package/src/lib/components/.config/input/README.md +24 -0
  24. package/src/lib/components/.config/input/input.classes.ts +119 -0
  25. package/src/lib/components/alert/alert-dialog/dialog-alert.component.css +177 -6
  26. package/src/lib/components/alert/alert-dialog/dialog-alert.component.html +24 -37
  27. package/src/lib/components/alert/alert-dialog/dialog-alert.component.ts +66 -56
  28. package/src/lib/components/alert/alert-dialog/dialog-alert.types.ts +19 -0
  29. package/src/lib/components/alert/alert-toast/toast-alert.component.css +494 -14
  30. package/src/lib/components/alert/alert-toast/toast-alert.component.html +106 -102
  31. package/src/lib/components/alert/alert-toast/toast-alert.component.ts +485 -128
  32. package/src/lib/components/alert/alert-toast/toast-alert.types.ts +25 -0
  33. package/src/lib/components/badge/badge.component.html +34 -21
  34. package/src/lib/components/badge/badge.component.ts +140 -31
  35. package/src/lib/components/button/button.component.html +16 -10
  36. package/src/lib/components/button/button.component.ts +162 -22
  37. package/src/lib/components/card/card-complete/complete-card.component.html +2 -2
  38. package/src/lib/components/card/card-complete/complete-card.component.ts +26 -16
  39. package/src/lib/components/card/card-crud-complete/complete-crud-card.component.html +2 -2
  40. package/src/lib/components/card/card-crud-complete/complete-crud-card.component.ts +26 -16
  41. package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.css +30 -0
  42. package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.html +58 -46
  43. package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.ts +135 -64
  44. package/src/lib/components/checkbox/checkbox-input/input-checkbox.types.ts +3 -0
  45. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.css +62 -0
  46. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.html +39 -25
  47. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.ts +74 -15
  48. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.types.ts +1 -0
  49. package/src/lib/components/coach-mark/coach-mark.component.html +6 -24
  50. package/src/lib/components/coach-mark/coach-mark.component.scss +1 -7
  51. package/src/lib/components/coach-mark/coach-mark.component.ts +51 -18
  52. package/src/lib/components/coach-mark/coach-mark.directive.ts +133 -78
  53. package/src/lib/components/coach-mark/coach-mark.types.ts +12 -0
  54. package/src/lib/components/dialog/dialog.component.css +1 -1
  55. package/src/lib/components/dialog/dialog.component.html +56 -65
  56. package/src/lib/components/dialog/dialog.component.ts +136 -110
  57. package/src/lib/components/dialog/dialog.types.ts +19 -0
  58. package/src/lib/components/filter/filter-complete/complete-filter.component.html +17 -20
  59. package/src/lib/components/filter/filter-complete/complete-filter.component.scss +25 -0
  60. package/src/lib/components/filter/filter-complete/complete-filter.component.ts +58 -34
  61. package/src/lib/components/filter/filter-complete/complete-filter.types.ts +7 -0
  62. package/src/lib/components/filter/filter-complete/complete-filter.util.ts +16 -0
  63. package/src/lib/components/form/form-container/container-form.component.css +4 -0
  64. package/src/lib/components/form/form-container/container-form.component.html +2 -2
  65. package/src/lib/components/form/form-container/container-form.component.ts +72 -16
  66. package/src/lib/components/form/form-container/container-form.types.ts +42 -0
  67. package/src/lib/components/form/form-container/form-col-span.directive.ts +25 -0
  68. package/src/lib/components/form/form-sidebar/sidebar-form.component.css +45 -0
  69. package/src/lib/components/form/form-sidebar/sidebar-form.component.html +128 -124
  70. package/src/lib/components/form/form-sidebar/sidebar-form.component.ts +114 -34
  71. package/src/lib/components/form/form-sidebar/sidebar-form.types.ts +3 -0
  72. package/src/lib/components/{toggle-radio/toggle-radio.component.css → form/form-validation/validation-form.component.css} +0 -1
  73. package/src/lib/components/form/form-validation/validation-form.component.html +10 -6
  74. package/src/lib/components/form/form-validation/validation-form.component.ts +99 -12
  75. package/src/lib/components/form/form-validation/validation-form.types.ts +33 -0
  76. package/src/lib/components/icon/icon.component.html +8 -5
  77. package/src/lib/components/icon/icon.component.ts +111 -9
  78. package/src/lib/components/input/input/input.component.css +0 -14
  79. package/src/lib/components/input/input/input.component.html +19 -16
  80. package/src/lib/components/input/input/input.component.ts +130 -53
  81. package/src/lib/components/input/input/input.types.ts +8 -0
  82. package/src/lib/components/input/input-file/file-input.component.html +65 -56
  83. package/src/lib/components/input/input-file/file-input.component.ts +276 -173
  84. package/src/lib/components/input/input-file/file-input.types.ts +2 -0
  85. package/src/lib/components/input/input-range/range-input.component.css +67 -0
  86. package/src/lib/components/input/input-range/range-input.component.html +50 -58
  87. package/src/lib/components/input/input-range/range-input.component.ts +148 -60
  88. package/src/lib/components/input/input-range/range-input.types.ts +7 -0
  89. package/src/lib/components/input/input-textarea/textarea-input.component.html +16 -7
  90. package/src/lib/components/input/input-textarea/textarea-input.component.ts +140 -50
  91. package/src/lib/components/input/input-textarea/textarea-input.types.ts +2 -0
  92. package/src/lib/components/label/label.component.html +17 -16
  93. package/src/lib/components/label/label.component.ts +94 -16
  94. package/src/lib/components/label/label.types.ts +2 -0
  95. package/src/lib/components/menu/menu-options-table/menu-options-defaults.ts +34 -0
  96. package/src/lib/components/menu/menu-options-table/options-table-menu.component.html +34 -20
  97. package/src/lib/components/menu/menu-options-table/options-table-menu.component.ts +211 -58
  98. package/src/lib/components/menu/menu-options-table/options-table-menu.types.ts +38 -0
  99. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.html +49 -52
  100. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.ts +112 -24
  101. package/src/lib/components/menu/options-coach-menu/options-coach-menu.types.ts +9 -0
  102. package/src/lib/components/mode-toggle/mode-toggle.component.html +11 -16
  103. package/src/lib/components/mode-toggle/mode-toggle.component.ts +69 -33
  104. package/src/lib/components/paginator/paginator-complete/complete-paginator.component.html +4 -4
  105. package/src/lib/components/paginator/paginator-complete/complete-paginator.component.ts +31 -7
  106. package/src/lib/components/paginator/paginator-complete/complete-paginator.types.ts +12 -0
  107. package/src/lib/components/paginator/paginator-complete/complete-paginator.util.ts +36 -0
  108. package/src/lib/components/progress-bar/progress-bar.component.html +41 -40
  109. package/src/lib/components/progress-bar/progress-bar.component.ts +95 -11
  110. package/src/lib/components/progress-bar/progress-bar.types.ts +2 -0
  111. package/src/lib/components/select/select-dropdown/dropdown-select.component.html +56 -46
  112. package/src/lib/components/select/select-dropdown/dropdown-select.component.ts +450 -509
  113. package/src/lib/components/select/select-dropdown/dropdown-select.types.ts +43 -0
  114. package/src/lib/components/select/select-dropdown/dropdown-select.util.ts +179 -0
  115. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.html +131 -42
  116. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.ts +491 -475
  117. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.types.ts +22 -0
  118. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.util.ts +20 -0
  119. package/src/lib/components/select/select-multi-table/multi-table-select.component.css +4 -0
  120. package/src/lib/components/select/select-multi-table/multi-table-select.component.html +76 -60
  121. package/src/lib/components/select/select-multi-table/multi-table-select.component.ts +250 -313
  122. package/src/lib/components/select/select-multi-table/multi-table-select.types.ts +10 -0
  123. package/src/lib/components/select/select-multi-table/multi-table-select.util.ts +5 -0
  124. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.css +155 -0
  125. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.html +72 -53
  126. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.ts +84 -27
  127. package/src/lib/components/sidebar/sidebar-static/static-sidebar.types.ts +2 -0
  128. package/src/lib/components/table/table-complete/complete-table.component.html +21 -23
  129. package/src/lib/components/table/table-complete/complete-table.component.ts +190 -338
  130. package/src/lib/components/table/table-complete/complete-table.types.ts +28 -0
  131. package/src/lib/components/table/table-complete/complete-table.util.ts +236 -0
  132. package/src/lib/components/table/table-complete/index.ts +2 -0
  133. package/src/lib/components/table/table-crud-complete/complete-crud-table.animations.ts +34 -0
  134. package/src/lib/components/table/table-crud-complete/complete-crud-table.component.html +87 -142
  135. package/src/lib/components/table/table-crud-complete/complete-crud-table.component.scss +0 -63
  136. package/src/lib/components/table/table-crud-complete/complete-crud-table.component.ts +544 -831
  137. package/src/lib/components/table/table-crud-complete/complete-crud-table.types.ts +57 -0
  138. package/src/lib/components/table/table-crud-complete/complete-crud-table.util.ts +723 -0
  139. package/src/lib/components/table/table-crud-complete/index.ts +3 -0
  140. package/src/lib/components/theme-generator/theme-generator.component.css +21 -0
  141. package/src/lib/components/theme-generator/theme-generator.component.html +141 -116
  142. package/src/lib/components/theme-generator/theme-generator.component.ts +44 -24
  143. package/src/lib/components/toggle-radio/shared/toggle-options.types.ts +8 -0
  144. package/src/lib/components/toggle-radio/shared/toggle-options.util.ts +62 -0
  145. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.css +22 -0
  146. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.html +65 -0
  147. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.ts +192 -0
  148. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.types.ts +1 -0
  149. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.css +34 -0
  150. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.html +47 -0
  151. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.ts +187 -0
  152. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.types.ts +1 -0
  153. package/src/lib/components/tooltip/tooltip.directive.ts +12 -9
  154. package/src/lib/components/tooltip/tooltip.service.ts +331 -133
  155. package/src/lib/components/tooltip/tooltip.types.ts +9 -0
  156. package/src/lib/components/viewer/viewer-image/image-viewer.component.css +14 -4
  157. package/src/lib/components/viewer/viewer-image/image-viewer.component.html +61 -95
  158. package/src/lib/components/viewer/viewer-image/image-viewer.component.ts +182 -177
  159. package/src/lib/components/viewer/viewer-image/image-viewer.types.ts +3 -0
  160. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.css +25 -0
  161. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.html +95 -24
  162. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.ts +168 -15
  163. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.types.ts +1 -0
  164. package/src/styles.css +2 -2
  165. package/lib/services/static/icons.service.d.ts +0 -65
  166. package/src/lib/components/colors-config/README.md +0 -38
  167. package/src/lib/components/form/form-sidebar/sidebar-form.component.scss +0 -0
  168. package/src/lib/components/form/form-validation/validation-form.component.scss +0 -0
  169. package/src/lib/components/menu/menu-options-table/options-table-menu.component.scss +0 -0
  170. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.scss +0 -12
  171. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.scss +0 -0
  172. package/src/lib/components/toggle-radio/toggle-radio.component.html +0 -51
  173. package/src/lib/components/toggle-radio/toggle-radio.component.ts +0 -222
  174. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.scss +0 -0
  175. package/tailjng-0.1.6.tgz +0 -0
@@ -1,107 +1,184 @@
1
+ import { NgClass } from '@angular/common';
1
2
  import { Component, Input, forwardRef } from '@angular/core';
2
- import { FormsModule, ReactiveFormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
3
- import { NgClass, CommonModule } from '@angular/common';
4
- import { LucideAngularModule } from 'lucide-angular';
5
- import { JIconsService } from 'tailjng';
6
-
3
+ import {
4
+ ControlValueAccessor,
5
+ FormsModule,
6
+ NG_VALUE_ACCESSOR,
7
+ ReactiveFormsModule,
8
+ } from '@angular/forms';
9
+ import { Icons } from '../../.config/icons/icons.lucide';
10
+ import {
11
+ INPUT_DISABLED_OVERLAY_CLASSES,
12
+ INPUT_FOCUS_CLASSES,
13
+ INPUT_PADDING_X_SINGLE,
14
+ INPUT_SINGLE_LINE_HEIGHT_CLASSES,
15
+ INPUT_SURFACE_CLASSES,
16
+ inputActionButtonClasses,
17
+ mergeInputClasses,
18
+ } from '../../.config/input/input.classes';
19
+ import { JIconComponent } from '../../icon/icon.component';
20
+ import { JInputType } from './input.types';
21
+
22
+ export type { JInputType } from './input.types';
23
+
24
+ /**
25
+ * Text input with ControlValueAccessor, clear button, and theme-aware styling.
26
+ *
27
+ * Install: `npx tailjng add input`
28
+ */
7
29
  @Component({
8
30
  selector: 'JInput',
9
- imports: [FormsModule, ReactiveFormsModule, NgClass, LucideAngularModule, CommonModule],
31
+ imports: [FormsModule, ReactiveFormsModule, NgClass, JIconComponent],
10
32
  templateUrl: './input.component.html',
11
- styleUrls: ['./input.component.css'],
33
+ styleUrl: './input.component.css',
12
34
  providers: [
13
35
  {
14
36
  provide: NG_VALUE_ACCESSOR,
15
37
  useExisting: forwardRef(() => JInputComponent),
16
- multi: true
17
- }
18
- ]
38
+ multi: true,
39
+ },
40
+ ],
19
41
  })
20
42
  export class JInputComponent implements ControlValueAccessor {
43
+ // Project Icons registry — template usage: Icons.X
44
+ readonly Icons = Icons;
21
45
 
22
- @Input() type: 'text' | 'password' | 'number' | 'date' | 'datetime-local' | 'email' = 'text';
46
+ // Native input type
47
+ @Input() type: JInputType = 'text';
23
48
 
24
49
  @Input() id?: string;
25
50
  @Input() name?: string;
26
- @Input() placeholder: string = '';
51
+ @Input() placeholder = '';
52
+
53
+ @Input() isDisabled = false;
54
+ @Input() isReadonly = false;
55
+ @Input() required = false;
56
+
57
+ // Show clear (X) button when the field has a value
58
+ @Input() clearButton = false;
59
+
60
+ // Extra Tailwind classes on the `<input>`
61
+ @Input() classes = '';
27
62
 
28
- @Input() isDisabled: boolean = false;
29
- @Input() isReadonly: boolean = false;
30
- @Input() required: boolean = false;
31
- @Input() clearButton: boolean = false;
63
+ // Extra conditional classes (same role as [ngClass] on the input)
64
+ @Input() ngClasses: Record<string, boolean> = {};
32
65
 
33
- @Input() classes: string = '';
34
- @Input() ngClass: { [key: string]: boolean } = {};
66
+ innerValue = '';
35
67
 
36
- innerValue: any = '';
68
+ private onChange: (value: string) => void = () => {};
69
+ private onTouched: () => void = () => {};
37
70
 
38
- get value(): any {
71
+ /**
72
+ * Current value bound to the native input.
73
+ * @returns The internal string value.
74
+ */
75
+ get value(): string {
39
76
  return this.innerValue;
40
77
  }
41
78
 
42
- set value(val: any) {
43
- if (val !== this.innerValue) {
44
- this.innerValue = val;
45
- this.onChange(val);
46
- }
79
+ /**
80
+ * Whether the clear button should be visible.
81
+ * @returns `true` when `clearButton` is enabled and the field is not empty.
82
+ */
83
+ get showClearButton(): boolean {
84
+ return this.clearButton && this.hasValue;
47
85
  }
48
86
 
49
- get combinedNgClass() {
50
- return {
51
- ...(this.ngClass || {}),
52
- 'opacity-50': this.isDisabled
53
- };
87
+ /**
88
+ * Whether the field has a non-empty value.
89
+ * @returns `true` when `innerValue` is not an empty string.
90
+ */
91
+ get hasValue(): boolean {
92
+ return this.innerValue !== '';
54
93
  }
55
94
 
56
- // ControlValueAccessor methods
57
- onChange: any = () => { };
58
- onTouched: any = () => { };
95
+ /**
96
+ * Whether to show the fake date placeholder overlay (mobile / coarse pointer).
97
+ * @returns `true` for date inputs with placeholder and no value yet.
98
+ */
99
+ get showDatePlaceholder(): boolean {
100
+ return this.type === 'date' && !this.hasValue && !!this.placeholder;
101
+ }
59
102
 
60
- constructor(public readonly iconsService: JIconsService) { }
103
+ /**
104
+ * Class map for the native `<input>` element.
105
+ * @returns Base input styles merged with `ngClasses` and disabled opacity.
106
+ */
107
+ get computedClasses(): Record<string, boolean> {
108
+ return mergeInputClasses(
109
+ INPUT_SURFACE_CLASSES,
110
+ INPUT_SINGLE_LINE_HEIGHT_CLASSES,
111
+ INPUT_FOCUS_CLASSES,
112
+ INPUT_PADDING_X_SINGLE,
113
+ this.ngClasses,
114
+ { 'pr-3': !this.clearButton, 'pr-7': this.clearButton },
115
+ this.isDisabled ? INPUT_DISABLED_OVERLAY_CLASSES : {},
116
+ );
117
+ }
61
118
 
62
119
  /**
63
- * Writes a value to the component.
64
- * @param value - The value to write.
120
+ * Class map for the clear button.
121
+ * @returns Hover and disabled utilities for the clear control.
65
122
  */
66
- writeValue(value: any): void {
67
- if (value !== undefined) {
68
- this.value = value;
69
- }
123
+ get clearButtonClasses(): Record<string, boolean> {
124
+ return inputActionButtonClasses(this.isDisabled);
70
125
  }
71
126
 
72
127
  /**
73
- * Registers a callback function to be called when the input value changes.
74
- * @param fn - The callback function to register.
128
+ * Writes the value from the form model into the view.
129
+ * @param value Value from Angular forms.
75
130
  */
76
- registerOnChange(fn: (value: any) => void): void {
131
+ writeValue(value: unknown): void {
132
+ this.innerValue = value != null ? String(value) : '';
133
+ }
134
+
135
+ /**
136
+ * Registers the change callback for Angular forms.
137
+ * @param fn Callback invoked when the value changes.
138
+ */
139
+ registerOnChange(fn: (value: string) => void): void {
77
140
  this.onChange = fn;
78
141
  }
79
142
 
80
143
  /**
81
- * Registers a callback function to be called when the input is touched.
82
- * @param fn - The callback function to register.
144
+ * Registers the touched callback for Angular forms.
145
+ * @param fn Callback invoked when the control is touched.
83
146
  */
84
147
  registerOnTouched(fn: () => void): void {
85
148
  this.onTouched = fn;
86
149
  }
87
150
 
88
151
  /**
89
- * Writes a value to the component.
90
- * @param event
152
+ * Syncs disabled state from Angular forms.
153
+ * @param isDisabled Whether the control is disabled.
154
+ */
155
+ setDisabledState(isDisabled: boolean): void {
156
+ this.isDisabled = isDisabled;
157
+ }
158
+
159
+ /**
160
+ * Handles native input events and propagates the value to forms.
161
+ * @param event Native input event.
91
162
  */
92
163
  onInput(event: Event): void {
93
- const target = event.target as HTMLInputElement | HTMLTextAreaElement;
94
- this.value = target.value;
95
- this.onChange(this.value);
164
+ const target = event.target as HTMLInputElement;
165
+ this.innerValue = target.value;
166
+ this.onChange(this.innerValue);
167
+ this.onTouched();
168
+ }
169
+
170
+ /**
171
+ * Marks the control as touched on blur.
172
+ */
173
+ onBlur(): void {
96
174
  this.onTouched();
97
175
  }
98
176
 
99
177
  /**
100
- * Clears the input value and resets the component state.
101
- * This method is typically used when a clear button is clicked.
178
+ * Clears the field value and notifies Angular forms.
102
179
  */
103
180
  clearInput(): void {
104
- this.value = '';
181
+ this.innerValue = '';
105
182
  this.onChange('');
106
183
  this.onTouched();
107
184
  }
@@ -0,0 +1,8 @@
1
+ /** Supported native input types for {@link JInputComponent}. */
2
+ export type JInputType =
3
+ | 'text'
4
+ | 'password'
5
+ | 'number'
6
+ | 'date'
7
+ | 'datetime-local'
8
+ | 'email';
@@ -1,66 +1,75 @@
1
- <div class="relative w-full select-none">
2
- <input
3
- #fileInput
4
- type="file"
5
- [id]="id"
6
- [name]="name ?? ''"
7
- [accept]="accept"
8
- [multiple]="multiple"
9
- (change)="onFileSelected($event)"
10
- [required]="required"
11
- [disabled]="isDisabled"
12
- class="hidden"
13
- (blur)="onTouched()"
1
+ <div class="relative w-full">
2
+ <input
3
+ #fileInput
4
+ type="file"
5
+ [id]="id"
6
+ [name]="name ?? ''"
7
+ [accept]="accept"
8
+ [multiple]="multiple"
9
+ (change)="onFileSelected($event)"
10
+ [required]="required"
11
+ [disabled]="isDisabled"
12
+ class="hidden"
13
+ (blur)="onBlur()"
14
14
  />
15
-
16
- <label
17
- [for]="id"
18
- class="input block text-sm w-full h-[40px] max-[400px]:h-[35px] text-[12px] pr-1 bg-background dark:bg-dark-background border border-border dark:border-dark-border text-black dark:text-white placeholder:text-muted-foreground dark:placeholder:text-dark-muted-foreground rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary dark:focus:ring-dark-primary transition duration-200 resize-y disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-between transition duration-200 cursor-pointer"
19
- >
20
- <div class="truncate" [ngClass]="{ 'opacity-80' : !innerValue?.name }">
21
- @if (innerValue?.name) {
22
- <span>{{ innerValue?.name }}</span>
23
- } @else {
24
- <span class="flex items-center gap-2 max-[400px]:h-[35px] text-muted-foreground dark:text-dark-muted-foreground">
25
- <lucide-icon [name]="iconsService.icons.upload" [size]="15" />
26
- Seleccionar archivo...
27
- </span>
28
- }
29
- </div>
30
15
 
31
- <div class="flex gap-1">
32
- @if (value && clearButton) {
33
- <button
34
- type="button"
35
- class="text-gray-400 hover:text-gray-500 pr-1 mr-1 hover:text-gray-600 focus:outline-none cursor-pointer"
36
- (click)="clearFile()"
37
- >
38
- <lucide-icon [name]="iconsService.icons.close" class="w-4 h-4" />
39
- </button>
16
+ <label [attr.for]="id" [ngClass]="computedClasses" [class]="classes">
17
+ <div class="min-w-0 flex-1 truncate" [class.opacity-80]="!hasValue">
18
+ @if (displayFileName) {
19
+ <span>{{ displayFileName }}</span>
20
+ } @else {
21
+ <span class="flex items-center gap-2 text-muted-foreground dark:text-dark-muted-foreground">
22
+ <JIcon [icon]="Icons.Upload" [size]="15" [inheritParentColor]="true" [ariaHidden]="true" />
23
+ {{ placeholder }}
24
+ </span>
40
25
  }
41
-
42
- <button
43
- type="button"
44
- class="text-gray-400 hover:text-gray-500 pr-1 mr-1 hover:text-gray-600 focus:outline-none cursor-pointer"
45
- (click)="getImageFromClipboard()"
46
- >
47
- <lucide-icon [name]="iconsService.icons.clipboard" class="w-4 h-4" />
48
- </button>
49
26
  </div>
50
27
 
28
+ <div class="flex shrink-0 items-center gap-1">
29
+ @if (showClearButton) {
30
+ <button
31
+ type="button"
32
+ class="inline-flex cursor-pointer items-center justify-center p-0 focus:outline-none"
33
+ [ngClass]="actionButtonClasses"
34
+ (click)="onClearClick($event)"
35
+ [disabled]="isDisabled"
36
+ aria-label="Clear"
37
+ >
38
+ <JIcon
39
+ [icon]="Icons.X"
40
+ [size]="16"
41
+ [inheritParentColor]="true"
42
+ [ariaHidden]="true"
43
+ />
44
+ </button>
45
+ }
46
+
47
+ <button
48
+ type="button"
49
+ class="inline-flex cursor-pointer items-center justify-center p-0 focus:outline-none"
50
+ [ngClass]="actionButtonClasses"
51
+ (click)="onClipboardClick($event)"
52
+ [disabled]="isDisabled"
53
+ aria-label="Paste from clipboard"
54
+ >
55
+ <JIcon
56
+ [icon]="Icons.Clipboard"
57
+ [size]="16"
58
+ [inheritParentColor]="true"
59
+ [ariaHidden]="true"
60
+ />
61
+ </button>
62
+ </div>
51
63
  </label>
52
64
 
53
- @if (previewUrl && showImage) {
54
- <div class="mt-2 w-full align-center justify-center flex">
55
- <img
56
- [src]="previewUrl"
57
- alt="Vista previa"
58
- [ngStyle]="{
59
- width: widthImgFile ? widthImgFile + 'px' : '100%',
60
- height: heightImgFile ? heightImgFile + 'px' : 'auto'
61
- }"
62
- class="rounded border border-border dark:border-dark-border shadow-sm object-cover"
63
- />
65
+ @if (showPreview) {
66
+ <div class="mt-2 flex w-full items-center justify-center">
67
+ <img
68
+ [src]="previewImageUrl"
69
+ alt="Preview"
70
+ [ngStyle]="previewStyles"
71
+ class="rounded border border-border object-cover shadow-sm dark:border-dark-border"
72
+ />
64
73
  </div>
65
74
  }
66
75
  </div>