B. lib / js / custom / md-options-menu.js

1import { abreElementoHtml } from "../abreElementoHtml.js"
2import { cierraElementoHtmo } from "../cierraElementoHtmo.js"
3import { querySelector } from "../querySelector.js"
4
5export class MdOptionsMenu extends HTMLElement {
6
7 getContent() {
8 return /* HTML */`
9
10 <style>
11
12 :host {
13 position: absolute;
14 }
15
16 </style>
17
18 <slot></slot>`
19 }
20
21 constructor() {
22 super()
23 const shadow = this.attachShadow({ mode: "open" })
24 shadow.innerHTML = this.getContent()
25 this._configuraOpciones = this._configuraOpciones.bind(this)
26
27 /**
28 * @private
29 * @type { HTMLSlotElement }
30 */
31 this._slot = querySelector(shadow, "slot")
32 /**
33 * @private
34 * @type { HTMLElement[] }
35 */
36 this._opciones = []
37 this._slot.addEventListener("slotchange", this._configuraOpciones)
38 }
39
40 connectedCallback() {
41 this.classList.add("md-menu")
42 this.hidden = true
43 this.role = "listbox"
44 }
45
46 /**
47 * @returns {readonly Readonly<HTMLElement>[]}
48 */
49 get opciones() {
50 return this._opciones
51 }
52
53 get seleccion() {
54 /** @type { HTMLInputElement | null } */
55 const seleccionado = this.querySelector(".selected")
56 return seleccionado === null ? "" : seleccionado.value
57 }
58
59 _configuraOpciones() {
60 /**
61 * @type {HTMLElement[]}
62 */
63 const opciones = []
64 for (const opcion of this._slot.assignedElements()) {
65 opcion.role = "option"
66 if (opcion instanceof HTMLElement) {
67 opciones.push(opcion)
68 }
69 }
70 this._opciones = opciones
71 }
72
73 abre() {
74 abreElementoHtml(this)
75 }
76
77
78 cierra() {
79 cierraElementoHtmo(this)
80 }
81
82 /**
83 * @param {string} value
84 */
85 muestraValue(value) {
86 let texto = ""
87 for (const opcion of this._opciones) {
88 if (opcion.dataset.value === value) {
89 opcion.classList.add("selected")
90 let textContent = opcion.textContent
91 if (texto === "" && textContent !== null) {
92 textContent = textContent.trim()
93 if (textContent !== "") {
94 texto = textContent
95 }
96 }
97 } else {
98 opcion.classList.remove("selected")
99 }
100 }
101 return texto
102 }
103
104}
105
106customElements.define("md-options-menu", MdOptionsMenu)
skip_previous skip_next