@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
@@ -22,49 +22,49 @@ gsap.registerPlugin(Flip, CustomEase);
22
22
  CustomEase.create('morph-open', '0.15, 0.85, 0.2, 1');
23
23
  CustomEase.create('morph-close', '0.4, 0, 0.2, 1');
24
24
  /**
25
- * Material Design 3 Morph Modal component.
25
+ * Componente Material Design 3 Morph Modal.
26
26
  *
27
- * A highly interactive dialog that uses GSAP FLIP (First, Last, Invert, Play)
28
- * animations to seamlessly "morph" any clicked element on the page into a full
29
- * modal surface, and morph it back when closed.
27
+ * Un diálogo altamente interactivo que usa animaciones GSAP FLIP (First, Last, Invert, Play)
28
+ * para "transformar" (morph) sin problemas cualquier elemento clickeado en la página en una superficie
29
+ * modal completa, y transformarlo de vuelta cuando se cierra.
30
30
  *
31
- * **Motion choreography:**
32
- * This component implements the complex M3 container transform pattern. When
33
- * triggered, the source element visually expands into the modal. The modal's
34
- * background color, border radius, and typography fade and cross-dissolve
35
- * perfectly with the origin element.
31
+ * **Coreografía de movimiento:**
32
+ * Este componente implementa el patrón complejo de transformación de contenedor de M3. Cuando
33
+ * se activa, el elemento origen se expande visualmente hacia el modal. El color de fondo,
34
+ * el radio del borde y la tipografía del modal se desvanecen y se funden
35
+ * perfectamente con el elemento de origen.
36
36
  *
37
- * **Triggering mechanism:**
38
- * Consumers must provide the `triggerEvent` property containing the original
39
- * pointer/click `Event` that initiated the open action. The component extracts
40
- * the `event.target` (or uses `clientX/Y` as a fallback) to determine the exact
41
- * origin coordinates for the GSAP FLIP animation.
37
+ * **Mecanismo de activación:**
38
+ * Los consumidores deben proporcionar la propiedad `triggerEvent` que contenga el `Event`
39
+ * de puntero/clic original que inició la acción de apertura. El componente extrae
40
+ * el `event.target` (o usa `clientX/Y` como respaldo) para determinar las coordenadas
41
+ * de origen exactas para la animación GSAP FLIP.
42
42
  *
43
- * **Dialog behavior:**
44
- * Internally, it uses the native `<dialog>` element. It traps focus, supports
45
- * `Escape` to close, and handles scrim/backdrop clicks (which trigger the
46
- * reverse morph animation before actually closing the native dialog).
43
+ * **Comportamiento del diálogo:**
44
+ * Internamente, utiliza el elemento nativo `<dialog>`. Atrapa el foco, soporta
45
+ * `Escape` para cerrar, y maneja clics en el fondo/scrim (que activan la
46
+ * animación de morphing inverso antes de cerrar realmente el diálogo nativo).
47
47
  *
48
48
  * @example
49
49
  * ```html
50
- * <moni-morph-modal id="myModal" title="Details">
51
- * <p>This modal morphed from the button you just clicked.</p>
50
+ * <moni-morph-modal id="myModal" title="Detalles">
51
+ * <p>Este modal se transformó desde el botón que acabas de clickear.</p>
52
52
  * </moni-morph-modal>
53
53
  *
54
- * <moni-button id="openBtn">Open Details</moni-button>
54
+ * <moni-button id="openBtn">Abrir Detalles</moni-button>
55
55
  *
56
56
  * <script>
57
57
  * const modal = document.getElementById('myModal');
58
58
  * document.getElementById('openBtn').addEventListener('click', (e) => {
59
- * modal.triggerEvent = e; // Pass the event so it knows where to morph from
59
+ * modal.triggerEvent = e; // Pasa el evento para que sepa desde dónde transformarse
60
60
  * modal.open = true;
61
61
  * });
62
62
  * </script>
63
63
  * ```
64
64
  *
65
- * @slot default - The main body content of the modal.
66
- * @slot header - Custom header content (overrides `title` attribute).
67
- * @slot actions - Action buttons displayed at the bottom right.
65
+ * @slot default - El contenido del cuerpo principal del modal.
66
+ * @slot header - Contenido de encabezado personalizado (sobrescribe el atributo `title`).
67
+ * @slot actions - Botones de acción mostrados en la parte inferior derecha.
68
68
  */
