@moni-labs/moni-ui 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/custom-elements.json +5181 -1043
  2. package/dist/components/_base/moni-element.d.ts +16 -9
  3. package/dist/components/_base/moni-element.d.ts.map +1 -1
  4. package/dist/components/_base/moni-element.js +63 -9
  5. package/dist/components/index.js +2 -2
  6. package/dist/components/loading-shapes.d.ts +19 -0
  7. package/dist/components/loading-shapes.d.ts.map +1 -1
  8. package/dist/components/loading-shapes.js +19 -0
  9. package/dist/components/moni-app-bar.d.ts +72 -62
  10. package/dist/components/moni-app-bar.d.ts.map +1 -1
  11. package/dist/components/moni-app-bar.js +72 -62
  12. package/dist/components/moni-badge.d.ts +64 -65
  13. package/dist/components/moni-badge.d.ts.map +1 -1
  14. package/dist/components/moni-badge.js +64 -66
  15. package/dist/components/moni-bottom-sheet.d.ts +129 -61
  16. package/dist/components/moni-bottom-sheet.d.ts.map +1 -1
  17. package/dist/components/moni-bottom-sheet.js +217 -131
  18. package/dist/components/moni-button-group.d.ts +107 -29
  19. package/dist/components/moni-button-group.d.ts.map +1 -1
  20. package/dist/components/moni-button-group.js +107 -29
  21. package/dist/components/moni-button-segment.d.ts +53 -12
  22. package/dist/components/moni-button-segment.d.ts.map +1 -1
  23. package/dist/components/moni-button-segment.js +53 -12
  24. package/dist/components/moni-button.d.ts +116 -38
  25. package/dist/components/moni-button.d.ts.map +1 -1
  26. package/dist/components/moni-button.js +128 -38
  27. package/dist/components/moni-card.d.ts +68 -50
  28. package/dist/components/moni-card.d.ts.map +1 -1
  29. package/dist/components/moni-card.js +68 -50
  30. package/dist/components/moni-carousel.d.ts +471 -53
  31. package/dist/components/moni-carousel.d.ts.map +1 -1
  32. package/dist/components/moni-carousel.js +862 -264
  33. package/dist/components/moni-checkbox.d.ts +49 -46
  34. package/dist/components/moni-checkbox.d.ts.map +1 -1
  35. package/dist/components/moni-checkbox.js +55 -48
  36. package/dist/components/moni-chip.d.ts +100 -33
  37. package/dist/components/moni-chip.d.ts.map +1 -1
  38. package/dist/components/moni-chip.js +104 -34
  39. package/dist/components/moni-color-field.d.ts +99 -24
  40. package/dist/components/moni-color-field.d.ts.map +1 -1
  41. package/dist/components/moni-color-field.js +99 -24
  42. package/dist/components/moni-context-menu.d.ts +72 -26
  43. package/dist/components/moni-context-menu.d.ts.map +1 -1
  44. package/dist/components/moni-context-menu.js +76 -30
  45. package/dist/components/moni-dialog.d.ts +84 -59
  46. package/dist/components/moni-dialog.d.ts.map +1 -1
  47. package/dist/components/moni-dialog.js +105 -58
  48. package/dist/components/moni-divider.d.ts +39 -27
  49. package/dist/components/moni-divider.d.ts.map +1 -1
  50. package/dist/components/moni-divider.js +42 -30
  51. package/dist/components/moni-expansion.d.ts +32 -22
  52. package/dist/components/moni-expansion.d.ts.map +1 -1
  53. package/dist/components/moni-expansion.js +32 -22
  54. package/dist/components/moni-fab-menu.d.ts +61 -23
  55. package/dist/components/moni-fab-menu.d.ts.map +1 -1
  56. package/dist/components/moni-fab-menu.js +69 -31
  57. package/dist/components/moni-fab.d.ts +86 -28
  58. package/dist/components/moni-fab.d.ts.map +1 -1
  59. package/dist/components/moni-fab.js +92 -34
  60. package/dist/components/moni-file-field.d.ts +118 -30
  61. package/dist/components/moni-file-field.d.ts.map +1 -1
  62. package/dist/components/moni-file-field.js +118 -30
  63. package/dist/components/moni-icon.d.ts +40 -35
  64. package/dist/components/moni-icon.d.ts.map +1 -1
  65. package/dist/components/moni-icon.js +43 -38
  66. package/dist/components/moni-list-item.d.ts +46 -33
  67. package/dist/components/moni-list-item.d.ts.map +1 -1
  68. package/dist/components/moni-list-item.js +61 -41
  69. package/dist/components/moni-list.d.ts +30 -20
  70. package/dist/components/moni-list.d.ts.map +1 -1
  71. package/dist/components/moni-list.js +36 -21
  72. package/dist/components/moni-loading-indicator.d.ts +54 -22
  73. package/dist/components/moni-loading-indicator.d.ts.map +1 -1
  74. package/dist/components/moni-loading-indicator.js +54 -22
  75. package/dist/components/moni-menu-item.d.ts +23 -16
  76. package/dist/components/moni-menu-item.d.ts.map +1 -1
  77. package/dist/components/moni-menu-item.js +23 -16
  78. package/dist/components/moni-menu.d.ts +81 -28
  79. package/dist/components/moni-menu.d.ts.map +1 -1
  80. package/dist/components/moni-menu.js +81 -30
  81. package/dist/components/moni-morph-modal.d.ts +141 -0
  82. package/dist/components/moni-morph-modal.d.ts.map +1 -1
  83. package/dist/components/moni-morph-modal.js +295 -58
  84. package/dist/components/moni-nav-item.d.ts +59 -29
  85. package/dist/components/moni-nav-item.d.ts.map +1 -1
  86. package/dist/components/moni-nav-item.js +59 -29
  87. package/dist/components/moni-nav.d.ts +94 -35
  88. package/dist/components/moni-nav.d.ts.map +1 -1
  89. package/dist/components/moni-nav.js +94 -35
  90. package/dist/components/moni-progress.d.ts +99 -55
  91. package/dist/components/moni-progress.d.ts.map +1 -1
  92. package/dist/components/moni-progress.js +99 -55
  93. package/dist/components/moni-radio.d.ts +62 -50
  94. package/dist/components/moni-radio.d.ts.map +1 -1
  95. package/dist/components/moni-radio.js +65 -52
  96. package/dist/components/moni-ripple.d.ts +74 -59
  97. package/dist/components/moni-ripple.d.ts.map +1 -1
  98. package/dist/components/moni-ripple.js +74 -59
  99. package/dist/components/moni-segmented-button.d.ts +91 -16
  100. package/dist/components/moni-segmented-button.d.ts.map +1 -1
  101. package/dist/components/moni-segmented-button.js +94 -17
  102. package/dist/components/moni-select-option.d.ts +30 -23
  103. package/dist/components/moni-select-option.d.ts.map +1 -1
  104. package/dist/components/moni-select-option.js +30 -23
  105. package/dist/components/moni-select.d.ts +300 -35
  106. package/dist/components/moni-select.d.ts.map +1 -1
  107. package/dist/components/moni-select.js +323 -39
  108. package/dist/components/moni-side-sheet.d.ts +94 -32
  109. package/dist/components/moni-side-sheet.d.ts.map +1 -1
  110. package/dist/components/moni-side-sheet.js +94 -32
  111. package/dist/components/moni-slider.d.ts +152 -41
  112. package/dist/components/moni-slider.d.ts.map +1 -1
  113. package/dist/components/moni-slider.js +154 -42
  114. package/dist/components/moni-snackbar.d.ts +53 -43
  115. package/dist/components/moni-snackbar.d.ts.map +1 -1
  116. package/dist/components/moni-snackbar.js +53 -43
  117. package/dist/components/moni-split-button.d.ts +63 -18
  118. package/dist/components/moni-split-button.d.ts.map +1 -1
  119. package/dist/components/moni-split-button.js +63 -18
  120. package/dist/components/moni-step.d.ts +36 -24
  121. package/dist/components/moni-step.d.ts.map +1 -1
  122. package/dist/components/moni-step.js +41 -29
  123. package/dist/components/moni-stepper.d.ts +64 -27
  124. package/dist/components/moni-stepper.d.ts.map +1 -1
  125. package/dist/components/moni-stepper.js +72 -34
  126. package/dist/components/moni-switch.d.ts +57 -46
  127. package/dist/components/moni-switch.d.ts.map +1 -1
  128. package/dist/components/moni-switch.js +59 -47
  129. package/dist/components/moni-tab.d.ts +26 -18
  130. package/dist/components/moni-tab.d.ts.map +1 -1
  131. package/dist/components/moni-tab.js +29 -21
  132. package/dist/components/moni-tabs.d.ts +34 -28
  133. package/dist/components/moni-tabs.d.ts.map +1 -1
  134. package/dist/components/moni-tabs.js +34 -28
  135. package/dist/components/moni-text-field.d.ts +139 -29
  136. package/dist/components/moni-text-field.d.ts.map +1 -1
  137. package/dist/components/moni-text-field.js +157 -31
  138. package/dist/components/moni-textarea.d.ts +127 -29
  139. package/dist/components/moni-textarea.d.ts.map +1 -1
  140. package/dist/components/moni-textarea.js +131 -32
  141. package/dist/components/moni-time-picker.d.ts +114 -24
  142. package/dist/components/moni-time-picker.d.ts.map +1 -1
  143. package/dist/components/moni-time-picker.js +127 -33
  144. package/dist/components/moni-toolbar.d.ts +37 -23
  145. package/dist/components/moni-toolbar.d.ts.map +1 -1
  146. package/dist/components/moni-toolbar.js +37 -23
  147. package/dist/components/moni-tooltip.d.ts +100 -36
  148. package/dist/components/moni-tooltip.d.ts.map +1 -1
  149. package/dist/components/moni-tooltip.js +104 -40
  150. package/dist/components/moni-typography.d.ts +68 -30
  151. package/dist/components/moni-typography.d.ts.map +1 -1
  152. package/dist/components/moni-typography.js +70 -32
  153. package/dist/styles/tokens.css +7 -7
  154. package/dist/types/events.d.ts +17 -0
  155. package/dist/types/events.d.ts.map +1 -0
  156. package/dist/types/events.js +1 -0
  157. package/dist/utils/event-emitter.d.ts +13 -0
  158. package/dist/utils/event-emitter.d.ts.map +1 -0
  159. package/dist/utils/event-emitter.js +13 -0
  160. package/package.json +2 -1
  161. package/src/components/_base/moni-element.ts +73 -9
  162. package/src/components/index.ts +2 -2
  163. package/src/components/loading-shapes.ts +19 -0
  164. package/src/components/moni-app-bar.test.ts +10 -10
  165. package/src/components/moni-app-bar.ts +72 -62
  166. package/src/components/moni-badge.ts +64 -66
  167. package/src/components/moni-bottom-sheet.test.ts +39 -45
  168. package/src/components/moni-bottom-sheet.ts +222 -131
  169. package/src/components/moni-button-group.test.ts +14 -14
  170. package/src/components/moni-button-group.ts +107 -29
  171. package/src/components/moni-button-segment.ts +53 -12
  172. package/src/components/moni-button.test.ts +28 -26
  173. package/src/components/moni-button.ts +139 -39
  174. package/src/components/moni-card.test.ts +6 -6
  175. package/src/components/moni-card.ts +70 -50
  176. package/src/components/moni-carousel.test.ts +12 -12
  177. package/src/components/moni-carousel.ts +953 -290
  178. package/src/components/moni-checkbox.test.ts +7 -7
  179. package/src/components/moni-checkbox.ts +62 -48
  180. package/src/components/moni-chip.test.ts +17 -17
  181. package/src/components/moni-chip.ts +112 -34
  182. package/src/components/moni-color-field.test.ts +5 -5
  183. package/src/components/moni-color-field.ts +108 -24
  184. package/src/components/moni-context-menu.test.ts +11 -11
  185. package/src/components/moni-context-menu.ts +76 -30
  186. package/src/components/moni-dialog.ts +108 -59
  187. package/src/components/moni-divider.test.ts +4 -4
  188. package/src/components/moni-divider.ts +42 -30
  189. package/src/components/moni-expansion.ts +32 -22
  190. package/src/components/moni-fab-menu.test.ts +11 -11
  191. package/src/components/moni-fab-menu.ts +69 -31
  192. package/src/components/moni-fab.test.ts +16 -16
  193. package/src/components/moni-fab.ts +100 -34
  194. package/src/components/moni-file-field.test.ts +8 -8
  195. package/src/components/moni-file-field.ts +132 -30
  196. package/src/components/moni-icon.test.ts +11 -11
  197. package/src/components/moni-icon.ts +43 -38
  198. package/src/components/moni-list-item.test.ts +10 -10
  199. package/src/components/moni-list-item.ts +61 -41
  200. package/src/components/moni-list.ts +37 -21
  201. package/src/components/moni-loading-indicator.test.ts +3 -3
  202. package/src/components/moni-loading-indicator.ts +54 -22
  203. package/src/components/moni-menu-item.ts +23 -16
  204. package/src/components/moni-menu.test.ts +7 -7
  205. package/src/components/moni-menu.ts +87 -30
  206. package/src/components/moni-morph-modal.test.ts +18 -17
  207. package/src/components/moni-morph-modal.ts +327 -60
  208. package/src/components/moni-nav-item.ts +59 -29
  209. package/src/components/moni-nav.test.ts +11 -11
  210. package/src/components/moni-nav.ts +94 -35
  211. package/src/components/moni-progress.test.ts +9 -9
  212. package/src/components/moni-progress.ts +100 -56
  213. package/src/components/moni-radio.test.ts +8 -8
  214. package/src/components/moni-radio.ts +71 -51
  215. package/src/components/moni-ripple.ts +74 -59
  216. package/src/components/moni-segmented-button.test.ts +4 -4
  217. package/src/components/moni-segmented-button.ts +94 -17
  218. package/src/components/moni-select-option.ts +30 -23
  219. package/src/components/moni-select.test.ts +11 -11
  220. package/src/components/moni-select.ts +361 -50
  221. package/src/components/moni-side-sheet.test.ts +7 -7
  222. package/src/components/moni-side-sheet.ts +94 -32
  223. package/src/components/moni-slider.test.ts +7 -7
  224. package/src/components/moni-slider.ts +165 -42
  225. package/src/components/moni-snackbar.test.ts +8 -8
  226. package/src/components/moni-snackbar.ts +53 -43
  227. package/src/components/moni-split-button.ts +63 -18
  228. package/src/components/moni-step.test.ts +7 -7
  229. package/src/components/moni-step.ts +41 -29
  230. package/src/components/moni-stepper.test.ts +7 -7
  231. package/src/components/moni-stepper.ts +72 -34
  232. package/src/components/moni-switch.test.ts +12 -12
  233. package/src/components/moni-switch.ts +66 -47
  234. package/src/components/moni-tab.test.ts +5 -5
  235. package/src/components/moni-tab.ts +29 -21
  236. package/src/components/moni-tabs.ts +34 -28
  237. package/src/components/moni-text-field.test.ts +13 -13
  238. package/src/components/moni-text-field.ts +181 -30
  239. package/src/components/moni-textarea.test.ts +17 -17
  240. package/src/components/moni-textarea.ts +155 -31
  241. package/src/components/moni-time-picker.test.ts +5 -5
  242. package/src/components/moni-time-picker.ts +128 -33
  243. package/src/components/moni-toolbar.test.ts +8 -8
  244. package/src/components/moni-toolbar.ts +37 -23
  245. package/src/components/moni-tooltip.test.ts +15 -15
  246. package/src/components/moni-tooltip.ts +107 -40
  247. package/src/components/moni-typography.test.ts +10 -10
  248. package/src/components/moni-typography.ts +73 -32
  249. package/src/styles/tokens.css +7 -7
  250. package/src/types/events.ts +17 -0
  251. 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 component.
