@moni-labs/moni-ui 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +5181 -1043
- package/dist/components/_base/moni-element.d.ts +16 -9
- package/dist/components/_base/moni-element.d.ts.map +1 -1
- package/dist/components/_base/moni-element.js +63 -9
- package/dist/components/index.js +2 -2
- package/dist/components/loading-shapes.d.ts +19 -0
- package/dist/components/loading-shapes.d.ts.map +1 -1
- package/dist/components/loading-shapes.js +19 -0
- package/dist/components/moni-app-bar.d.ts +72 -62
- package/dist/components/moni-app-bar.d.ts.map +1 -1
- package/dist/components/moni-app-bar.js +72 -62
- package/dist/components/moni-badge.d.ts +64 -65
- package/dist/components/moni-badge.d.ts.map +1 -1
- package/dist/components/moni-badge.js +64 -66
- package/dist/components/moni-bottom-sheet.d.ts +129 -61
- package/dist/components/moni-bottom-sheet.d.ts.map +1 -1
- package/dist/components/moni-bottom-sheet.js +217 -131
- package/dist/components/moni-button-group.d.ts +107 -29
- package/dist/components/moni-button-group.d.ts.map +1 -1
- package/dist/components/moni-button-group.js +107 -29
- package/dist/components/moni-button-segment.d.ts +53 -12
- package/dist/components/moni-button-segment.d.ts.map +1 -1
- package/dist/components/moni-button-segment.js +53 -12
- package/dist/components/moni-button.d.ts +116 -38
- package/dist/components/moni-button.d.ts.map +1 -1
- package/dist/components/moni-button.js +128 -38
- package/dist/components/moni-card.d.ts +68 -50
- package/dist/components/moni-card.d.ts.map +1 -1
- package/dist/components/moni-card.js +68 -50
- package/dist/components/moni-carousel.d.ts +471 -53
- package/dist/components/moni-carousel.d.ts.map +1 -1
- package/dist/components/moni-carousel.js +862 -264
- package/dist/components/moni-checkbox.d.ts +49 -46
- package/dist/components/moni-checkbox.d.ts.map +1 -1
- package/dist/components/moni-checkbox.js +55 -48
- package/dist/components/moni-chip.d.ts +100 -33
- package/dist/components/moni-chip.d.ts.map +1 -1
- package/dist/components/moni-chip.js +104 -34
- package/dist/components/moni-color-field.d.ts +99 -24
- package/dist/components/moni-color-field.d.ts.map +1 -1
- package/dist/components/moni-color-field.js +99 -24
- package/dist/components/moni-context-menu.d.ts +72 -26
- package/dist/components/moni-context-menu.d.ts.map +1 -1
- package/dist/components/moni-context-menu.js +76 -30
- package/dist/components/moni-dialog.d.ts +84 -59
- package/dist/components/moni-dialog.d.ts.map +1 -1
- package/dist/components/moni-dialog.js +105 -58
- package/dist/components/moni-divider.d.ts +39 -27
- package/dist/components/moni-divider.d.ts.map +1 -1
- package/dist/components/moni-divider.js +42 -30
- package/dist/components/moni-expansion.d.ts +32 -22
- package/dist/components/moni-expansion.d.ts.map +1 -1
- package/dist/components/moni-expansion.js +32 -22
- package/dist/components/moni-fab-menu.d.ts +61 -23
- package/dist/components/moni-fab-menu.d.ts.map +1 -1
- package/dist/components/moni-fab-menu.js +69 -31
- package/dist/components/moni-fab.d.ts +86 -28
- package/dist/components/moni-fab.d.ts.map +1 -1
- package/dist/components/moni-fab.js +92 -34
- package/dist/components/moni-file-field.d.ts +118 -30
- package/dist/components/moni-file-field.d.ts.map +1 -1
- package/dist/components/moni-file-field.js +118 -30
- package/dist/components/moni-icon.d.ts +40 -35
- package/dist/components/moni-icon.d.ts.map +1 -1
- package/dist/components/moni-icon.js +43 -38
- package/dist/components/moni-list-item.d.ts +46 -33
- package/dist/components/moni-list-item.d.ts.map +1 -1
- package/dist/components/moni-list-item.js +61 -41
- package/dist/components/moni-list.d.ts +30 -20
- package/dist/components/moni-list.d.ts.map +1 -1
- package/dist/components/moni-list.js +36 -21
- package/dist/components/moni-loading-indicator.d.ts +54 -22
- package/dist/components/moni-loading-indicator.d.ts.map +1 -1
- package/dist/components/moni-loading-indicator.js +54 -22
- package/dist/components/moni-menu-item.d.ts +23 -16
- package/dist/components/moni-menu-item.d.ts.map +1 -1
- package/dist/components/moni-menu-item.js +23 -16
- package/dist/components/moni-menu.d.ts +81 -28
- package/dist/components/moni-menu.d.ts.map +1 -1
- package/dist/components/moni-menu.js +81 -30
- package/dist/components/moni-morph-modal.d.ts +141 -0
- package/dist/components/moni-morph-modal.d.ts.map +1 -1
- package/dist/components/moni-morph-modal.js +295 -58
- package/dist/components/moni-nav-item.d.ts +59 -29
- package/dist/components/moni-nav-item.d.ts.map +1 -1
- package/dist/components/moni-nav-item.js +59 -29
- package/dist/components/moni-nav.d.ts +94 -35
- package/dist/components/moni-nav.d.ts.map +1 -1
- package/dist/components/moni-nav.js +94 -35
- package/dist/components/moni-progress.d.ts +99 -55
- package/dist/components/moni-progress.d.ts.map +1 -1
- package/dist/components/moni-progress.js +99 -55
- package/dist/components/moni-radio.d.ts +62 -50
- package/dist/components/moni-radio.d.ts.map +1 -1
- package/dist/components/moni-radio.js +65 -52
- package/dist/components/moni-ripple.d.ts +74 -59
- package/dist/components/moni-ripple.d.ts.map +1 -1
- package/dist/components/moni-ripple.js +74 -59
- package/dist/components/moni-segmented-button.d.ts +91 -16
- package/dist/components/moni-segmented-button.d.ts.map +1 -1
- package/dist/components/moni-segmented-button.js +94 -17
- package/dist/components/moni-select-option.d.ts +30 -23
- package/dist/components/moni-select-option.d.ts.map +1 -1
- package/dist/components/moni-select-option.js +30 -23
- package/dist/components/moni-select.d.ts +300 -35
- package/dist/components/moni-select.d.ts.map +1 -1
- package/dist/components/moni-select.js +323 -39
- package/dist/components/moni-side-sheet.d.ts +94 -32
- package/dist/components/moni-side-sheet.d.ts.map +1 -1
- package/dist/components/moni-side-sheet.js +94 -32
- package/dist/components/moni-slider.d.ts +152 -41
- package/dist/components/moni-slider.d.ts.map +1 -1
- package/dist/components/moni-slider.js +154 -42
- package/dist/components/moni-snackbar.d.ts +53 -43
- package/dist/components/moni-snackbar.d.ts.map +1 -1
- package/dist/components/moni-snackbar.js +53 -43
- package/dist/components/moni-split-button.d.ts +63 -18
- package/dist/components/moni-split-button.d.ts.map +1 -1
- package/dist/components/moni-split-button.js +63 -18
- package/dist/components/moni-step.d.ts +36 -24
- package/dist/components/moni-step.d.ts.map +1 -1
- package/dist/components/moni-step.js +41 -29
- package/dist/components/moni-stepper.d.ts +64 -27
- package/dist/components/moni-stepper.d.ts.map +1 -1
- package/dist/components/moni-stepper.js +72 -34
- package/dist/components/moni-switch.d.ts +57 -46
- package/dist/components/moni-switch.d.ts.map +1 -1
- package/dist/components/moni-switch.js +59 -47
- package/dist/components/moni-tab.d.ts +26 -18
- package/dist/components/moni-tab.d.ts.map +1 -1
- package/dist/components/moni-tab.js +29 -21
- package/dist/components/moni-tabs.d.ts +34 -28
- package/dist/components/moni-tabs.d.ts.map +1 -1
- package/dist/components/moni-tabs.js +34 -28
- package/dist/components/moni-text-field.d.ts +139 -29
- package/dist/components/moni-text-field.d.ts.map +1 -1
- package/dist/components/moni-text-field.js +157 -31
- package/dist/components/moni-textarea.d.ts +127 -29
- package/dist/components/moni-textarea.d.ts.map +1 -1
- package/dist/components/moni-textarea.js +131 -32
- package/dist/components/moni-time-picker.d.ts +114 -24
- package/dist/components/moni-time-picker.d.ts.map +1 -1
- package/dist/components/moni-time-picker.js +127 -33
- package/dist/components/moni-toolbar.d.ts +37 -23
- package/dist/components/moni-toolbar.d.ts.map +1 -1
- package/dist/components/moni-toolbar.js +37 -23
- package/dist/components/moni-tooltip.d.ts +100 -36
- package/dist/components/moni-tooltip.d.ts.map +1 -1
- package/dist/components/moni-tooltip.js +104 -40
- package/dist/components/moni-typography.d.ts +68 -30
- package/dist/components/moni-typography.d.ts.map +1 -1
- package/dist/components/moni-typography.js +70 -32
- package/dist/styles/tokens.css +7 -7
- package/dist/types/events.d.ts +17 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +1 -0
- package/dist/utils/event-emitter.d.ts +13 -0
- package/dist/utils/event-emitter.d.ts.map +1 -0
- package/dist/utils/event-emitter.js +13 -0
- package/package.json +2 -1
- package/src/components/_base/moni-element.ts +73 -9
- package/src/components/index.ts +2 -2
- package/src/components/loading-shapes.ts +19 -0
- package/src/components/moni-app-bar.test.ts +10 -10
- package/src/components/moni-app-bar.ts +72 -62
- package/src/components/moni-badge.ts +64 -66
- package/src/components/moni-bottom-sheet.test.ts +39 -45
- package/src/components/moni-bottom-sheet.ts +222 -131
- package/src/components/moni-button-group.test.ts +14 -14
- package/src/components/moni-button-group.ts +107 -29
- package/src/components/moni-button-segment.ts +53 -12
- package/src/components/moni-button.test.ts +28 -26
- package/src/components/moni-button.ts +139 -39
- package/src/components/moni-card.test.ts +6 -6
- package/src/components/moni-card.ts +70 -50
- package/src/components/moni-carousel.test.ts +12 -12
- package/src/components/moni-carousel.ts +953 -290
- package/src/components/moni-checkbox.test.ts +7 -7
- package/src/components/moni-checkbox.ts +62 -48
- package/src/components/moni-chip.test.ts +17 -17
- package/src/components/moni-chip.ts +112 -34
- package/src/components/moni-color-field.test.ts +5 -5
- package/src/components/moni-color-field.ts +108 -24
- package/src/components/moni-context-menu.test.ts +11 -11
- package/src/components/moni-context-menu.ts +76 -30
- package/src/components/moni-dialog.ts +108 -59
- package/src/components/moni-divider.test.ts +4 -4
- package/src/components/moni-divider.ts +42 -30
- package/src/components/moni-expansion.ts +32 -22
- package/src/components/moni-fab-menu.test.ts +11 -11
- package/src/components/moni-fab-menu.ts +69 -31
- package/src/components/moni-fab.test.ts +16 -16
- package/src/components/moni-fab.ts +100 -34
- package/src/components/moni-file-field.test.ts +8 -8
- package/src/components/moni-file-field.ts +132 -30
- package/src/components/moni-icon.test.ts +11 -11
- package/src/components/moni-icon.ts +43 -38
- package/src/components/moni-list-item.test.ts +10 -10
- package/src/components/moni-list-item.ts +61 -41
- package/src/components/moni-list.ts +37 -21
- package/src/components/moni-loading-indicator.test.ts +3 -3
- package/src/components/moni-loading-indicator.ts +54 -22
- package/src/components/moni-menu-item.ts +23 -16
- package/src/components/moni-menu.test.ts +7 -7
- package/src/components/moni-menu.ts +87 -30
- package/src/components/moni-morph-modal.test.ts +18 -17
- package/src/components/moni-morph-modal.ts +327 -60
- package/src/components/moni-nav-item.ts +59 -29
- package/src/components/moni-nav.test.ts +11 -11
- package/src/components/moni-nav.ts +94 -35
- package/src/components/moni-progress.test.ts +9 -9
- package/src/components/moni-progress.ts +100 -56
- package/src/components/moni-radio.test.ts +8 -8
- package/src/components/moni-radio.ts +71 -51
- package/src/components/moni-ripple.ts +74 -59
- package/src/components/moni-segmented-button.test.ts +4 -4
- package/src/components/moni-segmented-button.ts +94 -17
- package/src/components/moni-select-option.ts +30 -23
- package/src/components/moni-select.test.ts +11 -11
- package/src/components/moni-select.ts +361 -50
- package/src/components/moni-side-sheet.test.ts +7 -7
- package/src/components/moni-side-sheet.ts +94 -32
- package/src/components/moni-slider.test.ts +7 -7
- package/src/components/moni-slider.ts +165 -42
- package/src/components/moni-snackbar.test.ts +8 -8
- package/src/components/moni-snackbar.ts +53 -43
- package/src/components/moni-split-button.ts +63 -18
- package/src/components/moni-step.test.ts +7 -7
- package/src/components/moni-step.ts +41 -29
- package/src/components/moni-stepper.test.ts +7 -7
- package/src/components/moni-stepper.ts +72 -34
- package/src/components/moni-switch.test.ts +12 -12
- package/src/components/moni-switch.ts +66 -47
- package/src/components/moni-tab.test.ts +5 -5
- package/src/components/moni-tab.ts +29 -21
- package/src/components/moni-tabs.ts +34 -28
- package/src/components/moni-text-field.test.ts +13 -13
- package/src/components/moni-text-field.ts +181 -30
- package/src/components/moni-textarea.test.ts +17 -17
- package/src/components/moni-textarea.ts +155 -31
- package/src/components/moni-time-picker.test.ts +5 -5
- package/src/components/moni-time-picker.ts +128 -33
- package/src/components/moni-toolbar.test.ts +8 -8
- package/src/components/moni-toolbar.ts +37 -23
- package/src/components/moni-tooltip.test.ts +15 -15
- package/src/components/moni-tooltip.ts +107 -40
- package/src/components/moni-typography.test.ts +10 -10
- package/src/components/moni-typography.ts +73 -32
- package/src/styles/tokens.css +7 -7
- package/src/types/events.ts +17 -0
- package/src/utils/event-emitter.ts +26 -0
|
@@ -16,60 +16,104 @@ import { customElement, property } from 'lit/decorators.js';
|
|
|
16
16
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
17
17
|
import './moni-icon.js';
|
|
18
18
|
/**
|
|
19
|
-
* Material Design 3 Floating Action Button (FAB)
|
|
19
|
+
* Componente Material Design 3 Floating Action Button (FAB).
|
|
20
20
|
*
|
|
21
|
-
* FABs
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* Los FABs representan la acción principal, o más común, en una pantalla. Aparecen
|
|
22
|
+
* frente a todo el contenido de la pantalla, típicamente como una forma circular con un icono en
|
|
23
|
+
* su centro.
|
|
24
24
|
*
|
|
25
|
-
* **
|
|
25
|
+
* **Referencia de la especificación M3:** `m3-docs/components/floating-action-buttons/specs.md`
|
|
26
26
|
*
|
|
27
|
-
* **
|
|
28
|
-
* - `size="small"`
|
|
29
|
-
*
|
|
30
|
-
* - `shape="circle"`
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* - `color="surface"`
|
|
34
|
-
*
|
|
27
|
+
* **Actualizaciones y Deprecaciones de M3 Expressive (Mayo 2025):**
|
|
28
|
+
* - `size="small"` **ya no es recomendado** por M3. Use `medium` (40dp o 56dp)
|
|
29
|
+
* o `large` (96dp). Deprecado en v0.3.1; se eliminará en v1.0.
|
|
30
|
+
* - `shape="circle"` **no es parte de M3**. Los FABs M3 usan una forma `rounded` (redondeada) con un
|
|
31
|
+
* radio de esquina de 16dp (que se transforma a un radio `full` al pasar el cursor/enfocar).
|
|
32
|
+
* Deprecado en v0.3.1; se eliminará en v1.0.
|
|
33
|
+
* - `color="surface"` **ya no es recomendado**. Use `primary`, `secondary`,
|
|
34
|
+
* o `tertiary` para asegurar un mapeo de color adecuado al tema M3.
|
|
35
35
|
*
|
|
36
|
-
* **
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
36
|
+
* **FABs Extendidos:**
|
|
37
|
+
* Cuando `extended` es true, el FAB muestra una etiqueta de texto junto al icono.
|
|
38
|
+
* Los FABs extendidos son más anchos y se usan típicamente cuando la acción necesita texto explícito
|
|
39
|
+
* para ser clara. El atributo `expanded` fuerza al FAB a su ancho extendido completo,
|
|
40
|
+
* útil para animar entre los estados estándar y extendido al desplazarse.
|
|
41
41
|
*
|
|
42
|
-
* **
|
|
43
|
-
*
|
|
44
|
-
* (
|
|
42
|
+
* **Posicionamiento:**
|
|
43
|
+
* El atributo `position` aplica un posicionamiento absoluto/fijo predefinido
|
|
44
|
+
* (ej. `bottom-trailing`), encajando el FAB en las esquinas estándar de la pantalla.
|
|
45
45
|
*
|
|
46
46
|
* @example
|
|
47
47
|
* ```html
|
|
48
|
-
* <!--
|
|
48
|
+
* <!-- FAB primario estándar -->
|
|
49
49
|
* <moni-fab icon="edit"></moni-fab>
|
|
50
50
|
*
|
|
51
|
-
* <!--
|
|
52
|
-
* <moni-fab color="tertiary" extended icon="add" label="
|
|
51
|
+
* <!-- FAB terciario extendido -->
|
|
52
|
+
* <moni-fab color="tertiary" extended icon="add" label="Nueva tarea"></moni-fab>
|
|
53
53
|
*
|
|
54
|
-
* <!--
|
|
54
|
+
* <!-- FAB posicionado -->
|
|
55
55
|
* <moni-fab position="bottom-trailing" icon="navigation"></moni-fab>
|
|
56
56
|
* ```
|
|
57
57
|
*
|
|
58
|
-
* @csspart button -
|
|
59
|
-
* @csspart icon -
|
|
60
|
-
* @csspart label -
|
|
58
|
+
* @csspart button - El elemento `<button>` interno.
|
|
59
|
+
* @csspart icon - El contenedor para el icono.
|
|
60
|
+
* @csspart label - La etiqueta de texto (solo visible cuando está extendido).
|
|
61
61
|
*/
|
|
62
62
|
let MoniFab = class MoniFab extends MoniElement {
|
|
63
63
|
constructor() {
|
|
64
64
|
super(...arguments);
|
|
65
|
+
/**
|
|
66
|
+
* Define las dimensiones del FAB.
|
|
67
|
+
* `small` está deprecado en M3 Expressive.
|
|
68
|
+
* @type {'small' | 'medium' | 'large'}
|
|
69
|
+
* @default 'medium'
|
|
70
|
+
*/
|
|
65
71
|
this.size = 'medium';
|
|
72
|
+
/**
|
|
73
|
+
* Mapeo de color semántico del FAB.
|
|
74
|
+
* `surface` está deprecado en M3.
|
|
75
|
+
* @type {'primary' | 'secondary' | 'tertiary' | 'surface'}
|
|
76
|
+
* @default 'primary'
|
|
77
|
+
*/
|
|
66
78
|
this.color = 'primary';
|
|
79
|
+
/**
|
|
80
|
+
* Forma de las esquinas del FAB.
|
|
81
|
+
* `circle` está deprecado en M3 (los FABs deben ser cuadrados redondeados).
|
|
82
|
+
* @type {'rounded' | 'circle'}
|
|
83
|
+
* @default 'rounded'
|
|
84
|
+
*/
|
|
67
85
|
this.shape = 'rounded';
|
|
86
|
+
/**
|
|
87
|
+
* Alias heredado de `expanded`. Indica si el FAB muestra una etiqueta de texto.
|
|
88
|
+
* @type {boolean}
|
|
89
|
+
*/
|
|
68
90
|
this.extended = false;
|
|
91
|
+
/**
|
|
92
|
+
* Si es true, expande el FAB para mostrar su etiqueta de texto junto al icono.
|
|
93
|
+
* @type {boolean}
|
|
94
|
+
*/
|
|
69
95
|
this.expanded = false;
|
|
96
|
+
/**
|
|
97
|
+
* Deshabilita el FAB.
|
|
98
|
+
* @type {boolean}
|
|
99
|
+
*/
|
|
70
100
|
this.disabled = false;
|
|
101
|
+
/**
|
|
102
|
+
* Nombre del icono (Material Symbols) mostrado dentro del FAB.
|
|
103
|
+
* @type {string}
|
|
104
|
+
* @default 'add'
|
|
105
|
+
*/
|
|
71
106
|
this.icon = 'add';
|
|
107
|
+
/**
|
|
108
|
+
* Etiqueta de texto mostrada cuando el FAB se expande/extiende.
|
|
109
|
+
* @type {string}
|
|
110
|
+
*/
|
|
72
111
|
this.label = '';
|
|
112
|
+
/**
|
|
113
|
+
* Fija la posición del FAB relativa a los bordes de la pantalla.
|
|
114
|
+
* @type {'bottom-trailing' | 'bottom-leading' | 'top-trailing' | 'top-leading'}
|
|
115
|
+
* @default 'bottom-trailing'
|
|
116
|
+
*/
|
|
73
117
|
this.position = 'bottom-trailing';
|
|
74
118
|
}
|
|
75
119
|
static { MoniFab_1 = this; }
|
|
@@ -127,7 +171,7 @@ let MoniFab = class MoniFab extends MoniElement {
|
|
|
127
171
|
font-size: 1rem;
|
|
128
172
|
font-weight: 500;
|
|
129
173
|
color: var(--on-primary);
|
|
130
|
-
/*
|
|
174
|
+
/* Por defecto: sin relleno para que el icono se centre; el relleno se añade cuando existe etiqueta */
|
|
131
175
|
padding: 0 1.5rem;
|
|
132
176
|
background-color: var(--primary);
|
|
133
177
|
border: 0.0625rem solid transparent;
|
|
@@ -157,7 +201,7 @@ let MoniFab = class MoniFab extends MoniElement {
|
|
|
157
201
|
box-shadow: var(--elevate1);
|
|
158
202
|
}
|
|
159
203
|
|
|
160
|
-
/*
|
|
204
|
+
/* Cuando no hay etiqueta: solo icono, eliminar relleno horizontal para que el icono se centre */
|
|
161
205
|
.button:not(:has(> .label:not(:empty))) {
|
|
162
206
|
padding-inline: 0;
|
|
163
207
|
}
|
|
@@ -226,8 +270,8 @@ let MoniFab = class MoniFab extends MoniElement {
|
|
|
226
270
|
color: inherit;
|
|
227
271
|
}
|
|
228
272
|
|
|
229
|
-
/*
|
|
230
|
-
|
|
273
|
+
/* La etiqueta siempre se renderiza pero la cadena vacía se oculta mediante overflow.
|
|
274
|
+
Cuando se establece la propiedad label, aparece. */
|
|
231
275
|
.label {
|
|
232
276
|
white-space: nowrap;
|
|
233
277
|
max-inline-size: 16rem;
|
|
@@ -240,17 +284,31 @@ let MoniFab = class MoniFab extends MoniElement {
|
|
|
240
284
|
display: none;
|
|
241
285
|
}
|
|
242
286
|
|
|
243
|
-
/*
|
|
287
|
+
/* Forma circular: ocultar etiqueta completamente */
|
|
244
288
|
:host([shape='circle']) .label,
|
|
245
289
|
:host([shape='circle']) slot {
|
|
246
290
|
display: none !important;
|
|
247
291
|
}
|
|
248
|
-
/*
|
|
292
|
+
/* Círculo: eliminar relleno, hacerlo un círculo perfecto */
|
|
249
293
|
:host([shape='circle']) .button {
|
|
250
294
|
padding: 0 !important;
|
|
251
295
|
}
|
|
252
296
|
`
|
|
253
297
|
]; }
|
|
298
|
+
/**
|
|
299
|
+
* Renderiza el botón FAB con su icono, etiqueta extendida opcional, y estado de carga.
|
|
300
|
+
*
|
|
301
|
+
* **Composición de clases:**
|
|
302
|
+
* - `'fab'` — estilos base del FAB (redondo, 56dp, elevado).
|
|
303
|
+
* - `this.size` (`'small'` = 40dp, `'large'` = 96dp, por defecto = 56dp).
|
|
304
|
+
* - `this.variant` — esquema de color (`'primary'`, `'secondary'`, `'tertiary'`, `'surface'`).
|
|
305
|
+
* - `'extended'` — se añade cuando se establece `label`; ensancha el FAB en forma de píldora
|
|
306
|
+
* y revela el texto de la etiqueta con una transición CSS `max-width`.
|
|
307
|
+
*
|
|
308
|
+
* **Estado de carga:**
|
|
309
|
+
* Cuando `loading=true`, un spinner `<moni-progress>` reemplaza el icono. La etiqueta
|
|
310
|
+
* permanece visible para mantener el ancho del FAB extendido y prevenir saltos de diseño.
|
|
311
|
+
*/
|
|
254
312
|
render() {
|
|
255
313
|
const classes = [
|
|
256
314
|
'button',
|
|
@@ -7,75 +7,163 @@
|
|
|
7
7
|
import { MoniElement } from './_base/index.js';
|
|
8
8
|
import './moni-icon.js';
|
|
9
9
|
/**
|
|
10
|
-
* Material Design 3 File Field
|
|
10
|
+
* Componente Material Design 3 File Field (Campo de Archivo).
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* Un componente de campo especializado que proporciona una alternativa estilizada y accesible
|
|
13
|
+
* al `<input type="file">` nativo. Envuelve un input de archivo nativo dentro de
|
|
14
|
+
* la carcasa `.field` de M3 y presenta un input de texto de solo lectura que muestra los
|
|
15
|
+
* nombres de archivo(s) seleccionado(s) junto a un botón de acción "Seleccionar archivo" estilizado.
|
|
16
16
|
*
|
|
17
|
-
* **
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* **Arquitectura visual:**
|
|
18
|
+
* El componente aprovecha los patrones CSS `fieldStyles`. La estructura interna del DOM
|
|
19
|
+
* está ordenada específicamente como:
|
|
20
20
|
* `[text input] -> [label] -> [file input] -> [output]`
|
|
21
|
-
*
|
|
22
|
-
* (`input + label`)
|
|
23
|
-
*
|
|
21
|
+
* Este ordenamiento específico asegura que el selector CSS de hermano adyacente
|
|
22
|
+
* (`input + label`) pueda flotar correctamente la etiqueta cuando el campo está poblado,
|
|
23
|
+
* a pesar de que el campo visible sea realmente el input de texto de solo lectura.
|
|
24
24
|
*
|
|
25
|
-
* **
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
25
|
+
* **Gestión del estado:**
|
|
26
|
+
* Cuando el usuario selecciona archivos a través del input de archivo oculto, el componente escucha
|
|
27
|
+
* el evento nativo `change`, lee `input.files`, y actualiza el input de texto
|
|
28
|
+
* de solo lectura con una lista separada por comas de los nombres de archivo. La propiedad `value`
|
|
29
|
+
* se mantiene sincronizada, y se re-despacha un evento compuesto `'change'`.
|
|
30
30
|
*
|
|
31
|
-
* @fires change -
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* @fires change - Burbujea y está compuesto. Se dispara cuando se seleccionan o borran
|
|
32
|
+
* archivos. El consumidor puede leer la lista de `files` del input interno
|
|
33
|
+
* consultando el componente.
|
|
34
34
|
*
|
|
35
35
|
* @example
|
|
36
36
|
* ```html
|
|
37
|
-
* <!--
|
|
37
|
+
* <!-- Carga de un solo archivo -->
|
|
38
38
|
* <moni-file-field
|
|
39
|
-
* label="
|
|
39
|
+
* label="Foto de perfil"
|
|
40
40
|
* name="avatar"
|
|
41
41
|
* accept="image/png, image/jpeg"
|
|
42
|
-
* button-label="
|
|
42
|
+
* button-label="Explorar..."
|
|
43
43
|
* ></moni-file-field>
|
|
44
44
|
*
|
|
45
|
-
* <!--
|
|
45
|
+
* <!-- Carga de múltiples archivos con estado de error -->
|
|
46
46
|
* <moni-file-field
|
|
47
|
-
* label="
|
|
47
|
+
* label="Documentos"
|
|
48
48
|
* multiple
|
|
49
49
|
* error
|
|
50
|
-
* error-text="
|
|
50
|
+
* error-text="Los archivos superan el límite de tamaño máximo"
|
|
51
51
|
* ></moni-file-field>
|
|
52
52
|
* ```
|
|
53
53
|
*
|
|
54
|
-
* @csspart field -
|
|
55
|
-
* @csspart input-text -
|
|
56
|
-
* @csspart label -
|
|
57
|
-
* @csspart input-file -
|
|
58
|
-
* @csspart button -
|
|
54
|
+
* @csspart field - El contenedor div exterior `.field`.
|
|
55
|
+
* @csspart input-text - El `<input type="text">` de solo lectura visible.
|
|
56
|
+
* @csspart label - El elemento `<label>` flotante.
|
|
57
|
+
* @csspart input-file - El `<input type="file">` nativo oculto.
|
|
58
|
+
* @csspart button - El elemento de botón (estilizado vía CSS `::file-selector-button`).
|
|
59
59
|
*/
|
|
60
60
|
export declare class MoniFileField extends MoniElement {
|
|
61
|
+
/**
|
|
62
|
+
* El nombre del input, enviado con los datos del formulario.
|
|
63
|
+
* @type {string}
|
|
64
|
+
*/
|
|
61
65
|
name: string;
|
|
66
|
+
/**
|
|
67
|
+
* El texto de la etiqueta flotante.
|
|
68
|
+
* @type {string}
|
|
69
|
+
*/
|
|
62
70
|
label: string;
|
|
71
|
+
/**
|
|
72
|
+
* Variante visual del campo de texto.
|
|
73
|
+
* @type {'filled' | 'outlined'}
|
|
74
|
+
* @default 'outlined'
|
|
75
|
+
*/
|
|
63
76
|
variant: 'filled' | 'outlined';
|
|
77
|
+
/**
|
|
78
|
+
* Define las dimensiones del campo de texto.
|
|
79
|
+
* @type {'small' | 'medium' | 'large' | 'extra'}
|
|
80
|
+
* @default 'medium'
|
|
81
|
+
*/
|
|
64
82
|
size: 'small' | 'medium' | 'large' | 'extra';
|
|
83
|
+
/**
|
|
84
|
+
* Forma del radio del borde del campo.
|
|
85
|
+
* @type {'round' | 'square' | 'no-round'}
|
|
86
|
+
* @default 'no-round'
|
|
87
|
+
*/
|
|
65
88
|
shape: 'round' | 'square' | 'no-round';
|
|
89
|
+
/**
|
|
90
|
+
* El atributo `accept` para el input de archivo (ej. `image/*, .pdf`).
|
|
91
|
+
* @type {string}
|
|
92
|
+
*/
|
|
66
93
|
accept: string;
|
|
94
|
+
/**
|
|
95
|
+
* Permite seleccionar múltiples archivos si es true.
|
|
96
|
+
* @type {boolean}
|
|
97
|
+
*/
|
|
67
98
|
multiple: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Texto para el botón de selección de archivo.
|
|
101
|
+
* @type {string}
|
|
102
|
+
* @default 'Choose file'
|
|
103
|
+
*/
|
|
68
104
|
buttonLabel: string;
|
|
105
|
+
/**
|
|
106
|
+
* Deshabilita el campo de archivo.
|
|
107
|
+
* @type {boolean}
|
|
108
|
+
*/
|
|
69
109
|
disabled: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Texto de ayuda mostrado debajo del campo.
|
|
112
|
+
* @type {string}
|
|
113
|
+
*/
|
|
70
114
|
helper: string;
|
|
115
|
+
/**
|
|
116
|
+
* Texto de error mostrado debajo del campo cuando `error` es true.
|
|
117
|
+
* Sobrescribe el texto de ayuda.
|
|
118
|
+
* @type {string}
|
|
119
|
+
*/
|
|
71
120
|
errorText: string;
|
|
121
|
+
/**
|
|
122
|
+
* Si es true, establece el campo en un estado de error.
|
|
123
|
+
* @type {boolean}
|
|
124
|
+
*/
|
|
72
125
|
error: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* La representación en cadena de los archivos seleccionados (solo lectura para el usuario).
|
|
128
|
+
* @type {string}
|
|
129
|
+
*/
|
|
73
130
|
value: string;
|
|
131
|
+
/**
|
|
132
|
+
* Nombre del icono inicial (Material Symbols).
|
|
133
|
+
* @type {string}
|
|
134
|
+
*/
|
|
74
135
|
icon: string;
|
|
136
|
+
/**
|
|
137
|
+
* Nombre del icono final (Material Symbols).
|
|
138
|
+
* @type {string}
|
|
139
|
+
* @default 'folder_open'
|
|
140
|
+
*/
|
|
75
141
|
trailingIcon: string;
|
|
76
142
|
private _fileInput;
|
|
143
|
+
/**
|
|
144
|
+
* Hook del ciclo de vida reactivo (Lit).
|
|
145
|
+
* Transfiere de manera imperativa el estado de discapacidad (disabled) de Lit
|
|
146
|
+
* hacia el nodo `<input type="file">` invisible en el Shadow DOM, asegurando
|
|
147
|
+
* que el componente nativo reaccione adecuadamente a nivel navegador.
|
|
148
|
+
*/
|
|
77
149
|
updated(changed: Map<string, unknown>): void;
|
|
78
150
|
static styles: import("lit").CSSResult[];
|
|
151
|
+
/**
|
|
152
|
+
* Renderiza el campo de archivo como un `<input type="file">` oculto + una zona de soltar visible.
|
|
153
|
+
*
|
|
154
|
+
* El `<input type="file">` está oculto (pero no con `display: none`) para
|
|
155
|
+
* aprovechar el selector de archivos nativo del navegador. Al hacer clic en la zona de soltar visible
|
|
156
|
+
* se invoca programáticamente `_input.click()` para abrir el diálogo de archivo.
|
|
157
|
+
*
|
|
158
|
+
* **Arrastrar y soltar (Drag-and-drop):**
|
|
159
|
+
* `@dragover` / `@dragleave` / `@drop` en el contenedor de la zona de soltar gestionan
|
|
160
|
+
* el estado `dragging` que aplica una clase de resaltado CSS.
|
|
161
|
+
*
|
|
162
|
+
* **Visualización del nombre del archivo:**
|
|
163
|
+
* `_fileName` (derivado del `.name` del último archivo seleccionado) se muestra
|
|
164
|
+
* como una cadena de una sola línea truncada. Cuando no hay ningún archivo seleccionado,
|
|
165
|
+
* se muestra en su lugar el atributo `label` o un marcador de posición genérico.
|
|
166
|
+
*/
|
|
79
167
|
render(): import("lit").TemplateResult<1>;
|
|
80
168
|
}
|
|
81
169
|
declare global {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moni-file-field.d.ts","sourceRoot":"","sources":["../../src/components/moni-file-field.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,WAAW,EAA6B,MAAM,kBAAkB,CAAC;AAC1E,OAAO,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBACa,aAAc,SAAQ,WAAW;
|
|
1
|
+
{"version":3,"file":"moni-file-field.d.ts","sourceRoot":"","sources":["../../src/components/moni-file-field.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,WAAW,EAA6B,MAAM,kBAAkB,CAAC;AAC1E,OAAO,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBACa,aAAc,SAAQ,WAAW;IAC7C;;;OAGG;IAC0B,IAAI,SAAM;IAEvC;;;OAGG;IAC0B,KAAK,SAAM;IAExC;;;;OAIG;IAC0B,OAAO,EAAE,QAAQ,GAAG,UAAU,CAAc;IAEzE;;;;OAIG;IAEH,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAY;IAExD;;;;OAIG;IAEH,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAc;IAEpD;;;OAGG;IAC0B,MAAM,SAAM;IAEzC;;;OAGG;IACyC,QAAQ,UAAS;IAE7D;;;;OAIG;IAEH,WAAW,SAAiB;IAE5B;;;OAGG;IACyC,QAAQ,UAAS;IAE7D;;;OAGG;IAC0B,MAAM,SAAM;IAEzC;;;;OAIG;IACmD,SAAS,SAAM;IAErE;;;OAGG;IACyC,KAAK,UAAS;IAE1D;;;OAGG;IAC0B,KAAK,SAAM;IAExC;;;OAGG;IAC0B,IAAI,SAAM;IAEvC;;;;OAIG;IACsD,YAAY,SACtD;IAEc,OAAO,CAAC,UAAU,CAAoB;IAEnE;;;;;OAKG;IACM,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAO9C,OAAgB,MAAM,4BAepB;IAEF;;;;;;;;;;;;;;;OAeG;IACM,MAAM;CAoEf;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,iBAAiB,EAAE,aAAa,CAAC;KACjC;CACD;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -17,75 +17,147 @@ import { classMap } from 'lit/directives/class-map.js';
|
|
|
17
17
|
import { MoniElement, sharedStyles, fieldStyles } from './_base/index.js';
|
|
18
18
|
import './moni-icon.js';
|
|
19
19
|
/**
|
|
20
|
-
* Material Design 3 File Field
|
|
20
|
+
* Componente Material Design 3 File Field (Campo de Archivo).
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* Un componente de campo especializado que proporciona una alternativa estilizada y accesible
|
|
23
|
+
* al `<input type="file">` nativo. Envuelve un input de archivo nativo dentro de
|
|
24
|
+
* la carcasa `.field` de M3 y presenta un input de texto de solo lectura que muestra los
|
|
25
|
+
* nombres de archivo(s) seleccionado(s) junto a un botón de acción "Seleccionar archivo" estilizado.
|
|
26
26
|
*
|
|
27
|
-
* **
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* **Arquitectura visual:**
|
|
28
|
+
* El componente aprovecha los patrones CSS `fieldStyles`. La estructura interna del DOM
|
|
29
|
+
* está ordenada específicamente como:
|
|
30
30
|
* `[text input] -> [label] -> [file input] -> [output]`
|
|
31
|
-
*
|
|
32
|
-
* (`input + label`)
|
|
33
|
-
*
|
|
31
|
+
* Este ordenamiento específico asegura que el selector CSS de hermano adyacente
|
|
32
|
+
* (`input + label`) pueda flotar correctamente la etiqueta cuando el campo está poblado,
|
|
33
|
+
* a pesar de que el campo visible sea realmente el input de texto de solo lectura.
|
|
34
34
|
*
|
|
35
|
-
* **
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
35
|
+
* **Gestión del estado:**
|
|
36
|
+
* Cuando el usuario selecciona archivos a través del input de archivo oculto, el componente escucha
|
|
37
|
+
* el evento nativo `change`, lee `input.files`, y actualiza el input de texto
|
|
38
|
+
* de solo lectura con una lista separada por comas de los nombres de archivo. La propiedad `value`
|
|
39
|
+
* se mantiene sincronizada, y se re-despacha un evento compuesto `'change'`.
|
|
40
40
|
*
|
|
41
|
-
* @fires change -
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* @fires change - Burbujea y está compuesto. Se dispara cuando se seleccionan o borran
|
|
42
|
+
* archivos. El consumidor puede leer la lista de `files` del input interno
|
|
43
|
+
* consultando el componente.
|
|
44
44
|
*
|
|
45
45
|
* @example
|
|
46
46
|
* ```html
|
|
47
|
-
* <!--
|
|
47
|
+
* <!-- Carga de un solo archivo -->
|
|
48
48
|
* <moni-file-field
|
|
49
|
-
* label="
|
|
49
|
+
* label="Foto de perfil"
|
|
50
50
|
* name="avatar"
|
|
51
51
|
* accept="image/png, image/jpeg"
|
|
52
|
-
* button-label="
|
|
52
|
+
* button-label="Explorar..."
|
|
53
53
|
* ></moni-file-field>
|
|
54
54
|
*
|
|
55
|
-
* <!--
|
|
55
|
+
* <!-- Carga de múltiples archivos con estado de error -->
|
|
56
56
|
* <moni-file-field
|
|
57
|
-
* label="
|
|
57
|
+
* label="Documentos"
|
|
58
58
|
* multiple
|
|
59
59
|
* error
|
|
60
|
-
* error-text="
|
|
60
|
+
* error-text="Los archivos superan el límite de tamaño máximo"
|
|
61
61
|
* ></moni-file-field>
|
|
62
62
|
* ```
|
|
63
63
|
*
|
|
64
|
-
* @csspart field -
|
|
65
|
-
* @csspart input-text -
|
|
66
|
-
* @csspart label -
|
|
67
|
-
* @csspart input-file -
|
|
68
|
-
* @csspart button -
|
|
64
|
+
* @csspart field - El contenedor div exterior `.field`.
|
|
65
|
+
* @csspart input-text - El `<input type="text">` de solo lectura visible.
|
|
66
|
+
* @csspart label - El elemento `<label>` flotante.
|
|
67
|
+
* @csspart input-file - El `<input type="file">` nativo oculto.
|
|
68
|
+
* @csspart button - El elemento de botón (estilizado vía CSS `::file-selector-button`).
|
|
69
69
|
*/
|
|
70
70
|
let MoniFileField = class MoniFileField extends MoniElement {
|
|
71
71
|
constructor() {
|
|
72
72
|
super(...arguments);
|
|
73
|
+
/**
|
|
74
|
+
* El nombre del input, enviado con los datos del formulario.
|
|
75
|
+
* @type {string}
|
|
76
|
+
*/
|
|
73
77
|
this.name = '';
|
|
78
|
+
/**
|
|
79
|
+
* El texto de la etiqueta flotante.
|
|
80
|
+
* @type {string}
|
|
81
|
+
*/
|
|
74
82
|
this.label = '';
|
|
83
|
+
/**
|
|
84
|
+
* Variante visual del campo de texto.
|
|
85
|
+
* @type {'filled' | 'outlined'}
|
|
86
|
+
* @default 'outlined'
|
|
87
|
+
*/
|
|
75
88
|
this.variant = 'outlined';
|
|
89
|
+
/**
|
|
90
|
+
* Define las dimensiones del campo de texto.
|
|
91
|
+
* @type {'small' | 'medium' | 'large' | 'extra'}
|
|
92
|
+
* @default 'medium'
|
|
93
|
+
*/
|
|
76
94
|
this.size = 'medium';
|
|
95
|
+
/**
|
|
96
|
+
* Forma del radio del borde del campo.
|
|
97
|
+
* @type {'round' | 'square' | 'no-round'}
|
|
98
|
+
* @default 'no-round'
|
|
99
|
+
*/
|
|
77
100
|
this.shape = 'no-round';
|
|
101
|
+
/**
|
|
102
|
+
* El atributo `accept` para el input de archivo (ej. `image/*, .pdf`).
|
|
103
|
+
* @type {string}
|
|
104
|
+
*/
|
|
78
105
|
this.accept = '';
|
|
106
|
+
/**
|
|
107
|
+
* Permite seleccionar múltiples archivos si es true.
|
|
108
|
+
* @type {boolean}
|
|
109
|
+
*/
|
|
79
110
|
this.multiple = false;
|
|
111
|
+
/**
|
|
112
|
+
* Texto para el botón de selección de archivo.
|
|
113
|
+
* @type {string}
|
|
114
|
+
* @default 'Choose file'
|
|
115
|
+
*/
|
|
80
116
|
this.buttonLabel = 'Choose file';
|
|
117
|
+
/**
|
|
118
|
+
* Deshabilita el campo de archivo.
|
|
119
|
+
* @type {boolean}
|
|
120
|
+
*/
|
|
81
121
|
this.disabled = false;
|
|
122
|
+
/**
|
|
123
|
+
* Texto de ayuda mostrado debajo del campo.
|
|
124
|
+
* @type {string}
|
|
125
|
+
*/
|
|
82
126
|
this.helper = '';
|
|
127
|
+
/**
|
|
128
|
+
* Texto de error mostrado debajo del campo cuando `error` es true.
|
|
129
|
+
* Sobrescribe el texto de ayuda.
|
|
130
|
+
* @type {string}
|
|
131
|
+
*/
|
|
83
132
|
this.errorText = '';
|
|
133
|
+
/**
|
|
134
|
+
* Si es true, establece el campo en un estado de error.
|
|
135
|
+
* @type {boolean}
|
|
136
|
+
*/
|
|
84
137
|
this.error = false;
|
|
138
|
+
/**
|
|
139
|
+
* La representación en cadena de los archivos seleccionados (solo lectura para el usuario).
|
|
140
|
+
* @type {string}
|
|
141
|
+
*/
|
|
85
142
|
this.value = '';
|
|
143
|
+
/**
|
|
144
|
+
* Nombre del icono inicial (Material Symbols).
|
|
145
|
+
* @type {string}
|
|
146
|
+
*/
|
|
86
147
|
this.icon = '';
|
|
148
|
+
/**
|
|
149
|
+
* Nombre del icono final (Material Symbols).
|
|
150
|
+
* @type {string}
|
|
151
|
+
* @default 'folder_open'
|
|
152
|
+
*/
|
|
87
153
|
this.trailingIcon = 'folder_open';
|
|
88
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Hook del ciclo de vida reactivo (Lit).
|
|
157
|
+
* Transfiere de manera imperativa el estado de discapacidad (disabled) de Lit
|
|
158
|
+
* hacia el nodo `<input type="file">` invisible en el Shadow DOM, asegurando
|
|
159
|
+
* que el componente nativo reaccione adecuadamente a nivel navegador.
|
|
160
|
+
*/
|
|
89
161
|
updated(changed) {
|
|
90
162
|
if (this._fileInput) {
|
|
91
163
|
if (changed.has('disabled'))
|
|
@@ -108,6 +180,22 @@ let MoniFileField = class MoniFileField extends MoniElement {
|
|
|
108
180
|
}
|
|
109
181
|
`
|
|
110
182
|
]; }
|
|
183
|
+
/**
|
|
184
|
+
* Renderiza el campo de archivo como un `<input type="file">` oculto + una zona de soltar visible.
|
|
185
|
+
*
|
|
186
|
+
* El `<input type="file">` está oculto (pero no con `display: none`) para
|
|
187
|
+
* aprovechar el selector de archivos nativo del navegador. Al hacer clic en la zona de soltar visible
|
|
188
|
+
* se invoca programáticamente `_input.click()` para abrir el diálogo de archivo.
|
|
189
|
+
*
|
|
190
|
+
* **Arrastrar y soltar (Drag-and-drop):**
|
|
191
|
+
* `@dragover` / `@dragleave` / `@drop` en el contenedor de la zona de soltar gestionan
|
|
192
|
+
* el estado `dragging` que aplica una clase de resaltado CSS.
|
|
193
|
+
*
|
|
194
|
+
* **Visualización del nombre del archivo:**
|
|
195
|
+
* `_fileName` (derivado del `.name` del último archivo seleccionado) se muestra
|
|
196
|
+
* como una cadena de una sola línea truncada. Cuando no hay ningún archivo seleccionado,
|
|
197
|
+
* se muestra en su lugar el atributo `label` o un marcador de posición genérico.
|
|
198
|
+
*/
|
|
111
199
|
render() {
|
|
112
200
|
const isActive = Boolean(this.value);
|
|
113
201
|
const hasLeading = Boolean(this.icon);
|