69
69
  const litBool = {
70
70
  fromAttribute: (value) => value !== 'false' && value !== null,
@@ -73,20 +73,95 @@ const litBool = {
73
73
  let MoniMorphModal = class MoniMorphModal extends MoniElement {
74
74
  constructor() {
75
75
  super(...arguments);
76
+ /**
77
+ * Selector del elemento disparador desde el cual transformarse (ej. '#fab' o '.my-button').
78
+ * Si se omite, el modal aún puede activarse programáticamente estableciendo `open = true`.
79
+ * @type {string}
80
+ */
76
81
  this.target = '';
82
+ /**
83
+ * Controla el estado abierto/cerrado del modal.
84
+ * Puede establecerse directamente, o se gestiona internamente cuando se hace clic en el elemento `target`.
85
+ * @type {boolean}
86
+ */
77
87
  this.open = false;
88
+ /**
89
+ * Si es true, renderiza un fondo y atrapa el foco, actuando como un verdadero diálogo modal.
90
+ * @type {boolean}
91
+ * @default true
92
+ */
78
93
  this.modal = true;
94
+ /**
95
+ * Posición preferida del modal en relación con la ventana gráfica.
96
+ * @type {Placement}
97
+ * @default 'center'
98
+ */
79
99
  this.placement = 'center';
100
+ /**
101
+ * El ancho del modal cuando está completamente expandido.
102
+ * @type {string}
103
+ * @default '22rem'
104
+ */
80
105
  this.expandedWidth = '22rem';
106
+ /**
107
+ * La altura del modal cuando está completamente expandido.
108
+ * @type {string}
109
+ * @default '18rem'
110
+ */
81
111
  this.expandedHeight = '18rem';
112
+ /**
113
+ * Si es true, hacer clic fuera del modal lo cerrará.
114
+ * @type {boolean}
115
+ * @default true
116
+ */
82
117
  this.closeOnClickOutside = true;
118
+ /**
119
+ * Si es true, presionar la tecla Escape cerrará el modal.
120
+ * @type {boolean}
121
+ * @default true
122
+ */
83
123
  this.closeOnEsc = true;
124
+ /**
125
+ * Si es true, muestra un botón de icono de cierre por defecto en el encabezado.
126
+ * @type {boolean}
127
+ */
84
128
  this.showCloseButton = false;
129
+ /**
130
+ * Si es true, intenta fundir/transformar una etiqueta del disparador hacia el encabezado del modal.
131
+ * @type {boolean}
132
+ */
85
133
  this.morphLabel = false;
134
+ /**
135
+ * Un selector CSS personalizado utilizado para encontrar el elemento de etiqueta específico dentro del target a transformar.
136
+ * @type {string}
137
+ */
86
138
  this.morphLabelSelector = '';
139
+ /**
140
+ * Si es true, renderiza un fondo atenuado detrás del modal.
141
+ * @type {boolean}
142
+ * @default true
143
+ */
87
144
  this.hasBackdrop = true;
145
+ /**
146
+ * Si es true, oculta el elemento disparador (target) mientras el modal está abierto.
147
+ * @type {boolean}
148
+ */
88
149
  this.hideTarget = false;
150
+ /**
151
+ * Si es true, fuerza al modal a cubrir visualmente la ubicación original del target antes de expandirse.
152
+ * @type {boolean}
153
+ */
89
154
  this.coverTarget = false;
155
+ /**
156
+ * Si es true, el modal calcula automáticamente su tamaño final basándose en el contenido interno (ignora expandedWidth y expandedHeight).
157
+ * @type {boolean}
158
+ */
159
+ this.autoSize = false;
160
+ /**
161
+ * Si es true, aplica un efecto de desenfoque (blur) al contenido durante la animación de entrada y salida.
162
+ * @type {boolean}
163
+ */
164
+ this.blurContent = false;
90
165
  this._hasHeader = false;
91
166
  this._hasFooter = false;
92
167
  this._hasTriggerLabel = false;
@@ -97,8 +172,20 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
97
172
  this._zIndex = 100;
98
173
  this._morphEls = { text: null, icon: null };
99
174
  this._targetStylesCache = new Map();
175
+ /**
176
+ * Handler encapsulado para el evento click en el trigger.
177
+ * Dispara la animación de apertura.
178
+ */
100
179
  this._onTargetClick = () => this.show();
180
+ /**
181
+ * Handler encapsulado para interceptar teclas a nivel global (ej: Escape).
182
+ */
101
183
  this._onDocKeydown = (e) => this._handleDocKeydown(e);
184
+ /**
185
+ * Handler de clics globales para detectar interacciones fuera del modal (Click outside).
186
+ * Sólo cierra el modal si `closeOnClickOutside` es true y el usuario no hizo clic
187
+ * dentro de las dimensiones del panel animado ni del botón original.
188
+ */
102
189
  this._onDocClick = (e) => {
103
190
  if (!this.open || !this._visible || !this.closeOnClickOutside)
104
191
  return;
@@ -134,6 +221,12 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
134
221
  this._restoreTargetContent();
135
222
  super.disconnectedCallback();
136
223
  }
224
+ /**
225
+ * Hook del ciclo de vida reactivo (Lit).
226
+ * Observa cambios asíncronos en el atributo `target` para re-bindear el disparador,
227
+ * y reacciona a cambios programáticos de la propiedad `open` para ejecutar
228
+ * imperativamente la animación de apertura (`show`) o cierre (`hide`).
229
+ */
137
230
  updated(changed) {
138
231
  super.updated(changed);
139
232
  if (changed.has('target')) {
@@ -146,21 +239,34 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
146
239
  this.hide();
147
240
  }
148
241
  }
242
+ /**
243
+ * Busca en el DOM el elemento que dispara el modal (el trigger) basándose en la propiedad `target`.
244
+ * Establece el listener de click que iniciará la animación de morphing.
245
+ */
149
246
  _resolveTarget() {
150
247
  if (!this.target)
151
248
  return;
152
249
  const el = document.querySelector(this.target);
153
250
  if (!el) {
154
- console.warn(`[moni-morph-modal] target "${this.target}" not found`);
251
+ // Es normal que no se encuentre el target si está condicionado por un #if en Svelte
252
+ // Se intentará resolver nuevamente al llamar a show()
155
253
  return;
156
254
  }
255
+ // Si el target cambió dinámicamente, limpiamos el listener anterior para evitar memory leaks
157
256
  if (this._targetEl && this._targetEl !== el) {
158
257
  this._targetEl.removeEventListener('click', this._onTargetClick);
159
258
  }
160
259
  this._targetEl = el;
161
260
  this._targetEl.addEventListener('click', this._onTargetClick);
162
261
  }
262
+ /**
263
+ * Dispara la apertura del modal y coordina la animación de FLIP (First, Last, Invert, Play) / Morphing.
264
+ * 1. Oculta visualmente el target original.
265
+ * 2. Posiciona el modal colapsado exactamente sobre el target original (mismas dimensiones, color, y radios).
266
+ * 3. Expande fluidamente el modal a sus dimensiones finales mediante transformaciones CSS.
267
+ */
163
268
  show() {
269
+ // Prevenimos ejecuciones concurrentes si ya se está animando o está visible
164
270
  if (this._isAnimating || this._visible)
165
271
  return;
166
272
  if (!this._targetEl)
@@ -170,25 +276,35 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
170
276
  return;
171
277
  }
172
278
  this._isAnimating = true;
279
+ // Flag interno para evitar loops infinitos en el hook `updated()`
173
280
  this._handlingOpenChange = true;
174
281
  this.open = true;
175
282
  this._handlingOpenChange = false;
283
+ // Apilamos el modal globalmente para manejar correctamente el z-index en modales anidados
176
284
  MoniMorphModal_1._openStack.push(this);
177
285
  this._zIndex = 1000 + MoniMorphModal_1._openStack.length;
286
+ // Aplicamos variables CSS inline para gestionar las transiciones del backdrop y el modal
178
287
  this.style.zIndex = String(this._zIndex);
179
288
  this.style.setProperty('--_z-index', String(this._zIndex));
180
289
  this.style.setProperty('--_backdrop-duration', '0.38s');
181
290
  this.style.setProperty('--_backdrop-ease', 'cubic-bezier(0.15, 0.85, 0.2, 1)');
291
+ // Fase "First": Ocultamos o cubrimos el trigger original según la configuración del desarrollador
182
292
  this._hideTargetContent();
183
293
  void this.updateComplete.then(async () => {
184
294
  if (!this._targetEl || !this._panel || !this._inner) {
185
295
  this._isAnimating = false;
186
296
  return;
187
297
  }
298
+ // Añadimos clase para prevenir interacciones durante la animación
188
299
  this._panel.classList.add('is-animating');
300
+ // Esperamos un frame para asegurar que el navegador aplicó el `display: block`
301
+ // necesario antes de poder leer las dimensiones.
189
302
  await new Promise((resolve) => requestAnimationFrame(resolve));
303
+ // 1. "First": Calculamos el estado visual actual del trigger
190
304
  const targetState = this._getTargetState(this._targetEl);
191
305
  const panel = this._panel;
306
+ // 2. "Invert": Posicionamos el modal como un clon visual exacto del trigger.
307
+ // Desactivamos la sombra y forzamos el color/borde para coincidir con el botón/FAB.
192
308
  this._applyRect(panel, targetState.rect);
193
309
  panel.style.backgroundColor = targetState.backgroundColor;
194
310
  panel.style.color = targetState.color;
@@ -201,20 +317,27 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
201
317
  if (this._backdrop) {
202
318
  this._backdrop.style.zIndex = String(this._zIndex - 1);
203
319
  }
320
+ // Limpiamos elementos fantasma previos si el usuario interactuó muy rápido
204
321
  this._cleanupMorphElements();
322
+ // Respetamos la preferencia de sistema de animaciones reducidas por accesibilidad (a11y)
205
323
  const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
324
+ // 3. Verificamos si debemos orquestar la animación compleja del label flotante cruzado
206
325
  let shouldMorph = this._shouldMorphLabel() && !prefersReducedMotion;
207
326
  const morphTargets = [];
208
327
  let source = null;
209
328
  const headerWrapper = this.shadowRoot.querySelector('.header-morph-wrapper');
210
329
  if (shouldMorph) {
330
+ // Preparamos la estructura del header para que el texto real entre con un fade in
211
331
  this._animateLabelOpen();
332
+ // Buscamos el ícono y el texto dentro del botón de origen (trigger)
212
333
  source = this._resolveMorphSource();
334
+ // Si existe un nodo de texto, creamos un elemento flotante (fantasma) en el modal
213
335
  if (source.text) {
214
336
  const el = this._createMorphText(source.text.content, source.text.sourceEl);
215
337
  this._positionElement(el, source.text.rect);
216
338
  morphTargets.push(el);
217
339
  }
340
+ // Hacemos lo mismo si el botón original contenía un icono
218
341
  if (source.icon) {
219
342
  const el = this._createMorphIcon(source.icon.element);
220
343
  this._positionElement(el, source.icon.rect);
@@ -224,27 +347,56 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
224
347
  shouldMorph = false;
225
348
  }
226
349
  if (shouldMorph && headerWrapper) {
350
+ // Ocultamos temporalmente el contenido final del header mientras animamos los elementos flotantes
227
351
  headerWrapper.style.opacity = '0';
228
352
  }
353
+ // Capturamos el estado "First" del panel (tamaño pequeño de botón) y de los elementos flotantes
229
354
  const state = Flip.getState(panel, {
230
355
  props: 'backgroundColor,borderRadius,color,boxShadow'
231
356
  });
232
357
  const morphState = Flip.getState(morphTargets, {
233
358
  props: 'color,fontSize,fontWeight,lineHeight'
234
359
  });
235
- const finalRect = this._computeFinalRect(targetState.rect);
360
+ // Fase "Last": Calculamos las dimensiones expandidas del modal basándonos en la configuración
361
+ let naturalSize;
362
+ if (this.autoSize) {
363
+ const prevW = panel.style.getPropertyValue('--_panel-width');
364
+ const prevH = panel.style.getPropertyValue('--_panel-height');
365
+ const prevPanelW = panel.style.width;
366
+ const prevPanelH = panel.style.height;
367
+ panel.style.width = 'auto';
368
+ panel.style.height = 'auto';
369
+ panel.style.setProperty('--_panel-width', 'max-content');
370
+ panel.style.setProperty('--_panel-height', 'max-content');
371
+ const bodyEl = this.shadowRoot.querySelector('.body');
372
+ const prevOverflow = bodyEl ? bodyEl.style.overflow : '';
373
+ if (bodyEl)
374
+ bodyEl.style.overflow = 'visible';
375
+ // Forzamos al panel-inner a expandirse para medir su contenido real
376
+ naturalSize = { width: this._inner.scrollWidth, height: this._inner.scrollHeight };
377
+ panel.style.setProperty('--_panel-width', prevW);
378
+ panel.style.setProperty('--_panel-height', prevH);
379
+ panel.style.width = prevPanelW;
380
+ panel.style.height = prevPanelH;
381
+ if (bodyEl)
382
+ bodyEl.style.overflow = prevOverflow;
383
+ }
384
+ const finalRect = this._computeFinalRect(targetState.rect, naturalSize);
236
385
  panel.style.setProperty('--_panel-width', `${finalRect.width}px`);
237
386
  panel.style.setProperty('--_panel-height', `${finalRect.height}px`);
238
387
  this._applyRect(panel, finalRect);
388
+ // Removemos las forzadas de estilo del trigger para que herede las propias del modal
239
389
  panel.style.backgroundColor = '';
240
390
  panel.style.color = '';
241
391
  panel.style.borderRadius = '';
242
392
  panel.style.boxShadow = '';
243
393
  if (shouldMorph && source) {
394
+ // Medimos dónde van a terminar el icono y el texto dentro del modal ya expandido
244
395
  const textRect = this._measureHeaderTextRect();
245
396
  const iconRect = this._measureHeaderIconRect();
246
397
  const headerComputed = window.getComputedStyle(this._header);
247
398
  if (this._morphEls.text && textRect) {
399
+ // Movemos el texto flotante a su destino y le pedimos que adopte los estilos del header
248
400
  this._positionElement(this._morphEls.text, textRect);
249
401
  this._morphEls.text.style.color = headerComputed.color || 'var(--on-surface)';
250
402
  this._morphEls.text.style.fontSize = headerComputed.fontSize || 'inherit';
@@ -252,6 +404,7 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
252
404
  this._morphEls.text.style.lineHeight = headerComputed.lineHeight || 'inherit';
253
405
  }
254
406
  if (this._morphEls.icon && iconRect) {
407
+ // Hacemos lo mismo con el icono
255
408
  this._positionElement(this._morphEls.icon, iconRect);
256
409
  this._morphEls.icon.style.color = headerComputed.color || 'var(--on-surface)';
257
410
  }
@@ -264,28 +417,34 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
264
417
  onComplete: () => {
265
418
  this._isAnimating = false;
266
419
  this._visible = true;
267
- this._panel.classList.remove('is-animating');
268
420
  this._cleanupMorphElements();
269
421
  if (headerWrapper)
270
422
  headerWrapper.style.opacity = '1';
271
423
  }
272
424
  });
273
425
  if (morphTargets.length > 0) {
274
- Flip.from(morphState, {
426
+ if (this.blurContent) {
427
+ gsap.set(morphTargets, { filter: 'blur(16px)' });
428
+ }
429
+ const flipConfig = {
275
430
  targets: morphTargets,
276
431
  duration: 0.38,
277
432
  ease: 'morph-open',
278
433
  zIndex: this._zIndex + 10
279
- });
434
+ };
435
+ if (this.blurContent) {
436
+ flipConfig.filter = 'blur(0px)';
437
+ flipConfig.clearProps = 'filter';
438
+ }
439
+ Flip.from(morphState, flipConfig);
280
440
  }
281
- const bodyChildren = Array.from(this.shadowRoot.querySelectorAll('.body > *'));
282
- const fadeTargets = [
283
- ...bodyChildren,
284
- this.shadowRoot.querySelector('footer'),
285
- this.shadowRoot.querySelector('.close-btn')
286
- ].filter(Boolean);
287
- gsap.set(fadeTargets, { opacity: 0, y: 8, filter: 'blur(8px)' });
288
- gsap.fromTo(fadeTargets, { opacity: 0, y: 8, filter: 'blur(8px)' }, {
441
+ const body = this.shadowRoot.querySelector('.body');
442
+ const footer = this.shadowRoot.querySelector('footer');
443
+ const closeBtn = this.shadowRoot.querySelector('.close-btn');
444
+ const fadeTargets = [body, footer, closeBtn].filter(Boolean);
445
+ const initialBlur = this.blurContent ? 'blur(16px)' : 'blur(0px)';
446
+ gsap.set(fadeTargets, { opacity: 0, y: 8, filter: initialBlur });
447
+ gsap.fromTo(fadeTargets, { opacity: 0, y: 8, filter: initialBlur }, {
289
448
  opacity: 1,
290
449
  y: 0,
291
450
  filter: 'blur(0px)',
@@ -295,10 +454,18 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
295
454
  ease: 'power2.out',
296
455
  onComplete: () => {
297
456
  gsap.set(fadeTargets, { clearProps: 'opacity,transform,filter' });
457
+ this._panel.classList.remove('is-animating');
298
458
  }
299
459
  });
300
460
  });
301
461
  }
462
+ /**
463
+ * Solución a un caso borde de FLIP Animations:
464
+ * Si el `.panel` original carece de un color de fondo sólido, la interpolación
465
+ * de GSAP puede comportarse erráticamente. Este método "asciende" el árbol del DOM
466
+ * hasta encontrar un padre con un color de fondo sólido y lo aplica, garantizando
467
+ * que el modal no colapse de forma transparente de regreso hacia el gatillo.
468
+ */
302
469
  _ensureSolidPanelBackground() {
303
470
  if (!this._panel)
304
471
  return;
@@ -327,16 +494,15 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
327
494
  this._ensureSolidPanelBackground();
328
495
  this.style.setProperty('--_backdrop-duration', '0.3s');
329
496
  this.style.setProperty('--_backdrop-ease', 'cubic-bezier(0.4, 0, 0.2, 1)');
330
- const bodyChildren = Array.from(this.shadowRoot.querySelectorAll('.body > *'));
331
- const fadeTargets = [
332
- ...bodyChildren,
333
- this.shadowRoot.querySelector('footer'),
334
- this.shadowRoot.querySelector('.close-btn')
335
- ].filter(Boolean);
497
+ const body = this.shadowRoot.querySelector('.body');
498
+ const footer = this.shadowRoot.querySelector('footer');
499
+ const closeBtn = this.shadowRoot.querySelector('.close-btn');
500
+ const fadeTargets = [body, footer, closeBtn].filter(Boolean);
336
501
  const headerWrapper = this.shadowRoot.querySelector('.header-morph-wrapper');
502
+ const targetBlur = this.blurContent ? 'blur(12px)' : 'blur(0px)';
337
503
  gsap.fromTo(fadeTargets, { opacity: 1, filter: 'blur(0px)' }, {
338
504
  opacity: 0,
339
- filter: 'blur(4px)',
505
+ filter: targetBlur,
340
506
  duration: 0.12,
341
507
  ease: 'power2.in',
342
508
  onComplete: () => {
@@ -380,7 +546,29 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
380
546
  props: 'color,fontSize,fontWeight,lineHeight'
381
547
  });
382
548
  const targetState = this._getTargetState(this._targetEl);
383
- const finalRect = this._computeFinalRect(targetState.rect);
549
+ let naturalSize;
550
+ if (this.autoSize) {
551
+ const prevW = panel.style.getPropertyValue('--_panel-width');
552
+ const prevH = panel.style.getPropertyValue('--_panel-height');
553
+ const prevPanelW = panel.style.width;
554
+ const prevPanelH = panel.style.height;
555
+ panel.style.width = 'auto';
556
+ panel.style.height = 'auto';
557
+ panel.style.setProperty('--_panel-width', 'max-content');
558
+ panel.style.setProperty('--_panel-height', 'max-content');
559
+ const bodyEl = this.shadowRoot.querySelector('.body');
560
+ const prevOverflow = bodyEl ? bodyEl.style.overflow : '';
561
+ if (bodyEl)
562
+ bodyEl.style.overflow = 'visible';
563
+ naturalSize = { width: this._inner.scrollWidth, height: this._inner.scrollHeight };
564
+ panel.style.setProperty('--_panel-width', prevW);
565
+ panel.style.setProperty('--_panel-height', prevH);
566
+ panel.style.width = prevPanelW;
567
+ panel.style.height = prevPanelH;
568
+ if (bodyEl)
569
+ bodyEl.style.overflow = prevOverflow;
570
+ }
571
+ const finalRect = this._computeFinalRect(targetState.rect, naturalSize);
384
572
  panel.style.setProperty('--_panel-width', `${finalRect.width}px`);
385
573
  panel.style.setProperty('--_panel-height', `${finalRect.height}px`);
386
574
  this._applyRect(panel, targetState.rect);
@@ -438,12 +626,19 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
438
626
  }
439
627
  });
440
628
  if (morphTargets.length > 0) {
441
- Flip.from(morphState, {
629
+ if (this.blurContent) {
630
+ gsap.set(morphTargets, { filter: 'blur(0px)' });
631
+ }
632
+ const flipConfig = {
442
633
  targets: morphTargets,
443
634
  duration: 0.3,
444
635
  ease: 'morph-close',
445
636
  zIndex: this._zIndex + 10
446
- });
637
+ };
638
+ if (this.blurContent) {
639
+ flipConfig.filter = 'blur(12px)';
640
+ }
641
+ Flip.from(morphState, flipConfig);
447
642
  }
448
643
  }
449
644
  });
@@ -463,6 +658,12 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
463
658
  e.stopPropagation();
464
659
  this.hide();
465
660
  }