13
+ * Componente Material Design 3 Progress Indicator (Indicador de Progreso).
14
14
  *
15
- * Progress indicators express an unspecified wait time or display the length
16
- * of a process. They inform users about the status of ongoing processes such
17
- * as loading an app, submitting a form, or saving updates.
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
- * **M3 spec reference:** `m3-docs/components/progress-indicators/specs.md`
19
+ * **Referencia a la especificación M3:** `m3-docs/components/progress-indicators/specs.md`
20
20
  *
21
- * **Variants:**
22
- * - `linear` (default) — A horizontal bar that fills left-to-right.
23
- * - `circular` — A circular SVG stroke indicator.
24
- * - `wavy` — An animated wave bar (Moni extension; not in M3 spec).
25
- * - `circular-wavy` — Circular + wave combo (Moni extension).
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 compatibility note:**
28
- * BeerCSS's progress uses native `<progress>` pseudo-elements (`::before`,
29
- * `::after`, `::webkit-progress-value`) and `mask-image`, which are blocked
30
- * by the UA shadow root in Chrome/Firefox. This component uses a plain `<div>`
31
- * wrapper that replicates the visual rules exactly, and an `<svg>` element
32
- * for the circular variant using SVG stroke-dashoffset animation for superior
33
- * cross-browser support compared to `conic-gradient`.
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
- * **Percentage computation:**
36
- * `_pct` is computed in `willUpdate()` as `(value / max) * 100`, clamped to
37
- * `[0, 100]`. When `indeterminate` is set, `_pct` is fixed at `50` to drive
38
- * the infinite loop animation.
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
- * <!-- Determinate linear progress -->
42
+ * <!-- Progreso lineal determinado -->
43
43
  * <moni-progress value="65" max="100"></moni-progress>
