@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.
Files changed (251) hide show
  1. package/custom-elements.json +5230 -1007
  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 +484 -53
  31. package/dist/components/moni-carousel.d.ts.map +1 -1
  32. package/dist/components/moni-carousel.js +1024 -245
  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 +1129 -269
  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
@@ -8,87 +8,88 @@
8
8
  import { html, css } from 'lit';
9
9
  import { customElement, property, query } from 'lit/decorators.js';
10
10
  import { MoniElement, sharedStyles } from './_base/index.js';
11
+ import { emitMoniEvent } from '../utils/event-emitter.js';
11
12
 
12
13
  /**
13
- * Material Design 3 Dialog component.
14
+ * Componente Material Design 3 Dialog (Diálogo).
14
15
  *
15
- * Dialogs inform users about a task and can contain critical information,
16
- * require decisions, or involve multiple tasks. They interrupt the user's
17
- * workflow and should be used sparingly.
16
+ * Los diálogos informan a los usuarios sobre una tarea y pueden contener información crítica,
17
+ * requerir decisiones o implicar múltiples tareas. Interrumpen el flujo de trabajo del
18
+ * usuario y deben usarse con moderación.
18
19
  *
19
- * **M3 spec reference:** `m3-docs/components/dialogs/specs.md`
20
+ * **Referencia de la especificación M3:** `m3-docs/components/dialogs/specs.md`
20
21
  *
21
- * **Implementation notenative `<dialog>` element:**
22
- * This component wraps the native `<dialog>` HTML element. Opening and closing
23
- * are controlled via the `open` attribute (and its JS property). The component
24
- * syncs `open` changes to the native `<dialog>` in `updated()`:
25
- * - `modal=true` → calls `dialog.showModal()` (blocks focus, adds backdrop).
26
- * - `modal=false` → calls `dialog.show()` (non-blocking, no backdrop).
27
- * - `open=false` → calls `dialog.close()`.
22
+ * **Nota de implementación elemento nativo `<dialog>`:**
23
+ * Este componente envuelve el elemento HTML nativo `<dialog>`. La apertura y cierre
24
+ * se controlan mediante el atributo `open` (y su propiedad JS). El componente
25
+ * sincroniza los cambios de `open` al `<dialog>` nativo en `updated()`:
26
+ * - `modal=true` → llama a `dialog.showModal()` (bloquea el foco, añade fondo oscuro).
27
+ * - `modal=false` → llama a `dialog.show()` (no bloquea, sin fondo oscuro).
28
+ * - `open=false` → llama a `dialog.close()`.
28
29
  *
29
- * **Placement (`side` attribute):**
30
- * - `center` (default) — Centered in the viewport. Standard M3 dialog.
31
- * - `top`, `right`, `bottom`, `left` — Edge-anchored panels (side sheet pattern).
32
- * - `max` — Full-screen dialog for complex flows.
30
+ * **Colocación (atributo `side`):**
31
+ * - `center` (por defecto) — Centrado en la ventana gráfica. Diálogo M3 estándar.
32
+ * - `top`, `right`, `bottom`, `left` — Paneles anclados a los bordes (patrón side sheet).
33
+ * - `max` — Diálogo a pantalla completa para flujos complejos.
33
34
  *
34
35
  * @example
35
36
  * ```html
36
- * <!-- Basic modal dialog -->
37
- * <moni-dialog open modal title="Delete item?" size="small">
38
- * <p>This action cannot be undone.</p>
37
+ * <!-- Diálogo modal básico -->
38
+ * <moni-dialog open modal title="Eliminar elemento?" size="small">
39
+ * <p>Esta acción no se puede deshacer.</p>
39
40
  * <div slot="footer">
40
- * <moni-button variant="text">Cancel</moni-button>
41
- * <moni-button>Delete</moni-button>
41
+ * <moni-button variant="text">Cancelar</moni-button>
42
+ * <moni-button>Eliminar</moni-button>
42
43
  * </div>
43
44
  * </moni-dialog>
44
45
  * ```
45
46
  *
46
- * @slot default - The dialog body content.
47
- * @slot header - Custom header content (overrides `title` attribute).
48
- * @slot footer - Action buttons row at the bottom of the dialog.
47
+ * @slot default - El contenido del cuerpo del diálogo.
48
+ * @slot header - Contenido personalizado del encabezado (sobrescribe el atributo `title`).
49
+ * @slot footer - Fila de botones de acción en la parte inferior del diálogo.
49
50
  *
50
- * @csspart dialog - The native `<dialog>` element.
51
- * @csspart header - The header container.
52
- * @csspart body - The body content wrapper.
53
- * @csspart footer - The footer actions wrapper.
51
+ * @csspart dialog - El elemento `<dialog>` nativo.
52
+ * @csspart header - El contenedor del encabezado.
53
+ * @csspart body - El envoltorio del contenido del cuerpo.
54
+ * @csspart footer - El envoltorio de acciones del pie de página.
54
55
  */
