@moni-labs/moni-ui 0.3.0 → 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 +5230 -1007
- 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 +484 -53
- package/dist/components/moni-carousel.d.ts.map +1 -1
- package/dist/components/moni-carousel.js +1024 -245
- 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 +1129 -269
- 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
|
@@ -13,38 +13,39 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
13
13
|
import { html, css } from 'lit';
|
|
14
14
|
import { customElement, property, query } from 'lit/decorators.js';
|
|
15
15
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
16
|
+
import { emitMoniEvent } from '../utils/event-emitter.js';
|
|
16
17
|
/**
|
|
17
|
-
* Material Design 3 Bottom Sheet
|
|
18
|
+
* Componente Material Design 3 Bottom Sheet.
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* Los bottom sheets son superficies ancladas a la parte inferior de la pantalla que
|
|
21
|
+
* complementan la vista principal. Muestran contenido complementario, acciones
|
|
22
|
+
* contextuales, o flujos de tareas sin ocultar por completo el contenido principal.
|
|
22
23
|
*
|
|
23
|
-
* **
|
|
24
|
+
* **Referencia de la especificación M3:** `m3-docs/components/sheets-bottom/specs.md`
|
|
24
25
|
*
|
|
25
|
-
* **
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* `modal=true` (
|
|
26
|
+
* **Nota de implementación — elemento nativo `<dialog>`:**
|
|
27
|
+
* Al igual que `<moni-dialog>`, este componente envuelve el elemento nativo `<dialog>`.
|
|
28
|
+
* La propiedad `open` controla `dialog.showModal()` / `dialog.close()`. Cuando
|
|
29
|
+
* `modal=true` (por defecto), se renderiza automáticamente un fondo `::backdrop`.
|
|
29
30
|
*
|
|
30
|
-
* **
|
|
31
|
-
*
|
|
32
|
-
* `document.body`
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
31
|
+
* **Teletransportación (montaje a nivel del body):**
|
|
32
|
+
* Cuando `positioning="body"` (por defecto), el componente se mueve a
|
|
33
|
+
* `document.body` en `connectedCallback` para que el diálogo inferior fijo se renderice
|
|
34
|
+
* por encima de todos los contextos de apilamiento. En `disconnectedCallback`, se mueve de nuevo
|
|
35
|
+
* a su posición original en el DOM. Esto evita el recorte por un ancestro con `overflow: hidden`
|
|
36
|
+
* o `transform`.
|
|
36
37
|
*
|
|
37
|
-
* **
|
|
38
|
-
* - `small` —
|
|
39
|
-
* - `medium` —
|
|
40
|
-
* - `large` —
|
|
41
|
-
* - `auto` —
|
|
38
|
+
* **Tamaños:**
|
|
39
|
+
* - `small` — Hoja compacta; adecuada para menús de acciones simples.
|
|
40
|
+
* - `medium` — Altura estándar (por defecto).
|
|
41
|
+
* - `large` — Altura expandida (`expandedHeight` controla el block-size máximo).
|
|
42
|
+
* - `auto` — Altura impulsada por el contenido.
|
|
42
43
|
*
|
|
43
44
|
* @example
|
|
44
45
|
* ```html
|
|
45
|
-
* <moni-bottom-sheet title="
|
|
46
|
-
* <moni-list-item icon="share">
|
|
47
|
-
* <moni-list-item icon="mail">
|
|
46
|
+
* <moni-bottom-sheet title="Compartir">
|
|
47
|
+
* <moni-list-item icon="share">Copiar enlace</moni-list-item>
|
|
48
|
+
* <moni-list-item icon="mail">Enviar por correo</moni-list-item>
|
|
48
49
|
* </moni-bottom-sheet>
|
|
49
50
|
*
|
|
50
51
|
* <script>
|
|
@@ -52,91 +53,91 @@ import { MoniElement, sharedStyles } from './_base/index.js';
|
|
|
52
53
|
* </script>
|
|
53
54
|
* ```
|
|
54
55
|
*
|
|
55
|
-
* @slot default -
|
|
56
|
-
* @slot handle -
|
|
57
|
-
* @slot footer -
|
|
56
|
+
* @slot default - El contenido principal del bottom sheet.
|
|
57
|
+
* @slot handle - El área del asa de arrastre en la parte superior.
|
|
58
|
+
* @slot footer - Botones de acción en la parte inferior de la hoja.
|
|
58
59
|
*
|
|
59
|
-
* @csspart dialog -
|
|
60
|
-
* @csspart header -
|
|
61
|
-
* @csspart body -
|
|
62
|
-
* @csspart footer -
|
|
60
|
+
* @csspart dialog - El elemento nativo `<dialog>`.
|
|
61
|
+
* @csspart header - El contenedor del encabezado con el título y el botón de cierre.
|
|
62
|
+
* @csspart body - El área de contenido principal desplazable (scrollable).
|
|
63
|
+
* @csspart footer - El área de los botones de acción en el pie.
|
|
63
64
|
*/
|
|
64
65
|
let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
65
66
|
constructor() {
|
|
66
67
|
super(...arguments);
|
|
67
68
|
/**
|
|
68
|
-
*
|
|
69
|
+
* Controla el estado abierto/cerrado del bottom sheet.
|
|
69
70
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
71
|
+
* Cuando se establece en `true`, llama a `dialog.showModal()` o `dialog.show()`
|
|
72
|
+
* dependiendo de la propiedad `modal`. Cuando se establece en `false`, llama a `dialog.close()`.
|
|
72
73
|
*
|
|
73
74
|
* @default false
|
|
74
75
|
*/
|
|
75
76
|
this.open = false;
|
|
76
77
|
/**
|
|
77
|
-
*
|
|
78
|
+
* Variante de altura del contenedor de la hoja.
|
|
78
79
|
*
|
|
79
|
-
* - `'small'` —
|
|
80
|
-
* - `'medium'` —
|
|
81
|
-
* - `'large'` —
|
|
82
|
-
* - `'auto'` —
|
|
80
|
+
* - `'small'` — Compacta; adecuada para confirmaciones rápidas.
|
|
81
|
+
* - `'medium'` — Altura estándar (por defecto).
|
|
82
|
+
* - `'large'` — Llena el `expandedHeight` de la ventana gráfica.
|
|
83
|
+
* - `'auto'` — Depende del contenido; la altura se adapta al contenido en el slot.
|
|
83
84
|
*
|
|
84
85
|
* @default 'medium'
|
|
85
86
|
*/
|
|
86
87
|
this.size = 'medium';
|
|
87
88
|
/**
|
|
88
|
-
*
|
|
89
|
-
* scrim.
|
|
89
|
+
* Cuando es `true` (por defecto), la hoja se abre como un diálogo modal con un
|
|
90
|
+
* fondo translúcido (scrim). Cuando es `false`, se abre como una superposición no modal sin scrim.
|
|
90
91
|
*
|
|
91
92
|
* @default true
|
|
92
93
|
*/
|
|
93
94
|
this.modal = true;
|
|
94
95
|
/**
|
|
95
|
-
*
|
|
96
|
+
* Texto de encabezado mostrado en el área del encabezado de la hoja.
|
|
96
97
|
*
|
|
97
98
|
* @default ''
|
|
98
99
|
*/
|
|
99
100
|
this.title = '';
|
|
100
101
|
/**
|
|
101
|
-
*
|
|
102
|
+
* Controla cómo se posiciona la hoja en el documento.
|
|
102
103
|
*
|
|
103
|
-
* - `'body'` (
|
|
104
|
-
*
|
|
105
|
-
* - `'fixed'` —
|
|
106
|
-
* - `'absolute'` —
|
|
107
|
-
* - `'static'` —
|
|
104
|
+
* - `'body'` (por defecto) — Teletransporta el elemento a `document.body` para que
|
|
105
|
+
* la superposición fija se renderice por encima de todos los contextos de apilamiento.
|
|
106
|
+
* - `'fixed'` — Posicionamiento fijo dentro de su subárbol DOM actual.
|
|
107
|
+
* - `'absolute'` — Absoluto dentro del ancestro posicionado más cercano.
|
|
108
|
+
* - `'static'` — Flujo estático (rara vez necesario; solo para pruebas).
|
|
108
109
|
*
|
|
109
110
|
* @default 'fixed'
|
|
110
111
|
*/
|
|
111
112
|
this.positioning = 'fixed';
|
|
112
113
|
/**
|
|
113
|
-
*
|
|
114
|
+
* Block-size (altura) máximo de la hoja cuando `size="large"`.
|
|
114
115
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
116
|
+
* Acepta cualquier valor válido de `max-block-size` en CSS (ej. `'85%'`, `'600px'`).
|
|
117
|
+
* Por defecto es `'85%'` que es el máximo recomendado por M3 para bottom sheets
|
|
118
|
+
* en pantallas compactas.
|
|
118
119
|
*
|
|
119
120
|
* @default '85%'
|
|
120
121
|
*/
|
|
121
122
|
this.expandedHeight = '85%';
|
|
122
123
|
/**
|
|
123
|
-
*
|
|
124
|
+
* Restricción opcional de inline-size (ancho) máximo para la hoja.
|
|
124
125
|
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* modal
|
|
126
|
+
* Cuando se establece (ej. `'640px'`), la hoja no excederá este ancho incluso en
|
|
127
|
+
* pantallas anchas. Útil para puntos de interrupción de tableta/escritorio donde se prefiere
|
|
128
|
+
* un modal centrado en lugar de una hoja de ancho completo.
|
|
128
129
|
*
|
|
129
|
-
* @default '' (
|
|
130
|
+
* @default '' (sin restricción)
|
|
130
131
|
*/
|
|
131
132
|
this.maxWidth = '';
|
|
132
133
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
134
|
+
* Nodo padre original antes de la teletransportación a `document.body`.
|
|
135
|
+
* Utilizado para restaurar la posición DOM del elemento en `disconnectedCallback`.
|
|
135
136
|
*/
|
|
136
137
|
this._originalParent = null;
|
|
137
138
|
/**
|
|
138
|
-
*
|
|
139
|
-
*
|
|
139
|
+
* Hermano siguiente original antes de la teletransportación a `document.body`.
|
|
140
|
+
* Utilizado junto con `_originalParent` para restaurar la posición exacta en el DOM.
|
|
140
141
|
*/
|
|
141
142
|
this._originalSibling = null;
|
|
142
143
|
this._isDragging = false;
|
|
@@ -145,7 +146,57 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
145
146
|
this._sheetHeight = 0;
|
|
146
147
|
this._defaultHeight = 0;
|
|
147
148
|
this._justDragged = false;
|
|
149
|
+
this._skipRequestClose = false;
|
|
148
150
|
}
|
|
151
|
+
willUpdate(changed) {
|
|
152
|
+
if (changed.has('open') && this.open !== changed.get('open')) {
|
|
153
|
+
const isOpening = this.open;
|
|
154
|
+
if (isOpening) {
|
|
155
|
+
const allowed = emitMoniEvent(this, 'moni-request-open', { cancelable: true });
|
|
156
|
+
if (!allowed) {
|
|
157
|
+
this.open = false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (!this._skipRequestClose) {
|
|
161
|
+
const allowed = emitMoniEvent(this, 'moni-request-close', { cancelable: true });
|
|
162
|
+
if (!allowed) {
|
|
163
|
+
this.open = true;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async _animateAndClose() {
|
|
169
|
+
this._skipRequestClose = true;
|
|
170
|
+
const allowed = emitMoniEvent(this, 'moni-request-close', { cancelable: true });
|
|
171
|
+
this._skipRequestClose = false;
|
|
172
|
+
if (!allowed)
|
|
173
|
+
return false;
|
|
174
|
+
this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));
|
|
175
|
+
emitMoniEvent(this, 'moni-close');
|
|
176
|
+
this._dialog.classList.remove('expanded');
|
|
177
|
+
this._dialog.style.transform = 'translateY(100%)';
|
|
178
|
+
this._dialog.style.height = '';
|
|
179
|
+
await new Promise(resolve => {
|
|
180
|
+
const onEnd = () => {
|
|
181
|
+
this._dialog.removeEventListener('transitionend', onEnd);
|
|
182
|
+
resolve(null);
|
|
183
|
+
};
|
|
184
|
+
this._dialog.addEventListener('transitionend', onEnd);
|
|
185
|
+
setTimeout(onEnd, 300);
|
|
186
|
+
});
|
|
187
|
+
this._dialog.style.transform = '';
|
|
188
|
+
this._skipRequestClose = true;
|
|
189
|
+
this.open = false;
|
|
190
|
+
this._skipRequestClose = false;
|
|
191
|
+
emitMoniEvent(this, 'moni-closed');
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Calcula la altura máxima permitida en píxeles basándose en la propiedad `expandedHeight`.
|
|
196
|
+
* Útil para la lógica de arrastre donde necesitamos valores numéricos absolutos (px) en
|
|
197
|
+
* lugar de porcentajes o unidades de viewport, asegurando que el bottom-sheet no exceda
|
|
198
|
+
* el tamaño permitido en pantalla.
|
|
199
|
+
*/
|
|
149
200
|
_getMaxHeightPx() {
|
|
150
201
|
const val = this.expandedHeight || '85%';
|
|
151
202
|
if (val.endsWith('%')) {
|
|
@@ -159,64 +210,84 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
159
210
|
}
|
|
160
211
|
return window.innerHeight * 0.85;
|
|
161
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Inicia el proceso de arrastre (drag) cuando el usuario presiona sobre el `handle` o el `header`.
|
|
215
|
+
* Captura el puntero para asegurar que los eventos de movimiento se sigan recibiendo incluso si
|
|
216
|
+
* el cursor se sale de los límites físicos del elemento.
|
|
217
|
+
*/
|
|
162
218
|
_onPointerDown(e) {
|
|
163
219
|
const target = e.target;
|
|
220
|
+
// Solo iniciamos el arrastre si el click provino del asa superior (handle) o del encabezado.
|
|
164
221
|
if (!target.closest('.handle') && !target.closest('header'))
|
|
165
222
|
return;
|
|
166
223
|
this._isDragging = true;
|
|
167
|
-
this._startY = e.clientY;
|
|
168
|
-
this._sheetHeight = this._dialog.getBoundingClientRect().height;
|
|
224
|
+
this._startY = e.clientY; // Almacenamos la coordenada inicial Y para calcular el delta luego
|
|
225
|
+
this._sheetHeight = this._dialog.getBoundingClientRect().height; // Capturamos la altura actual
|
|
169
226
|
this._currentTranslationY = 0;
|
|
170
227
|
const isExpanded = this._dialog.classList.contains('expanded');
|
|
228
|
+
// Si no estaba expandido previamente, guardamos su altura por defecto para usarla como punto de retorno.
|
|
171
229
|
if (!isExpanded) {
|
|
172
230
|
this._defaultHeight = this._sheetHeight;
|
|
173
231
|
}
|
|
232
|
+
// setPointerCapture enruta todos los eventos subsecuentes a este target
|
|
174
233
|
target.setPointerCapture(e.pointerId);
|
|
175
|
-
this._dialog.classList.add('dragging');
|
|
234
|
+
this._dialog.classList.add('dragging'); // Desactiva las transiciones CSS para un seguimiento suave 1:1
|
|
176
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Maneja el movimiento del puntero mientras se arrastra el componente.
|
|
238
|
+
* Interpola la altura o la transformación Y dependiendo de si se está expandiendo o colapsando,
|
|
239
|
+
* y de su estado actual (expandido o normal).
|
|
240
|
+
*/
|
|
177
241
|
_onPointerMove(e) {
|
|
178
242
|
if (!this._isDragging)
|
|
179
243
|
return;
|
|
244
|
+
// Diferencia en píxeles desde donde se inició el click
|
|
180
245
|
const deltaY = e.clientY - this._startY;
|
|
181
246
|
const isExpanded = this._dialog.classList.contains('expanded');
|
|
182
247
|
const maxHeight = this._getMaxHeightPx();
|
|
183
248
|
if (isExpanded) {
|
|
184
249
|
if (deltaY > 0) {
|
|
185
|
-
//
|
|
250
|
+
// Arrastrando hacia abajo desde el estado expandido: reducimos su altura
|
|
186
251
|
const newHeight = this._sheetHeight - deltaY;
|
|
187
252
|
this._dialog.style.transform = '';
|
|
188
253
|
this._dialog.style.height = `${Math.max(0, newHeight)}px`;
|
|
189
254
|
}
|
|
190
255
|
else {
|
|
191
|
-
//
|
|
192
|
-
const newHeight = this._sheetHeight - deltaY * 0.2;
|
|
256
|
+
// Tirando hacia arriba cuando ya está expandido: aplicamos resistencia friccional
|
|
257
|
+
const newHeight = this._sheetHeight - deltaY * 0.2; // 0.2 simula tensión (rubber-band)
|
|
193
258
|
this._dialog.style.transform = '';
|
|
194
259
|
this._dialog.style.height = `${Math.min(maxHeight, newHeight)}px`;
|
|
195
260
|
}
|
|
196
261
|
}
|
|
197
262
|
else {
|
|
198
263
|
if (deltaY > 0) {
|
|
199
|
-
//
|
|
264
|
+
// Arrastrando hacia abajo desde su estado inicial: lo empujamos visualmente hacia abajo (translate)
|
|
200
265
|
this._currentTranslationY = deltaY;
|
|
201
266
|
this._dialog.style.transform = `translateY(${deltaY}px)`;
|
|
202
267
|
this._dialog.style.height = '';
|
|
203
268
|
}
|
|
204
269
|
else {
|
|
205
|
-
//
|
|
270
|
+
// Arrastrando hacia arriba desde su estado inicial: hacemos que crezca su altura
|
|
206
271
|
const newHeight = this._sheetHeight - deltaY;
|
|
207
272
|
this._dialog.style.transform = '';
|
|
208
273
|
this._dialog.style.height = `${Math.min(maxHeight, newHeight)}px`;
|
|
209
274
|
}
|
|
210
275
|
}
|
|
211
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* Finaliza la interacción de arrastre, evaluando si el bottom-sheet debe
|
|
279
|
+
* expandirse, regresar a su estado original o cerrarse completamente según la
|
|
280
|
+
* inercia o la distancia arrastrada.
|
|
281
|
+
*/
|
|
212
282
|
_onPointerUp(e) {
|
|
213
283
|
if (!this._isDragging)
|
|
214
284
|
return;
|
|
215
285
|
const target = e.target;
|
|
216
|
-
target.releasePointerCapture(e.pointerId);
|
|
286
|
+
target.releasePointerCapture(e.pointerId); // Liberamos el control del puntero
|
|
217
287
|
this._isDragging = false;
|
|
218
|
-
this._dialog.classList.remove('dragging');
|
|
288
|
+
this._dialog.classList.remove('dragging'); // Reactivamos las transiciones CSS
|
|
219
289
|
const deltaY = e.clientY - this._startY;
|
|
290
|
+
// Si se movió más de 5px, bloqueamos clics accidentales para evitar disparar eventos subyacentes
|
|
220
291
|
if (Math.abs(deltaY) > 5) {
|
|
221
292
|
this._justDragged = true;
|
|
222
293
|
setTimeout(() => {
|
|
@@ -226,80 +297,62 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
226
297
|
const isExpanded = this._dialog.classList.contains('expanded');
|
|
227
298
|
const maxHeight = this._getMaxHeightPx();
|
|
228
299
|
if (isExpanded) {
|
|
300
|
+
// Evaluamos la altura final tras soltar el ratón/dedo
|
|
229
301
|
const finalHeight = this._sheetHeight - deltaY;
|
|
230
302
|
if (finalHeight < this._defaultHeight - 80) {
|
|
231
|
-
//
|
|
232
|
-
this.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
this.open = false;
|
|
240
|
-
this.dispatchEvent(new CustomEvent('close'));
|
|
241
|
-
};
|
|
242
|
-
this._dialog.addEventListener('transitionend', onTransitionEnd);
|
|
243
|
-
setTimeout(() => {
|
|
244
|
-
if (this.open)
|
|
245
|
-
onTransitionEnd();
|
|
246
|
-
}, 300);
|
|
303
|
+
// Si se arrastró significativamente por debajo de la altura por defecto, lo cerramos
|
|
304
|
+
this._animateAndClose().then((closed) => {
|
|
305
|
+
if (!closed) {
|
|
306
|
+
// Si se canceló el evento, regresamos a su lugar
|
|
307
|
+
this._dialog.style.transform = '';
|
|
308
|
+
this._dialog.style.height = '';
|
|
309
|
+
}
|
|
310
|
+
});
|
|
247
311
|
}
|
|
248
312
|
else if (finalHeight < (maxHeight + this._defaultHeight) / 2) {
|
|
249
|
-
//
|
|
313
|
+
// Si se soltó a medio camino, lo colapsamos a su altura normal
|
|
250
314
|
this._dialog.classList.remove('expanded');
|
|
251
315
|
this._dialog.style.transform = '';
|
|
252
316
|
this._dialog.style.height = '';
|
|
253
317
|
}
|
|
254
318
|
else {
|
|
255
|
-
//
|
|
319
|
+
// Si no se arrastró lo suficiente hacia abajo, retorna a estado expandido (snap back)
|
|
256
320
|
this._dialog.style.transform = '';
|
|
257
321
|
this._dialog.style.height = '';
|
|
258
322
|
}
|
|
259
323
|
}
|
|
260
324
|
else {
|
|
261
325
|
if (deltaY < 0) {
|
|
262
|
-
//
|
|
326
|
+
// Evaluamos el arrastre hacia arriba desde el estado colapsado
|
|
263
327
|
const finalHeight = this._sheetHeight - deltaY;
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
// Snap to expanded
|
|
328
|
+
if (finalHeight > this._sheetHeight + 80) {
|
|
329
|
+
// Expandimos el bottom-sheet hasta la altura máxima
|
|
267
330
|
this._dialog.classList.add('expanded');
|
|
268
|
-
this._dialog.style.transform = '';
|
|
269
|
-
this._dialog.style.height = '';
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
// Revert to normal
|
|
273
|
-
this._dialog.style.transform = '';
|
|
274
|
-
this._dialog.style.height = '';
|
|
275
331
|
}
|
|
332
|
+
this._dialog.style.transform = '';
|
|
333
|
+
this._dialog.style.height = '';
|
|
276
334
|
}
|
|
277
335
|
else {
|
|
278
|
-
//
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
this._dialog.style.transform = '';
|
|
286
|
-
this._dialog.style.height = '';
|
|
287
|
-
this.open = false;
|
|
288
|
-
this.dispatchEvent(new CustomEvent('close'));
|
|
289
|
-
};
|
|
290
|
-
this._dialog.addEventListener('transitionend', onTransitionEnd);
|
|
291
|
-
setTimeout(() => {
|
|
292
|
-
if (this.open)
|
|
293
|
-
onTransitionEnd();
|
|
294
|
-
}, 300);
|
|
336
|
+
// Evaluamos el arrastre hacia abajo para cerrar el componente
|
|
337
|
+
if (this._currentTranslationY > 80) {
|
|
338
|
+
this._animateAndClose().then((closed) => {
|
|
339
|
+
if (!closed) {
|
|
340
|
+
this._dialog.style.transform = '';
|
|
341
|
+
}
|
|
342
|
+
});
|
|
295
343
|
}
|
|
296
344
|
else {
|
|
345
|
+
// Regresa a su estado colapsado (snap back al inicio)
|
|
297
346
|
this._dialog.style.transform = '';
|
|
298
|
-
this._dialog.style.height = '';
|
|
299
347
|
}
|
|
300
348
|
}
|
|
301
349
|
}
|
|
302
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Aborta limpiamente la interacción de arrastre (Pointer Cancel).
|
|
353
|
+
* Se dispara cuando el SO interrumpe el touch (ej: entrada de una llamada)
|
|
354
|
+
* o si el navegador toma el control para un scroll nativo imprevisto.
|
|
355
|
+
*/
|
|
303
356
|
_onPointerCancel(e) {
|
|
304
357
|
if (!this._isDragging)
|
|
305
358
|
return;
|
|
@@ -310,6 +363,12 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
310
363
|
this._dialog.style.transform = '';
|
|
311
364
|
this._dialog.style.height = '';
|
|
312
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* Handler de clicks en la superficie del modal (Backdrop).
|
|
368
|
+
* Si el clic cae exactamente en el fondo (`this._dialog`) y no en el contenedor de
|
|
369
|
+
* contenido interno (`this._sheetContent`), y si el sheet acaba de ser arrastrado
|
|
370
|
+
* sin soltar, ignora el click. De lo contrario, cierra fluidamente el modal deslizando hacia abajo.
|
|
371
|
+
*/
|
|
313
372
|
_onDialogClick(e) {
|
|
314
373
|
if (this._justDragged) {
|
|
315
374
|
this._justDragged = false;
|
|
@@ -320,21 +379,16 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
320
379
|
// Click on backdrop targets the dialog element itself. Clicks on children target the children.
|
|
321
380
|
if (e.target !== this._dialog)
|
|
322
381
|
return;
|
|
323
|
-
this.
|
|
324
|
-
this._dialog.style.height = '';
|
|
325
|
-
const onTransitionEnd = () => {
|
|
326
|
-
this._dialog.removeEventListener('transitionend', onTransitionEnd);
|
|
327
|
-
this._dialog.style.transform = '';
|
|
328
|
-
this._dialog.style.height = '';
|
|
329
|
-
this.open = false;
|
|
330
|
-
this.dispatchEvent(new CustomEvent('close'));
|
|
331
|
-
};
|
|
332
|
-
this._dialog.addEventListener('transitionend', onTransitionEnd);
|
|
333
|
-
setTimeout(() => {
|
|
334
|
-
if (this.open)
|
|
335
|
-
onTransitionEnd();
|
|
336
|
-
}, 300);
|
|
382
|
+
this._animateAndClose();
|
|
337
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Hook del ciclo de vida reactivo (Lit).
|
|
386
|
+
* Gestiona inyecciones de variables CSS dinámicas para anchos y alturas máximas.
|
|
387
|
+
*
|
|
388
|
+
* Fundamental: Resuelve problemas de `z-index` y `overflow: hidden` en ancestros
|
|
389
|
+
* mediante el Portal Pattern (moviendo físicamente el DOM element al `document.body`)
|
|
390
|
+
* si `positioning === 'body'` cuando se abre, y devolviéndolo a su DOM originario al cerrar.
|
|
391
|
+
*/
|
|
338
392
|
updated(changed) {
|
|
339
393
|
super.updated(changed);
|
|
340
394
|
if (changed.has('expandedHeight')) {
|
|
@@ -345,11 +399,18 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
345
399
|
}
|
|
346
400
|
if (changed.has('open')) {
|
|
347
401
|
if (this.open) {
|
|
402
|
+
if (changed.get('open') !== undefined) {
|
|
403
|
+
emitMoniEvent(this, 'moni-open');
|
|
404
|
+
}
|
|
348
405
|
if (this.positioning === 'body' && this.parentNode !== document.body) {
|
|
349
406
|
this._originalParent = this.parentNode;
|
|
350
407
|
this._originalSibling = this.nextSibling;
|
|
351
408
|
document.body.appendChild(this);
|
|
352
409
|
}
|
|
410
|
+
if (changed.get('open') !== undefined) {
|
|
411
|
+
// Simulamos el final de la transición de apertura
|
|
412
|
+
setTimeout(() => emitMoniEvent(this, 'moni-opened'), 300);
|
|
413
|
+
}
|
|
353
414
|
}
|
|
354
415
|
else {
|
|
355
416
|
if (this._dialog) {
|
|
@@ -363,6 +424,11 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
363
424
|
}
|
|
364
425
|
}
|
|
365
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* Limpieza (Garbage Collection).
|
|
429
|
+
* Si el Bottom Sheet fue destruido mientras estaba inyectado en el `document.body`
|
|
430
|
+
* (Portal Pattern), lo retorna a su padre original para evitar orfandad de nodos.
|
|
431
|
+
*/
|
|
366
432
|
disconnectedCallback() {
|
|
367
433
|
super.disconnectedCallback();
|
|
368
434
|
if (this.parentNode === document.body && this.positioning === 'body' && this._originalParent) {
|
|
@@ -491,6 +557,26 @@ let MoniBottomSheet = class MoniBottomSheet extends MoniElement {
|
|
|
491
557
|
}
|
|
492
558
|
`
|
|
493
559
|
]; }
|
|
560
|
+
/**
|
|
561
|
+
* Renders the native `<dialog>` element that serves as the bottom sheet container.
|
|
562
|
+
*
|
|
563
|
+
* **Why `<dialog>` instead of `<div>`?**
|
|
564
|
+
* Using the native `<dialog>` element provides:
|
|
565
|
+
* - Built-in focus trapping via the `open` attribute (browser handles `inert`).
|
|
566
|
+
* - The `::backdrop` pseudo-element for the translucent overlay (styled via CSS).
|
|
567
|
+
* - Screen reader accessibility (`role="dialog"` / `aria-modal`) for free.
|
|
568
|
+
*
|
|
569
|
+
* **Positioning class mapping:**
|
|
570
|
+
* `posClass` maps `positioning='body'` to `'fixed'` (the CSS class name), while
|
|
571
|
+
* other positioning values pass through unchanged. `'body'` positioning anchors
|
|
572
|
+
* the sheet to the viewport; `'parent'` keeps it within the nearest `position: relative` ancestor.
|
|
573
|
+
*
|
|
574
|
+
* **Touch-to-dismiss via pointer events:**
|
|
575
|
+
* `@pointerdown`, `@pointermove`, and `@pointerup` on the `<dialog>` element
|
|
576
|
+
* power the swipe-down-to-dismiss gesture. `_onPointerDown` records the start Y;
|
|
577
|
+
* `_onPointerMove` applies a CSS `translateY` to provide live drag feedback;
|
|
578
|
+
* `_onPointerUp` determines if the drag exceeded the dismiss threshold.
|
|
579
|
+
*/
|
|
494
580
|
render() {
|
|
495
581
|
const posClass = this.positioning === 'body' ? 'fixed' : this.positioning;
|
|
496
582
|
const dialogClasses = `${this.size} ${posClass}`;
|