44
44
  *
45
- * <!-- Indeterminate circular progress (loading spinner) -->
45
+ * <!-- Progreso circular indeterminado (spinner de carga) -->
46
46
  * <moni-progress variant="circular" indeterminate></moni-progress>
47
47
  * ```
48
48
  *
49
- * @csspart bar - The outer container div.
50
- * @csspart fill - The inner fill element (linear variant).
51
- * @csspart svg - The SVG element (circular variant).
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
- * Current progress value.
56
+ * Valor de progreso actual.
57
57
  *
58
- * Must be in the range `[0, max]`. Values outside this range are clamped
59
- * during percentage computation in `willUpdate()`. Ignored when
60
- * `indeterminate` is set.
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
- * Maximum value of the progress range.
67
+ * Valor máximo del rango de progreso.
68
68
  *
69
- * Defaults to `100` so `value` can be set as a percentage directly.
70
- * For non-percentage ranges (e.g. steps), set `max` to the total step count
71
- * and `value` to the current step.
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
- * Visual variant of the progress indicator.
78
+ * Variante visual del indicador de progreso.
79
79
  *
80
- * - `'linear'` (default) — Horizontal fill bar.
81
- * - `'circular'` — SVG circle with stroke-dashoffset animation.
82
- * - `'wavy'` — Animated wave bar.
83
- * - `'circular-wavy'` — Combination of circular and wave.
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
- * Visual size of the progress indicator.
91
+ * Tamaño visual del indicador de progreso.
92
92
  *
93
- * - `'small'` — Compact; suitable for inline or tight layouts.
94
- * - `'medium'` — Standard M3 size (default).
95
- * - `'large'` — Prominent; for full-page loading states.
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
- * When `true`, the indicator animates in an infinite loop regardless of `value`.
103
+ * Cuando es `true`, el indicador se anima en un bucle infinito independientemente del `value`.
104
104
  *
105
- * Use for operations where the completion percentage is unknown
106
- * (e.g. network requests, file processing). When `indeterminate` is set,
107
- * `_pct` is fixed at `50` to drive a continuous sweep animation.
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
- * Computed fill percentage in the range `[0, 100]`.
114
+ * Porcentaje de llenado calculado en el rango `[0, 100]`.
115
115
  *
116
- * Updated in `willUpdate()` whenever `value`, `max`, or `indeterminate` changes.
117
- * Used directly in CSS custom property bindings and SVG stroke attributes.
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
- * Computes the fill percentage before each render.
124
+ * Hook de ciclo de vida de Lit. Calcula la fracción de llenado antes de pintar.
125
125
  *
126
- * Recalculates `_pct` whenever `value`, `max`, or `indeterminate` changes.
127
- * The `Math.max(1, max)` guard prevents division-by-zero when `max` is 0.
128
- *
129
- * @param changed - Map of property names to their previous values.
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
- /** Unique ID per instance for SVG clipPath IDs */
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('renders an input and a span for visual styling', async () => {
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('forwards checked state to the input', async () => {
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 is contained in the label (for click handling)', async () => {
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('renders a label span when label attribute is set', async () => {
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('forwards disabled to the input', async () => {
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('reflects the checked attribute', async () => {
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('forwards name to the input', async () => {
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('forwards value to the input', async () => {
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 component.
15
+ * Componente Material Design 3 Radio Button (Botón de Opción).
16
16
  *
17
- * Radio buttons allow users to select exactly one item from a set of mutually
18
- * exclusive options. They share the same visual architecture as
19
- * `<moni-checkbox>` but use `type="radio"` and implement group deselection.
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
- * **M3 spec reference:** `m3-docs/components/radio/specs.md`
21
+ * **Referencia a la especificación M3:** `m3-docs/components/radio/specs.md`
22
22
  *
23
- * **Visual architecture (BeerCSS pattern):**
24
- * Identical to the checkbox pattern: the native `<input type="radio">` occupies
25
- * real layout space at `--_size` × `--_size` but is hidden via `opacity: 0`.
26
- * A sibling `<span>` renders:
27
- * - `::before` — the radio icon (`radio_button_unchecked` / `radio_button_checked`).
28
- * - `::after` — the hover/focus ripple ring.
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
- * **Group deselection:**
31
- * When a radio is checked, `_onChange` queries the component's `getRootNode()`
32
- * for all `moni-radio` elements sharing the same `name` attribute and sets
33
- * their `checked` property to `false`. This mirrors native browser behavior
34
- * for radio groups across shadow DOM boundaries where `name` grouping does
35
- * not work natively.
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 - Bubbles and is composed. Fired when this radio is selected.
38
- * Read `element.checked` for the new state.
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="Red"></moni-radio>
43
- * <moni-radio name="color" value="green" label="Green"></moni-radio>
44
- * <moni-radio name="color" value="blue" label="Blue" checked></moni-radio>
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 - The outer `<label>` element.
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
- * Text label displayed to the right of the radio icon.
60
+ * Etiqueta de texto mostrada a la derecha del icono de radio.
53
61
  *
54
- * When non-empty, renders as a text node. When empty, the default slot
55
- * is rendered, allowing slotted HTML content as the label.
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
- * Whether this radio button is currently selected.
70
+ * Indica si este botón de opción está actualmente seleccionado.
63
71
  *
64
- * Reflected as an attribute so CSS selectors can target it. Synced to
65
- * the native input via `updated()`.
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
- * When `true`, the radio is non-interactive and renders at 50% opacity.
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
- * Visual size of the radio icon and its invisible hit area.
87
+ * Tamaño visual del icono de radio y su área de interacción (hit area) invisible.
80
88
  *
81
- * | Value | `--_size` |
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
- * Radio group name. Radios with the same `name` in the same root node
95
- * are treated as a mutual-exclusion group by `_onChange`.
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
- * Note: Native `<input type="radio">` groups only work within the same
98
- * document root. Since `moni-radio` uses shadow DOM, the deselection
99
- * of siblings is handled imperatively in `_onChange`.
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
- * Forwarded to the native `<input value>` attribute.
107
- * The value submitted in a form when this radio is selected.
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
- /** Direct reference to the native input element for programmatic access. */
121
+ /** Referencia directa al elemento input nativo para acceso programático. */
114
122
  @query('input') private _input!: HTMLInputElement;
115
123
 
116
124
  /**
117
- * Syncs `checked` and `disabled` to the native input after each render cycle.
125
+ * Sincroniza `checked` y `disabled` con el input nativo después de cada ciclo de renderizado.
118
126
  *
119
- * @param changed - Map of changed property names to their previous values.
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')) this._input.checked = this.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
- * Handles the native input `change` event.
252
+ * Maneja el evento nativo `change` del input.
242
253
  *
243
- * On selection, deselects all sibling `moni-radio` elements with the same
244
- * `name` in the same root node (document or shadow root). This is necessary
245
- * because native radio group exclusion only works within the same document
246
- * root and does not cross shadow DOM boundaries.
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
- * After deselection, dispatches a composed `'change'` event so it is
249
- * audible to parent elements in the light DOM.
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 - The native `change` event from the hidden `<input>`.
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