@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
@@ -14,7 +14,7 @@ describe('moni-side-sheet', () => {
14
14
  el.remove();
15
15
  });
16
16
 
17
- it('initializes with default values', async () => {
17
+ it('se inicializa con valores por defecto', async () => {
18
18
  await el.updateComplete;
19
19
  expect(el.open).toBe(false);
20
20
  expect(el.modal).toBe(false);
@@ -25,7 +25,7 @@ describe('moni-side-sheet', () => {
25
25
  expect(el.showBack).toBe(false);
26
26
  });
27
27
 
28
- it('reflects open state to underlaying dialog', async () => {
28
+ it('refleja el estado open al dialog subyacente', async () => {
29
29
  await el.updateComplete;
30
30
  const dialog = el.shadowRoot?.querySelector('dialog') as HTMLDialogElement;
31
31
  expect(dialog.open).toBe(false);
@@ -35,7 +35,7 @@ describe('moni-side-sheet', () => {
35
35
  expect(dialog.open).toBe(true);
36
36
  });
37
37
 
38
- it('renders title and handles close click', async () => {
38
+ it('renderiza el título y maneja el clic de cerrar', async () => {
39
39
  el.title = 'Configuración';
40
40
  el.open = true;
41
41
  await el.updateComplete;
@@ -57,7 +57,7 @@ describe('moni-side-sheet', () => {
57
57
  expect(eventFired).toBe(true);
58
58
  });
59
59
 
60
- it('fires back event when back button clicked', async () => {
60
+ it('dispara el evento back cuando se hace clic en el botón de volver', async () => {
61
61
  el.showBack = true;
62
62
  await el.updateComplete;
63
63
 
@@ -73,7 +73,7 @@ describe('moni-side-sheet', () => {
73
73
  expect(backFired).toBe(true);
74
74
  });
75
75
 
76
- it('applies correct class for noBorder', async () => {
76
+ it('aplica la clase correcta para noBorder', async () => {
77
77
  const dialog = el.shadowRoot?.querySelector('dialog');
78
78
  expect(dialog?.classList.contains('no-border')).toBe(false);
79
79
 
@@ -82,7 +82,7 @@ describe('moni-side-sheet', () => {
82
82
  expect(dialog?.classList.contains('no-border')).toBe(true);
83
83
  });
84
84
 
85
- it('renders handle and supports drag dismissal when withHandle is true', async () => {
85
+ it('renderiza el tirador (handle) y soporta el cierre por arrastre cuando withHandle es true', async () => {
86
86
  el.withHandle = true;
87
87
  el.open = true;
88
88
  await el.updateComplete;
@@ -113,7 +113,7 @@ describe('moni-side-sheet', () => {
113
113
  closeFired = true;
114
114
  });
115
115
 
116
- // Trigger pointer drag to the right on a right aligned sheet
116
+ // Activar el arrastre del puntero hacia la derecha en una hoja alineada a la derecha
117
117
  handle.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, clientX: 300, pointerId: 1 }));
118
118
  dialog.dispatchEvent(new PointerEvent('pointermove', { bubbles: true, clientX: 550, pointerId: 1 })); // 250px right (greater than 400 * 0.4 = 160px)
119
119
  handle.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, clientX: 550, pointerId: 1 }));
@@ -12,55 +12,55 @@ import './moni-icon.js';
12
12
  import './moni-button.js';
13
13
 
14
14
  /**
15
- * Material Design 3 Side Sheet component.
15
+ * Componente Material Design 3 Side Sheet (Hoja o panel lateral).
16
16
  *
17
- * Side sheets show supplementary content that is anchored to the left or right
18
- * edge of the screen. They can be standard (inline with content) or modal
19
- * (overlaying content with a scrim).
17
+ * Los paneles laterales muestran contenido complementario que está anclado al borde
18
+ * izquierdo o derecho de la pantalla. Pueden ser estándar (en línea con el contenido)
19
+ * o modales (superpuestos al contenido con un fondo/scrim oscurecido).
20
20
  *
21
- * **M3 spec reference:** `m3-docs/components/side-sheets/specs.md`
21
+ * **Referencia a la especificación M3:** `m3-docs/components/side-sheets/specs.md`
22
22
  *
23
- * **Dialog behavior:**
24
- * Internally, this component uses the native HTML `<dialog>` element for robust
25
- * accessibility, focus trapping, and top-layer rendering.
26
- * - When `modal=true`, the sheet uses `dialog.showModal()`, rendering a scrim
27
- * backdrop and trapping focus. Pressing `Escape` closes it.
28
- * - When `modal=false`, the sheet uses `dialog.show()` and remains interactive
29
- * alongside the main page content.
23
+ * **Comportamiento del cuadro de diálogo (Dialog behavior):**
24
+ * Internamente, este componente utiliza el elemento HTML nativo `<dialog>` para una
25
+ * accesibilidad robusta, captura de foco y renderizado en la capa superior (top-layer).
26
+ * - Cuando `modal=true`, el panel usa `dialog.showModal()`, renderizando un fondo
27
+ * (scrim backdrop) y capturando el foco. Al presionar `Escape` se cierra.
28
+ * - Cuando `modal=false`, el panel usa `dialog.show()` y permanece interactivo
29
+ * junto al contenido de la página principal.
30
30
  *
31
- * **Drag & Resize (Moni feature):**
32
- * Setting the `with-handle` attribute adds a draggable grab handle to the inner
33
- * edge of the sheet. Users can click and drag this handle to resize the sheet's
34
- * width up to the `max-width` limit. If the user drags the sheet towards the
35
- * screen edge quickly or beyond a certain threshold, it automatically closes.
31
+ * **Arrastrar y redimensionar (Característica Moni):**
32
+ * Al configurar el atributo `with-handle`, se agrega un controlador de arrastre en el borde
33
+ * interior del panel. Los usuarios pueden hacer clic y arrastrar este controlador para
34
+ * redimensionar el ancho del panel hasta el límite `max-width`. Si el usuario arrastra
35
+ * el panel hacia el borde de la pantalla rápidamente o más allá de cierto umbral, se cierra automáticamente.
36
36
  *
37
- * **Animations:**
38
- * Side sheets slide in from the specified `side` (`left` or `right`). The open
39
- * and close animations are handled via CSS transitions tied to the `open` property.
37
+ * **Animaciones:**
38
+ * Los paneles laterales se deslizan desde el `side` (lado) especificado (`left` o `right`).
39
+ * Las animaciones de apertura y cierre se manejan a través de transiciones CSS vinculadas a la propiedad `open`.
40
40
  *
41
- * @fires close - Fired when the side sheet is completely closed (after animations
42
- * finish), either via the close button, scrim click, drag-to-close,
43
- * or `Escape` key.
41
+ * @fires close - Se dispara cuando el panel lateral está completamente cerrado (después de
42
+ * que terminan las animaciones), ya sea a través del botón de cierre, clic en el fondo (scrim),
43
+ * arrastrar para cerrar o la tecla `Escape`.
44
44
  *
45
45
  * @example
46
46
  * ```html
47
- * <!-- Modal side sheet on the right -->
48
- * <moni-side-sheet id="details-sheet" modal title="Item Details">
49
- * <p>Here is more information about the selected item.</p>
47
+ * <!-- Panel lateral modal a la derecha -->
48
+ * <moni-side-sheet id="details-sheet" modal title="Detalles del artículo">
49
+ * <p>Aquí hay más información sobre el artículo seleccionado.</p>
50
50
  * <div slot="footer">
51
- * <moni-button>Save</moni-button>
51
+ * <moni-button>Guardar</moni-button>
52
52
  * </div>
53
53
  * </moni-side-sheet>
54
54
  *
55
- * <!-- Resizable, detached side sheet on the left -->
55
+ * <!-- Panel lateral a la izquierda, desvinculado (detached) y redimensionable -->
56
56
  * <moni-side-sheet side="left" detached with-handle max-width="50vw">
57
- * <p>Navigation options</p>
57
+ * <p>Opciones de navegación</p>
58
58
  * </moni-side-sheet>
59
59
  * ```
60
60
  *
61
- * @slot default - Main body content.
62
- * @slot header - Custom header content (overrides `title`, close/back buttons remain).
63
- * @slot footer - Bottom-anchored action area.
61
+ * @slot default - Contenido del cuerpo principal.
62
+ * @slot header - Contenido de encabezado personalizado (anula `title`, los botones de cerrar/volver permanecen).
63
+ * @slot footer - Área de acción anclada en la parte inferior.
64
64
  */
65
65
  @customElement('moni-side-sheet')
66
66
  export class MoniSideSheet extends MoniElement {
@@ -99,6 +99,14 @@ export class MoniSideSheet extends MoniElement {
99
99
  return 600;
100
100
  }
101
101
 
102
+ /**
103
+ * Hook del ciclo de vida reactivo (Lit).
104
+ * Coordina la transición del elemento `<dialog>` nativo.
105
+ * Utiliza `showModal()` para Side Sheets modales (con backdrop) y `show()`
106
+ * para Side Sheets estándar. Administra manualmente la clase `.opened` y escucha
107
+ * eventos `transitionend` para cerrar limpiamente el `<dialog>` sólo cuando
108
+ * las animaciones CSS terminan.
109
+ */
102
110
  override updated(changedProperties: PropertyValues) {
103
111
  super.updated(changedProperties);
104
112
 
@@ -156,6 +164,12 @@ export class MoniSideSheet extends MoniElement {
156
164
  }
157
165
  }
158
166
 
167
+ /**
168
+ * Inicia la interacción de arrastre (Drag) del Side Sheet.
169
+ * Verifica si el usuario agarró el componente desde el "handle" o la cabecera.
170
+ * Captura el ancho actual para determinar si el usuario pretende expandir o contraer
171
+ * el panel lateral mediante gestos.
172
+ */
159
173
  private _onPointerDown(e: PointerEvent) {
160
174
  if (!this.withHandle) return;
161
175
  const target = e.target as HTMLElement;
@@ -175,6 +189,13 @@ export class MoniSideSheet extends MoniElement {
175
189
  this._dialog.classList.add('dragging');
176
190
  }
177
191
 
192
+ /**
193
+ * Procesa el movimiento del arrastre y aplica transformaciones CSS inline
194
+ * imperativamente a 60FPS. Diferencia la lógica dependiendo de la posición
195
+ * de anclaje (izquierdo vs derecho) y del estado actual (expandido vs contraído).
196
+ * Introduce una "resistencia elástica" si el usuario intenta expandir el panel
197
+ * más allá de su ancho máximo permitido (`maxWidth`).
198
+ */
178
199
  private _onPointerMove(e: PointerEvent) {
179
200
  if (!this._isDragging) return;
180
201
 
@@ -209,6 +230,15 @@ export class MoniSideSheet extends MoniElement {
209
230
  }
210
231
  }
211
232
 
233
+ /**
234
+ * Evalúa el resultado de la interacción de arrastre (Pointer Up).
235
+ *
236
+ * Basado en umbrales de distancia física (`threshold`) y el estado actual, decide:
237
+ * 1. Expandir el panel por completo (modo "expanded").
238
+ * 2. Contraer el panel de vuelta a su tamaño estándar.
239
+ * 3. Cerrar el Side Sheet totalmente y disparar el evento `close`.
240
+ * Utiliza transiciones CSS nativas en vez de animar por frame para la resolución final.
241
+ */
212
242
  private _onPointerUp(e: PointerEvent) {
213
243
  if (!this._isDragging) return;
214
244
 
@@ -290,6 +320,11 @@ export class MoniSideSheet extends MoniElement {
290
320
  }
291
321
  }
292
322
 
323
+ /**
324
+ * Aborta limpiamente la interacción de arrastre (Pointer Cancel).
325
+ * Remueve estilos imperativos y clases de estado (`dragging`) si el navegador
326
+ * toma el control o la interacción se interrumpe prematuramente.
327
+ */
293
328
  private _onPointerCancel(e: PointerEvent) {
294
329
  if (!this._isDragging) return;
295
330
  const target = e.target as HTMLElement;
@@ -300,15 +335,30 @@ export class MoniSideSheet extends MoniElement {
300
335
  this._dialog.style.width = '';
301
336
  }
302
337
 
338
+ /**
339
+ * Manejador del botón "Cerrar" explícito (X).
340
+ * Modifica la propiedad `open` a false y despacha el evento de cierre.
341
+ */
303
342
  private _onCloseClick() {
304
343
  this.open = false;
305
344
  this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }));
306
345
  }
307
346
 
347
+ /**
348
+ * Manejador del botón "Atrás".
349
+ * Emite un evento especializado `back` útil para Side Sheets de navegación anidada,
350
+ * permitiendo a los controladores padres reaccionar cambiando la vista interna.
351
+ */
308
352
  private _onBackClick() {
309
353
  this.dispatchEvent(new CustomEvent('back', { bubbles: true, composed: true }));
310
354
  }
311
355
 
356
+ /**
357
+ * Intercepta clics en el backdrop nativo del `<dialog>`.
358
+ * Si el componente es `modal`, hacer clic fuera del panel cierra la interfaz.
359
+ * Verifica `_justDragged` para evitar cerrar si el usuario hizo un click
360
+ * "accidental" derivado del final de un arrastre.
361
+ */
312
362
  private _onDialogClick(e: MouseEvent) {
313
363
  if (this._justDragged) {
314
364
  this._justDragged = false;
@@ -513,6 +563,18 @@ export class MoniSideSheet extends MoniElement {
513
563
  `
514
564
  ];
515
565
 
566
+ /**
567
+ * Renderiza el panel lateral usando un elemento `<dialog>` nativo.
568
+ *
569
+ * **Manejo de estados:**
570
+ * Utiliza clases dinámicas para controlar el lado (`left`/`right`), el modo (`modal`/`standard`),
571
+ * y el estilo desvinculado (`detached`).
572
+ *
573
+ * **Atributo `[open]`:**
574
+ * La vinculación `?open=${this.open}` añade o remueve el atributo `open` nativo de HTML.
575
+ * Las transiciones visuales (slide-in/slide-out) son manejadas por el evento `transitionend`
576
+ * en el método `updated()` usando la clase `.opened`.
577
+ */
516
578
  override render() {
517
579
  const classes = [
518
580
  this.side,
@@ -14,13 +14,13 @@ describe('moni-slider (P3.4 — ticks)', () => {
14
14
  el.remove();
15
15
  });
16
16
 
17
- it('does not render a datalist by default', async () => {
17
+ it('no renderiza un datalist por defecto', async () => {
18
18
  await el.updateComplete;
19
19
  const datalist = el.shadowRoot?.querySelector('datalist');
20
20
  expect(datalist).toBeFalsy();
21
21
  });
22
22
 
23
- it('ticks=true renders a datalist with min and max options', async () => {
23
+ it('ticks=true renderiza un datalist con opciones min y max', async () => {
24
24
  el.ticks = true;
25
25
  await el.updateComplete;
26
26
  const datalist = el.shadowRoot?.querySelector('datalist');
@@ -31,7 +31,7 @@ describe('moni-slider (P3.4 — ticks)', () => {
31
31
  expect(options?.[1].getAttribute('value')).toBe('100');
32
32
  });
33
33
 
34
- it('tick-interval generates datalist options at every N units', async () => {
34
+ it('tick-interval genera opciones de datalist cada N unidades', async () => {
35
35
  el.min = '0';
36
36
  el.max = '10';
37
37
  el.tickInterval = 2;
@@ -43,7 +43,7 @@ describe('moni-slider (P3.4 — ticks)', () => {
43
43
  expect(values).toEqual(['0', '2', '4', '6', '8', '10']);
44
44
  });
45
45
 
46
- it('tick-interval respects a non-zero min', async () => {
46
+ it('tick-interval respeta un min distinto de cero', async () => {
47
47
  el.min = '5';
48
48
  el.max = '15';
49
49
  el.tickInterval = 5;
@@ -54,7 +54,7 @@ describe('moni-slider (P3.4 — ticks)', () => {
54
54
  expect(values).toEqual(['5', '10', '15']);
55
55
  });
56
56
 
57
- it('tick-interval takes precedence over the ticks boolean', async () => {
57
+ it('tick-interval tiene precedencia sobre el booleano ticks', async () => {
58
58
  el.ticks = true;
59
59
  el.min = '0';
60
60
  el.max = '4';
@@ -66,13 +66,13 @@ describe('moni-slider (P3.4 — ticks)', () => {
66
66
  expect(options.length).toBe(5);
67
67
  });
68
68
 
69
- it('reflects the tick-interval attribute on the host', async () => {
69
+ it('refleja el atributo tick-interval en el host', async () => {
70
70
  el.tickInterval = 5;
71
71
  await el.updateComplete;
72
72
  expect(el.getAttribute('tick-interval')).toBe('5');
73
73
  });
74
74
 
75
- it('reflects min and max on the host', async () => {
75
+ it('refleja min y max en el host', async () => {
76
76
  el.min = '10';
77
77
  el.max = '20';
78
78
  await el.updateComplete;
@@ -12,99 +12,190 @@ import { MoniElement, sharedStyles } from './_base/index.js';
12
12
  import './moni-icon.js';
13
13
 
14
14
  /**
15
- * Material Design 3 Slider component.
15
+ * Componente Material Design 3 Slider (Control deslizante).
16
16
  *
17
- * Sliders allow users to select a single value or a range of values from a
18
- * continuous or discrete scale.
17
+ * Los sliders permiten a los usuarios seleccionar un solo valor o un rango de valores
18
+ * desde una escala continua o discreta.
19
19
  *
20
- * **M3 spec reference:** `m3-docs/components/sliders/specs.md`
20
+ * **Referencia a la especificación M3:** `m3-docs/components/sliders/specs.md`
21
21
  *
22
- * **Slider modes:**
23
- * - **Continuous** (default) — Smooth drag between `min` and `max`. Use when
24
- * the exact value does not need to be defined by the user (e.g. volume).
25
- * - **Discrete** — Set `step` to snap to discrete intervals. Tick marks
26
- * appear via the native `<datalist>` element in Chrome/Edge. Firefox does
27
- * not render datalist ticks for range inputs.
28
- * - **Range** (`range` attribute) — Two thumbs that define a minimum and
29
- * maximum value within the slider's extent.
30
- * - **Vertical** (`vertical` attribute) — 90° rotated slider.
22
+ * **Modos de Slider:**
23
+ * - **Continuo (Continuous)** (por defecto) — Arrastre suave entre `min` y `max`. Úsalo cuando
24
+ * no sea necesario que el usuario defina un valor exacto (ej. volumen).
25
+ * - **Discreto (Discrete)** — Configura `step` para ajustarse a intervalos discretos. Las marcas
26
+ * (tick marks) aparecen a través del elemento nativo `<datalist>` en Chrome/Edge. Firefox no
27
+ * renderiza marcas de datalist para inputs de tipo rango.
28
+ * - **Rango (Range)** (atributo `range`) — Dos controles (thumbs) que definen un valor mínimo y
29
+ * máximo dentro de la extensión del slider.
30
+ * - **Vertical** (atributo `vertical`) — Slider rotado 90°.
31
31
  *
32
- * **Value label tooltip:**
33
- * When `indicator` is set, the current value is displayed in a tooltip above
34
- * (or below, via `indicator-placement`) the active thumb during focus/drag.
32
+ * **Tooltip indicador de valor (Value label tooltip):**
33
+ * Cuando se configura `indicator`, el valor actual se muestra en un tooltip por encima
34
+ * (o por debajo, a través de `indicator-placement`) del control activo durante el foco/arrastre.
35
35
  *
36
- * **Tick marks:**
37
- * - `ticks` attribute: adds datalist with marks at `min` and `max` only.
38
- * - `tick-interval` attribute: generates datalist options at every N units
39
- * between `min` and `max`, creating visible tick marks at those positions.
36
+ * **Marcas (Tick marks):**
37
+ * - Atributo `ticks`: agrega datalist con marcas solo en `min` y `max`.
38
+ * - Atributo `tick-interval`: genera opciones de datalist cada N unidades
39
+ * entre `min` y `max`, creando marcas visibles en esas posiciones.
40
40
  *
41
- * **Internal state management:**
42
- * Uses `@state()` for `_value` and `_valueHigh` so the fill track width and
43
- * tooltip position update reactively on every drag `input` event without
44
- * waiting for the `change` event.
41
+ * **Manejo del estado interno:**
42
+ * Usa `@state()` para `_value` y `_valueHigh` de modo que el ancho de la pista de llenado y
43
+ * la posición del tooltip se actualicen de forma reactiva en cada evento `input` de arrastre sin
44
+ * esperar al evento `change`.
45
45
  *
46
- * @fires change - Bubbles and is composed. Fired when dragging ends and the
47
- * value is committed. Read `element.value` for the new value.
48
- * @fires input - Fired on every drag step. Read `element.value` for the
49
- * live value during drag.
46
+ * @fires change - Burbujea y está compuesto. Se dispara cuando termina el arrastre y el
47
+ * valor se confirma. Lee `element.value` para el nuevo valor.
48
+ * @fires input - Se dispara en cada paso del arrastre. Lee `element.value` para el
49
+ * valor en vivo durante el arrastre.
50
50
  *
51
51
  * @example
52
52
  * ```html
53
- * <!-- Continuous slider -->
53
+ * <!-- Slider continuo -->
54
54
  * <moni-slider name="volume" min="0" max="100" value="60"></moni-slider>
55
55
  *
56
- * <!-- Discrete slider with ticks every 10 units -->
56
+ * <!-- Slider discreto con marcas cada 10 unidades -->
57
57
  * <moni-slider step="10" tick-interval="10" indicator></moni-slider>
58
58
  *
59
- * <!-- Range slider -->
59
+ * <!-- Slider de rango -->
60
60
  * <moni-slider range min="0" max="100" value="20" value-high="80"></moni-slider>
61
61
  * ```
62
62
  *
63
- * @csspart slider - The outer slider container.
64
- * @csspart track - The track background.
65
- * @csspart fill - The filled portion of the track.
66
- * @csspart indicator - The value label tooltip.
63
+ * @csspart slider - El contenedor exterior del slider.
64
+ * @csspart track - El fondo de la pista.
65
+ * @csspart fill - La porción llena de la pista.
66
+ * @csspart indicator - El tooltip de la etiqueta de valor.
67
67
  */
68
68
  @customElement('moni-slider')
69
69
  export class MoniSlider extends MoniElement {
70
+ /**
71
+ * Nombre del input del slider, usado en el envío de formularios.
72
+ * @type {string}
73
+ */
70
74
  @property({ reflect: true }) name = '';
75
+
76
+ /**
77
+ * Valor mínimo del slider.
78
+ * @type {string}
79
+ * @default '0'
80
+ */
71
81
  @property({ reflect: true }) min = '0';
82
+
83
+ /**
84
+ * Valor máximo del slider.
85
+ * @type {string}
86
+ * @default '100'
87
+ */
72
88
  @property({ reflect: true }) max = '100';
89
+
90
+ /**
91
+ * Granularidad del slider. Debe ser un número positivo.
92
+ * @type {string}
93
+ */
73
94
  @property({ reflect: true }) step = '';
95
+
96
+ /**
97
+ * Anula (overrides) el intervalo predeterminado de las marcas cuando `ticks` es verdadero.
98
+ * @type {number | null}
99
+ */
74
100
  @property({ type: Number, reflect: true, attribute: 'tick-interval' })
75
101
  tickInterval: number | null = null;
102
+
103
+ /**
104
+ * Nombre del icono (Material Symbols) mostrado dentro del control (thumb) del slider.
105
+ * @type {string}
106
+ */
76
107
  @property({ reflect: true, attribute: 'inset-icon' }) insetIcon = '';
108
+
109
+ /**
110
+ * Ubicación del tooltip indicador de valor.
111
+ * @type {'top' | 'bottom'}
112
+ * @default 'top'
113
+ */
77
114
  @property({ reflect: true, attribute: 'indicator-placement' })
78
115
  indicatorPlacement: 'top' | 'bottom' = 'top';
116
+
117
+ /**
118
+ * Grosor/tamaño de la pista y el control (thumb) del slider.
119
+ * @type {'tiny' | 'small' | 'medium' | 'large' | 'extra'}
120
+ * @default 'medium'
121
+ */
79
122
  @property({ reflect: true })
80
123
  size: 'tiny' | 'small' | 'medium' | 'large' | 'extra' = 'medium';
81
124
 
82
- // Boolean attributes
125
+ /**
126
+ * Habilita el modo de rango (dos controles: `value` y `valueEnd`).
127
+ * @type {boolean}
128
+ */
83
129
  @property({ type: Boolean, reflect: true }) range = false;
130
+
131
+ /**
132
+ * Deshabilita el slider.
133
+ * @type {boolean}
134
+ */
84
135
  @property({ type: Boolean, reflect: true }) disabled = false;
136
+
137
+ /**
138
+ * Renderiza marcas (tick marks) a lo largo de la pista en cada intervalo de paso.
139
+ * @type {boolean}
140
+ */
85
141
  @property({ type: Boolean, reflect: true }) ticks = false;
142
+
143
+ /**
144
+ * Muestra un indicador de tooltip mostrando el(los) valor(es) actual(es) mientras se arrastra.
145
+ * @type {boolean}
146
+ */
86
147
  @property({ type: Boolean, reflect: true }) indicator = false;
148
+
149
+ /**
150
+ * Renderiza el slider de forma vertical en lugar de horizontal.
151
+ * @type {boolean}
152
+ */
87
153
  @property({ type: Boolean, reflect: true, attribute: 'vertical' }) isVertical = false;
88
154
 
89
- /** Internal reactive statetriggers CSS var updates on every input event */
155
+ /** Estado reactivo internodispara actualizaciones de variables CSS en cada evento de input */
90
156
  @state() private _value = '50';
91
157
  @state() private _valueEnd = '75';
92
158
 
159
+ /**
160
+ * El valor primario actual del slider (o el límite inferior en modo de rango).
161
+ * @type {string}
162
+ */
93
163
  @property({ reflect: true })
94
164
  get value() { return this._value; }
165
+ /**
166
+ * Intercepta asignaciones imperativas (`element.value = "X"`) para actualizar
167
+ * el estado interno de Lit, garantizando reactividad instantánea del DOM.
168
+ */
95
169
  set value(v: string) { this._value = v; }
96
170
 
171
+ /**
172
+ * El valor límite superior actual (solo usado cuando `range` es verdadero).
173
+ * @type {string}
174
+ */
97
175
  @property({ reflect: true, attribute: 'value-end' })
98
176
  get valueEnd() { return this._valueEnd; }
177
+ /**
178
+ * Setter reactivo para el límite superior (usado exclusivamente en modo `range`).
179
+ */
99
180
  set valueEnd(v: string) { this._valueEnd = v; }
100
181
 
182
+ /**
183
+ * Calcula el porcentaje de llenado de la barra (0-100) basándose en el valor actual,
184
+ * el mínimo y el máximo. Se utiliza intensivamente para definir variables CSS (como `--_pct`).
185
+ */
101
186
  private _pct(v: string) {
102
187
  const min = parseFloat(this.min) || 0;
103
188
  const max = parseFloat(this.max) || 100;
104
189
  const val = parseFloat(v) || 0;
190
+ // Math.max/min asegura que no desborde si por alguna razón val > max o val < min
105
191
  return Math.max(0, Math.min(100, ((val - min) / (max - min)) * 100));
106
192
  }
107
193
 
194
+ /**
195
+ * Maneja el evento nativo "input" de los inputs type="range" subyacentes.
196
+ * Se dispara contínuamente mientras el usuario arrastra el slider.
197
+ * Actualiza el estado reactivo inmediatamente para que la UI responda en tiempo real (60fps).
198
+ */
108
199
  private _onInput(e: Event, index: number) {
109
200
  const target = e.target as HTMLInputElement;
110
201
  if (index === 0) {
@@ -112,9 +203,14 @@ export class MoniSlider extends MoniElement {
112
203
  } else {
113
204
  this._valueEnd = target.value;
114
205
  }
206
+ // Redisparamos el evento hacia afuera para que los frameworks (React/Vue/Angular) puedan atraparlo
115
207
  this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
116
208
  }
117
209
 
210
+ /**
211
+ * Maneja el evento nativo "change", que se dispara solo cuando el usuario SUELTA el slider
212
+ * (al terminar la interacción). Útil para peticiones HTTP pesadas o validaciones finales.
213
+ */
118
214
  private _onChange(e: Event, index: number) {
119
215
  const target = e.target as HTMLInputElement;
120
216
  if (index === 0) {
@@ -126,11 +222,11 @@ export class MoniSlider extends MoniElement {
126
222
  }
127
223
 
128
224
  /**
129
- * Render a `<datalist>` element with tick options. When `tick-interval`
130
- * is set, generates options at every N units between min and max.
131
- * Otherwise, if `ticks` is set, just min and max.
132
- * Browsers that support datalist ticks for range (Chrome, Edge) will
133
- * render visual marks; Firefox ignores them.
225
+ * Renderiza un elemento `<datalist>` con opciones de marcas. Cuando se establece
226
+ * `tick-interval`, genera opciones cada N unidades entre el mínimo y el máximo.
227
+ * De lo contrario, si se establece `ticks`, solo mínimo y máximo.
228
+ * Los navegadores que soportan marcas de datalist para inputs de rango (Chrome, Edge)
229
+ * renderizarán marcas visuales; Firefox las ignora.
134
230
  */
135
231
  private _renderDatalist() {
136
232
  if (this.tickInterval != null && this.tickInterval > 0) {
@@ -358,6 +454,33 @@ export class MoniSlider extends MoniElement {
358
454
  `
359
455
  ];
360
456
 
457
+ /**
458
+ * Ensambla la estructura del Shadow DOM del slider.
459
+ *
460
+ * **Cálculo de la pista llena:**
461
+ * `pct` y `pctEnd` son valores porcentuales (0–100) derivados de
462
+ * `_pct(value)`. Se inyectan como propiedades CSS personalizadas `--_start` y `--_end`
463
+ * en el contenedor `.slider`. El pseudo-elemento CSS `::before`
464
+ * utiliza estos valores en un `clip-path: polygon(...)` para renderizar la parte
465
+ * no llena de la pista, mientras que el `<span>` renderiza la parte llena.
466
+ *
467
+ * **Modo Rango (`range=true`):**
468
+ * - Se renderizan dos elementos `<input type="range">` (uno para el límite inferior,
469
+ * otro para el límite superior).
470
+ * - El CSS los superpone absolutamente para que los controles (thumbs) compartan la misma línea de pista.
471
+ * - `--_start` equivale al porcentaje del control inferior; `--_end` equivale a `100 - pctEnd`.
472
+ *
473
+ * **Tooltip indicador:**
474
+ * Los elementos tooltip `.tooltip-1` / `.tooltip-2` están posicionados absolutamente
475
+ * utilizando `inset-inline-start: ${pct}%` de modo que siguen al control activo
476
+ * por encima (o por debajo) a medida que el usuario arrastra. La visibilidad se controla
477
+ * puramente a través de selectores CSS `:focus` — no se requiere JavaScript.
478
+ *
479
+ * **Datalist de marcas (Tick datalist):**
480
+ * `_renderDatalist()` emite un `<datalist id="ticks">` solo cuando `ticks` o
481
+ * `tick-interval` está establecido. Chrome/Edge renderizan marcas nativas en inputs de rango
482
+ * que referencian un datalist a través del atributo `list`; Firefox lo ignora.
483
+ */
361
484
  override render() {
362
485
  const pct = this._pct(this._value);
363
486
  const pctEnd = this._pct(this._valueEnd);