@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
|
@@ -10,77 +10,77 @@ import { customElement, property, state } from 'lit/decorators.js';
|
|
|
10
10
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Material Design 3 Progress Indicator
|
|
13
|
+
* Componente Material Design 3 Progress Indicator (Indicador de Progreso).
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Los indicadores de progreso expresan un tiempo de espera no especificado o muestran la duración
|
|
16
|
+
* de un proceso. Informan a los usuarios sobre el estado de procesos en curso, como
|
|
17
|
+
* cargar una aplicación, enviar un formulario o guardar actualizaciones.
|
|
18
18
|
*
|
|
19
|
-
* **
|
|
19
|
+
* **Referencia a la especificación M3:** `m3-docs/components/progress-indicators/specs.md`
|
|
20
20
|
*
|
|
21
|
-
* **
|
|
22
|
-
* - `linear` (
|
|
23
|
-
* - `circular` —
|
|
24
|
-
* - `wavy` —
|
|
25
|
-
* - `circular-wavy` —
|
|
21
|
+
* **Variantes:**
|
|
22
|
+
* - `linear` (por defecto) — Una barra horizontal que se llena de izquierda a derecha.
|
|
23
|
+
* - `circular` — Un indicador circular SVG de trazo (stroke).
|
|
24
|
+
* - `wavy` — Una barra de ondas animada (extensión de Moni; no en la especificación M3).
|
|
25
|
+
* - `circular-wavy` — Combinación de circular + ondas (extensión de Moni).
|
|
26
26
|
*
|
|
27
|
-
* **Shadow DOM
|
|
28
|
-
* BeerCSS
|
|
29
|
-
* `::after`, `::webkit-progress-value`)
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
27
|
+
* **Nota de compatibilidad con Shadow DOM:**
|
|
28
|
+
* El progreso de BeerCSS usa pseudo-elementos `<progress>` nativos (`::before`,
|
|
29
|
+
* `::after`, `::webkit-progress-value`) y `mask-image`, que son bloqueados
|
|
30
|
+
* por la raíz shadow del User Agent en Chrome/Firefox. Este componente usa un envoltorio
|
|
31
|
+
* `<div>` simple que replica las reglas visuales exactamente, y un elemento `<svg>`
|
|
32
|
+
* para la variante circular usando animación SVG stroke-dashoffset para un soporte
|
|
33
|
+
* superior entre navegadores comparado con `conic-gradient`.
|
|
34
34
|
*
|
|
35
|
-
* **
|
|
36
|
-
* `_pct`
|
|
37
|
-
* `[0, 100]`.
|
|
38
|
-
*
|
|
35
|
+
* **Cálculo de porcentaje:**
|
|
36
|
+
* `_pct` se calcula en `willUpdate()` como `(value / max) * 100`, restringido a
|
|
37
|
+
* `[0, 100]`. Cuando `indeterminate` está establecido, `_pct` se fija en `50` para impulsar
|
|
38
|
+
* la animación de bucle infinito.
|
|
39
39
|
*
|
|
40
40
|
* @example
|
|
41
41
|
* ```html
|
|
42
|
-
* <!--
|
|
42
|
+
* <!-- Progreso lineal determinado -->
|
|
43
43
|
* <moni-progress value="65" max="100"></moni-progress>
|
|
44
44
|
*
|
|
45
|
-
* <!--
|
|
45
|
+
* <!-- Progreso circular indeterminado (spinner de carga) -->
|
|
46
46
|
* <moni-progress variant="circular" indeterminate></moni-progress>
|
|
47
47
|
* ```
|
|
48
48
|
*
|
|
49
|
-
* @csspart bar -
|
|
50
|
-
* @csspart fill -
|
|
51
|
-
* @csspart svg -
|
|
49
|
+
* @csspart bar - El div contenedor exterior.
|
|
50
|
+
* @csspart fill - El elemento de llenado interior (variante lineal).
|
|
51
|
+
* @csspart svg - El elemento SVG (variante circular).
|
|
52
52
|
*/
|
|
53
53
|
@customElement('moni-progress')
|
|
54
54
|
export class MoniProgress extends MoniElement {
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
56
|
+
* Valor de progreso actual.
|
|
57
57
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* `indeterminate`
|
|
58
|
+
* Debe estar en el rango `[0, max]`. Los valores fuera de este rango se restringen
|
|
59
|
+
* durante el cálculo del porcentaje en `willUpdate()`. Se ignora cuando
|
|
60
|
+
* `indeterminate` está establecido.
|
|
61
61
|
*
|
|
62
62
|
* @default 0
|
|
63
63
|
*/
|
|
64
64
|
@property({ type: Number, reflect: true }) value = 0;
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* Valor máximo del rango de progreso.
|
|
68
68
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
69
|
+
* Por defecto es `100` para que el `value` pueda establecerse como porcentaje directamente.
|
|
70
|
+
* Para rangos que no son porcentajes (ej. pasos), establece `max` al recuento total de pasos
|
|
71
|
+
* y `value` al paso actual.
|
|
72
72
|
*
|
|
73
73
|
* @default 100
|
|
74
74
|
*/
|
|
75
75
|
@property({ type: Number, reflect: true }) max = 100;
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* Variante visual del indicador de progreso.
|
|
79
79
|
*
|
|
80
|
-
* - `'linear'` (
|
|
81
|
-
* - `'circular'` — SVG
|
|
82
|
-
* - `'wavy'` —
|
|
83
|
-
* - `'circular-wavy'` —
|
|
80
|
+
* - `'linear'` (por defecto) — Barra de llenado horizontal.
|
|
81
|
+
* - `'circular'` — Círculo SVG con animación stroke-dashoffset.
|
|
82
|
+
* - `'wavy'` — Barra de ondas animada.
|
|
83
|
+
* - `'circular-wavy'` — Combinación de circular y ondas.
|
|
84
84
|
*
|
|
85
85
|
* @default 'linear'
|
|
86
86
|
*/
|
|
@@ -88,11 +88,11 @@ export class MoniProgress extends MoniElement {
|
|
|
88
88
|
variant: 'linear' | 'circular' | 'wavy' | 'circular-wavy' = 'linear';
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
91
|
+
* Tamaño visual del indicador de progreso.
|
|
92
92
|
*
|
|
93
|
-
* - `'small'` —
|
|
94
|
-
* - `'medium'` —
|
|
95
|
-
* - `'large'` —
|
|
93
|
+
* - `'small'` — Compacto; adecuado para diseños en línea o ajustados.
|
|
94
|
+
* - `'medium'` — Tamaño estándar M3 (por defecto).
|
|
95
|
+
* - `'large'` — Prominente; para estados de carga a pantalla completa.
|
|
96
96
|
*
|
|
97
97
|
* @default 'medium'
|
|
98
98
|
*/
|
|
@@ -100,33 +100,36 @@ export class MoniProgress extends MoniElement {
|
|
|
100
100
|
size: 'small' | 'medium' | 'large' = 'medium';
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
*
|
|
103
|
+
* Cuando es `true`, el indicador se anima en un bucle infinito independientemente del `value`.
|
|
104
104
|
*
|
|
105
|
-
*
|
|
106
|
-
* (
|
|
107
|
-
* `_pct`
|
|
105
|
+
* Úsalo para operaciones donde el porcentaje de finalización es desconocido
|
|
106
|
+
* (ej. peticiones de red, procesamiento de archivos). Cuando `indeterminate` está establecido,
|
|
107
|
+
* `_pct` se fija en `50` para impulsar una animación de barrido continuo.
|
|
108
108
|
*
|
|
109
109
|
* @default false
|
|
110
110
|
*/
|
|
111
111
|
@property({ type: Boolean, reflect: true }) indeterminate = false;
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
114
|
+
* Porcentaje de llenado calculado en el rango `[0, 100]`.
|
|
115
115
|
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
116
|
+
* Actualizado en `willUpdate()` cada vez que cambia `value`, `max` o `indeterminate`.
|
|
117
|
+
* Usado directamente en vinculaciones de propiedades personalizadas de CSS y atributos de trazo (stroke) SVG.
|
|
118
118
|
*
|
|
119
119
|
* @internal
|
|
120
120
|
*/
|
|
121
121
|
@state() private _pct = 0;
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
*
|
|
124
|
+
* Hook de ciclo de vida de Lit. Calcula la fracción de llenado antes de pintar.
|
|
125
125
|
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
126
|
+
* A diferencia de los componentes nativos, necesitamos computar explícitamente el
|
|
127
|
+
* progreso como un número de 0 a 100 para inyectarlo en variables CSS (Lineal)
|
|
128
|
+
* o calcular el `stroke-dashoffset` (Circular).
|
|
129
|
+
*
|
|
130
|
+
* Se usa `Math.max(1, this.max)` para evitar un NaN / Infinity por división entre cero.
|
|
131
|
+
*
|
|
132
|
+
* @param changed - Mapa de propiedades reactivas que detonaron la actualización.
|
|
130
133
|
*/
|
|
131
134
|
override willUpdate(changed: Map<string, unknown>) {
|
|
132
135
|
if (changed.has('value') || changed.has('max') || changed.has('indeterminate')) {
|
|
@@ -263,6 +266,13 @@ export class MoniProgress extends MoniElement {
|
|
|
263
266
|
`
|
|
264
267
|
];
|
|
265
268
|
|
|
269
|
+
/**
|
|
270
|
+
* Motor de Renderizado: Linear Progress Bar.
|
|
271
|
+
*
|
|
272
|
+
* Renderiza un contenedor horizontal clásico. Pasa el porcentaje computado
|
|
273
|
+
* como variable CSS `--_p` para que el navegador lo interpole usando `transform: scaleX`.
|
|
274
|
+
* Expone los atributos ARIA completos para lectores de pantalla.
|
|
275
|
+
*/
|
|
266
276
|
private _renderLinear() {
|
|
267
277
|
const isIndet = this.indeterminate;
|
|
268
278
|
return html`
|
|
@@ -280,6 +290,13 @@ export class MoniProgress extends MoniElement {
|
|
|
280
290
|
`;
|
|
281
291
|
}
|
|
282
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Motor de Renderizado: Wavy Progress Bar (Estilo BeerCSS/Material You).
|
|
295
|
+
*
|
|
296
|
+
* Utiliza un `<svg>` con una animación de `clip-path` y ondas sinusoidales
|
|
297
|
+
* inyectadas directamente. Ajusta matemáticamente el ancho y la posición de la onda
|
|
298
|
+
* dependiendo de si está en modo indeterminado (infinito) o con un progreso específico (`_pct`).
|
|
299
|
+
*/
|
|
283
300
|
private _renderWavy() {
|
|
284
301
|
// BeerCSS wavy uses an SVG mask. We replicate with an SVG clipPath wave.
|
|
285
302
|
const isIndet = this.indeterminate;
|
|
@@ -337,6 +354,15 @@ export class MoniProgress extends MoniElement {
|
|
|
337
354
|
`;
|
|
338
355
|
}
|
|
339
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Algoritmo de renderizado para el spinner circular.
|
|
359
|
+
* Utiliza la técnica de SVG `stroke-dasharray` y `stroke-dashoffset` para animar o
|
|
360
|
+
* fijar el arco de progreso sin utilizar gradientes CSS cónicos (mejor compatibilidad).
|
|
361
|
+
*
|
|
362
|
+
* Matemáticas del círculo:
|
|
363
|
+
* Perímetro = 2 * π * radio.
|
|
364
|
+
* Para r=20, Perímetro ≈ 125.66. El porcentaje vacío se resta para desplazar (offset) el trazo.
|
|
365
|
+
*/
|
|
340
366
|
private _renderCircular(withWavy = false) {
|
|
341
367
|
const isIndet = this.indeterminate;
|
|
342
368
|
// SVG circle math: r=20, circumference = 2π*20 ≈ 125.66
|
|
@@ -389,9 +415,27 @@ export class MoniProgress extends MoniElement {
|
|
|
389
415
|
`;
|
|
390
416
|
}
|
|
391
417
|
|
|
392
|
-
/**
|
|
418
|
+
/** ID único por instancia para los IDs de SVG clipPath */
|
|
393
419
|
private readonly _instanceId = Math.random().toString(36).slice(2, 8);
|
|
394
420
|
|
|
421
|
+
/**
|
|
422
|
+
* Despacha el renderizado al sub-renderizador privado apropiado basado en `variant`.
|
|
423
|
+
*
|
|
424
|
+
* **¿Por qué sub-renderizadores separados?**
|
|
425
|
+
* Cada variante de progreso tiene una estructura DOM fundamentalmente diferente:
|
|
426
|
+
* - Lineal: un `<div>` con un `<div>` de llenado escalado por una propiedad personalizada CSS.
|
|
427
|
+
* - Wavy (Ondulado): un `<svg>` con un `<clipPath>` animado para la máscara de onda sinusoidal.
|
|
428
|
+
* - Circular: un `<svg>` con `stroke-dasharray`/`stroke-dashoffset` para el arco.
|
|
429
|
+
*
|
|
430
|
+
* Fusionar los tres en una sola plantilla crearía un marcado profundamente condicional;
|
|
431
|
+
* dividir en `_renderLinear()`, `_renderWavy()` y `_renderCircular()` mantiene
|
|
432
|
+
* cada variante auto-contenida y permite una exposición específica de `@csspart` por variante.
|
|
433
|
+
*
|
|
434
|
+
* **`_instanceId`:**
|
|
435
|
+
* Los IDs de `<clipPath>` SVG deben ser únicos por documento; `_instanceId` es un
|
|
436
|
+
* sufijo aleatorio generado una vez en el momento de la instanciación para evitar colisiones de IDs cuando
|
|
437
|
+
* hay múltiples elementos `<moni-progress>` en la misma página.
|
|
438
|
+
*/
|
|
395
439
|
override render() {
|
|
396
440
|
switch (this.variant) {
|
|
397
441
|
case 'circular':
|
|
@@ -14,7 +14,7 @@ describe('moni-radio', () => {
|
|
|
14
14
|
el.remove();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it('
|
|
17
|
+
it('renderiza un input y un span para el estilo visual', async () => {
|
|
18
18
|
await el.updateComplete;
|
|
19
19
|
const input = el.shadowRoot?.querySelector('input');
|
|
20
20
|
const span = el.shadowRoot?.querySelector('span');
|
|
@@ -22,7 +22,7 @@ describe('moni-radio', () => {
|
|
|
22
22
|
expect(span).toBeTruthy();
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
it('
|
|
25
|
+
it('reenvía el estado checked al input', async () => {
|
|
26
26
|
el.checked = true;
|
|
27
27
|
await el.updateComplete;
|
|
28
28
|
const input = el.shadowRoot?.querySelector(
|
|
@@ -35,7 +35,7 @@ describe('moni-radio', () => {
|
|
|
35
35
|
expect(input.checked).toBe(false);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
it('input
|
|
38
|
+
it('el input está contenido en el label (para el manejo de clics)', async () => {
|
|
39
39
|
await el.updateComplete;
|
|
40
40
|
const input = el.shadowRoot?.querySelector(
|
|
41
41
|
'input'
|
|
@@ -44,14 +44,14 @@ describe('moni-radio', () => {
|
|
|
44
44
|
expect(label?.contains(input)).toBe(true);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
it('
|
|
47
|
+
it('renderiza un span de label cuando se establece el atributo label', async () => {
|
|
48
48
|
el.label = 'Option A';
|
|
49
49
|
await el.updateComplete;
|
|
50
50
|
const span = el.shadowRoot?.querySelector('span');
|
|
51
51
|
expect(span?.textContent?.trim()).toBe('Option A');
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
it('
|
|
54
|
+
it('reenvía disabled al input', async () => {
|
|
55
55
|
el.disabled = true;
|
|
56
56
|
await el.updateComplete;
|
|
57
57
|
const input = el.shadowRoot?.querySelector(
|
|
@@ -60,13 +60,13 @@ describe('moni-radio', () => {
|
|
|
60
60
|
expect(input.disabled).toBe(true);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
it('
|
|
63
|
+
it('refleja el atributo checked', async () => {
|
|
64
64
|
el.checked = true;
|
|
65
65
|
await el.updateComplete;
|
|
66
66
|
expect(el.hasAttribute('checked')).toBe(true);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
it('
|
|
69
|
+
it('reenvía name al input', async () => {
|
|
70
70
|
el.name = 'group1';
|
|
71
71
|
await el.updateComplete;
|
|
72
72
|
const input = el.shadowRoot?.querySelector(
|
|
@@ -75,7 +75,7 @@ describe('moni-radio', () => {
|
|
|
75
75
|
expect(input.name).toBe('group1');
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
it('
|
|
78
|
+
it('reenvía value al input', async () => {
|
|
79
79
|
el.value = 'a';
|
|
80
80
|
await el.updateComplete;
|
|
81
81
|
const input = el.shadowRoot?.querySelector(
|
|
@@ -12,73 +12,81 @@ import { live } from 'lit/directives/live.js';
|
|
|
12
12
|
import { MoniElement, sharedStyles } from './_base/index.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Material Design 3 Radio Button
|
|
15
|
+
* Componente Material Design 3 Radio Button (Botón de Opción).
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `<moni-checkbox>`
|
|
17
|
+
* Los botones de opción permiten a los usuarios seleccionar exactamente un elemento de un conjunto de opciones
|
|
18
|
+
* mutuamente excluyentes. Comparten la misma arquitectura visual que
|
|
19
|
+
* `<moni-checkbox>` pero usan `type="radio"` e implementan la deselección de grupo.
|
|
20
20
|
*
|
|
21
|
-
* **
|
|
21
|
+
* **Referencia a la especificación M3:** `m3-docs/components/radio/specs.md`
|
|
22
22
|
*
|
|
23
|
-
* **
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* - `::before` —
|
|
28
|
-
* - `::after` —
|
|
23
|
+
* **Arquitectura visual (Patrón BeerCSS):**
|
|
24
|
+
* Idéntico al patrón de checkbox: el `<input type="radio">` nativo ocupa
|
|
25
|
+
* espacio de diseño real a `--_size` × `--_size` pero se oculta mediante `opacity: 0`.
|
|
26
|
+
* Un `<span>` hermano renderiza:
|
|
27
|
+
* - `::before` — el icono de radio (`radio_button_unchecked` / `radio_button_checked`).
|
|
28
|
+
* - `::after` — el anillo de onda (ripple) de hover/foco.
|
|
29
29
|
*
|
|
30
|
-
* **
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
30
|
+
* **Deselección de grupo:**
|
|
31
|
+
* Cuando se marca un radio, `_onChange` consulta el `getRootNode()` del componente
|
|
32
|
+
* para encontrar todos los elementos `moni-radio` que comparten el mismo atributo `name` y establece
|
|
33
|
+
* su propiedad `checked` en `false`. Esto refleja el comportamiento nativo del navegador
|
|
34
|
+
* para grupos de radio a través de los límites del shadow DOM, donde la agrupación por `name` no
|
|
35
|
+
* funciona de forma nativa.
|
|
36
36
|
*
|
|
37
|
-
* @fires change -
|
|
38
|
-
*
|
|
37
|
+
* @fires change - Burbujea y está compuesto. Se dispara cuando este radio es seleccionado.
|
|
38
|
+
* Lee `element.checked` para obtener el nuevo estado.
|
|
39
39
|
*
|
|
40
40
|
* @example
|
|
41
41
|
* ```html
|
|
42
|
-
* <moni-radio name="color" value="red" label="
|
|
43
|
-
* <moni-radio name="color" value="green" label="
|
|
44
|
-
* <moni-radio name="color" value="blue" label="
|
|
42
|
+
* <moni-radio name="color" value="red" label="Rojo"></moni-radio>
|
|
43
|
+
* <moni-radio name="color" value="green" label="Verde"></moni-radio>
|
|
44
|
+
* <moni-radio name="color" value="blue" label="Azul" checked></moni-radio>
|
|
45
45
|
* ```
|
|
46
46
|
*
|
|
47
|
-
* @csspart radio -
|
|
47
|
+
* @csspart radio - El elemento `<label>` exterior.
|
|
48
48
|
*/
|
|
49
49
|
@customElement('moni-radio')
|
|
50
50
|
export class MoniRadio extends MoniElement {
|
|
51
|
+
static formAssociated = true;
|
|
52
|
+
private _internals: ElementInternals;
|
|
53
|
+
|
|
54
|
+
constructor() {
|
|
55
|
+
super();
|
|
56
|
+
this._internals = this.attachInternals();
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
/**
|
|
52
|
-
*
|
|
60
|
+
* Etiqueta de texto mostrada a la derecha del icono de radio.
|
|
53
61
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
62
|
+
* Cuando no está vacía, se renderiza como un nodo de texto. Cuando está vacía, se renderiza la ranura (slot)
|
|
63
|
+
* por defecto, permitiendo contenido HTML en la ranura como etiqueta.
|
|
56
64
|
*
|
|
57
65
|
* @default ''
|
|
58
66
|
*/
|
|
59
67
|
@property({ reflect: true }) label = '';
|
|
60
68
|
|
|
61
69
|
/**
|
|
62
|
-
*
|
|
70
|
+
* Indica si este botón de opción está actualmente seleccionado.
|
|
63
71
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
72
|
+
* Se refleja como un atributo para que los selectores CSS puedan apuntarlo. Se sincroniza con
|
|
73
|
+
* el input nativo a través de `updated()`.
|
|
66
74
|
*
|
|
67
75
|
* @default false
|
|
68
76
|
*/
|
|
69
77
|
@property({ type: Boolean, reflect: true }) checked = false;
|
|
70
78
|
|
|
71
79
|
/**
|
|
72
|
-
*
|
|
80
|
+
* Cuando es `true`, el radio no es interactivo y se renderiza a un 50% de opacidad.
|
|
73
81
|
*
|
|
74
82
|
* @default false
|
|
75
83
|
*/
|
|
76
84
|
@property({ type: Boolean, reflect: true }) disabled = false;
|
|
77
85
|
|
|
78
86
|
/**
|
|
79
|
-
*
|
|
87
|
+
* Tamaño visual del icono de radio y su área de interacción (hit area) invisible.
|
|
80
88
|
*
|
|
81
|
-
* |
|
|
89
|
+
* | Valor | `--_size` |
|
|
82
90
|
* |------------|-----------|
|
|
83
91
|
* | `'small'` | 1rem |
|
|
84
92
|
* | `'medium'` | 1.5rem |
|
|
@@ -91,36 +99,39 @@ export class MoniRadio extends MoniElement {
|
|
|
91
99
|
size: 'small' | 'medium' | 'large' | 'extra' = 'medium';
|
|
92
100
|
|
|
93
101
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
102
|
+
* Nombre del grupo de radio. Los radios con el mismo `name` en el mismo nodo raíz
|
|
103
|
+
* se tratan como un grupo de exclusión mutua por `_onChange`.
|
|
96
104
|
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
105
|
+
* Nota: Los grupos nativos de `<input type="radio">` solo funcionan dentro de la misma
|
|
106
|
+
* raíz de documento. Dado que `moni-radio` usa shadow DOM, la deselección
|
|
107
|
+
* de los hermanos se maneja imperativamente en `_onChange`.
|
|
100
108
|
*
|
|
101
109
|
* @default ''
|
|
102
110
|
*/
|
|
103
111
|
@property({ reflect: true }) name = '';
|
|
104
112
|
|
|
105
113
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
114
|
+
* Se retransmite al atributo nativo `<input value>`.
|
|
115
|
+
* El valor enviado en un formulario cuando este radio es seleccionado.
|
|
108
116
|
*
|
|
109
117
|
* @default ''
|
|
110
118
|
*/
|
|
111
119
|
@property({ reflect: true }) value = '';
|
|
112
120
|
|
|
113
|
-
/**
|
|
121
|
+
/** Referencia directa al elemento input nativo para acceso programático. */
|
|
114
122
|
@query('input') private _input!: HTMLInputElement;
|
|
115
123
|
|
|
116
124
|
/**
|
|
117
|
-
*
|
|
125
|
+
* Sincroniza `checked` y `disabled` con el input nativo después de cada ciclo de renderizado.
|
|
118
126
|
*
|
|
119
|
-
* @param changed -
|
|
127
|
+
* @param changed - Mapa de los nombres de propiedades modificadas con sus valores anteriores.
|
|
120
128
|
*/
|
|
121
129
|
override updated(changed: Map<string, unknown>) {
|
|
122
130
|
if (this._input) {
|
|
123
|
-
if (changed.has('checked'))
|
|
131
|
+
if (changed.has('checked')) {
|
|
132
|
+
this._input.checked = this.checked;
|
|
133
|
+
this._internals?.setFormValue?.(this.checked ? (this.value || 'on') : null);
|
|
134
|
+
}
|
|
124
135
|
if (changed.has('disabled')) this._input.disabled = this.disabled;
|
|
125
136
|
}
|
|
126
137
|
}
|
|
@@ -238,17 +249,17 @@ export class MoniRadio extends MoniElement {
|
|
|
238
249
|
];
|
|
239
250
|
|
|
240
251
|
/**
|
|
241
|
-
*
|
|
252
|
+
* Maneja el evento nativo `change` del input.
|
|
242
253
|
*
|
|
243
|
-
*
|
|
244
|
-
* `name`
|
|
245
|
-
*
|
|
246
|
-
*
|
|
254
|
+
* Al seleccionarse, deselecciona todos los elementos `moni-radio` hermanos con el mismo
|
|
255
|
+
* `name` en el mismo nodo raíz (documento o raíz shadow). Esto es necesario
|
|
256
|
+
* porque la exclusión de grupo de radio nativa solo funciona dentro de la misma raíz
|
|
257
|
+
* de documento y no cruza los límites del shadow DOM.
|
|
247
258
|
*
|
|
248
|
-
*
|
|
249
|
-
* audible
|
|
259
|
+
* Después de la deselección, despacha un evento `'change'` compuesto para que sea
|
|
260
|
+
* audible para los elementos padres en el DOM ligero (light DOM).
|
|
250
261
|
*
|
|
251
|
-
* @param e -
|
|
262
|
+
* @param e - El evento nativo `change` del `<input>` oculto.
|
|
252
263
|
*/
|
|
253
264
|
private _onChange(e: Event) {
|
|
254
265
|
this.checked = (e.target as HTMLInputElement).checked;
|
|
@@ -266,6 +277,15 @@ export class MoniRadio extends MoniElement {
|
|
|
266
277
|
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
267
278
|
}
|
|
268
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Renderiza el radio como un `<input type="radio">` oculto + indicador visual `<span>`.
|
|
282
|
+
*
|
|
283
|
+
* El input oculto se mantiene en el DOM (opacity: 0) para participar en el envío nativo
|
|
284
|
+
* de formularios y exclusión de grupo de radios. Los navegadores aplican automáticamente
|
|
285
|
+
* exclusión mutua entre entradas de radio que comparten el mismo atributo `name`.
|
|
286
|
+
* El círculo visual es dibujado por los pseudo-elementos `::before` / `::after` en
|
|
287
|
+
* el `<span>` y animado mediante transiciones CSS de `scale`.
|
|
288
|
+
*/
|
|
269
289
|
override render() {
|
|
270
290
|
return html`<label part="radio">
|
|
271
291
|
<input
|