@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
|
@@ -8,87 +8,88 @@
|
|
|
8
8
|
import { html, css } from 'lit';
|
|
9
9
|
import { customElement, property, query } from 'lit/decorators.js';
|
|
10
10
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
11
|
+
import { emitMoniEvent } from '../utils/event-emitter.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
* Material Design 3 Dialog
|
|
14
|
+
* Componente Material Design 3 Dialog (Diálogo).
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Los diálogos informan a los usuarios sobre una tarea y pueden contener información crítica,
|
|
17
|
+
* requerir decisiones o implicar múltiples tareas. Interrumpen el flujo de trabajo del
|
|
18
|
+
* usuario y deben usarse con moderación.
|
|
18
19
|
*
|
|
19
|
-
* **
|
|
20
|
+
* **Referencia de la especificación M3:** `m3-docs/components/dialogs/specs.md`
|
|
20
21
|
*
|
|
21
|
-
* **
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* - `modal=true` →
|
|
26
|
-
* - `modal=false` →
|
|
27
|
-
* - `open=false` →
|
|
22
|
+
* **Nota de implementación — elemento nativo `<dialog>`:**
|
|
23
|
+
* Este componente envuelve el elemento HTML nativo `<dialog>`. La apertura y cierre
|
|
24
|
+
* se controlan mediante el atributo `open` (y su propiedad JS). El componente
|
|
25
|
+
* sincroniza los cambios de `open` al `<dialog>` nativo en `updated()`:
|
|
26
|
+
* - `modal=true` → llama a `dialog.showModal()` (bloquea el foco, añade fondo oscuro).
|
|
27
|
+
* - `modal=false` → llama a `dialog.show()` (no bloquea, sin fondo oscuro).
|
|
28
|
+
* - `open=false` → llama a `dialog.close()`.
|
|
28
29
|
*
|
|
29
|
-
* **
|
|
30
|
-
* - `center` (
|
|
31
|
-
* - `top`, `right`, `bottom`, `left` —
|
|
32
|
-
* - `max` —
|
|
30
|
+
* **Colocación (atributo `side`):**
|
|
31
|
+
* - `center` (por defecto) — Centrado en la ventana gráfica. Diálogo M3 estándar.
|
|
32
|
+
* - `top`, `right`, `bottom`, `left` — Paneles anclados a los bordes (patrón side sheet).
|
|
33
|
+
* - `max` — Diálogo a pantalla completa para flujos complejos.
|
|
33
34
|
*
|
|
34
35
|
* @example
|
|
35
36
|
* ```html
|
|
36
|
-
* <!--
|
|
37
|
-
* <moni-dialog open modal title="
|
|
38
|
-
* <p>
|
|
37
|
+
* <!-- Diálogo modal básico -->
|
|
38
|
+
* <moni-dialog open modal title="Eliminar elemento?" size="small">
|
|
39
|
+
* <p>Esta acción no se puede deshacer.</p>
|
|
39
40
|
* <div slot="footer">
|
|
40
|
-
* <moni-button variant="text">
|
|
41
|
-
* <moni-button>
|
|
41
|
+
* <moni-button variant="text">Cancelar</moni-button>
|
|
42
|
+
* <moni-button>Eliminar</moni-button>
|
|
42
43
|
* </div>
|
|
43
44
|
* </moni-dialog>
|
|
44
45
|
* ```
|
|
45
46
|
*
|
|
46
|
-
* @slot default -
|
|
47
|
-
* @slot header -
|
|
48
|
-
* @slot footer -
|
|
47
|
+
* @slot default - El contenido del cuerpo del diálogo.
|
|
48
|
+
* @slot header - Contenido personalizado del encabezado (sobrescribe el atributo `title`).
|
|
49
|
+
* @slot footer - Fila de botones de acción en la parte inferior del diálogo.
|
|
49
50
|
*
|
|
50
|
-
* @csspart dialog -
|
|
51
|
-
* @csspart header -
|
|
52
|
-
* @csspart body -
|
|
53
|
-
* @csspart footer -
|
|
51
|
+
* @csspart dialog - El elemento `<dialog>` nativo.
|
|
52
|
+
* @csspart header - El contenedor del encabezado.
|
|
53
|
+
* @csspart body - El envoltorio del contenido del cuerpo.
|
|
54
|
+
* @csspart footer - El envoltorio de acciones del pie de página.
|
|
54
55
|
*/
|
|
55
56
|
@customElement('moni-dialog')
|
|
56
57
|
export class MoniDialog extends MoniElement {
|
|
57
58
|
/**
|
|
58
|
-
*
|
|
59
|
+
* Controla el estado abierto/cerrado del diálogo.
|
|
59
60
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
61
|
+
* Cuando se establece en `true`, el componente llama a `dialog.showModal()` (si `modal`)
|
|
62
|
+
* o `dialog.show()`. Cuando se establece en `false`, llama a `dialog.close()`.
|
|
63
|
+
* Reflejado como un atributo HTML para CSS y lectores de estado externos.
|
|
63
64
|
*
|
|
64
65
|
* @default false
|
|
65
66
|
*/
|
|
66
67
|
@property({ type: Boolean, reflect: true }) open = false;
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
|
-
*
|
|
70
|
+
* Cuando es `true`, abre el diálogo como un modal usando `<dialog>.showModal()`.
|
|
70
71
|
*
|
|
71
|
-
*
|
|
72
|
-
* -
|
|
73
|
-
* -
|
|
74
|
-
* -
|
|
72
|
+
* Diálogos modales:
|
|
73
|
+
* - Bloquean que el foco del teclado salga del diálogo.
|
|
74
|
+
* - Renderizan una capa `::backdrop` sobre el resto de la página.
|
|
75
|
+
* - Se pueden cerrar presionando `Escape` (comportamiento nativo del navegador).
|
|
75
76
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
77
|
+
* Cuando es `false`, usa `<dialog>.show()` que no es bloqueante (sin trampa de foco
|
|
78
|
+
* y sin capa de fondo).
|
|
78
79
|
*
|
|
79
80
|
* @default false
|
|
80
81
|
*/
|
|
81
82
|
@property({ type: Boolean, reflect: true }) modal = false;
|
|
82
83
|
|
|
83
84
|
/**
|
|
84
|
-
*
|
|
85
|
+
* Colocación del diálogo dentro de la ventana gráfica.
|
|
85
86
|
*
|
|
86
|
-
* - `'center'` (
|
|
87
|
-
* - `'top'` —
|
|
88
|
-
* - `'right'` —
|
|
89
|
-
* - `'bottom'` —
|
|
90
|
-
* - `'left'` —
|
|
91
|
-
* - `'max'` —
|
|
87
|
+
* - `'center'` (por defecto) — Centrado. Colocación de diálogo M3 estándar.
|
|
88
|
+
* - `'top'` — Anclado al borde superior (cajón desde arriba).
|
|
89
|
+
* - `'right'` — Anclado al borde derecho (patrón de hoja lateral).
|
|
90
|
+
* - `'bottom'` — Anclado al borde inferior (alternativa de hoja inferior).
|
|
91
|
+
* - `'left'` — Anclado al borde izquierdo (patrón de cajón de navegación).
|
|
92
|
+
* - `'max'` — Pantalla completa (cubre toda la ventana gráfica).
|
|
92
93
|
*
|
|
93
94
|
* @default 'center'
|
|
94
95
|
*/
|
|
@@ -96,11 +97,11 @@ export class MoniDialog extends MoniElement {
|
|
|
96
97
|
side: 'center' | 'top' | 'right' | 'bottom' | 'left' | 'max' = 'center';
|
|
97
98
|
|
|
98
99
|
/**
|
|
99
|
-
*
|
|
100
|
+
* Tamaño del contenedor del diálogo.
|
|
100
101
|
*
|
|
101
|
-
* - `'small'` —
|
|
102
|
-
* - `'medium'` —
|
|
103
|
-
* - `'large'` —
|
|
102
|
+
* - `'small'` — Diálogo estrecho; ideal para confirmaciones simples.
|
|
103
|
+
* - `'medium'` — Ancho de diálogo estándar (por defecto).
|
|
104
|
+
* - `'large'` — Diálogo ancho; para formularios o contenido complejo.
|
|
104
105
|
*
|
|
105
106
|
* @default 'medium'
|
|
106
107
|
*/
|
|
@@ -108,30 +109,47 @@ export class MoniDialog extends MoniElement {
|
|
|
108
109
|
size: 'small' | 'medium' | 'large' = 'medium';
|
|
109
110
|
|
|
110
111
|
/**
|
|
111
|
-
*
|
|
112
|
+
* Texto mostrado en el área del encabezado del diálogo.
|
|
112
113
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
114
|
+
* Cuando no está vacío, se renderiza como un encabezado estilizado dentro del contenedor del encabezado.
|
|
115
|
+
* El slot `header` tiene prioridad sobre este atributo cuando ambos están presentes.
|
|
115
116
|
*
|
|
116
117
|
* @default ''
|
|
117
118
|
*/
|
|
118
119
|
@property({ reflect: true }) title = '';
|
|
119
120
|
|
|
120
|
-
/**
|
|
121
|
+
/** Referencia directa al elemento `<dialog>` nativo para acceso programático. */
|
|
121
122
|
@query('dialog') private _dialog!: HTMLDialogElement;
|
|
122
123
|
|
|
124
|
+
override willUpdate(changed: Map<string, unknown>) {
|
|
125
|
+
if (changed.has('open') && this.open !== changed.get('open')) {
|
|
126
|
+
const isOpening = this.open;
|
|
127
|
+
const eventName = isOpening ? 'moni-request-open' : 'moni-request-close';
|
|
128
|
+
const allowed = emitMoniEvent(this, eventName, { cancelable: true });
|
|
129
|
+
|
|
130
|
+
if (!allowed) {
|
|
131
|
+
this.open = !isOpening;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
123
136
|
/**
|
|
124
|
-
*
|
|
137
|
+
* Hook de ciclo de vida de Lit. Sincroniza el estado declarativo (`open`, `modal`)
|
|
138
|
+
* con la API imperativa del elemento `<dialog>` nativo de HTML5.
|
|
125
139
|
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* (
|
|
140
|
+
* - `showModal()`: Bloquea el resto del DOM (Inert), atrapa el foco del teclado (Focus Trap)
|
|
141
|
+
* y renderiza el seudoelemento `::backdrop`.
|
|
142
|
+
* - `show()`: Permite interacción con el fondo (Non-modal).
|
|
129
143
|
*
|
|
130
|
-
*
|
|
144
|
+
* IMPORTANTE: Previene la excepción `InvalidStateError` validando si el
|
|
145
|
+
* diálogo ya está abierto antes de llamar a `show()` o `showModal()`.
|
|
146
|
+
*
|
|
147
|
+
* @param changed - Mapa de propiedades reactivas modificadas.
|
|
131
148
|
*/
|
|
132
149
|
override updated(changed: Map<string, unknown>) {
|
|
133
150
|
if (changed.has('open') && this._dialog) {
|
|
134
151
|
if (this.open) {
|
|
152
|
+
emitMoniEvent(this, 'moni-open');
|
|
135
153
|
if (this.modal) {
|
|
136
154
|
if (!this._dialog.open) {
|
|
137
155
|
this._dialog.showModal();
|
|
@@ -142,6 +160,7 @@ export class MoniDialog extends MoniElement {
|
|
|
142
160
|
}
|
|
143
161
|
}
|
|
144
162
|
} else {
|
|
163
|
+
emitMoniEvent(this, 'moni-close');
|
|
145
164
|
if (this._dialog.open) {
|
|
146
165
|
this._dialog.close();
|
|
147
166
|
}
|
|
@@ -149,6 +168,16 @@ export class MoniDialog extends MoniElement {
|
|
|
149
168
|
}
|
|
150
169
|
}
|
|
151
170
|
|
|
171
|
+
private _onTransitionEnd(e: TransitionEvent) {
|
|
172
|
+
if (e.target === this._dialog && e.propertyName === 'transform') {
|
|
173
|
+
if (this.open) {
|
|
174
|
+
emitMoniEvent(this, 'moni-opened');
|
|
175
|
+
} else {
|
|
176
|
+
emitMoniEvent(this, 'moni-closed');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
152
181
|
static override styles = [
|
|
153
182
|
sharedStyles,
|
|
154
183
|
css`
|
|
@@ -311,6 +340,25 @@ export class MoniDialog extends MoniElement {
|
|
|
311
340
|
`
|
|
312
341
|
];
|
|
313
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Renderiza el elemento `<dialog>` nativo con la estructura semántica de slots del diálogo.
|
|
345
|
+
*
|
|
346
|
+
* **¿Por qué `<dialog>`?**
|
|
347
|
+
* El elemento nativo `<dialog>` proporciona captura de foco, renderizado de fondo (backdrop)
|
|
348
|
+
* y semántica modal accesible sin JavaScript. El enlace `?open` de Lit
|
|
349
|
+
* alterna el atributo de forma imperativa, mientras que `updated()` llama a `.show()` /
|
|
350
|
+
* `.showModal()` / `.close()` para conducir la pila de abrir/cerrar nativa del navegador.
|
|
351
|
+
*
|
|
352
|
+
* **Estructura de slots:**
|
|
353
|
+
* - `[slot="header"]` — se repliega al valor del atributo `title`.
|
|
354
|
+
* - Slot por defecto — la región de contenido principal del diálogo.
|
|
355
|
+
* - `[slot="footer"]` — botones de acción (típicamente elementos `<moni-button>`).
|
|
356
|
+
*
|
|
357
|
+
* **Composición de `classes`:**
|
|
358
|
+
* `side`, `size`, y `modal` (si `modal=true`) se unen como clases CSS.
|
|
359
|
+
* `side` posiciona el diálogo en `start`, `end`, `top`, o `bottom`; usado
|
|
360
|
+
* para diálogos de panel lateral. `size` controla max-width/height.
|
|
361
|
+
*/
|
|
314
362
|
override render() {
|
|
315
363
|
const classes = [this.side, this.size, this.modal ? 'modal' : '']
|
|
316
364
|
.filter(Boolean)
|
|
@@ -318,6 +366,7 @@ export class MoniDialog extends MoniElement {
|
|
|
318
366
|
return html`<dialog
|
|
319
367
|
part="dialog"
|
|
320
368
|
class=${classes}
|
|
369
|
+
@transitionend=${this._onTransitionEnd}
|
|
321
370
|
>
|
|
322
371
|
<header part="header">
|
|
323
372
|
<slot name="header">${this.title}</slot>
|
|
@@ -14,13 +14,13 @@ describe('moni-divider (P5.1 — recreated)', () => {
|
|
|
14
14
|
el.remove();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it('
|
|
17
|
+
it('por defecto es inset=leading', async () => {
|
|
18
18
|
await el.updateComplete;
|
|
19
19
|
expect(el.inset).toBe('leading');
|
|
20
20
|
expect(el.getAttribute('inset')).toBe('leading');
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
it('
|
|
23
|
+
it('refleja las tres inserciones M3: leading / middle / none', async () => {
|
|
24
24
|
for (const inset of ['leading', 'middle', 'none'] as const) {
|
|
25
25
|
el.inset = inset;
|
|
26
26
|
await el.updateComplete;
|
|
@@ -28,13 +28,13 @@ describe('moni-divider (P5.1 — recreated)', () => {
|
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
it('
|
|
31
|
+
it('renderiza un slot por defecto vacío para contenido en línea', async () => {
|
|
32
32
|
await el.updateComplete;
|
|
33
33
|
const slot = el.shadowRoot?.querySelector('slot');
|
|
34
34
|
expect(slot).toBeTruthy();
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
it('
|
|
37
|
+
it('refleja el atributo vertical', async () => {
|
|
38
38
|
el.setAttribute('vertical', '');
|
|
39
39
|
await el.updateComplete;
|
|
40
40
|
expect(el.hasAttribute('vertical')).toBe(true);
|
|
@@ -10,53 +10,53 @@ import { customElement, property } from 'lit/decorators.js';
|
|
|
10
10
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Material Design 3 Divider
|
|
13
|
+
* Componente Material Design 3 Divider (Separador).
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Una regla delgada horizontal (o vertical) utilizada para separar visualmente secciones
|
|
16
|
+
* de contenido dentro de listas, diseños y tarjetas.
|
|
17
17
|
*
|
|
18
|
-
* **
|
|
18
|
+
* **Referencia de la especificación M3:** `m3-docs/components/divider/specs.md`
|
|
19
19
|
*
|
|
20
|
-
* **M3
|
|
21
|
-
* -
|
|
22
|
-
* - Color: `outline-variant` —
|
|
23
|
-
* -
|
|
24
|
-
* - `leading` — 16dp
|
|
25
|
-
* - `middle` — 16dp
|
|
26
|
-
* - `none` —
|
|
20
|
+
* **Medidas M3:**
|
|
21
|
+
* - Grosor: 1dp (`0.0625rem`).
|
|
22
|
+
* - Color: `outline-variant` — sutil en todos los fondos de superficie.
|
|
23
|
+
* - Las variantes insertadas (inset) alinean la línea con el contenido de la lista:
|
|
24
|
+
* - `leading` — margen de 16dp desde el borde inicial (se alinea con el texto del icono).
|
|
25
|
+
* - `middle` — margen de 16dp en ambos bordes.
|
|
26
|
+
* - `none` — sangría completa (sin margen).
|
|
27
27
|
*
|
|
28
|
-
* **
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* vertical
|
|
28
|
+
* **Uso vertical:**
|
|
29
|
+
* Aunque todavía no se expone como un atributo, el selector de atributos CSS `[vertical]`
|
|
30
|
+
* está soportado. Establezca `vertical` como un atributo HTML para renderizar un separador
|
|
31
|
+
* vertical de 1dp de ancho que se estira para coincidir con el eje transversal de su contenedor flex.
|
|
32
32
|
*
|
|
33
33
|
* @example
|
|
34
34
|
* ```html
|
|
35
|
-
* <!--
|
|
35
|
+
* <!-- Separador de sangría completa entre secciones -->
|
|
36
36
|
* <moni-divider inset="none"></moni-divider>
|
|
37
37
|
*
|
|
38
|
-
* <!--
|
|
38
|
+
* <!-- Separador de inserción inicial en una lista (se alinea con el texto del elemento de lista) -->
|
|
39
39
|
* <moni-divider></moni-divider>
|
|
40
40
|
*
|
|
41
|
-
* <!--
|
|
41
|
+
* <!-- Separador vertical dentro de un contenedor flex -->
|
|
42
42
|
* <div style="display:flex; height: 3rem; align-items:center; gap: 1rem;">
|
|
43
|
-
* <span>
|
|
43
|
+
* <span>Sección A</span>
|
|
44
44
|
* <moni-divider vertical></moni-divider>
|
|
45
|
-
* <span>
|
|
45
|
+
* <span>Sección B</span>
|
|
46
46
|
* </div>
|
|
47
47
|
* ```
|
|
48
48
|
*/
|
|
49
49
|
@customElement('moni-divider')
|
|
50
50
|
export class MoniDivider extends MoniElement {
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* Controla el margen horizontal en la línea del separador.
|
|
53
53
|
*
|
|
54
|
-
* - `'leading'` (
|
|
55
|
-
*
|
|
56
|
-
* - `'middle'` — 16dp
|
|
57
|
-
*
|
|
58
|
-
* - `'none'` —
|
|
59
|
-
*
|
|
54
|
+
* - `'leading'` (por defecto) — Margen de 16dp solo desde el borde inicial (inicio).
|
|
55
|
+
* Usar en listas para alinear el separador con el texto principal de los elementos de la lista.
|
|
56
|
+
* - `'middle'` — Margen de 16dp tanto en el borde inicial como en el final.
|
|
57
|
+
* Usar para separar secciones donde una sangría completa sería visualmente demasiado pesada.
|
|
58
|
+
* - `'none'` — Sin margen; la línea abarca todo el ancho del padre.
|
|
59
|
+
* Usar como separador de secciones o entre tarjetas.
|
|
60
60
|
*
|
|
61
61
|
* @default 'leading'
|
|
62
62
|
*/
|
|
@@ -69,7 +69,7 @@ export class MoniDivider extends MoniElement {
|
|
|
69
69
|
:host {
|
|
70
70
|
display: block;
|
|
71
71
|
font-family: var(--font);
|
|
72
|
-
/* M3
|
|
72
|
+
/* Especificación M3: grosor de 1dp, on-surface-variant para una separación sutil. */
|
|
73
73
|
block-size: 0.0625rem;
|
|
74
74
|
min-inline-size: 0;
|
|
75
75
|
background-color: var(--outline-variant);
|
|
@@ -77,7 +77,7 @@ export class MoniDivider extends MoniElement {
|
|
|
77
77
|
margin: 0;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
/*
|
|
80
|
+
/* Variantes de inserción. Especificación M3: 16dp desde el borde inicial. */
|
|
81
81
|
:host([inset='leading']) {
|
|
82
82
|
margin-inline-start: 1rem;
|
|
83
83
|
margin-inline-end: 0;
|
|
@@ -89,7 +89,7 @@ export class MoniDivider extends MoniElement {
|
|
|
89
89
|
margin-inline: 0;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
/*
|
|
92
|
+
/* Separador vertical (la especificación M3 también define el uso vertical). */
|
|
93
93
|
:host([vertical]) {
|
|
94
94
|
inline-size: 0.0625rem;
|
|
95
95
|
block-size: auto;
|
|
@@ -99,6 +99,18 @@ export class MoniDivider extends MoniElement {
|
|
|
99
99
|
`
|
|
100
100
|
];
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Renderiza un paso a través de slot transparente.
|
|
104
|
+
*
|
|
105
|
+
* `moni-divider` es un componente impulsado puramente por CSS — la línea visual es
|
|
106
|
+
* renderizada por el elemento `:host` en sí (a través de `background-color` y
|
|
107
|
+
* `block-size: 0.0625rem`). No se necesitan elementos internos.
|
|
108
|
+
*
|
|
109
|
+
* El `<slot>` vacío se incluye para que los consumidores puedan insertar etiquetas de texto
|
|
110
|
+
* o iconos entre secciones (ej. `<moni-divider>O</moni-divider>`).
|
|
111
|
+
* El contenido renderizado en el slot no tiene estilo visual de este componente; el consumidor
|
|
112
|
+
* debe aplicar estilo a los elementos del slot directamente.
|
|
113
|
+
*/
|
|
102
114
|
override render() {
|
|
103
115
|
return html`<slot></slot>`;
|
|
104
116
|
}
|
|
@@ -10,45 +10,45 @@ import { customElement, property } from 'lit/decorators.js';
|
|
|
10
10
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Material Design 3 Expansion panel
|
|
13
|
+
* Componente Material Design 3 Expansion panel (Panel de expansión).
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Un envoltorio ligero alrededor de los elementos HTML nativos `<details>` y `<summary>`,
|
|
16
|
+
* estilizado de acuerdo con las pautas de superficie y elevación de M3.
|
|
17
|
+
* Los paneles de expansión contienen flujos de creación y permiten la edición ligera de un elemento.
|
|
18
18
|
*
|
|
19
|
-
* **
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* `<details>`
|
|
23
|
-
*
|
|
24
|
-
* `::after`
|
|
19
|
+
* **Arquitectura visual:**
|
|
20
|
+
* El componente renderiza un elemento `<details>` con un `<summary>` que actúa
|
|
21
|
+
* como el encabezado expandible. El contenido del slot por defecto se coloca dentro de la
|
|
22
|
+
* etiqueta `<details>` (pero fuera del `<summary>`), ocultándose y mostrándose naturalmente
|
|
23
|
+
* según el comportamiento nativo. Se añade un icono `expand_more` de M3 mediante un
|
|
24
|
+
* pseudo-elemento CSS `::after` que rota cuando el panel está abierto.
|
|
25
25
|
*
|
|
26
|
-
* **
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* **Uso:**
|
|
27
|
+
* Establezca el atributo `title` para un encabezado de texto simple, o use el slot `summary`
|
|
28
|
+
* para proyectar contenido enriquecido personalizado (como iconos o texto secundario) en el
|
|
29
|
+
* área del encabezado.
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
32
32
|
* ```html
|
|
33
|
-
* <!--
|
|
34
|
-
* <moni-expansion title="
|
|
35
|
-
* <p>
|
|
33
|
+
* <!-- Título de texto simple -->
|
|
34
|
+
* <moni-expansion title="Configuración Avanzada">
|
|
35
|
+
* <p>Habilite las características del modo de desarrollador aquí.</p>
|
|
36
36
|
* </moni-expansion>
|
|
37
37
|
*
|
|
38
|
-
* <!--
|
|
38
|
+
* <!-- Contenido de resumen enriquecido a través de slot -->
|
|
39
39
|
* <moni-expansion open>
|
|
40
40
|
* <div slot="summary" style="display: flex; gap: 8px;">
|
|
41
41
|
* <moni-icon>person</moni-icon>
|
|
42
|
-
* <span>Personal
|
|
42
|
+
* <span>Información Personal</span>
|
|
43
43
|
* </div>
|
|
44
44
|
* <form>
|
|
45
|
-
* <moni-text-field label="
|
|
45
|
+
* <moni-text-field label="Nombre"></moni-text-field>
|
|
46
46
|
* </form>
|
|
47
47
|
* </moni-expansion>
|
|
48
48
|
* ```
|
|
49
49
|
*
|
|
50
|
-
* @slot default -
|
|
51
|
-
* @slot summary -
|
|
50
|
+
* @slot default - El contenido del cuerpo del panel de expansión.
|
|
51
|
+
* @slot summary - Contenido personalizado del encabezado (sobrescribe el atributo `title`).
|
|
52
52
|
*/
|
|
53
53
|
@customElement('moni-expansion')
|
|
54
54
|
export class MoniExpansion extends MoniElement {
|
|
@@ -102,6 +102,16 @@ export class MoniExpansion extends MoniElement {
|
|
|
102
102
|
`
|
|
103
103
|
];
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Renderiza el panel de expansión utilizando el elemento nativo `<details>`.
|
|
107
|
+
*
|
|
108
|
+
* El atributo `open` en
|
|
109
|
+
* `:host` impulsa la rotación de la flecha indicadora CSS (`::after` en `summary`).
|
|
110
|
+
*
|
|
111
|
+
* **Estructura de slots:**
|
|
112
|
+
* - `[slot="summary"]` — la fila de encabezado siempre visible (título, iconos).
|
|
113
|
+
* - Slot por defecto — la región de contenido colapsable.
|
|
114
|
+
*/
|
|
105
115
|
override render() {
|
|
106
116
|
return html`<details ?open=${this.open} part="expansion">
|
|
107
117
|
<summary part="summary">
|
|
@@ -15,7 +15,7 @@ describe('moni-fab-menu', () => {
|
|
|
15
15
|
el.remove();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
it('
|
|
18
|
+
it('renderiza un .fab-menu y un <moni-fab> como activador', async () => {
|
|
19
19
|
await el.updateComplete;
|
|
20
20
|
const menu = el.shadowRoot?.querySelector('.fab-menu');
|
|
21
21
|
const trigger = el.shadowRoot?.querySelector('moni-fab');
|
|
@@ -23,7 +23,7 @@ describe('moni-fab-menu', () => {
|
|
|
23
23
|
expect(trigger).toBeTruthy();
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
it('
|
|
26
|
+
it('pasa icon, size, color, shape, position al activador', async () => {
|
|
27
27
|
el.icon = 'menu';
|
|
28
28
|
el.size = 'large';
|
|
29
29
|
el.color = 'secondary';
|
|
@@ -36,7 +36,7 @@ describe('moni-fab-menu', () => {
|
|
|
36
36
|
expect(trigger?.getAttribute('shape')).toBe('circle');
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
it('
|
|
39
|
+
it('refleja el atributo open', async () => {
|
|
40
40
|
el.open = true;
|
|
41
41
|
await el.updateComplete;
|
|
42
42
|
expect(el.hasAttribute('open')).toBe(true);
|
|
@@ -46,13 +46,13 @@ describe('moni-fab-menu', () => {
|
|
|
46
46
|
expect(el.hasAttribute('open')).toBe(false);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
it('
|
|
49
|
+
it('refleja el atributo direction', async () => {
|
|
50
50
|
el.direction = 'down';
|
|
51
51
|
await el.updateComplete;
|
|
52
52
|
expect(el.getAttribute('direction')).toBe('down');
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
it('
|
|
55
|
+
it('cambia el estado open cuando se hace clic en el activador', async () => {
|
|
56
56
|
await el.updateComplete;
|
|
57
57
|
expect(el.open).toBe(false);
|
|
58
58
|
|
|
@@ -73,13 +73,13 @@ describe('moni-fab-menu', () => {
|
|
|
73
73
|
expect(el.open).toBe(false);
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
it('
|
|
76
|
+
it('el menú tiene role="menu" para la semántica del lector de pantalla', async () => {
|
|
77
77
|
await el.updateComplete;
|
|
78
78
|
const menu = el.shadowRoot?.querySelector('.fab-menu');
|
|
79
79
|
expect(menu?.getAttribute('role')).toBe('menu');
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
it('Escape
|
|
82
|
+
it('la tecla Escape cierra un menú abierto', async () => {
|
|
83
83
|
el.open = true;
|
|
84
84
|
await el.updateComplete;
|
|
85
85
|
expect(el.open).toBe(true);
|
|
@@ -89,7 +89,7 @@ describe('moni-fab-menu', () => {
|
|
|
89
89
|
expect(el.open).toBe(false);
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
it('Escape
|
|
92
|
+
it('presionar Escape en un menú cerrado no hace nada', async () => {
|
|
93
93
|
await el.updateComplete;
|
|
94
94
|
expect(el.open).toBe(false);
|
|
95
95
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));
|
|
@@ -97,17 +97,17 @@ describe('moni-fab-menu', () => {
|
|
|
97
97
|
expect(el.open).toBe(false);
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
it('
|
|
100
|
+
it('hacer clic fuera del menú lo cierra', async () => {
|
|
101
101
|
el.open = true;
|
|
102
102
|
await el.updateComplete;
|
|
103
103
|
|
|
104
|
-
//
|
|
104
|
+
// Despachar un clic en el body del documento (fuera del menú).
|
|
105
105
|
document.body.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
106
106
|
await el.updateComplete;
|
|
107
107
|
expect(el.open).toBe(false);
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
-
it('
|
|
110
|
+
it('hacer clic dentro del menú no lo cierra', async () => {
|
|
111
111
|
el.open = true;
|
|
112
112
|
await el.updateComplete;
|
|
113
113
|
const menu = el.shadowRoot?.querySelector('.fab-menu') as HTMLElement;
|