@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
@@ -12,49 +12,49 @@ import { MoniElement, sharedStyles } from './_base/index.js';
12
12
  import './moni-icon.js';
13
13
 
14
14
  /**
15
- * Material Design 3 Navigation Item component.
15
+ * Componente Material Design 3 Navigation Item (Elemento de Navegación).
16
16
  *
17
- * A single destination item within a `<moni-nav>` container. Renders as an
18
- * accessible `<a>` element with an icon, label, and M3 state layer.
17
+ * Un elemento de destino individual dentro de un contenedor `<moni-nav>`. Se renderiza como un
18
+ * elemento `<a>` accesible con un icono, etiqueta y capa de estado M3.
19
19
  *
20
- * **M3 spec references:**
21
- * - Navigation bar item: `m3-docs/components/navigation-bar/specs.md`
22
- * - Navigation rail item: `m3-docs/components/navigation-rail/specs.md`
23
- * - Navigation drawer item: `m3-docs/components/navigation-drawer/specs.md`
20
+ * **Referencias a la especificación M3:**
21
+ * - Elemento de barra de navegación: `m3-docs/components/navigation-bar/specs.md`
22
+ * - Elemento de riel de navegación: `m3-docs/components/navigation-rail/specs.md`
23
+ * - Elemento de cajón de navegación: `m3-docs/components/navigation-drawer/specs.md`
24
24
  *
25
- * **Layout adaptation:**
26
- * The `placement`, `variant`, and `layout` properties are forwarded from
27
- * the parent `<moni-nav>` (typically via attribute binding in the parent's
28
- * render method). The nav item uses these to conditionally render:
29
- * - Icon + label below (navigation bar).
30
- * - Icon only + horizontal label (rail).
31
- * - Icon + full label (drawer).
25
+ * **Adaptación de diseño:**
26
+ * Las propiedades `placement`, `variant` y `layout` son retransmitidas desde
27
+ * el padre `<moni-nav>` (típicamente a través de vinculación de atributos en el
28
+ * método render del padre). El elemento de navegación las usa para renderizar condicionalmente:
29
+ * - Icono + etiqueta abajo (barra de navegación).
30
+ * - Solo icono + etiqueta horizontal (riel).
31
+ * - Icono + etiqueta completa (cajón).
32
32
  *
33
- * **Responsive behavior:**
34
- * Uses `window.matchMedia('(min-width: 601px)')` to detect medium screens
35
- * and stores the result in `_isMediumScreen`. This drives automatic layout
36
- * switching between bar and rail styles.
33
+ * **Comportamiento responsivo:**
34
+ * Usa `window.matchMedia('(min-width: 601px)')` para detectar pantallas medianas
35
+ * y almacena el resultado en `_isMediumScreen`. Esto impulsa el cambio de diseño
36
+ * automático entre estilos de barra y riel.
37
37
  *
38
- * **Active state:**
39
- * The `active` attribute applies the M3 active indicator: a pill-shaped
40
- * `secondary-container` background behind the icon and a darker label color.
38
+ * **Estado activo:**
39
+ * El atributo `active` aplica el indicador activo M3: un fondo `secondary-container`
40
+ * en forma de píldora detrás del icono y un color de etiqueta más oscuro.
41
41
  *
42
42
  * @example
43
43
  * ```html
44
44
  * <moni-nav placement="bottom">
45
- * <moni-nav-item href="/" icon="home" label="Home" active></moni-nav-item>
46
- * <moni-nav-item href="/search" icon="search" label="Search"></moni-nav-item>
47
- * <moni-nav-item href="/profile" icon="person" label="Profile">
48
- * <moni-badge value="3"></moni-badge> <!-- notification badge -->
45
+ * <moni-nav-item href="/" icon="home" label="Inicio" active></moni-nav-item>
46
+ * <moni-nav-item href="/search" icon="search" label="Buscar"></moni-nav-item>
47
+ * <moni-nav-item href="/profile" icon="person" label="Perfil">
48
+ * <moni-badge value="3"></moni-badge> <!-- insignia de notificación -->
49
49
  * </moni-nav-item>
50
50
  * </moni-nav>
51
51
  * ```
52
52
  *
53
- * @slot default - Additional content slotted after the icon (e.g. `<moni-badge>`).
53
+ * @slot default - Contenido adicional colocado después del icono (ej. `<moni-badge>`).
54
54
  *
55
- * @csspart item - The outer `<a>` element.
56
- * @csspart icon - The icon container.
57
- * @csspart label - The label text element.
55
+ * @csspart item - El elemento exterior `<a>`.
56
+ * @csspart icon - El contenedor del icono.
57
+ * @csspart label - El elemento de texto de la etiqueta.
58
58
  */