55
56
  @customElement('moni-dialog')
56
57
  export class MoniDialog extends MoniElement {
57
58
  /**
58
- * Controls the open/closed state of the dialog.
59
+ * Controla el estado abierto/cerrado del diálogo.
59
60
  *
60
- * When set to `true`, the component calls `dialog.showModal()` (if `modal`)
61
- * or `dialog.show()`. When set to `false`, calls `dialog.close()`.
62
- * Reflected as an HTML attribute for CSS and external state readers.
61
+ * Cuando se establece en `true`, el componente llama a `dialog.showModal()` (si `modal`)
62
+ * o `dialog.show()`. Cuando se establece en `false`, llama a `dialog.close()`.
63
+ * Reflejado como un atributo HTML para CSS y lectores de estado externos.
63
64
  *
64
65
  * @default false
65
66
  */
66
67
  @property({ type: Boolean, reflect: true }) open = false;
67
68
 
68
69
  /**
69
- * When `true`, opens the dialog as a modal using `<dialog>.showModal()`.
70
+ * Cuando es `true`, abre el diálogo como un modal usando `<dialog>.showModal()`.
70
71
  *
71
- * Modal dialogs:
72
- * - Block keyboard focus from leaving the dialog.
73
- * - Render a `::backdrop` scrim over the rest of the page.
74
- * - Can be closed by pressing `Escape` (native browser behavior).
72
+ * Diálogos modales:
73
+ * - Bloquean que el foco del teclado salga del diálogo.
74
+ * - Renderizan una capa `::backdrop` sobre el resto de la página.
75
+ * - Se pueden cerrar presionando `Escape` (comportamiento nativo del navegador).
75
76
  *
76
- * When `false`, uses `<dialog>.show()` which is non-blocking (no focus trap
77
- * and no backdrop).
77
+ * Cuando es `false`, usa `<dialog>.show()` que no es bloqueante (sin trampa de foco
78
+ * y sin capa de fondo).
78
79
  *
79
80
  * @default false
80
81
  */
81
82
  @property({ type: Boolean, reflect: true }) modal = false;
82
83
 
83
84
  /**
84
- * Placement of the dialog within the viewport.
85
+ * Colocación del diálogo dentro de la ventana gráfica.
85
86
  *
86
- * - `'center'` (default) — Centered. Standard M3 dialog placement.
87
- * - `'top'` — Anchored to the top edge (drawer from top).
88
- * - `'right'` — Anchored to the right edge (side sheet pattern).
89
- * - `'bottom'` — Anchored to the bottom edge (bottom sheet alternative).
90
- * - `'left'` — Anchored to the left edge (navigation drawer pattern).
91
- * - `'max'` — Full-screen (covers the entire viewport).
87
+ * - `'center'` (por defecto) — Centrado. Colocación de diálogo M3 estándar.
88
+ * - `'top'` — Anclado al borde superior (cajón desde arriba).
89
+ * - `'right'` — Anclado al borde derecho (patrón de hoja lateral).
90
+ * - `'bottom'` — Anclado al borde inferior (alternativa de hoja inferior).
91
+ * - `'left'` — Anclado al borde izquierdo (patrón de cajón de navegación).
92
+ * - `'max'` — Pantalla completa (cubre toda la ventana gráfica).
92
93
  *
93
94
  * @default 'center'
94
95
  */
@@ -96,11 +97,11 @@ export class MoniDialog extends MoniElement {
96
97
  side: 'center' | 'top' | 'right' | 'bottom' | 'left' | 'max' = 'center';
97
98
 
98
99
  /**
99
- * Size of the dialog container.
100
+ * Tamaño del contenedor del diálogo.
100
101
  *
101
- * - `'small'` — Narrow dialog; ideal for simple confirmations.
102
- * - `'medium'` — Standard dialog width (default).
103
- * - `'large'` — Wide dialog; for forms or complex content.
102
+ * - `'small'` — Diálogo estrecho; ideal para confirmaciones simples.
103
+ * - `'medium'` — Ancho de diálogo estándar (por defecto).
104
+ * - `'large'` — Diálogo ancho; para formularios o contenido complejo.
104
105
  *
105
106
  * @default 'medium'
106
107
  */
@@ -108,30 +109,47 @@ export class MoniDialog extends MoniElement {
108
109
  size: 'small' | 'medium' | 'large' = 'medium';
109
110
 
110
111
  /**
111
- * Text displayed in the dialog header area.
112
+ * Texto mostrado en el área del encabezado del diálogo.
112
113
  *
113
- * When non-empty, renders as a styled heading inside the header container.
114
- * The `header` slot takes precedence over this attribute when both are present.
114
+ * Cuando no está vacío, se renderiza como un encabezado estilizado dentro del contenedor del encabezado.
115
+ * El slot `header` tiene prioridad sobre este atributo cuando ambos están presentes.
115
116
  *
116
117
  * @default ''
117
118
  */
118
119
  @property({ reflect: true }) title = '';
119
120
 
120
- /** Direct reference to the native `<dialog>` element for programmatic access. */
121
+ /** Referencia directa al elemento `<dialog>` nativo para acceso programático. */
121
122
  @query('dialog') private _dialog!: HTMLDialogElement;
122
123
 
124
+ override willUpdate(changed: Map<string, unknown>) {
125
+ if (changed.has('open') && this.open !== changed.get('open')) {
126
+ const isOpening = this.open;
127
+ const eventName = isOpening ? 'moni-request-open' : 'moni-request-close';
128
+ const allowed = emitMoniEvent(this, eventName, { cancelable: true });
129
+
130
+ if (!allowed) {
131
+ this.open = !isOpening;
132
+ }
133
+ }
134
+ }
135
+
123
136
  /**
124
- * Syncs the `open` and `modal` state to the native `<dialog>` element.
137
+ * Hook de ciclo de vida de Lit. Sincroniza el estado declarativo (`open`, `modal`)
138
+ * con la API imperativa del elemento `<dialog>` nativo de HTML5.
125
139
  *
126
- * Called by Lit after every render cycle where tracked properties change.
127
- * Avoids calling `showModal()` or `show()` if the dialog is already open
128
- * (prevents the `InvalidStateError` DOMException).
140
+ * - `showModal()`: Bloquea el resto del DOM (Inert), atrapa el foco del teclado (Focus Trap)
141
+ * y renderiza el seudoelemento `::backdrop`.
142
+ * - `show()`: Permite interacción con el fondo (Non-modal).
129
143
  *
130
- * @param changed - Map of changed property names to their previous values.
144
+ * IMPORTANTE: Previene la excepción `InvalidStateError` validando si el
145
+ * diálogo ya está abierto antes de llamar a `show()` o `showModal()`.
146
+ *
147
+ * @param changed - Mapa de propiedades reactivas modificadas.
131
148
  */
132
149
  override updated(changed: Map<string, unknown>) {
133
150
  if (changed.has('open') && this._dialog) {
134
151
  if (this.open) {
152
+ emitMoniEvent(this, 'moni-open');
135
153
  if (this.modal) {
136
154
  if (!this._dialog.open) {
137
155
  this._dialog.showModal();
@@ -142,6 +160,7 @@ export class MoniDialog extends MoniElement {
142
160
  }
143
161
  }
144
162
  } else {
163
+ emitMoniEvent(this, 'moni-close');
145
164
  if (this._dialog.open) {
146
165
  this._dialog.close();
147
166
  }
@@ -149,6 +168,16 @@ export class MoniDialog extends MoniElement {
149
168
  }
150
169
  }
151
170
 
171
+ private _onTransitionEnd(e: TransitionEvent) {
172
+ if (e.target === this._dialog && e.propertyName === 'transform') {
173
+ if (this.open) {
174
+ emitMoniEvent(this, 'moni-opened');
175
+ } else {
176
+ emitMoniEvent(this, 'moni-closed');
177
+ }
178
+ }
179
+ }
180
+
152
181
  static override styles = [
153
182
  sharedStyles,
154
183
  css`
@@ -311,6 +340,25 @@ export class MoniDialog extends MoniElement {
311
340
  `
312
341
  ];
313
342
 
343
+ /**
344
+ * Renderiza el elemento `<dialog>` nativo con la estructura semántica de slots del diálogo.
345
+ *
346
+ * **¿Por qué `<dialog>`?**
347
+ * El elemento nativo `<dialog>` proporciona captura de foco, renderizado de fondo (backdrop)
348
+ * y semántica modal accesible sin JavaScript. El enlace `?open` de Lit
349
+ * alterna el atributo de forma imperativa, mientras que `updated()` llama a `.show()` /
350
+ * `.showModal()` / `.close()` para conducir la pila de abrir/cerrar nativa del navegador.
351
+ *
352
+ * **Estructura de slots:**
353
+ * - `[slot="header"]` — se repliega al valor del atributo `title`.
354
+ * - Slot por defecto — la región de contenido principal del diálogo.
355
+ * - `[slot="footer"]` — botones de acción (típicamente elementos `<moni-button>`).
356
+ *
357
+ * **Composición de `classes`:**
358
+ * `side`, `size`, y `modal` (si `modal=true`) se unen como clases CSS.
359
+ * `side` posiciona el diálogo en `start`, `end`, `top`, o `bottom`; usado
360
+ * para diálogos de panel lateral. `size` controla max-width/height.
361
+ */
314
362
  override render() {
315
363
  const classes = [this.side, this.size, this.modal ? 'modal' : '']
316
364
  .filter(Boolean)
@@ -318,6 +366,7 @@ export class MoniDialog extends MoniElement {
318
366
  return html`<dialog
319
367
  part="dialog"
320
368
  class=${classes}
369
+ @transitionend=${this._onTransitionEnd}
321
370
  >
322
371
  <header part="header">
323
372
  <slot name="header">${this.title}</slot>
@@ -14,13 +14,13 @@ describe('moni-divider (P5.1 — recreated)', () => {
14
14
  el.remove();
15
15
  });
16
16
 
17
- it('defaults to inset=leading', async () => {
17
+ it('por defecto es inset=leading', async () => {
18
18
  await el.updateComplete;
19
19
  expect(el.inset).toBe('leading');
20
20
  expect(el.getAttribute('inset')).toBe('leading');
21
21
  });
22
22
 
23
- it('reflects all three M3 insets: leading / middle / none', async () => {
23
+ it('refleja las tres inserciones M3: leading / middle / none', async () => {
24
24
  for (const inset of ['leading', 'middle', 'none'] as const) {
25
25
  el.inset = inset;
26
26
  await el.updateComplete;
@@ -28,13 +28,13 @@ describe('moni-divider (P5.1 — recreated)', () => {
28
28
  }
29
29
  });
30
30
 
31
- it('renders an empty default slot for inline content', async () => {
31
+ it('renderiza un slot por defecto vacío para contenido en línea', async () => {
32
32
  await el.updateComplete;
33
33
  const slot = el.shadowRoot?.querySelector('slot');
34
34
  expect(slot).toBeTruthy();
35
35
  });
36
36
 
37
- it('reflects the vertical attribute', async () => {
37
+ it('refleja el atributo vertical', async () => {
38
38
  el.setAttribute('vertical', '');
39
39
  await el.updateComplete;
40
40
  expect(el.hasAttribute('vertical')).toBe(true);
@@ -10,53 +10,53 @@ import { customElement, property } from 'lit/decorators.js';
10
10
  import { MoniElement, sharedStyles } from './_base/index.js';
11
11
 
12
12
  /**
13
- * Material Design 3 Divider component.
13
+ * Componente Material Design 3 Divider (Separador).
14
14
  *
15
- * A thin horizontal (or vertical) rule used to visually separate content
16
- * sections within lists, layouts, and cards.
15
+ * Una regla delgada horizontal (o vertical) utilizada para separar visualmente secciones
16
+ * de contenido dentro de listas, diseños y tarjetas.
17
17
  *
18
- * **M3 spec reference:** `m3-docs/components/divider/specs.md`
18
+ * **Referencia de la especificación M3:** `m3-docs/components/divider/specs.md`
19
19
  *
20
- * **M3 measurements:**
21
- * - Thickness: 1dp (`0.0625rem`).
22
- * - Color: `outline-variant` — subtle on all surface backgrounds.
23
- * - Inset variants align the line with list content:
24
- * - `leading` — 16dp margin from the leading edge (aligns with icon text).
25
- * - `middle` — 16dp margin on both edges.
26
- * - `none` — full-bleed (no margin).
20
+ * **Medidas M3:**
21
+ * - Grosor: 1dp (`0.0625rem`).
22
+ * - Color: `outline-variant` — sutil en todos los fondos de superficie.
23
+ * - Las variantes insertadas (inset) alinean la línea con el contenido de la lista:
24
+ * - `leading` — margen de 16dp desde el borde inicial (se alinea con el texto del icono).
25
+ * - `middle` — margen de 16dp en ambos bordes.
26
+ * - `none` — sangría completa (sin margen).
27
27
  *
28
- * **Vertical usage:**
29
- * While not yet exposed as an attribute, the `[vertical]` CSS attribute selector
30
- * is supported. Set `vertical` as an HTML attribute to render a 1dp-wide
31
- * vertical divider that stretches to match its flex container's cross-axis.
28
+ * **Uso vertical:**
29
+ * Aunque todavía no se expone como un atributo, el selector de atributos CSS `[vertical]`
30
+ * está soportado. Establezca `vertical` como un atributo HTML para renderizar un separador
31
+ * vertical de 1dp de ancho que se estira para coincidir con el eje transversal de su contenedor flex.
32
32
  *
33
33
  * @example
34
34
  * ```html
35
- * <!-- Full-bleed divider between sections -->
35
+ * <!-- Separador de sangría completa entre secciones -->
36
36
  * <moni-divider inset="none"></moni-divider>
37
37
  *
38
- * <!-- Leading-inset divider in a list (aligns with list item text) -->
38
+ * <!-- Separador de inserción inicial en una lista (se alinea con el texto del elemento de lista) -->
39
39
  * <moni-divider></moni-divider>
40
40
  *
41
- * <!-- Vertical divider inside a flex container -->
41
+ * <!-- Separador vertical dentro de un contenedor flex -->
42
42
  * <div style="display:flex; height: 3rem; align-items:center; gap: 1rem;">
43
- * <span>Section A</span>
43
+ * <span>Sección A</span>
44
44
  * <moni-divider vertical></moni-divider>
45
- * <span>Section B</span>
45
+ * <span>Sección B</span>
46
46
  * </div>
47
47
  * ```
48
48
  */
49
49
  @customElement('moni-divider')
50
50
  export class MoniDivider extends MoniElement {
51
51
  /**
52
- * Controls the horizontal margin on the divider line.
52
+ * Controla el margen horizontal en la línea del separador.
53
53
  *
54
- * - `'leading'` (default) — 16dp margin from the leading (start) edge only.
55
- * Use in lists to align the divider with the primary text of list items.
56
- * - `'middle'` — 16dp margin on both the leading and trailing edges.
57
- * Use to separate sections where full-bleed would be too visually heavy.
58
- * - `'none'` — No margin; the line spans the full parent width.
59
- * Use as a section separator or between cards.
54
+ * - `'leading'` (por defecto) — Margen de 16dp solo desde el borde inicial (inicio).
55
+ * Usar en listas para alinear el separador con el texto principal de los elementos de la lista.
56
+ * - `'middle'` — Margen de 16dp tanto en el borde inicial como en el final.
57
+ * Usar para separar secciones donde una sangría completa sería visualmente demasiado pesada.
58
+ * - `'none'` — Sin margen; la línea abarca todo el ancho del padre.
59
+ * Usar como separador de secciones o entre tarjetas.
60
60
  *
61
61
  * @default 'leading'
62
62
  */
@@ -69,7 +69,7 @@ export class MoniDivider extends MoniElement {
69
69
  :host {
70
70
  display: block;
71
71
  font-family: var(--font);
72
- /* M3 spec: 1dp thick, on-surface-variant for subtle separation. */
72
+ /* Especificación M3: grosor de 1dp, on-surface-variant para una separación sutil. */
73
73
  block-size: 0.0625rem;
74
74
  min-inline-size: 0;
75
75
  background-color: var(--outline-variant);
@@ -77,7 +77,7 @@ export class MoniDivider extends MoniElement {
77
77
  margin: 0;
78
78
  }
79
79
 
80
- /* Inset variants. M3 spec: 16dp from the leading edge. */
80
+ /* Variantes de inserción. Especificación M3: 16dp desde el borde inicial. */
81
81
  :host([inset='leading']) {
82
82
  margin-inline-start: 1rem;
83
83
  margin-inline-end: 0;
@@ -89,7 +89,7 @@ export class MoniDivider extends MoniElement {
89
89
  margin-inline: 0;
90
90
  }
91
91
 
92
- /* Vertical divider (M3 spec also defines vertical usage). */
92
+ /* Separador vertical (la especificación M3 también define el uso vertical). */
93
93
  :host([vertical]) {
94
94
  inline-size: 0.0625rem;
95
95
  block-size: auto;
@@ -99,6 +99,18 @@ export class MoniDivider extends MoniElement {
99
99
  `
100
100
  ];
101
101
 
102
+ /**
103
+ * Renderiza un paso a través de slot transparente.
104
+ *
105
+ * `moni-divider` es un componente impulsado puramente por CSS — la línea visual es
106
+ * renderizada por el elemento `:host` en sí (a través de `background-color` y
107
+ * `block-size: 0.0625rem`). No se necesitan elementos internos.
108
+ *
109
+ * El `<slot>` vacío se incluye para que los consumidores puedan insertar etiquetas de texto
110
+ * o iconos entre secciones (ej. `<moni-divider>O</moni-divider>`).
111
+ * El contenido renderizado en el slot no tiene estilo visual de este componente; el consumidor
112
+ * debe aplicar estilo a los elementos del slot directamente.
113
+ */
102
114
  override render() {
103
115
  return html`<slot></slot>`;
104
116
  }
@@ -10,45 +10,45 @@ import { customElement, property } from 'lit/decorators.js';
10
10
  import { MoniElement, sharedStyles } from './_base/index.js';
11
11
 
12
12
  /**
13
- * Material Design 3 Expansion panel component.
13
+ * Componente Material Design 3 Expansion panel (Panel de expansión).
14
14
  *
15
- * A lightweight wrapper around the native HTML `<details>` and `<summary>`
16
- * elements, styled according to M3 surface and elevation guidelines.
17
- * Expansion panels contain creation flows and allow lightweight editing of an element.
15
+ * Un envoltorio ligero alrededor de los elementos HTML nativos `<details>` y `<summary>`,
16
+ * estilizado de acuerdo con las pautas de superficie y elevación de M3.
17
+ * Los paneles de expansión contienen flujos de creación y permiten la edición ligera de un elemento.
18
18
  *
19
- * **Visual architecture:**
20
- * The component renders a `<details>` element with a `<summary>` that acts
21
- * as the expandable header. The default slot content is placed inside the
22
- * `<details>` tag (but outside the `<summary>`), naturally hiding and showing
23
- * based on the native behavior. An M3 `expand_more` icon is added via a CSS
24
- * `::after` pseudo-element and rotates when the panel is open.
19
+ * **Arquitectura visual:**
20
+ * El componente renderiza un elemento `<details>` con un `<summary>` que actúa
21
+ * como el encabezado expandible. El contenido del slot por defecto se coloca dentro de la
22
+ * etiqueta `<details>` (pero fuera del `<summary>`), ocultándose y mostrándose naturalmente
23
+ * según el comportamiento nativo. Se añade un icono `expand_more` de M3 mediante un
24
+ * pseudo-elemento CSS `::after` que rota cuando el panel está abierto.
25
25
  *
26
- * **Usage:**
27
- * Set the `title` attribute for a simple text header, or use the `summary`
28
- * slot to project custom rich content (like icons or secondary text) into the
29
- * header area.
26
+ * **Uso:**
27
+ * Establezca el atributo `title` para un encabezado de texto simple, o use el slot `summary`
28
+ * para proyectar contenido enriquecido personalizado (como iconos o texto secundario) en el
29
+ * área del encabezado.
30
30
  *
31
31
  * @example
32
32
  * ```html
33
- * <!-- Simple text title -->
34
- * <moni-expansion title="Advanced Settings">
35
- * <p>Enable developer mode features here.</p>
33
+ * <!-- Título de texto simple -->
34
+ * <moni-expansion title="Configuración Avanzada">
35
+ * <p>Habilite las características del modo de desarrollador aquí.</p>
36
36
  * </moni-expansion>
37
37
  *
38
- * <!-- Rich summary content via slot -->
38
+ * <!-- Contenido de resumen enriquecido a través de slot -->
39
39
  * <moni-expansion open>
40
40
  * <div slot="summary" style="display: flex; gap: 8px;">
41
41
  * <moni-icon>person</moni-icon>
42
- * <span>Personal Information</span>
42
+ * <span>Información Personal</span>
43
43
  * </div>
44
44
  * <form>
45
- * <moni-text-field label="Name"></moni-text-field>
45
+ * <moni-text-field label="Nombre"></moni-text-field>
46
46
  * </form>
47
47
  * </moni-expansion>
48
48
  * ```
49
49
  *
50
- * @slot default - The content of the expansion panel body.
51
- * @slot summary - Custom header content (overrides the `title` attribute).
50
+ * @slot default - El contenido del cuerpo del panel de expansión.
51
+ * @slot summary - Contenido personalizado del encabezado (sobrescribe el atributo `title`).
52
52
  */
53
53
  @customElement('moni-expansion')
54
54
  export class MoniExpansion extends MoniElement {
@@ -102,6 +102,16 @@ export class MoniExpansion extends MoniElement {
102
102
  `
103
103
  ];
104
104
 
105
+ /**
106
+ * Renderiza el panel de expansión utilizando el elemento nativo `<details>`.
107
+ *
108
+ * El atributo `open` en
109
+ * `:host` impulsa la rotación de la flecha indicadora CSS (`::after` en `summary`).
110
+ *
111
+ * **Estructura de slots:**
112
+ * - `[slot="summary"]` — la fila de encabezado siempre visible (título, iconos).
113
+ * - Slot por defecto — la región de contenido colapsable.
114
+ */
105
115
  override render() {
106
116
  return html`<details ?open=${this.open} part="expansion">
107
117
  <summary part="summary">
@@ -15,7 +15,7 @@ describe('moni-fab-menu', () => {
15
15
  el.remove();
16
16
  });
17
17
 
18
- it('renders a .fab-menu and a <moni-fab> trigger', async () => {
18
+ it('renderiza un .fab-menu y un <moni-fab> como activador', async () => {
19
19
  await el.updateComplete;
20
20
  const menu = el.shadowRoot?.querySelector('.fab-menu');
21
21
  const trigger = el.shadowRoot?.querySelector('moni-fab');
@@ -23,7 +23,7 @@ describe('moni-fab-menu', () => {
23
23
  expect(trigger).toBeTruthy();
24
24
  });
25
25
 
26
- it('passes icon, size, color, shape, position to the trigger', async () => {
26
+ it('pasa icon, size, color, shape, position al activador', async () => {
27
27
  el.icon = 'menu';
28
28
  el.size = 'large';
29
29
  el.color = 'secondary';
@@ -36,7 +36,7 @@ describe('moni-fab-menu', () => {
36
36
  expect(trigger?.getAttribute('shape')).toBe('circle');
37
37
  });
38
38
 
39
- it('reflects the open attribute', async () => {
39
+ it('refleja el atributo open', async () => {
40
40
  el.open = true;
41
41
  await el.updateComplete;
42
42
  expect(el.hasAttribute('open')).toBe(true);
@@ -46,13 +46,13 @@ describe('moni-fab-menu', () => {
46
46
  expect(el.hasAttribute('open')).toBe(false);
47
47
  });
48
48
 
49
- it('reflects the direction attribute', async () => {
49
+ it('refleja el atributo direction', async () => {
50
50
  el.direction = 'down';
51
51
  await el.updateComplete;
52
52
  expect(el.getAttribute('direction')).toBe('down');
53
53
  });
54
54
 
55
- it('toggles open when the trigger is clicked', async () => {
55
+ it('cambia el estado open cuando se hace clic en el activador', async () => {
56
56
  await el.updateComplete;
57
57
  expect(el.open).toBe(false);
58
58
 
@@ -73,13 +73,13 @@ describe('moni-fab-menu', () => {
73
73
  expect(el.open).toBe(false);
74
74
  });
75
75
 
76
- it('menu has role="menu" for screen reader semantics', async () => {
76
+ it('el menú tiene role="menu" para la semántica del lector de pantalla', async () => {
77
77
  await el.updateComplete;
78
78
  const menu = el.shadowRoot?.querySelector('.fab-menu');
79
79
  expect(menu?.getAttribute('role')).toBe('menu');
80
80
  });
81
81
 
82
- it('Escape key closes an open menu', async () => {
82
+ it('la tecla Escape cierra un menú abierto', async () => {
83
83
  el.open = true;
84
84
  await el.updateComplete;
85
85
  expect(el.open).toBe(true);
@@ -89,7 +89,7 @@ describe('moni-fab-menu', () => {
89
89
  expect(el.open).toBe(false);
90
90
  });
91
91
 
92
- it('Escape on a closed menu is a no-op', async () => {
92
+ it('presionar Escape en un menú cerrado no hace nada', async () => {
93
93
  await el.updateComplete;
94
94
  expect(el.open).toBe(false);
95
95
  document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));
@@ -97,17 +97,17 @@ describe('moni-fab-menu', () => {
97
97
  expect(el.open).toBe(false);
98
98
  });
99
99
 
100
- it('click outside the menu closes it', async () => {
100
+ it('hacer clic fuera del menú lo cierra', async () => {
101
101
  el.open = true;
102
102
  await el.updateComplete;
103
103
 
104
- // Dispatch a click on the document body (outside the menu).
104
+ // Despachar un clic en el body del documento (fuera del menú).
105
105
  document.body.dispatchEvent(new MouseEvent('click', { bubbles: true }));
106
106
  await el.updateComplete;
107
107
  expect(el.open).toBe(false);
108
108
  });
109
109
 
110
- it('click inside the menu does not close it', async () => {
110
+ it('hacer clic dentro del menú no lo cierra', async () => {
111
111
  el.open = true;
112
112
  await el.updateComplete;
113
113
  const menu = el.shadowRoot?.querySelector('.fab-menu') as HTMLElement;