661
+ /**
662
+ * Fase "First" de la animación (Cierre del Trigger):
663
+ * Determina cómo desaparecer u ocultar el botón original mientras el modal ocupa su lugar.
664
+ * Mantiene el cache de opacidades y colores originales para poder restaurarlos
665
+ * idénticamente al cerrar el modal (evitando saltos visuales).
666
+ */
466
667
  _hideTargetContent() {
467
668
  if (!this._targetEl)
468
669
  return;
@@ -495,6 +696,10 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
495
696
  saveAndHide(icon, 'opacity');
496
697
  }
497
698
  }
699
+ /**
700
+ * Restaura puramente los estilos originales del botón Trigger tras terminar
701
+ * la animación de cierre, leyendo las opacidades/colores almacenados en caché.
702
+ */
498
703
  _restoreTargetContent() {
499
704
  if (!this._targetEl)
500
705
  return;
@@ -559,10 +764,10 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
559
764
  }
560
765
  }
561
766
  _animateLabelOpen() {
562
- // No-op: label morphing is handled by the unified FLIP timeline in show()
767
+ // No-op: el morphing de la etiqueta es manejado por el timeline unificado FLIP en show()
563
768
  }
564
769
  _animateLabelClose() {
565
- // No-op: label morphing is handled by the unified FLIP timeline in hide()
770
+ // No-op: el morphing de la etiqueta es manejado por el timeline unificado FLIP en hide()
566
771
  }