59
59
  @customElement('moni-nav-item')
60
60
  export class MoniNavItem extends MoniElement {
@@ -74,6 +74,12 @@ export class MoniNavItem extends MoniElement {
74
74
  ? window.matchMedia('(min-width: 601px)')
75
75
  : null;
76
76
 
77
+ /**
78
+ * Hook de inicialización (Lit).
79
+ * Vincula un listener de `MediaQueryList` nativo para poder reaccionar en tiempo real
80
+ * cuando la pantalla cruza el breakpoint de 600px, adaptando la disposición
81
+ * (horizontal vs vertical) del ícono y la etiqueta automáticamente.
82
+ */
77
83
  override connectedCallback() {
78
84
  super.connectedCallback();
79
85
  if (this._query) {
@@ -82,6 +88,11 @@ export class MoniNavItem extends MoniElement {
82
88
  }
83
89
  }
84
90
 
91
+ /**
92
+ * Hook de destrucción (Lit).
93
+ * Desvincula rigurosamente el listener del `matchMedia` para
94
+ * prevenir fugas de memoria (memory leaks).
95
+ */
85
96
  override disconnectedCallback() {
86
97
  super.disconnectedCallback();
87
98
  if (this._query) {
@@ -89,6 +100,11 @@ export class MoniNavItem extends MoniElement {
89
100
  }
90
101
  }
91
102
 
103
+ /**
104
+ * Callback asíncrono disparado nativamente por el navegador cuando
105
+ * cambian las condiciones del Media Query.
106
+ * Actualiza el estado reactivo `_isMediumScreen` lo que fuerza a Lit a re-renderizar.
107
+ */
92
108
  private _handleQueryChange = (e: MediaQueryListEvent) => {
93
109
  this._isMediumScreen = e.matches;
94
110
  };
@@ -236,6 +252,20 @@ export class MoniNavItem extends MoniElement {
236
252
  `
237
253
  ];
238
254
 
255
+ /**
256
+ * Renderiza el elemento de navegación como un `<a>` o `<button>` con ranura de icono, etiqueta y badge (insignia).
257
+ *
258
+ * **Indicador activo:**
259
+ * La barra de navegación M3 usa un indicador en forma de píldora detrás del icono del
260
+ * elemento activo. Esto se implementa como el pseudo-elemento `::before` en
261
+ * `.item` que crece de `0` a `64px` de ancho usando una transición CSS.
262
+ * La clase `active` en `.item` activa la transición y también establece
263
+ * `aria-current="page"` para lectores de pantalla.
264
+ *
265
+ * **Ranura para badge (insignia):**
266
+ * `[slot="badge"]` se renderiza posicionado absolutamente sobre la esquina superior final del icono.
267
+ * Los consumidores colocan un `<moni-badge>` aquí para cuentas de notificaciones.
268
+ */
239
269
  override render() {
240
270
  const isHorizontal = this.computedLayout === 'horizontal';
241
271
 
@@ -16,7 +16,7 @@ describe('moni-nav / moni-nav-item', () => {
16
16
  el.remove();
17
17
  });
18
18
 
19
- it('renders a <nav> with a slot', async () => {
19
+ it('renderiza un <nav> con un slot', async () => {
20
20
  await el.updateComplete;
21
21
  const nav = el.shadowRoot?.querySelector('nav');
22
22
  const slot = el.shadowRoot?.querySelector('slot');
@@ -24,14 +24,14 @@ describe('moni-nav / moni-nav-item', () => {
24
24
  expect(slot).toBeTruthy();
25
25
  });
26
26
 
27
- it('applies the placement class to the nav', async () => {
27
+ it('aplica la clase de placement al nav', async () => {
28
28
  el.placement = 'bottom';
29
29
  await el.updateComplete;
30
30
  const nav = el.shadowRoot?.querySelector('nav');
31
31
  expect(nav?.classList.contains('bottom')).toBe(true);
32
32
  });
33
33
 
34
- it('applies the variant class (rail/drawer)', async () => {
34
+ it('aplica la clase de variante (rail/drawer)', async () => {
35
35
  el.placement = 'left';
36
36
  el.variant = 'drawer';
37
37
  await el.updateComplete;
@@ -40,19 +40,19 @@ describe('moni-nav / moni-nav-item', () => {
40
40
  expect(nav?.classList.contains('max')).toBe(true);
41
41
  });
42
42
 
43
- it('reflects the placement attribute', async () => {
43
+ it('refleja el atributo placement', async () => {
44
44
  el.placement = 'right';
45
45
  await el.updateComplete;
46
46
  expect(el.getAttribute('placement')).toBe('right');
47
47
  });
48
48
 
49
- it('reflects the variant attribute', async () => {
49
+ it('refleja el atributo variant', async () => {
50
50
  el.variant = 'rail';
51
51
  await el.updateComplete;
52
52
  expect(el.getAttribute('variant')).toBe('rail');
53
53
  });
54
54
 
55
- it('forwards icon, label and active to nav-item', async () => {
55
+ it('reenvía icon, label y active al nav-item', async () => {
56
56
  const item = document.createElement('moni-nav-item') as MoniNavItem;
57
57
  item.icon = 'home';
58
58
  item.label = 'Home';
@@ -68,7 +68,7 @@ describe('moni-nav / moni-nav-item', () => {
68
68
  expect(a?.querySelector('moni-icon')).toBeTruthy();
69
69
  });
70
70
 
71
- it('forwards href and target to the inner <a>', async () => {
71
+ it('reenvía href y target al <a> interno', async () => {
72
72
  const item = document.createElement('moni-nav-item') as MoniNavItem;
73
73
  item.href = '/home';
74
74
  item.target = '_blank';
@@ -79,7 +79,7 @@ describe('moni-nav / moni-nav-item', () => {
79
79
  expect(a?.getAttribute('target')).toBe('_blank');
80
80
  });
81
81
 
82
- it('propagates layout property to items and sets computed layout', async () => {
82
+ it('propaga la propiedad layout a los ítems y establece el layout computado', async () => {
83
83
  const item = document.createElement('moni-nav-item') as MoniNavItem;
84
84
  el.appendChild(item);
85
85
  el.layout = 'horizontal';
@@ -93,7 +93,7 @@ describe('moni-nav / moni-nav-item', () => {
93
93
  expect(a?.getAttribute('data-layout')).toBe('horizontal');
94
94
  });
95
95
 
96
- it('modal drawer renders a scrim and dialog semantics', async () => {
96
+ it('el modal drawer renderiza un scrim y semántica de dialog', async () => {
97
97
  el.placement = 'left';
98
98
  el.variant = 'drawer';
99
99
  el.modal = true;
@@ -108,7 +108,7 @@ describe('moni-nav / moni-nav-item', () => {
108
108
  expect(nav?.getAttribute('aria-expanded')).toBe('true');
109
109
  });
110
110
 
111
- it('modal drawer closes when the scrim is clicked', async () => {
111
+ it('el modal drawer se cierra cuando se hace clic en el scrim', async () => {
112
112
  el.placement = 'left';
113
113
  el.variant = 'drawer';
114
114
  el.modal = true;
@@ -124,7 +124,7 @@ describe('moni-nav / moni-nav-item', () => {
124
124
  expect(nav?.getAttribute('aria-expanded')).toBe('false');
125
125
  });
126
126
 
127
- it('modal drawer closes on Escape key', async () => {
127
+ it('el modal drawer se cierra con la tecla Escape', async () => {
128
128
  el.placement = 'left';
129
129
  el.variant = 'drawer';
130
130
  el.modal = true;
@@ -10,56 +10,56 @@ import { customElement, property } from 'lit/decorators.js';
10
10
  import { MoniElement, sharedStyles } from './_base/index.js';
11
11
 
12
12
  /**
13
- * Material Design 3 Navigation container component.
13
+ * Componente contenedor de Navegación Material Design 3.
14
14
  *
15
- * `<moni-nav>` is the container that wraps `<moni-nav-item>` elements and
16
- * controls the M3 navigation pattern: navigation bar, navigation rail, or
17
- * navigation drawer.
15
+ * `<moni-nav>` es el contenedor que envuelve los elementos `<moni-nav-item>` y
16
+ * controla el patrón de navegación M3: barra de navegación, riel de navegación o
17
+ * cajón de navegación.
18
18
  *
19
- * **M3 spec references:**
20
- * - Navigation bar: `m3-docs/components/navigation-bar/specs.md`
21
- * - Navigation rail: `m3-docs/components/navigation-rail/specs.md`
22
- * - Navigation drawer: `m3-docs/components/navigation-drawer/specs.md`
19
+ * **Referencias a la especificación M3:**
20
+ * - Barra de navegación: `m3-docs/components/navigation-bar/specs.md`
21
+ * - Riel de navegación: `m3-docs/components/navigation-rail/specs.md`
22
+ * - Cajón de navegación: `m3-docs/components/navigation-drawer/specs.md`
23
23
  *
24
- * **Navigation patterns:**
25
- * - **Navigation bar** (`placement="bottom"`) — Horizontal bar of icon+label
26
- * items at the bottom of the screen. Best for 3–5 top-level destinations.
27
- * - **Navigation rail** (`variant="rail"`) — Vertical rail of icon+label items
28
- * on the side of the screen. Best for medium/expanded breakpoints.
29
- * - **Standard drawer** (`variant="drawer"`) — Always-visible vertical panel
30
- * with full text labels. No scrim. Best for large screens.
31
- * - **Modal drawer** (`variant="drawer" modal`) — Overlay drawer with scrim.
32
- * Opened/closed via the `open` property. Traps keyboard focus while open.
33
- * Closes on `Escape` key press.
24
+ * **Patrones de navegación:**
25
+ * - **Barra de navegación** (`placement="bottom"`) — Barra horizontal de elementos de icono+etiqueta
26
+ * en la parte inferior de la pantalla. Ideal para 3–5 destinos de nivel superior.
27
+ * - **Riel de navegación** (`variant="rail"`) — Riel vertical de elementos de icono+etiqueta
28
+ * en el lateral de la pantalla. Ideal para puntos de interrupción medianos/expandidos.
29
+ * - **Cajón estándar** (`variant="drawer"`) — Panel vertical siempre visible
30
+ * con etiquetas de texto completo. Sin atenuación (scrim). Ideal para pantallas grandes.
31
+ * - **Cajón modal** (`variant="drawer" modal`) — Cajón superpuesto con atenuación (scrim).
32
+ * Se abre/cierra a través de la propiedad `open`. Atrapa el foco del teclado mientras está abierto.
33
+ * Se cierra al presionar la tecla `Escape`.
34
34
  *
35
- * **Keyboard handling:**
36
- * When `modal=true`, the component adds a global `keydown` listener in
37
- * `connectedCallback` that closes the drawer on `Escape`. The listener is
38
- * removed in `disconnectedCallback`.
35
+ * **Manejo del teclado:**
36
+ * Cuando `modal=true`, el componente añade un listener global de `keydown` en
37
+ * `connectedCallback` que cierra el cajón con `Escape`. El listener se
38
+ * elimina en `disconnectedCallback`.
39
39
  *
40
40
  * @example
41
41
  * ```html
42
- * <!-- Bottom navigation bar -->
42
+ * <!-- Barra de navegación inferior -->
43
43
  * <moni-nav placement="bottom">
44
- * <moni-nav-item icon="home" label="Home" active></moni-nav-item>
45
- * <moni-nav-item icon="search" label="Search"></moni-nav-item>
46
- * <moni-nav-item icon="person" label="Profile"></moni-nav-item>
44
+ * <moni-nav-item icon="home" label="Inicio" active></moni-nav-item>
45
+ * <moni-nav-item icon="search" label="Buscar"></moni-nav-item>
46
+ * <moni-nav-item icon="person" label="Perfil"></moni-nav-item>
47
47
  * </moni-nav>
48
48
  *
49
- * <!-- Modal navigation drawer -->
49
+ * <!-- Cajón de navegación modal -->
50
50
  * <moni-nav variant="drawer" modal open placement="left">
51
- * <h3 slot="header">My App</h3>
52
- * <moni-nav-item icon="home" label="Home" active></moni-nav-item>
53
- * <moni-nav-item icon="settings" label="Settings"></moni-nav-item>
51
+ * <h3 slot="header">Mi App</h3>
52
+ * <moni-nav-item icon="home" label="Inicio" active></moni-nav-item>
53
+ * <moni-nav-item icon="settings" label="Ajustes"></moni-nav-item>
54
54
  * </moni-nav>
55
55
  * ```
56
56
  *
57
- * @slot default - `<moni-nav-item>` children.
58
- * @slot header - Content above the nav items (drawer variant only).
59
- * @slot footer - Content below the nav items (drawer variant only).
57
+ * @slot default - Hijos `<moni-nav-item>`.
58
+ * @slot header - Contenido encima de los elementos de navegación (solo variante drawer).
59
+ * @slot footer - Contenido debajo de los elementos de navegación (solo variante drawer).
60
60
  *
61
- * @csspart nav - The inner `<nav>` element.
62
- * @csspart scrim - The backdrop scrim (modal drawer only).
61
+ * @csspart nav - El elemento `<nav>` interior.
62
+ * @csspart scrim - El atenuador de fondo (scrim) (solo cajón modal).
63
63
  */
64
64
  @customElement('moni-nav')
65
65
  export class MoniNav extends MoniElement {
@@ -72,29 +72,59 @@ export class MoniNav extends MoniElement {
72
72
  @property({ reflect: true })
73
73
  layout: 'vertical' | 'horizontal' | 'auto' = 'auto';
74
74
 
75
+ /**
76
+ * Hook de inicialización (Lit).
77
+ * Vincula el listener global para teclado, asegurando que `_onKeydown` mantenga
78
+ * el contexto correcto de `this` al ser disparado por el documento.
79
+ */
75
80
  override connectedCallback() {
76
81
  super.connectedCallback();
77
82
  this._onKeydown = this._onKeydown.bind(this);
78
83
  document.addEventListener('keydown', this._onKeydown);
79
84
  }
80
85
 
86
+ /**
87
+ * Hook de destrucción (Lit).
88
+ * Remueve el listener de teclado global para evitar fugas de memoria (memory leaks)
89
+ * cuando el componente de navegación es retirado del DOM.
90
+ */
81
91
  override disconnectedCallback() {
82
92
  super.disconnectedCallback();
83
93
  document.removeEventListener('keydown', this._onKeydown);
84
94
  }
85
95
 
96
+ /**
97
+ * Manejador global de eventos de teclado.
98
+ * Implementa el patrón de accesibilidad estándar: Si el drawer es modal y está abierto,
99
+ * presionar la tecla Escape forzará su cierre inmediato.
100
+ */
86
101
  private _onKeydown(e: KeyboardEvent) {
87
102
  if (e.key === 'Escape' && this.modal && this.open) {
88
103
  this.open = false;
89
104
  }
90
105
  }
91
106
 
107
+ /**
108
+ * Función de cierre rápido invocada típicamente al hacer clic en el backdrop/scrim.
109
+ * Modifica directamente la propiedad `open` a false si la navegación opera en modo modal.
110
+ */
92
111
  private _closeModal() {
93
112
  if (this.modal) {
94
113
  this.open = false;
95
114
  }
96
115
  }
97
116
 
117
+ /**
118
+ * Propaga los cambios estructurales a todos los hijos `<moni-nav-item>` insertados en la ranura.
119
+ *
120
+ * Cuando `placement`, `variant`, `layout`, `modal` o `open` cambian en el
121
+ * `<moni-nav>` padre, los elementos hijos `<moni-nav-item>` también deben actualizar su estado
122
+ * de diseño calculado (layout) y de apertura. Esto se hace imperativamente a través de `_propagateToItems()` en lugar
123
+ * de a través de la API de Contexto de Lit para evitar la sobrecarga del Proveedor de Contexto para una simple
124
+ * relación padre→hijo.
125
+ *
126
+ * @param changed - Mapa de los nombres de las propiedades reactivas que desencadenaron este ciclo de actualización.
127
+ */
98
128
  override updated(changed: Map<string, unknown>) {
99
129
  if (
100
130
  changed.has('placement') ||
@@ -107,6 +137,12 @@ export class MoniNav extends MoniElement {
107
137
  }
108
138
  }
109
139
 
140
+ /**
141
+ * Patrón de inyección de propiedades "Top-Down" sin usar Context API.
142
+ * Pasa las variables arquitectónicas (`placement`, `variant`, `layout`) a los `moni-nav-item`
143
+ * hijos para que ellos puedan adaptar su CSS (ej: ocultar la etiqueta en la variante 'rail').
144
+ * Se lanza al inicializar o cada vez que cambia una prop en el contenedor.
145
+ */
110
146
  private _propagateToItems = () => {
111
147
  const items = this.querySelectorAll('moni-nav-item');
112
148
  items.forEach(item => {
@@ -266,6 +302,29 @@ export class MoniNav extends MoniElement {
266
302
  `,
267
303
  ];
268
304
 
305
+ /**
306
+ * Renderiza el contenedor de navegación con su superposición opcional de atenuación (scrim).
307
+ *
308
+ * **Composición de clases:**
309
+ * - `this.placement` (`'left'`, `'right'`, `'bottom'`) — posiciona el cajón
310
+ * o la barra de navegación inferior contra el borde correcto de la ventana gráfica.
311
+ * - `'max'` — agregado cuando `variant='drawer'`; expande la navegación a toda altura
312
+ * y ancho según la especificación M3 Navigation Drawer.
313
+ *
314
+ * **Atenuación de cajón modal (Modal drawer scrim):**
315
+ * `isModalDrawer` es `true` cuando `variant='drawer'` Y `modal=true`. En este
316
+ * caso, se renderiza un div `.scrim` detrás del cajón como una superposición
317
+ * de hacer-clic-para-descartar. La atenuación tiene `aria-hidden="true"` ya que es puramente visual.
318
+ *
319
+ * **Atributo `[open]`:**
320
+ * La vinculación `?open=${this.open}` agrega/elimina el atributo `open` en el
321
+ * elemento `<nav>`. Los selectores de atributo CSS `[open]` impulsan la transición
322
+ * de deslizamiento hacia adentro/afuera, manteniendo la animación completamente en CSS (no se requiere GSAP para este componente).
323
+ *
324
+ * **Punto de referencia ARIA (ARIA landmark):**
325
+ * El elemento `<nav>` se usa directamente (no un `<div role="navigation">`) para
326
+ * proporcionar un punto de referencia ARIA implícito al que pueden saltar los lectores de pantalla.
327
+ */
269
328
  override render() {
270
329
  const isModalDrawer = this.variant === 'drawer' && this.modal;
271
330
  const classes = [this.placement, this.variant === 'drawer' ? 'max' : '']
@@ -14,26 +14,26 @@ describe('moni-progress', () => {
14
14
  el.remove();
15
15
  });
16
16
 
17
- it('renders a progress bar container', async () => {
17
+ it('renderiza un contenedor de barra de progreso', async () => {
18
18
  await el.updateComplete;
19
19
  const progress = el.shadowRoot?.querySelector('[role="progressbar"]');
20
20
  expect(progress).toBeTruthy();
21
21
  });
22
22
 
23
- it('applies the indeterminate class to the progress bar container', async () => {
23
+ it('aplica la clase indeterminate al contenedor de la barra de progreso', async () => {
24
24
  el.indeterminate = true;
25
25
  await el.updateComplete;
26
26
  const progress = el.shadowRoot?.querySelector('[role="progressbar"]');
27
27
  expect(progress?.classList.contains('indeterminate')).toBe(true);
28
28
  });
29
29
 
30
- it('does not apply the indeterminate class by default', async () => {
30
+ it('no aplica la clase indeterminate por defecto', async () => {
31
31
  await el.updateComplete;
32
32
  const progress = el.shadowRoot?.querySelector('[role="progressbar"]');
33
33
  expect(progress?.classList.contains('indeterminate')).toBe(false);
34
34
  });
35
35
 
36
- it('forwards value and max via aria attributes on progressbar', async () => {
36
+ it('reenvía value y max a través de los atributos aria en el progressbar', async () => {
37
37
  el.value = 42;
38
38
  el.max = 100;
39
39
  await el.updateComplete;
@@ -44,7 +44,7 @@ describe('moni-progress', () => {
44
44
  expect(progress.getAttribute('aria-valuemax')).toBe('100');
45
45
  });
46
46
 
47
- it('clamps the rendered percentage between 0 and 100', async () => {
47
+ it('limita el porcentaje renderizado entre 0 y 100', async () => {
48
48
  el.value = 150;
49
49
  el.max = 100;
50
50
  await el.updateComplete;
@@ -61,28 +61,28 @@ describe('moni-progress', () => {
61
61
  expect(style2).toContain('--_p: 0');
62
62
  });
63
63
 
64
- it('renders the progress-circular container for circular variant', async () => {
64
+ it('renderiza el contenedor progress-circular para la variante circular', async () => {
65
65
  el.variant = 'circular';
66
66
  await el.updateComplete;
67
67
  const progress = el.shadowRoot?.querySelector('[role="progressbar"]');
68
68
  expect(progress?.classList.contains('progress-circular')).toBe(true);
69
69
  });
70
70
 
71
- it('renders circle wavy for circular-wavy variant', async () => {
71
+ it('renderiza circle wavy para la variante circular-wavy', async () => {
72
72
  el.variant = 'circular-wavy';
73
73
  await el.updateComplete;
74
74
  const progress = el.shadowRoot?.querySelector('[role="progressbar"]');
75
75
  expect(progress?.classList.contains('progress-circular')).toBe(true);
76
76
  });
77
77
 
78
- it('renders progress-wavy container for wavy variant', async () => {
78
+ it('renderiza el contenedor progress-wavy para la variante wavy', async () => {
79
79
  el.variant = 'wavy';
80
80
  await el.updateComplete;
81
81
  const progress = el.shadowRoot?.querySelector('[role="progressbar"]');
82
82
  expect(progress?.classList.contains('progress-wavy')).toBe(true);
83
83
  });
84
84
 
85
- it('reflects the size attribute', async () => {
85
+ it('refleja el atributo size', async () => {
86
86
  el.size = 'large';
87
87
  await el.updateComplete;
88
88
  expect(el.getAttribute('size')).toBe('large');