@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,59 +13,64 @@ import './moni-icon.js';
|
|
|
13
13
|
import './moni-progress.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Material Design 3 Button
|
|
16
|
+
* Componente Material Design 3 Button.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Los botones permiten a los usuarios realizar acciones y hacer elecciones con un solo toque.
|
|
19
|
+
* Este componente proporciona todas las variantes de botones de M3, tamaños y capacidades
|
|
20
|
+
* de transformación de formas (ej. cambiar a una forma de píldora al presionar o alternar).
|
|
21
21
|
*
|
|
22
|
-
* **
|
|
22
|
+
* **Referencia de la especificación M3:** `m3-docs/components/buttons/specs.md`
|
|
23
23
|
*
|
|
24
|
-
* **
|
|
25
|
-
* - `filled` (
|
|
26
|
-
* - `tonal` —
|
|
27
|
-
* - `elevated` —
|
|
28
|
-
* - `outlined` —
|
|
29
|
-
* - `text` —
|
|
24
|
+
* **Variantes:**
|
|
25
|
+
* - `filled` (por defecto) — Énfasis alto. Úsalo para acciones principales.
|
|
26
|
+
* - `tonal` — Énfasis medio. Acciones secundarias que aún necesitan destacar.
|
|
27
|
+
* - `elevated` — Énfasis medio con sombra. Úsalo al sentarse sobre fondos con patrones.
|
|
28
|
+
* - `outlined` — Énfasis medio, sin relleno. Acciones secundarias o terciarias.
|
|
29
|
+
* - `text` — Énfasis bajo. Acciones terciarias (ej. botón de cancelar diálogo).
|
|
30
30
|
*
|
|
31
|
-
* **
|
|
32
|
-
* -
|
|
33
|
-
* "
|
|
34
|
-
* -
|
|
31
|
+
* **Transformación de forma (Característica M3 Expressive):**
|
|
32
|
+
* - Al presionar (estado activo): Los botones redondos y cuadrados se transforman a una forma
|
|
33
|
+
* "presionada" ligeramente más cuadrada con radios de esquina específicos de M3 (ej. XS/S 8dp, M 12dp).
|
|
34
|
+
* - Al alternar (atributo `active`): La forma de reposo se invierte (ej. redondo ↔ cuadrado).
|
|
35
35
|
*
|
|
36
|
-
* **
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
36
|
+
* **Renderizando como un enlace:**
|
|
37
|
+
* Cuando se proporciona el atributo `href`, el componente se renderiza internamente como
|
|
38
|
+
* un elemento `<a>` en lugar de un `<button>`, permitiendo enrutamiento nativo y comportamientos
|
|
39
|
+
* de clic central (abrir en nueva pestaña) mientras mantiene los visuales del botón.
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```html
|
|
43
|
-
* <!--
|
|
44
|
-
* <moni-button icon="add">
|
|
43
|
+
* <!-- Botón primario relleno -->
|
|
44
|
+
* <moni-button icon="add">Crear nuevo</moni-button>
|
|
45
45
|
*
|
|
46
|
-
* <!--
|
|
47
|
-
* <moni-button variant="outlined">
|
|
46
|
+
* <!-- Botón contorneado -->
|
|
47
|
+
* <moni-button variant="outlined">Cancelar</moni-button>
|
|
48
48
|
*
|
|
49
|
-
* <!--
|
|
50
|
-
* <moni-button icon="favorite" active>
|
|
49
|
+
* <!-- Botón de alternar (alterna estado activo al hacer clic) -->
|
|
50
|
+
* <moni-button icon="favorite" active>Me gusta</moni-button>
|
|
51
51
|
*
|
|
52
|
-
* <!--
|
|
53
|
-
* <moni-button href="/settings" icon="settings">
|
|
52
|
+
* <!-- Botón enlace -->
|
|
53
|
+
* <moni-button href="/settings" icon="settings">Ajustes</moni-button>
|
|
54
54
|
* ```
|
|
55
55
|
*
|
|
56
|
-
* @slot default -
|
|
57
|
-
* @slot icon -
|
|
58
|
-
* @slot icon-trailing -
|
|
56
|
+
* @slot default - El texto de la etiqueta del botón.
|
|
57
|
+
* @slot icon - Sobrescritura opcional para el icono inicial (leading).
|
|
58
|
+
* @slot icon-trailing - Sobrescritura opcional para el icono final (trailing).
|
|
59
59
|
*
|
|
60
|
-
* @csspart button -
|
|
61
|
-
* @csspart icon -
|
|
62
|
-
* @csspart label -
|
|
63
|
-
* @csspart trailing-icon -
|
|
60
|
+
* @csspart button - El elemento interno `<button>` o `<a>`.
|
|
61
|
+
* @csspart icon - El contenedor del icono inicial.
|
|
62
|
+
* @csspart label - El contenedor de la etiqueta.
|
|
63
|
+
* @csspart trailing-icon - El contenedor del icono final.
|
|
64
64
|
*/
|
|
65
65
|
@customElement('moni-button')
|
|
66
66
|
export class MoniButton extends MoniElement {
|
|
67
67
|
private static _deprecationWarned = false;
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Variante visual del botón.
|
|
71
|
+
* @type {'filled' | 'tonal' | 'outlined' | 'text' | 'fill' | 'elevated'}
|
|
72
|
+
* @default 'filled'
|
|
73
|
+
*/
|
|
69
74
|
@property({ reflect: true })
|
|
70
75
|
variant:
|
|
71
76
|
| 'filled'
|
|
@@ -73,14 +78,24 @@ export class MoniButton extends MoniElement {
|
|
|
73
78
|
| 'outlined'
|
|
74
79
|
| 'text'
|
|
75
80
|
| 'fill'
|
|
76
|
-
| 'elevated'
|
|
81
|
+
| 'elevated'
|
|
82
|
+
| 'error' = 'filled';
|
|
83
|
+
|
|
77
84
|
/**
|
|
78
|
-
* M3 Expressive
|
|
79
|
-
* `extra`
|
|
80
|
-
*
|
|
85
|
+
* Tamaños de M3 Expressive: xsmall, small, medium, large, xlarge.
|
|
86
|
+
* `extra` es un alias heredado de Moni para `xlarge`, obsoleto en v0.3.1; se
|
|
87
|
+
* eliminará en v1.0. Ver `m3-docs/components/buttons/overview.md` § Sizes.
|
|
88
|
+
* @type {'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'extra'}
|
|
89
|
+
* @default 'medium'
|
|
81
90
|
*/
|
|
82
91
|
@property({ reflect: true })
|
|
83
92
|
size: 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'extra' = 'medium';
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Forma de las esquinas del botón.
|
|
96
|
+
* @type {'round' | 'no-round' | 'square' | 'circle' | 'left-round' | 'right-round' | 'top-round' | 'bottom-round' | 'left-round-flat' | 'right-round-flat' | 'top-round-flat' | 'bottom-round-flat' | 'inner-round'}
|
|
97
|
+
* @default 'round'
|
|
98
|
+
*/
|
|
84
99
|
@property({ reflect: true })
|
|
85
100
|
shape:
|
|
86
101
|
| 'round'
|
|
@@ -96,14 +111,55 @@ export class MoniButton extends MoniElement {
|
|
|
96
111
|
| 'top-round-flat'
|
|
97
112
|
| 'bottom-round-flat'
|
|
98
113
|
| 'inner-round' = 'round';
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Deshabilita el botón.
|
|
117
|
+
* @type {boolean}
|
|
118
|
+
*/
|
|
99
119
|
@property({ type: Boolean, reflect: true }) disabled = false;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Si es verdadero, muestra un indicador de carga y deshabilita el botón.
|
|
123
|
+
* @type {boolean}
|
|
124
|
+
*/
|
|
100
125
|
@property({ type: Boolean, reflect: true }) loading = false;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Si es verdadero, establece el botón a un estado activo/seleccionado.
|
|
129
|
+
* @type {boolean}
|
|
130
|
+
*/
|
|
101
131
|
@property({ type: Boolean, reflect: true }) active = false;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Nombre del icono inicial (Material Symbols).
|
|
135
|
+
* @type {string}
|
|
136
|
+
*/
|
|
102
137
|
@property({ reflect: true }) icon = '';
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Nombre del icono final (Material Symbols).
|
|
141
|
+
* @type {string}
|
|
142
|
+
*/
|
|
103
143
|
@property({ reflect: true, attribute: 'icon-trailing' }) iconTrailing = '';
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Tipo nativo del botón (cuando se renderiza como un `<button>`).
|
|
147
|
+
* @type {'button' | 'submit' | 'reset'}
|
|
148
|
+
* @default 'button'
|
|
149
|
+
*/
|
|
104
150
|
@property({ reflect: true })
|
|
105
151
|
type: 'button' | 'submit' | 'reset' = 'button';
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Si está establecido, renderiza el botón como un elemento `<a>` con esta URL.
|
|
155
|
+
* @type {string}
|
|
156
|
+
*/
|
|
106
157
|
@property({ reflect: true }) href = '';
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Atributo target para los botones tipo enlace.
|
|
161
|
+
* @type {string}
|
|
162
|
+
*/
|
|
107
163
|
@property({ reflect: true }) target = '';
|
|
108
164
|
|
|
109
165
|
override connectedCallback(): void {
|
|
@@ -198,7 +254,7 @@ export class MoniButton extends MoniElement {
|
|
|
198
254
|
/* Square keeps horizontal padding (like a normal button) but
|
|
199
255
|
drops border-radius. Only the circle removes all padding. */
|
|
200
256
|
.button.circle {
|
|
201
|
-
padding: 0;
|
|
257
|
+
padding: 0 !important;
|
|
202
258
|
border-radius: 50%;
|
|
203
259
|
inline-size: 2.5rem;
|
|
204
260
|
aspect-ratio: 1;
|
|
@@ -529,6 +585,16 @@ export class MoniButton extends MoniElement {
|
|
|
529
585
|
color: var(--primary);
|
|
530
586
|
box-shadow: var(--elevate1);
|
|
531
587
|
}
|
|
588
|
+
.button.error {
|
|
589
|
+
background-color: var(--error);
|
|
590
|
+
color: var(--on-error);
|
|
591
|
+
}
|
|
592
|
+
.button.error:hover:not(:disabled) {
|
|
593
|
+
background-image: linear-gradient(color-mix(in srgb, currentColor 8%, transparent), color-mix(in srgb, currentColor 8%, transparent));
|
|
594
|
+
}
|
|
595
|
+
.button.error:focus-visible {
|
|
596
|
+
outline-color: var(--error);
|
|
597
|
+
}
|
|
532
598
|
|
|
533
599
|
/* Disabled / active */
|
|
534
600
|
.button:disabled,
|
|
@@ -630,6 +696,11 @@ export class MoniButton extends MoniElement {
|
|
|
630
696
|
`
|
|
631
697
|
];
|
|
632
698
|
|
|
699
|
+
/**
|
|
700
|
+
* Intercepta los clicks en botones tipo enlace (`href="..."`).
|
|
701
|
+
* Si el botón está desactivado (`disabled`), previene agresivamente
|
|
702
|
+
* tanto la navegación por defecto del navegador como la burbuja de eventos.
|
|
703
|
+
*/
|
|
633
704
|
private handleLinkClick(e: Event) {
|
|
634
705
|
if (this.disabled) {
|
|
635
706
|
e.preventDefault();
|
|
@@ -637,12 +708,41 @@ export class MoniButton extends MoniElement {
|
|
|
637
708
|
}
|
|
638
709
|
}
|
|
639
710
|
|
|
711
|
+
/**
|
|
712
|
+
* Assembles the button's Shadow DOM structure for each Lit render cycle.
|
|
713
|
+
*
|
|
714
|
+
* **Variant → CSS class mapping:**
|
|
715
|
+
* | `variant` | CSS class | Visual result |
|
|
716
|
+
* |--------------|---------------|-----------------------------|
|
|
717
|
+
* | `'filled'` | `''` (empty) | Primary filled button |
|
|
718
|
+
* | `'outlined'` | `'border'` | Outlined/stroked button |
|
|
719
|
+
* | `'tonal'` | `'fill'` | Secondary container fill |
|
|
720
|
+
* | `'text'` | `'transparent'` | Ghost/text button |
|
|
721
|
+
* | `'elevated'` | `'elevated'` | Tonal surface + shadow |
|
|
722
|
+
*
|
|
723
|
+
* **Shape morphing:**
|
|
724
|
+
* When `active=true`, the button inverts its corner-radius shape to create
|
|
725
|
+
* a micro-animation where clicking "morphs" the shape (round → square, etc.).
|
|
726
|
+
* This is used in toggle-button patterns (e.g., a nav-item that morphs to
|
|
727
|
+
* indicate the current page).
|
|
728
|
+
*
|
|
729
|
+
* **Icon resolution priority:**
|
|
730
|
+
* 1. `loading=true` → renders a `<moni-progress>` spinner (hides label at 50% opacity).
|
|
731
|
+
* 2. `icon` attribute → renders a `<moni-icon>` in the leading icon slot.
|
|
732
|
+
* 3. Otherwise → renders the `icon` named slot for slotted content.
|
|
733
|
+
*
|
|
734
|
+
* **Link vs. button:**
|
|
735
|
+
* When `href` is set, the root element is an `<a>` tag (with disabled click
|
|
736
|
+
* guard) for proper browser navigation semantics. Otherwise it's a `<button>`
|
|
737
|
+
* with `type="button"` to prevent accidental form submission.
|
|
738
|
+
*/
|
|
640
739
|
override render() {
|
|
641
740
|
let variantClass = '';
|
|
642
741
|
if (this.variant === 'outlined') variantClass = 'border';
|
|
643
742
|
else if (this.variant === 'tonal' || this.variant === 'fill') variantClass = 'fill';
|
|
644
743
|
else if (this.variant === 'text') variantClass = 'transparent';
|
|
645
744
|
else if (this.variant === 'elevated') variantClass = 'elevated';
|
|
745
|
+
else if (this.variant === 'error') variantClass = 'error';
|
|
646
746
|
|
|
647
747
|
let activeShape: string = this.shape;
|
|
648
748
|
if (this.active) {
|
|
@@ -14,7 +14,7 @@ describe('moni-card (P4.4 — recreated)', () => {
|
|
|
14
14
|
el.remove();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it('
|
|
17
|
+
it('renderiza las tres variantes M3: elevated (por defecto), filled, outlined', async () => {
|
|
18
18
|
expect(el.variant).toBe('elevated');
|
|
19
19
|
await el.updateComplete;
|
|
20
20
|
expect(el.getAttribute('variant')).toBe('elevated');
|
|
@@ -28,7 +28,7 @@ describe('moni-card (P4.4 — recreated)', () => {
|
|
|
28
28
|
expect(el.getAttribute('variant')).toBe('outlined');
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
it('
|
|
31
|
+
it('renderiza los slots media, body y actions', async () => {
|
|
32
32
|
await el.updateComplete;
|
|
33
33
|
const media = el.shadowRoot?.querySelector('[part="media"]');
|
|
34
34
|
const body = el.shadowRoot?.querySelector('[part="body"]');
|
|
@@ -38,7 +38,7 @@ describe('moni-card (P4.4 — recreated)', () => {
|
|
|
38
38
|
expect(actions).toBeTruthy();
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
it('
|
|
41
|
+
it('refleja los atributos clickable, draggable y disabled', async () => {
|
|
42
42
|
el.clickable = true;
|
|
43
43
|
await el.updateComplete;
|
|
44
44
|
expect(el.hasAttribute('clickable')).toBe(true);
|
|
@@ -52,7 +52,7 @@ describe('moni-card (P4.4 — recreated)', () => {
|
|
|
52
52
|
expect(el.hasAttribute('disabled')).toBe(true);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
it('
|
|
55
|
+
it('soporta encabezados insertados vía el slot headline', async () => {
|
|
56
56
|
const heading = document.createElement('h3');
|
|
57
57
|
heading.setAttribute('slot', 'headline');
|
|
58
58
|
heading.textContent = 'Card title';
|
|
@@ -68,10 +68,10 @@ describe('moni-card (P4.4 — recreated)', () => {
|
|
|
68
68
|
expect(text).toBe('Card title');
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
it('
|
|
71
|
+
it('soporta el slot por defecto para el contenido primario', async () => {
|
|
72
72
|
el.textContent = 'Body content';
|
|
73
73
|
await el.updateComplete;
|
|
74
|
-
//
|
|
74
|
+
// El slot por defecto está dentro del contenedor del slot headline.
|
|
75
75
|
const defaultSlot = el.shadowRoot?.querySelector(
|
|
76
76
|
'slot:not([name])'
|
|
77
77
|
) as HTMLSlotElement | null;
|
|
@@ -10,67 +10,67 @@ import { customElement, property } from 'lit/decorators.js';
|
|
|
10
10
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Material Design 3 Card
|
|
13
|
+
* Componente Material Design 3 Card.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Las tarjetas muestran contenido y acciones sobre un solo sujeto. Son
|
|
16
|
+
* superficies contenedoras que agrupan información relacionada junta, haciendo
|
|
17
|
+
* fácil para los usuarios escanear e interactuar con colecciones de datos relacionados.
|
|
18
18
|
*
|
|
19
|
-
* **
|
|
19
|
+
* **Referencia de la especificación M3:** `m3-docs/components/cards/specs.md`
|
|
20
20
|
*
|
|
21
|
-
* **
|
|
22
|
-
* - `elevated` (
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* - `filled` — `surface-container-highest
|
|
26
|
-
*
|
|
27
|
-
* - `outlined` — `surface`
|
|
28
|
-
*
|
|
21
|
+
* **Variantes:**
|
|
22
|
+
* - `elevated` (por defecto) — Fondo `surface-container-low` + sombra `--elevate1`.
|
|
23
|
+
* Mejor para colecciones donde la tarjeta necesita separación visual de un
|
|
24
|
+
* fondo con patrones o de color. Gana sombra al pasar el ratón/arrastrar.
|
|
25
|
+
* - `filled` — Fondo `surface-container-highest`, sin sombra.
|
|
26
|
+
* Énfasis más bajo; úsalo cuando las tarjetas se asientan directamente sobre la superficie del fondo principal.
|
|
27
|
+
* - `outlined` — Fondo `surface` + trazo `outline-variant` 1dp.
|
|
28
|
+
* Énfasis estructural más alto sin proyectar una sombra. Mejor en fondos sólidos.
|
|
29
29
|
*
|
|
30
|
-
* **M3
|
|
31
|
-
* -
|
|
32
|
-
* -
|
|
33
|
-
* -
|
|
34
|
-
* -
|
|
30
|
+
* **Medidas M3:**
|
|
31
|
+
* - Radio de esquina del contenedor: 12dp.
|
|
32
|
+
* - Relleno de contenido horizontal: 16dp.
|
|
33
|
+
* - Espacio entre tarjetas en una colección: máx. 8dp.
|
|
34
|
+
* - Alineación de texto del titular: inicio.
|
|
35
35
|
*
|
|
36
|
-
* **
|
|
37
|
-
*
|
|
38
|
-
* focus,
|
|
39
|
-
*
|
|
36
|
+
* **Tarjetas interactivas:**
|
|
37
|
+
* Cuando `clickable=true`, la tarjeta renderiza capas de estado M3 (hover,
|
|
38
|
+
* focus, press) a través del pseudo-elemento `::before`. El consumidor debe manejar
|
|
39
|
+
* el evento `click` para implementar la lógica de navegación o selección.
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```html
|
|
43
43
|
* <moni-card variant="outlined" clickable>
|
|
44
|
-
* <img slot="media" src="photo.jpg" alt="
|
|
45
|
-
* <h3 slot="headline">
|
|
46
|
-
* <p slot="supporting">
|
|
44
|
+
* <img slot="media" src="photo.jpg" alt="Imagen de la tarjeta" />
|
|
45
|
+
* <h3 slot="headline">Título de Tarjeta</h3>
|
|
46
|
+
* <p slot="supporting">Texto de soporte que describe el tema de la tarjeta.</p>
|
|
47
47
|
* <div slot="actions">
|
|
48
|
-
* <moni-button variant="text">
|
|
49
|
-
* <moni-button>
|
|
48
|
+
* <moni-button variant="text">Cancelar</moni-button>
|
|
49
|
+
* <moni-button>Confirmar</moni-button>
|
|
50
50
|
* </div>
|
|
51
51
|
* </moni-card>
|
|
52
52
|
* ```
|
|
53
53
|
*
|
|
54
|
-
* @slot media -
|
|
55
|
-
* @slot default -
|
|
56
|
-
* @slot headline -
|
|
57
|
-
* @slot subhead -
|
|
58
|
-
* @slot supporting -
|
|
59
|
-
* @slot actions -
|
|
54
|
+
* @slot media - Una imagen, video, o icono en la parte superior de la tarjeta.
|
|
55
|
+
* @slot default - Contenido del cuerpo principal (reemplaza todos los slots con nombre si se usa).
|
|
56
|
+
* @slot headline - Texto de título equivalente a H3.
|
|
57
|
+
* @slot subhead - Título secundario debajo del titular.
|
|
58
|
+
* @slot supporting - Texto de soporte descriptivo del cuerpo.
|
|
59
|
+
* @slot actions - Fila de botones de acción en la parte inferior de la tarjeta.
|
|
60
60
|
*
|
|
61
|
-
* @csspart card -
|
|
62
|
-
* @csspart media -
|
|
63
|
-
* @csspart content -
|
|
64
|
-
* @csspart actions -
|
|
61
|
+
* @csspart card - El contenedor exterior de la tarjeta.
|
|
62
|
+
* @csspart media - El contenedor del área de medios.
|
|
63
|
+
* @csspart content - El contenedor de contenido.
|
|
64
|
+
* @csspart actions - El contenedor de la fila de acciones.
|
|
65
65
|
*/
|
|
66
66
|
@customElement('moni-card')
|
|
67
67
|
export class MoniCard extends MoniElement {
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* Variante visual de la tarjeta.
|
|
70
70
|
*
|
|
71
|
-
* - `'elevated'` (
|
|
72
|
-
* - `'filled'` — Surface-highest
|
|
73
|
-
* - `'outlined'` — Surface
|
|
71
|
+
* - `'elevated'` (por defecto) — Fondo Surface-low + sombra de elevación.
|
|
72
|
+
* - `'filled'` — Fondo Surface-highest, sin sombra.
|
|
73
|
+
* - `'outlined'` — Fondo Surface + trazo outline-variant.
|
|
74
74
|
*
|
|
75
75
|
* @default 'elevated'
|
|
76
76
|
*/
|
|
@@ -78,34 +78,36 @@ export class MoniCard extends MoniElement {
|
|
|
78
78
|
variant: 'elevated' | 'filled' | 'outlined' = 'elevated';
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
81
|
+
* Cuando es `true`, aplica capas de estado M3 (hover, focus, pressed)
|
|
82
|
+
* para comunicar interactividad. El fondo de la tarjeta cambia ligeramente en hover.
|
|
83
83
|
*
|
|
84
|
-
*
|
|
84
|
+
* Úsalo cuando la tarjeta en sí es un objetivo de navegación o selección clicable.
|
|
85
85
|
*
|
|
86
86
|
* @default false
|
|
87
87
|
*/
|
|
88
88
|
@property({ type: Boolean, reflect: true }) clickable = false;
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
91
|
+
* Cuando es `true`, aplica box-shadow `--elevate3` para simular el estado "arrastrado"
|
|
92
|
+
* M3 según lo especificado en la especificación de interacción de tarjetas M3.
|
|
93
93
|
*
|
|
94
|
-
*
|
|
95
|
-
* (
|
|
94
|
+
* Los consumidores deben alternar este atributo basado en el estado de arrastre de la tarjeta
|
|
95
|
+
* (ej. a través de un callback de biblioteca drag-and-drop).
|
|
96
96
|
*
|
|
97
97
|
* @default false
|
|
98
98
|
*/
|
|
99
99
|
@property({ type: Boolean, reflect: true }) draggable = false;
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
102
|
+
* Cuando es `true`, la tarjeta se renderiza con opacidad del 50% con `cursor: not-allowed`,
|
|
103
|
+
* indicando que la tarjeta y sus acciones no están disponibles.
|
|
104
104
|
*
|
|
105
105
|
* @default false
|
|
106
106
|
*/
|
|
107
107
|
@property({ type: Boolean, reflect: true }) disabled = false;
|
|
108
108
|
|
|
109
|
+
|
|
110
|
+
|
|
109
111
|
static override styles = [
|
|
110
112
|
sharedStyles,
|
|
111
113
|
css`
|
|
@@ -239,6 +241,24 @@ export class MoniCard extends MoniElement {
|
|
|
239
241
|
`
|
|
240
242
|
];
|
|
241
243
|
|
|
244
|
+
/**
|
|
245
|
+
* Renderiza el contenedor de la tarjeta como un `<section>` con envoltorio interactivo opcional.
|
|
246
|
+
*
|
|
247
|
+
* **¿Por qué `<section>`?**
|
|
248
|
+
* Las tarjetas representan una unidad distintiva y cohesiva de contenido. Usar `<section>` da
|
|
249
|
+
* a los lectores de pantalla un punto de referencia ARIA implícito para que puedan navegar entre tarjetas.
|
|
250
|
+
*
|
|
251
|
+
* **Tarjetas interactivas (`clickable=true`):**
|
|
252
|
+
* Cuando es `clickable`, toda la superficie de la tarjeta se convierte en un `<button>` que envuelve
|
|
253
|
+
* all slots, giving the card keyboard focus and `click` semantics. A
|
|
254
|
+
* `<moni-ripple>` is rendered as the first child to provide the M3 touch feedback.
|
|
255
|
+
*
|
|
256
|
+
* **Slot zones:**
|
|
257
|
+
* - `[slot="media"]` — image or video area at the card's leading edge.
|
|
258
|
+
* - `[slot="header"]` — title and supporting text row.
|
|
259
|
+
* - Default slot — the card's main content body.
|
|
260
|
+
* - `[slot="footer"]` — action buttons row at the trailing edge.
|
|
261
|
+
*/
|
|
242
262
|
override render() {
|
|
243
263
|
return html`
|
|
244
264
|
<div class="media" part="media">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Simular ResizeObserver globalmente para el entorno jsdom antes de las importaciones de componentes
|
|
4
4
|
globalThis.ResizeObserver = class {
|
|
5
5
|
observe = vi.fn();
|
|
6
6
|
unobserve = vi.fn();
|
|
@@ -29,7 +29,7 @@ describe('moni-carousel', () => {
|
|
|
29
29
|
el.remove();
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
it('
|
|
32
|
+
it('renderiza el container, viewport y scroll-container', async () => {
|
|
33
33
|
await el.updateComplete;
|
|
34
34
|
const container = el.shadowRoot?.querySelector('.carousel-container');
|
|
35
35
|
const viewport = el.shadowRoot?.querySelector('.carousel-viewport');
|
|
@@ -40,7 +40,7 @@ describe('moni-carousel', () => {
|
|
|
40
40
|
expect(scrollContainer).toBeTruthy();
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
it('
|
|
43
|
+
it('renderiza el número correcto de cards y snap-items', async () => {
|
|
44
44
|
await el.updateComplete;
|
|
45
45
|
const cards = el.shadowRoot?.querySelectorAll('.card');
|
|
46
46
|
const snapItems = el.shadowRoot?.querySelectorAll('.snap-item');
|
|
@@ -49,7 +49,7 @@ describe('moni-carousel', () => {
|
|
|
49
49
|
expect(snapItems?.length).toBe(3);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
it('
|
|
52
|
+
it('renderiza el título del header y el botón show-all cuando se establecen', async () => {
|
|
53
53
|
el.headerText = 'Recent Highlights';
|
|
54
54
|
el.showAll = true;
|
|
55
55
|
el.showAllText = 'View All';
|
|
@@ -64,7 +64,7 @@ describe('moni-carousel', () => {
|
|
|
64
64
|
expect(showAllLink?.textContent?.trim()).toBe('View All');
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
it('
|
|
67
|
+
it('renderiza enlaces en las cards cuando href está especificado en los items', async () => {
|
|
68
68
|
const testEl = document.createElement('moni-carousel') as MoniCarousel;
|
|
69
69
|
testEl.items = [
|
|
70
70
|
{ title: 'Link Item', img: 'https://picsum.photos/200', href: 'https://moni.com', target: '_blank' }
|
|
@@ -82,7 +82,7 @@ describe('moni-carousel', () => {
|
|
|
82
82
|
testEl.remove();
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
it('
|
|
85
|
+
it('despacha el evento item-click cuando se hace clic en una card', async () => {
|
|
86
86
|
await el.updateComplete;
|
|
87
87
|
const card = el.shadowRoot?.querySelector('.card') as HTMLElement;
|
|
88
88
|
expect(card).toBeTruthy();
|
|
@@ -98,7 +98,7 @@ describe('moni-carousel', () => {
|
|
|
98
98
|
expect(eventDetail.item.title).toBe('Item 1');
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
it('
|
|
101
|
+
it('despacha el evento show-all-click cuando se hace clic en el enlace show-all', async () => {
|
|
102
102
|
el.showAll = true;
|
|
103
103
|
await el.updateComplete;
|
|
104
104
|
const showAllLink = el.shadowRoot?.querySelector('.show-all-link') as HTMLElement;
|
|
@@ -112,7 +112,7 @@ describe('moni-carousel', () => {
|
|
|
112
112
|
expect(clickSpy).toHaveBeenCalledOnce();
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
-
it('
|
|
115
|
+
it('actualiza el relleno de ajuste (snap padding) basándose en el tipo de diseño (layout)', async () => {
|
|
116
116
|
el.layout = 'hero';
|
|
117
117
|
await el.updateComplete;
|
|
118
118
|
let containerStyle = el.shadowRoot?.querySelector('.carousel-container')?.getAttribute('style');
|
|
@@ -124,7 +124,7 @@ describe('moni-carousel', () => {
|
|
|
124
124
|
expect(containerStyle?.includes('--carousel-right-padding')).toBe(true);
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
-
it('
|
|
127
|
+
it('renderiza las imágenes insertadas como items', async () => {
|
|
128
128
|
const testEl = document.createElement('moni-carousel') as MoniCarousel;
|
|
129
129
|
const img1 = document.createElement('img');
|
|
130
130
|
img1.src = 'https://picsum.photos/200?1';
|
|
@@ -152,7 +152,7 @@ describe('moni-carousel', () => {
|
|
|
152
152
|
testEl.remove();
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
-
it('
|
|
155
|
+
it('renderiza el botón show-all insertado y despacha el evento click', async () => {
|
|
156
156
|
const testEl = document.createElement('moni-carousel') as MoniCarousel;
|
|
157
157
|
const btn = document.createElement('button');
|
|
158
158
|
btn.setAttribute('slot', 'show-all');
|
|
@@ -180,7 +180,7 @@ describe('moni-carousel', () => {
|
|
|
180
180
|
testEl.remove();
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
-
it('
|
|
183
|
+
it('oculta los botones de navegación cuando hideNav es true', async () => {
|
|
184
184
|
const testEl = document.createElement('moni-carousel') as MoniCarousel;
|
|
185
185
|
testEl.hideNav = true;
|
|
186
186
|
document.body.appendChild(testEl);
|
|
@@ -195,7 +195,7 @@ describe('moni-carousel', () => {
|
|
|
195
195
|
testEl.remove();
|
|
196
196
|
});
|
|
197
197
|
|
|
198
|
-
it('
|
|
198
|
+
it('proporciona suficiente ancho de desplazamiento para alcanzar el último elemento (regresión de Firefox)', async () => {
|
|
199
199
|
const testEl = document.createElement('moni-carousel') as MoniCarousel;
|
|
200
200
|
testEl.items = Array.from({ length: 10 }, (_, i) => ({
|
|
201
201
|
title: `Item ${i}`,
|