567
772
  _createMorphText(sourceText, sourceEl) {
568
773
  const el = document.createElement('div');
@@ -866,12 +1071,12 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
866
1071
  el.style.width = `${rect.width}px`;
867
1072
  el.style.height = `${rect.height}px`;
868
1073
  }
869
- _computeFinalRect(targetRect) {
1074
+ _computeFinalRect(targetRect, naturalSize) {
870
1075
  const vw = window.innerWidth;
871
1076
  const vh = window.innerHeight;
872
1077
  const padding = 16;
873
- let width = this._parseSize(this.expandedWidth, vw);
874
- let height = this._parseSize(this.expandedHeight, vh);
1078
+ let width = this.autoSize && naturalSize ? naturalSize.width : this._parseSize(this.expandedWidth, vw);
1079
+ let height = this.autoSize && naturalSize ? naturalSize.height : this._parseSize(this.expandedHeight, vh);
875
1080
  width = Math.min(width, vw - padding * 2);
876
1081
  height = Math.min(height, vh - padding * 2);
877
1082
  let top = targetRect.top;
@@ -1046,7 +1251,7 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
1046
1251
  overflow: hidden;
1047
1252
  background-color: var(--surface-container-high);
1048
1253
  color: var(--on-surface);
1049
- border-radius: 1.75rem;
1254
+ border-radius: var(--moni-morph-panel-radius, 1.75rem);
1050
1255
  box-shadow: var(--elevate2);
1051
1256
  z-index: var(--_z-index, 100);
1052
1257
  }
@@ -1075,13 +1280,18 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
1075
1280
 
1076
1281
  .body {
1077
1282
  flex: 1;
1078
- overflow-y: auto;
1079
- padding: 0 1.5rem;
1080
- scrollbar-gutter: stable;
1283
+ overflow-y: var(--moni-morph-body-overflow-y, auto);
1284
+ overflow-x: var(--moni-morph-body-overflow-x, hidden);
1285
+ padding: var(--moni-morph-body-padding, 0 1.5rem);
1286
+ scrollbar-gutter: var(--moni-morph-body-scrollbar-gutter, stable);
1081
1287
  }
1082
1288
 
1083
1289
  .panel.is-animating .body {
1084
- overflow: hidden;
1290
+ overflow: hidden !important;
1291
+ }
1292
+
1293
+ .panel.is-animating .body::-webkit-scrollbar {
1294
+ display: none;
1085
1295
  }
1086
1296
 
1087
1297
  footer {
@@ -1130,6 +1340,27 @@ let MoniMorphModal = class MoniMorphModal extends MoniElement {
1130
1340
  }
1131
1341
  `
1132
1342
  ]; }
1343
+ /**
1344
+ * Renderiza el caparazón del modal morph: fondo opcional + contenedor de panel.
1345
+ *
1346
+ * **Bandera `_visible`:**
1347
+ * `visible = this._visible || this.open` mantiene vivo el DOM mientras se reproduce
1348
+ * la animación de cierre de GSAP. `_visible` se establece en `true` al inicio de la apertura y
1349
+ * en `false` solo después de que se dispara el `onComplete` de la animación de cierre. Sin esto,
1350
+ * Lit eliminaría el panel del DOM antes de que la animación termine.
1351
+ *
1352
+ * **Condicional del fondo (backdrop):**
1353
+ * El div `.backdrop` solo se renderiza cuando `hasBackdrop=true`. Cuando `modal=false`,
1354
+ * el `background-color` del fondo se establece en `transparent` para que el fondo superpuesto
1355
+ * (scrim) sea invisible, pero los eventos del puntero aún se consumen (clic para cerrar).
1356
+ *
1357
+ * **Objetivo de morphing de GSAP:**
1358
+ * `.panel` es el objetivo de la animación GSAP. Al abrir: se anima desde el
1359
+ * `getBoundingClientRect()` del elemento anclaje (posición + tamaño) a su tamaño CSS natural
1360
+ * mediante `gsap.fromTo()`. Al cerrar: a la inversa. `.panel-inner` recibe una
1361
+ * contra-escala para evitar que el contenido interno se escale junto con el panel,
1362
+ * creando una ilusión física de "expandirse desde el origen".
1363
+ */
1133
1364
  render() {
1134
1365
  const visible = this._visible || this.open;
1135
1366
  const headerEmpty = !this._hasHeader && !this.showCloseButton;
@@ -1217,6 +1448,12 @@ __decorate([
1217
1448
  __decorate([
1218
1449
  property({ type: Boolean, reflect: true, attribute: 'cover-target', converter: litBool })
1219
1450
  ], MoniMorphModal.prototype, "coverTarget", void 0);
1451
+ __decorate([
1452
+ property({ type: Boolean, reflect: true, attribute: 'auto-size', converter: litBool })
1453
+ ], MoniMorphModal.prototype, "autoSize", void 0);
1454
+ __decorate([
1455
+ property({ type: Boolean, reflect: true, attribute: 'blur-content', converter: litBool })
1456
+ ], MoniMorphModal.prototype, "blurContent", void 0);
1220
1457
  __decorate([
1221
1458
  query('.panel')
1222
1459
  ], MoniMorphModal.prototype, "_panel", void 0);