wj-elements 0.4.1 → 0.4.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.
- package/dist/custom-elements.json +21140 -0
- package/dist/packages/wje-dropdown/dropdown.element.d.ts +29 -1
- package/dist/packages/wje-option/option.element.d.ts +3 -0
- package/dist/packages/wje-select/select.element.d.ts +17 -0
- package/dist/web-types.json +3842 -0
- package/dist/wje-dropdown.js +66 -1
- package/dist/wje-dropdown.js.map +1 -1
- package/dist/wje-option.js +8 -2
- package/dist/wje-option.js.map +1 -1
- package/dist/wje-select.js +174 -26
- package/dist/wje-select.js.map +1 -1
- package/package.json +1 -1
package/dist/wje-dropdown.js
CHANGED
|
@@ -40,8 +40,14 @@ const _Dropdown = class _Dropdown extends WJElement {
|
|
|
40
40
|
this.popup.hide();
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
|
+
/**
|
|
44
|
+
* Handles popup hide events and closes only the dropdown that owns the popup.
|
|
45
|
+
* This prevents nested dropdowns from collapsing their parent dropdown when the
|
|
46
|
+
* child popup is hidden.
|
|
47
|
+
* @param {Event} e The popup hide event.
|
|
48
|
+
*/
|
|
43
49
|
__publicField(this, "popupHideCallback", (e) => {
|
|
44
|
-
if (this.classList.contains("active") && e.target
|
|
50
|
+
if (this.classList.contains("active") && e.target === this) {
|
|
45
51
|
this.toggleCallback(e);
|
|
46
52
|
}
|
|
47
53
|
});
|
|
@@ -53,6 +59,8 @@ const _Dropdown = class _Dropdown extends WJElement {
|
|
|
53
59
|
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
54
60
|
const item = path.find((n) => n && n.tagName === "WJE-MENU-ITEM");
|
|
55
61
|
if (!item) return;
|
|
62
|
+
const owner = this.getMenuItemOwner(path, item);
|
|
63
|
+
if (owner && owner !== this) return;
|
|
56
64
|
if (item.hasAttribute("disabled") || item.getAttribute("aria-disabled") === "true") return;
|
|
57
65
|
if (typeof item.querySelector === "function" && item.querySelector("wje-menu")) return;
|
|
58
66
|
this.onClose();
|
|
@@ -84,6 +92,7 @@ const _Dropdown = class _Dropdown extends WJElement {
|
|
|
84
92
|
throw new Error("beforeShow method returned false or not string");
|
|
85
93
|
}
|
|
86
94
|
this.popup.show(true);
|
|
95
|
+
this.syncPopupOwner();
|
|
87
96
|
event.addListener(document, "wje-menu-item:click", null, __privateGet(this, _onMenuItemCustom), false);
|
|
88
97
|
event.dispatchCustomEvent(this, "wje-dropdown:open", {
|
|
89
98
|
bubbles: true,
|
|
@@ -123,6 +132,8 @@ const _Dropdown = class _Dropdown extends WJElement {
|
|
|
123
132
|
if (!this.popup || !this.popup.floatingEl || !path.includes(this.popup.floatingEl)) return;
|
|
124
133
|
const item = path.find((n) => n && n.tagName === "WJE-MENU-ITEM");
|
|
125
134
|
if (!item) return;
|
|
135
|
+
const owner = this.getMenuItemOwner(path, item);
|
|
136
|
+
if (owner && owner !== this) return;
|
|
126
137
|
if (item.hasAttribute("disabled") || item.getAttribute("aria-disabled") === "true") return;
|
|
127
138
|
if (item.hasAttribute("has-submenu")) return;
|
|
128
139
|
this.classList.remove("active");
|
|
@@ -227,6 +238,8 @@ const _Dropdown = class _Dropdown extends WJElement {
|
|
|
227
238
|
* Adds event listeners for the mouseenter and mouseleave events.
|
|
228
239
|
*/
|
|
229
240
|
afterDraw() {
|
|
241
|
+
this.syncPopupOwner();
|
|
242
|
+
this.syncOwnedContentOwner();
|
|
230
243
|
event.addListener(this, "wje-popup:hide", null, this.popupHideCallback);
|
|
231
244
|
event.addListener(this.popup, "click", null, this.onMenuItemClick, { capture: true });
|
|
232
245
|
if (this.trigger !== "click") {
|
|
@@ -260,6 +273,58 @@ const _Dropdown = class _Dropdown extends WJElement {
|
|
|
260
273
|
event.removeListener(document, "wje-menu-item:click", null, __privateGet(this, _onMenuItemCustom), false);
|
|
261
274
|
(_a = this.anchorSlot) == null ? void 0 : _a.removeEventListener("slotchange", this.onSlotChange);
|
|
262
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Assigns the current dropdown instance as the owner of its popup layers.
|
|
278
|
+
* Owner metadata is later used to resolve which dropdown should react to
|
|
279
|
+
* delegated menu-item clicks, including portaled popup content.
|
|
280
|
+
*/
|
|
281
|
+
syncPopupOwner() {
|
|
282
|
+
if (!this.popup) return;
|
|
283
|
+
this.popup.ownerDropdown = this;
|
|
284
|
+
if (this.popup.native) {
|
|
285
|
+
this.popup.native.ownerDropdown = this;
|
|
286
|
+
}
|
|
287
|
+
if (this.popup.floatingEl) {
|
|
288
|
+
this.popup.floatingEl.ownerDropdown = this;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Recursively assigns owner metadata to the dropdown content subtree while
|
|
293
|
+
* leaving nested dropdown roots untouched, so each nested dropdown can keep
|
|
294
|
+
* its own ownership boundary.
|
|
295
|
+
* @param {HTMLElement} [root] The subtree root whose children should inherit this dropdown owner. Defaults to the current dropdown.
|
|
296
|
+
*/
|
|
297
|
+
syncOwnedContentOwner(root = this) {
|
|
298
|
+
const children = Array.from(root.children || []);
|
|
299
|
+
for (const child of children) {
|
|
300
|
+
if (child.tagName === "WJE-DROPDOWN" && child !== this) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
child.ownerDropdown = this;
|
|
304
|
+
this.syncOwnedContentOwner(child);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Resolves the dropdown that owns a clicked menu item. The lookup prefers
|
|
309
|
+
* explicit owner metadata and falls back to DOM traversal so both regular
|
|
310
|
+
* and portaled dropdown content can be scoped correctly.
|
|
311
|
+
* @param {EventTarget[]} path The composed event path.
|
|
312
|
+
* @param {HTMLElement} item The clicked menu item element.
|
|
313
|
+
* @returns {HTMLElement|null} The owning dropdown element or null when it cannot be resolved.
|
|
314
|
+
*/
|
|
315
|
+
getMenuItemOwner(path, item) {
|
|
316
|
+
var _a;
|
|
317
|
+
if (item == null ? void 0 : item.ownerDropdown) return item.ownerDropdown;
|
|
318
|
+
if (item == null ? void 0 : item.closest) {
|
|
319
|
+
const closestDropdown = item.closest("wje-dropdown");
|
|
320
|
+
if (closestDropdown) return closestDropdown;
|
|
321
|
+
}
|
|
322
|
+
const ownerFromPath = (_a = path.find((node) => node == null ? void 0 : node.ownerDropdown)) == null ? void 0 : _a.ownerDropdown;
|
|
323
|
+
if (ownerFromPath) return ownerFromPath;
|
|
324
|
+
const dropdownFromPath = path.find((node) => (node == null ? void 0 : node.tagName) === "WJE-DROPDOWN");
|
|
325
|
+
if (dropdownFromPath) return dropdownFromPath;
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
263
328
|
/**
|
|
264
329
|
* @summary Returns the content to be displayed before showing the dropdown.
|
|
265
330
|
* @returns {any} The content to be displayed.
|
package/dist/wje-dropdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wje-dropdown.js","sources":["../packages/wje-dropdown/dropdown.element.js","../packages/wje-dropdown/dropdown.js"],"sourcesContent":["import { default as WJElement, event } from '../wje-element/element.js';\nimport Popup from '../wje-popup/popup.element.js';\n\n/**\n * `Dropdown` is a custom element that displays a dropdown menu.\n * @summary This element represents a dropdown menu.\n * @documentation https://elements.webjet.sk/components/dropdown\n * @status stable\n * @augments {WJElement}\n * @csspart native - The native part of the dropdown.\n * @slot trigger - The slot for the trigger of the dropdown.\n * @slot - The default slot for the dropdown.\n * // @fires wje-dropdown:open - Event fired when the dropdown is opened.\n * // @fires wje-dropdown:close - Event fired when the dropdown is closed.\n * @tag wje-dropdown\n */\nexport default class Dropdown extends WJElement {\n static _instanceId = 0;\n /**\n * Creates an instance of Dropdown.\n * @class\n */\n constructor() {\n super();\n this._instanceId = ++Dropdown._instanceId;\n }\n\n /**\n * The placement of the dropdown.\n * @type {{\"wje-popup\": Popup}}\n */\n dependencies = {\n 'wje-popup': Popup,\n };\n\n /**\n * Sets or removes the 'portaled' attribute on the element.\n * When the value is truthy, the attribute 'portaled' is added to the element.\n * When the value is falsy, the attribute 'portaled' is removed from the element.\n * @param {boolean} value Determines whether to add or remove the 'portaled' attribute.\n */\n set portaled(value) {\n if (value) {\n this.setAttribute('portaled', value);\n } else {\n this.removeAttribute('portaled');\n }\n }\n\n /**\n * Getter method for the `portaled` property.\n * Checks if the `portaled` attribute is present on the element.\n * @returns {boolean} Returns `true` if the `portaled` attribute exists, otherwise `false`.\n */\n get portaled() {\n return this.getAttribute('portaled') || '';\n }\n\n /**\n * Checks whether the element has the 'portaled' attribute.\n * @returns {boolean} True if the element has the 'portaled' attribute, otherwise false.\n */\n get isPortaled() {\n return this.hasAttribute('portaled');\n }\n\n /**\n * Sets the placement of the dropdown.\n * @param value\n */\n set trigger(value) {\n this.setAttribute('trigger', value);\n }\n\n /**\n * Gets the placement of the dropdown.\n * @returns {string|string}\n */\n get trigger() {\n return this.getAttribute('trigger') || 'click';\n }\n\n /**\n * Sets the placement of the dropdown.\n * @type {string}\n */\n className = 'Dropdown';\n\n /**\n * Getter for the CSS stylesheet.\n * @returns {string[]}\n */\n static get observedAttributes() {\n return ['active'];\n }\n\n /**\n * Callback function to handle other dropdowns being opened. Close the dropdown if it is not the target and collapse is enabled.\n * @param {Event} e The event object.\n */\n otherDropdownOpennedCallback = (e) => {\n if (e.detail.detail.target !== this) {\n this.classList.remove('active');\n this.popup.hide();\n }\n };\n\n /**\n * Sets up the attributes for the dropdown.\n */\n setupAttributes() {\n this.isShadowRoot = 'open';\n }\n\n /**\n * Removes the popup element.\n */\n beforeDraw() {\n this.popup?.remove();\n this.popup = null;\n }\n\n /**\n * Draws the dropdown element and returns the created document fragment.\n * @returns {DocumentFragment}\n */\n draw() {\n let fragment = document.createDocumentFragment();\n\n this.classList.add('wje-placement', 'wje-' + this.placement || 'wje-start');\n\n let native = document.createElement('div');\n native.setAttribute('part', 'native');\n native.classList.add('native-dropdown');\n\n let tooltip = document.createElement('wje-tooltip');\n tooltip.setAttribute('content', this.tooltip);\n\n let anchorSlot = document.createElement('slot');\n anchorSlot.setAttribute('name', 'trigger');\n anchorSlot.setAttribute('slot', 'anchor');\n\n let slot = document.createElement('slot');\n\n let popup = document.createElement('wje-popup');\n popup.setAttribute('placement', this.placement);\n popup.setAttribute('offset', this.offset);\n popup.setAttribute('part', 'popup');\n\n if(this.isPortaled)\n popup.setAttribute('portal', this.portaled);\n\n popup.append(anchorSlot, slot);\n\n // if(this.trigger === \"click\")\n popup.setAttribute('manual', '');\n\n native.appendChild(popup);\n\n fragment.appendChild(native);\n\n this.popup = popup;\n this.anchorSlot = anchorSlot;\n\n return fragment;\n }\n\n /**\n * Adds event listeners for the mouseenter and mouseleave events.\n */\n afterDraw() {\n event.addListener(this, 'wje-popup:hide', null, this.popupHideCallback);\n\n // Close when any actionable wje-menu-item inside the popup is clicked (works across Shadow DOM via composed path)\n event.addListener(this.popup, 'click', null, this.onMenuItemClick, { capture: true });\n\n if (this.trigger !== 'click') {\n event.addListener(this, 'mouseenter', null, this.onOpen);\n event.addListener(this, 'mouseleave', null, this.onClose);\n } else {\n event.addListener(this.anchorSlot, 'click', null, this.toggleCallback, { capture: true });\n }\n\n if (this.hasAttribute('collapsible')) {\n event.addListener(\n Array.from(this.querySelectorAll('wje-menu-item')),\n 'click',\n 'wje-menu-item:click',\n this.onClose\n );\n }\n\n this.onSlotChange = () => this.syncAria();\n this.anchorSlot.addEventListener('slotchange', this.onSlotChange);\n\n this.syncAria();\n }\n\n /**\n * Adds event listeners for the mouseenter and mouseleave events.\n */\n afterDisconnect() {\n event.removeListener(this, 'mouseenter', null, this.onOpen);\n event.removeListener(this, 'mouseleave', null, this.onClose);\n event.removeListener(this.anchorSlot, 'click', null, this.toggleCallback, { capture: true });\n event.removeListener(this, 'wje-popup:hide', null, this.popupHideCallback);\n event.removeListener(this.popup, 'click', null, this.onMenuItemClick, { capture: true });\n event.removeListener(document, 'wje-menu-item:click', null, this.#onMenuItemCustom, false);\n this.anchorSlot?.removeEventListener('slotchange', this.onSlotChange);\n }\n\n popupHideCallback = (e) => {\n if (this.classList.contains('active') && e.target.tagName === \"WJE-DROPDOWN\") {\n this.toggleCallback(e);\n }\n };\n\n /**\n * Handles delegated clicks from inside the popup and closes the dropdown when a leaf menu item is selected.\n * This works even when the menu is portaled, because we rely on the composed path.\n */\n onMenuItemClick = (e) => {\n // Find nearest wje-menu-item in the composed path\n const path = typeof e.composedPath === 'function' ? e.composedPath() : [];\n const item = path.find((n) => n && n.tagName === 'WJE-MENU-ITEM');\n if (!item) return;\n\n // Ignore disabled items\n if (item.hasAttribute('disabled') || item.getAttribute('aria-disabled') === 'true') return;\n\n // If this item contains a nested submenu (wje-menu), it's not a leaf -> don't close yet\n if (typeof item.querySelector === 'function' && item.querySelector('wje-menu')) return;\n\n // Leaf item selected -> close dropdown (which calls popup.hide(true) inside onClose)\n this.onClose();\n }\n\n /**\n * @summary Toggles the dropdown element between active and inactive states.\n * Calls the `onOpen` method if the element is currently inactive,\n * and calls the `onClose` method if the element is currently active.\n * @param {Event} e The event object.\n */\n toggleCallback = (e) => {\n if (this.classList.contains('active')) {\n e.stopPropagation();\n this.onClose();\n } else {\n e.stopPropagation();\n this.onOpen(e);\n }\n };\n\n /**\n * @summary Returns the content to be displayed before showing the dropdown.\n * @returns {any} The content to be displayed.\n */\n beforeShow() {\n return this.content;\n }\n\n /**\n * This method is called after the dropdown is shown.\n */\n afterShow() {\n // Do nothing\n }\n\n /**\n * Open the popup element.\n * @param {object} e\n */\n onOpen = (e) => {\n this.classList.add('active');\n this.syncAria();\n Promise.resolve(this.beforeShow(this))\n .then((res) => {\n if (!this.classList.contains('active')) {\n throw new Error('beforeShow method returned false or not string');\n }\n\n this.popup.show(true); // Show tooltip\n\n event.addListener(document, 'wje-menu-item:click', null, this.#onMenuItemCustom, false);\n\n event.dispatchCustomEvent(this, 'wje-dropdown:open', {\n bubbles: true,\n detail: { target: this },\n });\n\n Promise.resolve(this.afterShow(this));\n })\n .catch((error) => {\n // ak je nejaka chyba tak to len zatvorime\n this.classList.remove('active');\n this.popup.hide(true);\n });\n };\n\n beforeClose = () => {\n // Do nothing\n };\n\n afterClose = () => {\n // Do nothing\n };\n\n onClose = () => {\n this.classList.remove('active');\n this.syncAria();\n Promise.resolve(this.beforeClose(this))\n .then((res) => {\n if (this.classList.contains('active')) {\n throw new Error('beforeShow method returned false or not string');\n }\n\n this.popup.hide(true); // Show tooltip\n\n event.removeListener(document, 'wje-menu-item:click', null, this.#onMenuItemCustom, false);\n\n event.dispatchCustomEvent(this, 'wje-dropdown:close', {\n bubbles: true,\n detail: { target: this },\n });\n\n Promise.resolve(this.afterClose(this));\n })\n .catch((error) => {\n this.classList.add('active');\n this.popup.show(true);\n });\n }\n\n /**\n * Syncs ARIA attributes for the trigger element.\n */\n syncAria() {\n const triggerEl = this.anchorSlot?.assignedElements?.({ flatten: true })?.[0];\n if (!triggerEl) return;\n\n const popupId = this.popup?.id || `wje-dropdown-popup-${this._instanceId}`;\n if (this.popup && !this.popup.id) this.popup.id = popupId;\n\n const hasMenu = !!this.querySelector('wje-menu');\n triggerEl.setAttribute('aria-haspopup', hasMenu ? 'menu' : 'dialog');\n triggerEl.setAttribute('aria-expanded', this.classList.contains('active') ? 'true' : 'false');\n triggerEl.setAttribute('aria-controls', popupId);\n }\n\n #onMenuItemCustom = (e) => {\n const path = typeof e.composedPath === 'function' ? e.composedPath() : [];\n if (!this.popup || !this.popup.floatingEl || !path.includes(this.popup.floatingEl)) return;\n\n const item = path.find(n => n && n.tagName === 'WJE-MENU-ITEM');\n if (!item) return;\n if (item.hasAttribute('disabled') || item.getAttribute('aria-disabled') === 'true') return;\n if (item.hasAttribute('has-submenu')) return; // parent; nezatváraj\n\n // Zavri len tento dropdown. NEvolaj stopPropagation na custom evente,\n // aby fungovali aj tvoje app-level listenery (riadok 480).\n this.classList.remove('active');\n this.popup.hide(true);\n }\n}\n","import Dropdown from './dropdown.element.js';\n\nexport default Dropdown;\n\nDropdown.define('wje-dropdown', Dropdown);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wje-dropdown.js","sources":["../packages/wje-dropdown/dropdown.element.js","../packages/wje-dropdown/dropdown.js"],"sourcesContent":["import { default as WJElement, event } from '../wje-element/element.js';\nimport Popup from '../wje-popup/popup.element.js';\n\n/**\n * `Dropdown` is a custom element that displays a dropdown menu.\n * @summary This element represents a dropdown menu.\n * @documentation https://elements.webjet.sk/components/dropdown\n * @status stable\n * @augments {WJElement}\n * @csspart native - The native part of the dropdown.\n * @slot trigger - The slot for the trigger of the dropdown.\n * @slot - The default slot for the dropdown.\n * // @fires wje-dropdown:open - Event fired when the dropdown is opened.\n * // @fires wje-dropdown:close - Event fired when the dropdown is closed.\n * @tag wje-dropdown\n */\nexport default class Dropdown extends WJElement {\n static _instanceId = 0;\n /**\n * Creates an instance of Dropdown.\n * @class\n */\n constructor() {\n super();\n this._instanceId = ++Dropdown._instanceId;\n }\n\n /**\n * The placement of the dropdown.\n * @type {{\"wje-popup\": Popup}}\n */\n dependencies = {\n 'wje-popup': Popup,\n };\n\n /**\n * Sets or removes the 'portaled' attribute on the element.\n * When the value is truthy, the attribute 'portaled' is added to the element.\n * When the value is falsy, the attribute 'portaled' is removed from the element.\n * @param {boolean} value Determines whether to add or remove the 'portaled' attribute.\n */\n set portaled(value) {\n if (value) {\n this.setAttribute('portaled', value);\n } else {\n this.removeAttribute('portaled');\n }\n }\n\n /**\n * Getter method for the `portaled` property.\n * Checks if the `portaled` attribute is present on the element.\n * @returns {boolean} Returns `true` if the `portaled` attribute exists, otherwise `false`.\n */\n get portaled() {\n return this.getAttribute('portaled') || '';\n }\n\n /**\n * Checks whether the element has the 'portaled' attribute.\n * @returns {boolean} True if the element has the 'portaled' attribute, otherwise false.\n */\n get isPortaled() {\n return this.hasAttribute('portaled');\n }\n\n /**\n * Sets the placement of the dropdown.\n * @param value\n */\n set trigger(value) {\n this.setAttribute('trigger', value);\n }\n\n /**\n * Gets the placement of the dropdown.\n * @returns {string|string}\n */\n get trigger() {\n return this.getAttribute('trigger') || 'click';\n }\n\n /**\n * Sets the placement of the dropdown.\n * @type {string}\n */\n className = 'Dropdown';\n\n /**\n * Getter for the CSS stylesheet.\n * @returns {string[]}\n */\n static get observedAttributes() {\n return ['active'];\n }\n\n /**\n * Callback function to handle other dropdowns being opened. Close the dropdown if it is not the target and collapse is enabled.\n * @param {Event} e The event object.\n */\n otherDropdownOpennedCallback = (e) => {\n if (e.detail.detail.target !== this) {\n this.classList.remove('active');\n this.popup.hide();\n }\n };\n\n /**\n * Sets up the attributes for the dropdown.\n */\n setupAttributes() {\n this.isShadowRoot = 'open';\n }\n\n /**\n * Removes the popup element.\n */\n beforeDraw() {\n this.popup?.remove();\n this.popup = null;\n }\n\n /**\n * Draws the dropdown element and returns the created document fragment.\n * @returns {DocumentFragment}\n */\n draw() {\n let fragment = document.createDocumentFragment();\n\n this.classList.add('wje-placement', 'wje-' + this.placement || 'wje-start');\n\n let native = document.createElement('div');\n native.setAttribute('part', 'native');\n native.classList.add('native-dropdown');\n\n let tooltip = document.createElement('wje-tooltip');\n tooltip.setAttribute('content', this.tooltip);\n\n let anchorSlot = document.createElement('slot');\n anchorSlot.setAttribute('name', 'trigger');\n anchorSlot.setAttribute('slot', 'anchor');\n\n let slot = document.createElement('slot');\n\n let popup = document.createElement('wje-popup');\n popup.setAttribute('placement', this.placement);\n popup.setAttribute('offset', this.offset);\n popup.setAttribute('part', 'popup');\n\n if(this.isPortaled)\n popup.setAttribute('portal', this.portaled);\n\n popup.append(anchorSlot, slot);\n\n // if(this.trigger === \"click\")\n popup.setAttribute('manual', '');\n\n native.appendChild(popup);\n\n fragment.appendChild(native);\n\n this.popup = popup;\n this.anchorSlot = anchorSlot;\n\n return fragment;\n }\n\n /**\n * Adds event listeners for the mouseenter and mouseleave events.\n */\n afterDraw() {\n this.syncPopupOwner();\n this.syncOwnedContentOwner();\n\n event.addListener(this, 'wje-popup:hide', null, this.popupHideCallback);\n\n // Close when any actionable wje-menu-item inside the popup is clicked (works across Shadow DOM via composed path)\n event.addListener(this.popup, 'click', null, this.onMenuItemClick, { capture: true });\n\n if (this.trigger !== 'click') {\n event.addListener(this, 'mouseenter', null, this.onOpen);\n event.addListener(this, 'mouseleave', null, this.onClose);\n } else {\n event.addListener(this.anchorSlot, 'click', null, this.toggleCallback, { capture: true });\n }\n\n if (this.hasAttribute('collapsible')) {\n event.addListener(\n Array.from(this.querySelectorAll('wje-menu-item')),\n 'click',\n 'wje-menu-item:click',\n this.onClose\n );\n }\n\n this.onSlotChange = () => this.syncAria();\n this.anchorSlot.addEventListener('slotchange', this.onSlotChange);\n\n this.syncAria();\n }\n\n /**\n * Adds event listeners for the mouseenter and mouseleave events.\n */\n afterDisconnect() {\n event.removeListener(this, 'mouseenter', null, this.onOpen);\n event.removeListener(this, 'mouseleave', null, this.onClose);\n event.removeListener(this.anchorSlot, 'click', null, this.toggleCallback, { capture: true });\n event.removeListener(this, 'wje-popup:hide', null, this.popupHideCallback);\n event.removeListener(this.popup, 'click', null, this.onMenuItemClick, { capture: true });\n event.removeListener(document, 'wje-menu-item:click', null, this.#onMenuItemCustom, false);\n this.anchorSlot?.removeEventListener('slotchange', this.onSlotChange);\n }\n\n /**\n * Handles popup hide events and closes only the dropdown that owns the popup.\n * This prevents nested dropdowns from collapsing their parent dropdown when the\n * child popup is hidden.\n * @param {Event} e The popup hide event.\n */\n popupHideCallback = (e) => {\n if (this.classList.contains('active') && e.target === this) {\n this.toggleCallback(e);\n }\n };\n\n /**\n * Assigns the current dropdown instance as the owner of its popup layers.\n * Owner metadata is later used to resolve which dropdown should react to\n * delegated menu-item clicks, including portaled popup content.\n */\n syncPopupOwner() {\n if (!this.popup) return;\n\n this.popup.ownerDropdown = this;\n\n if (this.popup.native) {\n this.popup.native.ownerDropdown = this;\n }\n\n if (this.popup.floatingEl) {\n this.popup.floatingEl.ownerDropdown = this;\n }\n }\n\n /**\n * Recursively assigns owner metadata to the dropdown content subtree while\n * leaving nested dropdown roots untouched, so each nested dropdown can keep\n * its own ownership boundary.\n * @param {HTMLElement} [root] The subtree root whose children should inherit this dropdown owner. Defaults to the current dropdown.\n */\n syncOwnedContentOwner(root = this) {\n const children = Array.from(root.children || []);\n\n for (const child of children) {\n if (child.tagName === 'WJE-DROPDOWN' && child !== this) {\n continue;\n }\n\n child.ownerDropdown = this;\n this.syncOwnedContentOwner(child);\n }\n }\n\n /**\n * Resolves the dropdown that owns a clicked menu item. The lookup prefers\n * explicit owner metadata and falls back to DOM traversal so both regular\n * and portaled dropdown content can be scoped correctly.\n * @param {EventTarget[]} path The composed event path.\n * @param {HTMLElement} item The clicked menu item element.\n * @returns {HTMLElement|null} The owning dropdown element or null when it cannot be resolved.\n */\n getMenuItemOwner(path, item) {\n if (item?.ownerDropdown) return item.ownerDropdown;\n\n if (item?.closest) {\n const closestDropdown = item.closest('wje-dropdown');\n if (closestDropdown) return closestDropdown;\n }\n\n const ownerFromPath = path.find((node) => node?.ownerDropdown)?.ownerDropdown;\n if (ownerFromPath) return ownerFromPath;\n\n const dropdownFromPath = path.find((node) => node?.tagName === 'WJE-DROPDOWN');\n if (dropdownFromPath) return dropdownFromPath;\n\n return null;\n }\n\n /**\n * Handles delegated clicks from inside the popup and closes the dropdown when a leaf menu item is selected.\n * This works even when the menu is portaled, because we rely on the composed path.\n */\n onMenuItemClick = (e) => {\n // Find nearest wje-menu-item in the composed path\n const path = typeof e.composedPath === 'function' ? e.composedPath() : [];\n const item = path.find((n) => n && n.tagName === 'WJE-MENU-ITEM');\n if (!item) return;\n\n const owner = this.getMenuItemOwner(path, item);\n if (owner && owner !== this) return;\n\n // Ignore disabled items\n if (item.hasAttribute('disabled') || item.getAttribute('aria-disabled') === 'true') return;\n\n // If this item contains a nested submenu (wje-menu), it's not a leaf -> don't close yet\n if (typeof item.querySelector === 'function' && item.querySelector('wje-menu')) return;\n\n // Leaf item selected -> close dropdown (which calls popup.hide(true) inside onClose)\n this.onClose();\n }\n\n /**\n * @summary Toggles the dropdown element between active and inactive states.\n * Calls the `onOpen` method if the element is currently inactive,\n * and calls the `onClose` method if the element is currently active.\n * @param {Event} e The event object.\n */\n toggleCallback = (e) => {\n if (this.classList.contains('active')) {\n e.stopPropagation();\n this.onClose();\n } else {\n e.stopPropagation();\n this.onOpen(e);\n }\n };\n\n /**\n * @summary Returns the content to be displayed before showing the dropdown.\n * @returns {any} The content to be displayed.\n */\n beforeShow() {\n return this.content;\n }\n\n /**\n * This method is called after the dropdown is shown.\n */\n afterShow() {\n // Do nothing\n }\n\n /**\n * Open the popup element.\n * @param {object} e\n */\n onOpen = (e) => {\n this.classList.add('active');\n this.syncAria();\n Promise.resolve(this.beforeShow(this))\n .then((res) => {\n if (!this.classList.contains('active')) {\n throw new Error('beforeShow method returned false or not string');\n }\n\n this.popup.show(true); // Show tooltip\n this.syncPopupOwner();\n\n event.addListener(document, 'wje-menu-item:click', null, this.#onMenuItemCustom, false);\n\n event.dispatchCustomEvent(this, 'wje-dropdown:open', {\n bubbles: true,\n detail: { target: this },\n });\n\n Promise.resolve(this.afterShow(this));\n })\n .catch((error) => {\n // ak je nejaka chyba tak to len zatvorime\n this.classList.remove('active');\n this.popup.hide(true);\n });\n };\n\n beforeClose = () => {\n // Do nothing\n };\n\n afterClose = () => {\n // Do nothing\n };\n\n onClose = () => {\n this.classList.remove('active');\n this.syncAria();\n Promise.resolve(this.beforeClose(this))\n .then((res) => {\n if (this.classList.contains('active')) {\n throw new Error('beforeShow method returned false or not string');\n }\n\n this.popup.hide(true); // Show tooltip\n\n event.removeListener(document, 'wje-menu-item:click', null, this.#onMenuItemCustom, false);\n\n event.dispatchCustomEvent(this, 'wje-dropdown:close', {\n bubbles: true,\n detail: { target: this },\n });\n\n Promise.resolve(this.afterClose(this));\n })\n .catch((error) => {\n this.classList.add('active');\n this.popup.show(true);\n });\n }\n\n /**\n * Syncs ARIA attributes for the trigger element.\n */\n syncAria() {\n const triggerEl = this.anchorSlot?.assignedElements?.({ flatten: true })?.[0];\n if (!triggerEl) return;\n\n const popupId = this.popup?.id || `wje-dropdown-popup-${this._instanceId}`;\n if (this.popup && !this.popup.id) this.popup.id = popupId;\n\n const hasMenu = !!this.querySelector('wje-menu');\n triggerEl.setAttribute('aria-haspopup', hasMenu ? 'menu' : 'dialog');\n triggerEl.setAttribute('aria-expanded', this.classList.contains('active') ? 'true' : 'false');\n triggerEl.setAttribute('aria-controls', popupId);\n }\n\n #onMenuItemCustom = (e) => {\n const path = typeof e.composedPath === 'function' ? e.composedPath() : [];\n if (!this.popup || !this.popup.floatingEl || !path.includes(this.popup.floatingEl)) return;\n\n const item = path.find(n => n && n.tagName === 'WJE-MENU-ITEM');\n if (!item) return;\n const owner = this.getMenuItemOwner(path, item);\n if (owner && owner !== this) return;\n if (item.hasAttribute('disabled') || item.getAttribute('aria-disabled') === 'true') return;\n if (item.hasAttribute('has-submenu')) return; // parent; nezatváraj\n\n // Zavri len tento dropdown. NEvolaj stopPropagation na custom evente,\n // aby fungovali aj tvoje app-level listenery (riadok 480).\n this.classList.remove('active');\n this.popup.hide(true);\n }\n}\n","import Dropdown from './dropdown.element.js';\n\nexport default Dropdown;\n\nDropdown.define('wje-dropdown', Dropdown);\n"],"names":[],"mappings":"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"}
|
package/dist/wje-option.js
CHANGED
|
@@ -135,7 +135,7 @@ class Option extends WJElement {
|
|
|
135
135
|
*/
|
|
136
136
|
get checkbox() {
|
|
137
137
|
var _a;
|
|
138
|
-
return (_a = this.
|
|
138
|
+
return (_a = this.ownerSelect) == null ? void 0 : _a.hasAttribute("checkbox");
|
|
139
139
|
}
|
|
140
140
|
/**
|
|
141
141
|
* Determines whether the closest 'wje-select' element has the 'multiple' attribute.
|
|
@@ -143,7 +143,13 @@ class Option extends WJElement {
|
|
|
143
143
|
*/
|
|
144
144
|
get multiple() {
|
|
145
145
|
var _a;
|
|
146
|
-
return ((_a = this.
|
|
146
|
+
return ((_a = this.ownerSelect) == null ? void 0 : _a.hasAttribute("multiple")) || false;
|
|
147
|
+
}
|
|
148
|
+
get ownerSelect() {
|
|
149
|
+
return this._ownerSelect || this.closest("wje-select");
|
|
150
|
+
}
|
|
151
|
+
set ownerSelect(value) {
|
|
152
|
+
this._ownerSelect = value;
|
|
147
153
|
}
|
|
148
154
|
/**
|
|
149
155
|
* Sets the value attribute of the option.
|
package/dist/wje-option.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wje-option.js","sources":["../packages/wje-option/option.element.js","../packages/wje-option/option.js"],"sourcesContent":["import { default as WJElement, event } from '../wje-element/element.js';\nimport Icon from '../wje-icon/icon.js';\nimport Checkbox from '../wje-checkbox/checkbox.js';\nimport styles from './styles/styles.css?inline';\n\n/**\n * `Option` is a custom web component that represents an option.\n * @summary This element represents an option.\n * @documentation https://elements.webjet.sk/components/option\n * @status stable\n * @augments {WJElement}\n * @csspart native - The native part of the option.\n * @slot start - The slot for the start of the option.\n * @slot - The default slot for the option.\n * @slot end - The slot for the end of the option.\n * // @fires wje-option:change - Event fired when the option is clicked.\n * @tag wje-option\n */\nexport default class Option extends WJElement {\n\t/**\n\t * Creates an instance of Option.\n\t * @class\n\t */\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\t/**\n\t * Dependencies of the Option component.\n\t */\n\tdependencies = {\n\t\t'wje-icon': Icon,\n\t\t'wje-checkbox': Checkbox,\n\t};\n\n\t/**\n\t * Sets the selected attribute of the option.\n\t * @param {boolean} value The value to set.\n\t */\n\tset selected(value) {\n\t\tif (value) {\n\t\t\tthis.setAttribute('selected', '');\n\t\t} else {\n\t\t\tthis.removeAttribute('selected');\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the 'selected' attribute status of the element.\n\t * @returns {boolean} Returns true if the 'selected' attribute is set on the element; otherwise, false.\n\t */\n\tget selected() {\n\t\treturn this.hasAttribute('selected');\n\t}\n\n\t/**\n\t * Retrieves the value indicating whether the closest 'wje-select' element has a 'checkbox' attribute.\n\t * @returns {boolean} True if the closest 'wje-select' element has a 'checkbox' attribute; otherwise, false.\n\t */\n\tget checkbox() {\n\t\treturn this.closest('wje-select')?.hasAttribute('checkbox');\n\t}\n\n\t/**\n\t * Determines whether the closest 'wje-select' element has the 'multiple' attribute.\n\t * @returns {boolean} Returns true if the 'wje-select' element has the 'multiple' attribute, otherwise false.\n\t */\n\tget multiple() {\n\t\treturn this.closest('wje-select')?.hasAttribute('multiple') || false;\n\t}\n\n\t/**\n\t * Sets the value attribute of the option.\n\t * @param {string} value The value to set.\n\t */\n\tset value(value) {\n\t\tthis.setAttribute('value', value);\n\t}\n\n\tget value() {\n\t\treturn this.getAttribute('value');\n\t}\n\n\t/**\n\t * Sets the text content of the option.\n\t * @param {string} value The text to set.\n\t */\n\tset text(value) {\n\t\tthis.innerText = value;\n\t}\n\n\tclassName = 'Option';\n\n\t/**\n\t * Returns the CSS styles for the component.\n\t * @static\n\t * @returns {CSSStyleSheet}\n\t */\n\tstatic get cssStyleSheet() {\n\t\treturn styles;\n\t}\n\n\t/**\n\t * Returns the list of attributes to observe for changes.\n\t * @static\n\t * @returns {Array<string>}\n\t */\n\tstatic get observedAttributes() {\n\t\treturn ['selected'];\n\t}\n\n\t/**\n\t * This method is called whenever an observed attribute is added, removed, or changed.\n\t * @param {string} name The name of the attribute that was changed.\n\t * @param {*} old The previous value of the attribute before the change.\n\t * @param {*} newName The new value of the attribute after the change.\n\t * @returns {void} This method does not return a value.\n\t */\n\tattributeChangedCallback(name, old, newName) {\n\t\tif (this.checkbox) {\n\t\t\tif (name === 'selected' && newName !== null) {\n\t\t\t\tthis.#setCheckbox(true);\n\t\t\t} else {\n\t\t\t\tthis.#setCheckbox(false);\n\t\t\t}\n\t\t}\n\t\tthis.syncAria();\n\t}\n\n\t/**\n\t * Sets up the attributes for the component.\n\t */\n\tsetupAttributes() {\n\t\tthis.isShadowRoot = 'open';\n\t\tthis.syncAria();\n\t}\n\n\t/**\n\t * Draws the component for the option.\n\t * @returns {DocumentFragment}\n\t */\n\tdraw() {\n\t\tlet fragment = document.createDocumentFragment();\n\n\t\tlet native = document.createElement('div');\n\t\tnative.classList.add('native-option');\n\t\tnative.setAttribute('part', 'native');\n\n\t\tlet icon = document.createElement('wje-icon');\n\t\ticon.setAttribute('name', 'check');\n\t\ticon.setAttribute('slot', 'check');\n\n\t\tlet checkboxEl = document.createElement('wje-checkbox');\n\t\tcheckboxEl.setAttribute('slot', 'check');\n\n\t\tlet check = document.createElement('slot');\n\t\tcheck.setAttribute('name', 'check');\n\t\tcheck.setAttribute('part', 'check');\n\n\t\tlet start = document.createElement('slot');\n\t\tstart.setAttribute('name', 'start');\n\n\t\tlet slot = document.createElement('slot');\n\n\t\tlet endWrapper = document.createElement('span');\n\t\tendWrapper.classList.add('end-slot');\n\n\t\tlet end = document.createElement('slot');\n\t\tend.setAttribute('name', 'end');\n\n\t\tendWrapper.append(end);\n\n\t\tconst hasCheckSlot = this.querySelector('[slot=\"check\"]') !== null;\n\n\t\tif (!hasCheckSlot) {\n\t\t\tif (this.checkbox && this.multiple) {\n\t\t\t\tthis.append(checkboxEl);\n\t\t\t} else {\n\t\t\t\tthis.append(icon);\n\t\t\t}\n\t\t}\n\n\t\tnative.append(check);\n\t\tnative.append(start);\n\t\tnative.append(slot);\n\t\tnative.append(endWrapper);\n\n\t\tfragment.append(native);\n\n\t\tthis.check = check;\n\n\t\treturn fragment;\n\t}\n\n\t/**\n\t * Method executed after the drawing process is completed.\n\t * Sets up an event listener for 'click' events, linking them to the specified callback function.\n\t * @returns {void} Does not return a value.\n\t */\n\tafterDraw() {\n\t\tevent.addListener(this, 'click', null, this.optionClickCallback);\n\n\t\t// If `selected` was set before render, attributeChangedCallback may have run\n\t\t// before `this.check` existed. Sync the checkbox state once slots exist.\n\t\tif (this.checkbox && this.multiple) {\n\t\t\tthis.#setCheckbox(this.selected);\n\t\t}\n\t\tthis.syncAria();\n\t}\n\n\t/**\n\t * Syncs ARIA attributes on the host element.\n\t */\n\tsyncAria() {\n\t\tthis.setAriaState({\n\t\t\trole: 'option',\n\t\t\tselected: this.selected,\n\t\t\tdisabled: this.hasAttribute('disabled'),\n\t\t});\n\t}\n\n\t/**\n\t * Handles operations or cleanup tasks that need to occur before disconnecting.\n\t * Removes an event listener associated with the 'click' event and a specified callback function.\n\t * @returns {void} This method does not return a value.\n\t */\n\tbeforeDisconnect() {\n\t\tevent.removeListener(this, 'click', null, this.optionClickCallback);\n\t}\n\n\t/**\n\t * Handles the click event on an option element and dispatches a custom event when triggered.\n\t * @param {Event} e The click event object that triggered the callback.\n\t * @returns {void} No return value.\n\t */\n\toptionClickCallback(e) {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\te.stopImmediatePropagation();\n\n\t\tif (this.hasAttribute('disabled')) return;\n\n\t\tevent.dispatchCustomEvent(this, 'wje-option:change', {\n\t\t\tvalue: this.value,\n\t\t\ttext: this.textContent,\n\t\t\toption: this,\n\t\t});\n\t}\n\n\t/**\n\t * Checks if the given DOM node represents a checkbox element.\n\t * @param {Node} node The DOM node to be checked.\n\t * @returns {boolean} Returns true if the node is an element with a class name of 'Checkbox', otherwise false.\n\t */\n\t#isCheckbox(node) {\n\t\treturn node instanceof Element && node.className === 'Checkbox';\n\t}\n\n\t/**\n\t * Updates the checked status of the first checkbox element found within the assigned elements of the specified container.\n\t * @param {boolean} checked The desired checked state to be applied to the checkbox.\n\t * @returns {void}\n\t */\n\t#setCheckbox(checked) {\n\t\tconst assigned = this.check?.assignedElements({ flatten: true }) ?? [];\n\t\tconst arr = assigned.filter((item) => this.#isCheckbox(item));\n\t\tif (arr.length > 0) arr[0].checked = checked;\n\t}\n}\n","import Option from './option.element.js';\n\nexport default Option;\n\nOption.define('wje-option', Option);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wje-option.js","sources":["../packages/wje-option/option.element.js","../packages/wje-option/option.js"],"sourcesContent":["import { default as WJElement, event } from '../wje-element/element.js';\nimport Icon from '../wje-icon/icon.js';\nimport Checkbox from '../wje-checkbox/checkbox.js';\nimport styles from './styles/styles.css?inline';\n\n/**\n * `Option` is a custom web component that represents an option.\n * @summary This element represents an option.\n * @documentation https://elements.webjet.sk/components/option\n * @status stable\n * @augments {WJElement}\n * @csspart native - The native part of the option.\n * @slot start - The slot for the start of the option.\n * @slot - The default slot for the option.\n * @slot end - The slot for the end of the option.\n * // @fires wje-option:change - Event fired when the option is clicked.\n * @tag wje-option\n */\nexport default class Option extends WJElement {\n\t/**\n\t * Creates an instance of Option.\n\t * @class\n\t */\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\t/**\n\t * Dependencies of the Option component.\n\t */\n\tdependencies = {\n\t\t'wje-icon': Icon,\n\t\t'wje-checkbox': Checkbox,\n\t};\n\n\t/**\n\t * Sets the selected attribute of the option.\n\t * @param {boolean} value The value to set.\n\t */\n\tset selected(value) {\n\t\tif (value) {\n\t\t\tthis.setAttribute('selected', '');\n\t\t} else {\n\t\t\tthis.removeAttribute('selected');\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the 'selected' attribute status of the element.\n\t * @returns {boolean} Returns true if the 'selected' attribute is set on the element; otherwise, false.\n\t */\n\tget selected() {\n\t\treturn this.hasAttribute('selected');\n\t}\n\n\t/**\n\t * Retrieves the value indicating whether the closest 'wje-select' element has a 'checkbox' attribute.\n\t * @returns {boolean} True if the closest 'wje-select' element has a 'checkbox' attribute; otherwise, false.\n\t */\n\tget checkbox() {\n\t\treturn this.ownerSelect?.hasAttribute('checkbox');\n\t}\n\n\t/**\n\t * Determines whether the closest 'wje-select' element has the 'multiple' attribute.\n\t * @returns {boolean} Returns true if the 'wje-select' element has the 'multiple' attribute, otherwise false.\n\t */\n\tget multiple() {\n\t\treturn this.ownerSelect?.hasAttribute('multiple') || false;\n\t}\n\n\tget ownerSelect() {\n\t\treturn this._ownerSelect || this.closest('wje-select');\n\t}\n\n\tset ownerSelect(value) {\n\t\tthis._ownerSelect = value;\n\t}\n\n\t/**\n\t * Sets the value attribute of the option.\n\t * @param {string} value The value to set.\n\t */\n\tset value(value) {\n\t\tthis.setAttribute('value', value);\n\t}\n\n\tget value() {\n\t\treturn this.getAttribute('value');\n\t}\n\n\t/**\n\t * Sets the text content of the option.\n\t * @param {string} value The text to set.\n\t */\n\tset text(value) {\n\t\tthis.innerText = value;\n\t}\n\n\tclassName = 'Option';\n\n\t/**\n\t * Returns the CSS styles for the component.\n\t * @static\n\t * @returns {CSSStyleSheet}\n\t */\n\tstatic get cssStyleSheet() {\n\t\treturn styles;\n\t}\n\n\t/**\n\t * Returns the list of attributes to observe for changes.\n\t * @static\n\t * @returns {Array<string>}\n\t */\n\tstatic get observedAttributes() {\n\t\treturn ['selected'];\n\t}\n\n\t/**\n\t * This method is called whenever an observed attribute is added, removed, or changed.\n\t * @param {string} name The name of the attribute that was changed.\n\t * @param {*} old The previous value of the attribute before the change.\n\t * @param {*} newName The new value of the attribute after the change.\n\t * @returns {void} This method does not return a value.\n\t */\n\tattributeChangedCallback(name, old, newName) {\n\t\tif (this.checkbox) {\n\t\t\tif (name === 'selected' && newName !== null) {\n\t\t\t\tthis.#setCheckbox(true);\n\t\t\t} else {\n\t\t\t\tthis.#setCheckbox(false);\n\t\t\t}\n\t\t}\n\t\tthis.syncAria();\n\t}\n\n\t/**\n\t * Sets up the attributes for the component.\n\t */\n\tsetupAttributes() {\n\t\tthis.isShadowRoot = 'open';\n\t\tthis.syncAria();\n\t}\n\n\t/**\n\t * Draws the component for the option.\n\t * @returns {DocumentFragment}\n\t */\n\tdraw() {\n\t\tlet fragment = document.createDocumentFragment();\n\n\t\tlet native = document.createElement('div');\n\t\tnative.classList.add('native-option');\n\t\tnative.setAttribute('part', 'native');\n\n\t\tlet icon = document.createElement('wje-icon');\n\t\ticon.setAttribute('name', 'check');\n\t\ticon.setAttribute('slot', 'check');\n\n\t\tlet checkboxEl = document.createElement('wje-checkbox');\n\t\tcheckboxEl.setAttribute('slot', 'check');\n\n\t\tlet check = document.createElement('slot');\n\t\tcheck.setAttribute('name', 'check');\n\t\tcheck.setAttribute('part', 'check');\n\n\t\tlet start = document.createElement('slot');\n\t\tstart.setAttribute('name', 'start');\n\n\t\tlet slot = document.createElement('slot');\n\n\t\tlet endWrapper = document.createElement('span');\n\t\tendWrapper.classList.add('end-slot');\n\n\t\tlet end = document.createElement('slot');\n\t\tend.setAttribute('name', 'end');\n\n\t\tendWrapper.append(end);\n\n\t\tconst hasCheckSlot = this.querySelector('[slot=\"check\"]') !== null;\n\n\t\tif (!hasCheckSlot) {\n\t\t\tif (this.checkbox && this.multiple) {\n\t\t\t\tthis.append(checkboxEl);\n\t\t\t} else {\n\t\t\t\tthis.append(icon);\n\t\t\t}\n\t\t}\n\n\t\tnative.append(check);\n\t\tnative.append(start);\n\t\tnative.append(slot);\n\t\tnative.append(endWrapper);\n\n\t\tfragment.append(native);\n\n\t\tthis.check = check;\n\n\t\treturn fragment;\n\t}\n\n\t/**\n\t * Method executed after the drawing process is completed.\n\t * Sets up an event listener for 'click' events, linking them to the specified callback function.\n\t * @returns {void} Does not return a value.\n\t */\n\tafterDraw() {\n\t\tevent.addListener(this, 'click', null, this.optionClickCallback);\n\n\t\t// If `selected` was set before render, attributeChangedCallback may have run\n\t\t// before `this.check` existed. Sync the checkbox state once slots exist.\n\t\tif (this.checkbox && this.multiple) {\n\t\t\tthis.#setCheckbox(this.selected);\n\t\t}\n\t\tthis.syncAria();\n\t}\n\n\t/**\n\t * Syncs ARIA attributes on the host element.\n\t */\n\tsyncAria() {\n\t\tthis.setAriaState({\n\t\t\trole: 'option',\n\t\t\tselected: this.selected,\n\t\t\tdisabled: this.hasAttribute('disabled'),\n\t\t});\n\t}\n\n\t/**\n\t * Handles operations or cleanup tasks that need to occur before disconnecting.\n\t * Removes an event listener associated with the 'click' event and a specified callback function.\n\t * @returns {void} This method does not return a value.\n\t */\n\tbeforeDisconnect() {\n\t\tevent.removeListener(this, 'click', null, this.optionClickCallback);\n\t}\n\n\t/**\n\t * Handles the click event on an option element and dispatches a custom event when triggered.\n\t * @param {Event} e The click event object that triggered the callback.\n\t * @returns {void} No return value.\n\t */\n\toptionClickCallback(e) {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\te.stopImmediatePropagation();\n\n\t\tif (this.hasAttribute('disabled')) return;\n\n\t\tevent.dispatchCustomEvent(this, 'wje-option:change', {\n\t\t\tvalue: this.value,\n\t\t\ttext: this.textContent,\n\t\t\toption: this,\n\t\t});\n\t}\n\n\t/**\n\t * Checks if the given DOM node represents a checkbox element.\n\t * @param {Node} node The DOM node to be checked.\n\t * @returns {boolean} Returns true if the node is an element with a class name of 'Checkbox', otherwise false.\n\t */\n\t#isCheckbox(node) {\n\t\treturn node instanceof Element && node.className === 'Checkbox';\n\t}\n\n\t/**\n\t * Updates the checked status of the first checkbox element found within the assigned elements of the specified container.\n\t * @param {boolean} checked The desired checked state to be applied to the checkbox.\n\t * @returns {void}\n\t */\n\t#setCheckbox(checked) {\n\t\tconst assigned = this.check?.assignedElements({ flatten: true }) ?? [];\n\t\tconst arr = assigned.filter((item) => this.#isCheckbox(item));\n\t\tif (arr.length > 0) arr[0].checked = checked;\n\t}\n}\n","import Option from './option.element.js';\n\nexport default Option;\n\nOption.define('wje-option', Option);\n"],"names":[],"mappings":"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"}
|
package/dist/wje-select.js
CHANGED
|
@@ -9,7 +9,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
9
9
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
10
10
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
11
11
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
12
|
-
var _addedOptions, _htmlOptions, _Select_instances, htmlSelectedItem_fn, getSelectedOptions_fn, hasVisibleOptions_fn, updateEmptyState_fn, _applySearchFilter, _onMenuItemClickCapture, syncOptionCheckbox_fn;
|
|
12
|
+
var _addedOptions, _htmlOptions, _portaledOptionRecords, _Select_instances, htmlSelectedItem_fn, getSelectedOptions_fn, hasVisibleOptions_fn, updateEmptyState_fn, _applySearchFilter, _handleOptionsLoad, _onMenuItemClickCapture, _syncPortalStyles, copyPortalCustomProperties_fn, syncOptionOwners_fn, portalOptions_fn, _restorePortaledOptions, syncOptionCheckbox_fn;
|
|
13
13
|
import { F as FormAssociatedElement } from "./form-associated-element-DEQ4y-jn.js";
|
|
14
14
|
import { event } from "./event.js";
|
|
15
15
|
import { Localizer } from "./localize.js";
|
|
@@ -30,6 +30,7 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
30
30
|
__privateAdd(this, _Select_instances);
|
|
31
31
|
__privateAdd(this, _addedOptions, []);
|
|
32
32
|
__privateAdd(this, _htmlOptions, []);
|
|
33
|
+
__privateAdd(this, _portaledOptionRecords, []);
|
|
33
34
|
/**
|
|
34
35
|
* An object representing component dependencies with their respective classes.
|
|
35
36
|
* Each property in the object maps a custom component name (as a string key)
|
|
@@ -146,6 +147,30 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
146
147
|
__privateMethod(this, _Select_instances, updateEmptyState_fn).call(this);
|
|
147
148
|
}
|
|
148
149
|
});
|
|
150
|
+
__privateAdd(this, _handleOptionsLoad, (e) => {
|
|
151
|
+
var _a;
|
|
152
|
+
this.selectedOptions.forEach((option) => {
|
|
153
|
+
this.getAllOptions().forEach((el) => {
|
|
154
|
+
if (el.value === option.value) {
|
|
155
|
+
el.selected = true;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
const attrValue = ((_a = this.getAttribute("value")) == null ? void 0 : _a.split(" ")) || [];
|
|
160
|
+
attrValue.forEach((val) => {
|
|
161
|
+
const existingOption = Array.from(this.getAllOptions()).find((el) => el.value === val);
|
|
162
|
+
if (existingOption) {
|
|
163
|
+
existingOption.selected = true;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
this.selectedOptions = __privateMethod(this, _Select_instances, getSelectedOptions_fn).call(this);
|
|
167
|
+
this.selections(true);
|
|
168
|
+
__privateMethod(this, _Select_instances, updateEmptyState_fn).call(this);
|
|
169
|
+
__privateMethod(this, _Select_instances, syncOptionOwners_fn).call(this);
|
|
170
|
+
__privateMethod(this, _Select_instances, portalOptions_fn).call(this);
|
|
171
|
+
this.list.scrollTo(0, 0);
|
|
172
|
+
event.dispatchCustomEvent(this.popup, "wje-popup:content-ready");
|
|
173
|
+
});
|
|
149
174
|
/**
|
|
150
175
|
* Prevent closing the parent <wje-select>'s popup when a nested <wje-dropdown>
|
|
151
176
|
* menu item is clicked. Closes only the dropdown that owns the clicked item.
|
|
@@ -163,6 +188,31 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
163
188
|
}
|
|
164
189
|
e.stopPropagation();
|
|
165
190
|
});
|
|
191
|
+
__privateAdd(this, _syncPortalStyles, (e) => {
|
|
192
|
+
var _a;
|
|
193
|
+
const container = (_a = e.detail) == null ? void 0 : _a.container;
|
|
194
|
+
if (!(container instanceof HTMLElement)) return;
|
|
195
|
+
container.setAttribute("data-wje-select-portal", "");
|
|
196
|
+
__privateMethod(this, _Select_instances, copyPortalCustomProperties_fn).call(this, container);
|
|
197
|
+
__privateMethod(this, _Select_instances, portalOptions_fn).call(this, container);
|
|
198
|
+
if (container.querySelector("style[data-wje-select-portal-style]")) return;
|
|
199
|
+
const style = document.createElement("style");
|
|
200
|
+
style.setAttribute("data-wje-select-portal-style", "");
|
|
201
|
+
style.textContent = _Select.portalStyles;
|
|
202
|
+
container.prepend(style);
|
|
203
|
+
});
|
|
204
|
+
__privateAdd(this, _restorePortaledOptions, () => {
|
|
205
|
+
if (__privateGet(this, _portaledOptionRecords).length === 0) return;
|
|
206
|
+
__privateGet(this, _portaledOptionRecords).forEach(({ option, placeholder }) => {
|
|
207
|
+
option.removeEventListener("wje-option:change", this.optionChange);
|
|
208
|
+
option.removeAttribute("data-wje-select-portaled-option");
|
|
209
|
+
if (placeholder.parentNode) {
|
|
210
|
+
placeholder.parentNode.insertBefore(option, placeholder);
|
|
211
|
+
placeholder.remove();
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
__privateSet(this, _portaledOptionRecords, []);
|
|
215
|
+
});
|
|
166
216
|
this.localizer = new Localizer(this);
|
|
167
217
|
this.counterEl = null;
|
|
168
218
|
this._wasOppened = false;
|
|
@@ -258,6 +308,32 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
258
308
|
get defaultValue() {
|
|
259
309
|
return this.getAttribute("value") ?? "";
|
|
260
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Sets or removes the `portaled` attribute on the select.
|
|
313
|
+
* Mirrors the dropdown API so popup content can be rendered in a portal root.
|
|
314
|
+
* @param {boolean|string} value Determines whether and where the popup should be portaled.
|
|
315
|
+
*/
|
|
316
|
+
set portaled(value) {
|
|
317
|
+
if (value) {
|
|
318
|
+
this.setAttribute("portaled", value);
|
|
319
|
+
} else {
|
|
320
|
+
this.removeAttribute("portaled");
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Getter for the `portaled` attribute value.
|
|
325
|
+
* @returns {string} The configured portal target or an empty string for the default body portal.
|
|
326
|
+
*/
|
|
327
|
+
get portaled() {
|
|
328
|
+
return this.getAttribute("portaled") || "";
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Checks whether popup content should be portaled.
|
|
332
|
+
* @returns {boolean} True when the `portaled` attribute is present.
|
|
333
|
+
*/
|
|
334
|
+
get isPortaled() {
|
|
335
|
+
return this.hasAttribute("portaled");
|
|
336
|
+
}
|
|
261
337
|
/**
|
|
262
338
|
* Sets the trigger value.
|
|
263
339
|
* @param {string} value The trigger value to set.
|
|
@@ -452,7 +528,7 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
452
528
|
* @returns {Array<string>}
|
|
453
529
|
*/
|
|
454
530
|
static get observedAttributes() {
|
|
455
|
-
return ["active", "disabled", "readonly"];
|
|
531
|
+
return ["active", "disabled", "readonly", "portaled"];
|
|
456
532
|
}
|
|
457
533
|
/**
|
|
458
534
|
* Sets up the attributes for the component.
|
|
@@ -558,6 +634,9 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
558
634
|
popup.setAttribute("size", "");
|
|
559
635
|
popup.setAttribute("part", "popup");
|
|
560
636
|
popup.setAttribute("offset", this.offset);
|
|
637
|
+
if (this.isPortaled) {
|
|
638
|
+
popup.setAttribute("portal", this.portaled);
|
|
639
|
+
}
|
|
561
640
|
if ((this.lazy || this.querySelector("wje-options")) && !this._wasOppened) {
|
|
562
641
|
popup.setAttribute("loader", "");
|
|
563
642
|
} else {
|
|
@@ -634,8 +713,11 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
634
713
|
}
|
|
635
714
|
this.syncAria();
|
|
636
715
|
(_a = this.getAllOptions()) == null ? void 0 : _a.forEach((option) => {
|
|
716
|
+
option.ownerSelect = this;
|
|
637
717
|
this.optionCheckSlot(option);
|
|
638
718
|
});
|
|
719
|
+
event.addListener(this.popup, "wje-router:rebind", null, __privateGet(this, _syncPortalStyles));
|
|
720
|
+
event.addListener(this.popup, "wje-portal:restored", null, __privateGet(this, _restorePortaledOptions));
|
|
639
721
|
this.selectedOptions = __privateMethod(this, _Select_instances, getSelectedOptions_fn).call(this);
|
|
640
722
|
this.selectOptions(this.value, true);
|
|
641
723
|
if (this.lazy) {
|
|
@@ -700,28 +782,8 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
700
782
|
e.stopPropagation();
|
|
701
783
|
this.clearSelections();
|
|
702
784
|
});
|
|
703
|
-
this.list.addEventListener("wje-options:load", (
|
|
704
|
-
|
|
705
|
-
this.selectedOptions.forEach((option) => {
|
|
706
|
-
this.getAllOptions().forEach((el) => {
|
|
707
|
-
if (el.value === option.value) {
|
|
708
|
-
el.selected = true;
|
|
709
|
-
}
|
|
710
|
-
});
|
|
711
|
-
});
|
|
712
|
-
const attrValue = ((_a2 = this.getAttribute("value")) == null ? void 0 : _a2.split(" ")) || [];
|
|
713
|
-
attrValue.forEach((val) => {
|
|
714
|
-
const existingOption = Array.from(this.getAllOptions()).find((el) => el.value === val);
|
|
715
|
-
if (existingOption) {
|
|
716
|
-
existingOption.selected = true;
|
|
717
|
-
}
|
|
718
|
-
});
|
|
719
|
-
this.selectedOptions = __privateMethod(this, _Select_instances, getSelectedOptions_fn).call(this);
|
|
720
|
-
this.selections(true);
|
|
721
|
-
__privateMethod(this, _Select_instances, updateEmptyState_fn).call(this);
|
|
722
|
-
this.list.scrollTo(0, 0);
|
|
723
|
-
event.dispatchCustomEvent(this.popup, "wje-popup:content-ready");
|
|
724
|
-
});
|
|
785
|
+
this.list.addEventListener("wje-options:load", __privateGet(this, _handleOptionsLoad));
|
|
786
|
+
this.addEventListener("wje-options:load", __privateGet(this, _handleOptionsLoad));
|
|
725
787
|
if (this.hasAttribute("find") && this.findEl instanceof HTMLElement) {
|
|
726
788
|
event.addListener(this.findEl, "keyup", "", __privateGet(this, _applySearchFilter));
|
|
727
789
|
event.addListener(this.findEl, "wje-input:clear", "", __privateGet(this, _applySearchFilter));
|
|
@@ -733,7 +795,9 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
733
795
|
* @returns {NodeList} The options as HTML.
|
|
734
796
|
*/
|
|
735
797
|
getAllOptions() {
|
|
736
|
-
|
|
798
|
+
const localOptions = Array.from(this.querySelectorAll("wje-option"));
|
|
799
|
+
const portaledOptions = __privateGet(this, _portaledOptionRecords).map(({ option }) => option);
|
|
800
|
+
return Array.from(/* @__PURE__ */ new Set([...localOptions, ...portaledOptions]));
|
|
737
801
|
}
|
|
738
802
|
/**
|
|
739
803
|
* Handles changes in the selection for a component, updating internal values, input fields,
|
|
@@ -993,6 +1057,7 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
993
1057
|
}
|
|
994
1058
|
}
|
|
995
1059
|
disconnectedCallback() {
|
|
1060
|
+
__privateGet(this, _restorePortaledOptions).call(this);
|
|
996
1061
|
document.removeEventListener("mousedown", __privateGet(this, _onMenuItemClickCapture), true);
|
|
997
1062
|
}
|
|
998
1063
|
/**
|
|
@@ -1014,6 +1079,7 @@ const _Select = class _Select extends FormAssociatedElement {
|
|
|
1014
1079
|
};
|
|
1015
1080
|
_addedOptions = new WeakMap();
|
|
1016
1081
|
_htmlOptions = new WeakMap();
|
|
1082
|
+
_portaledOptionRecords = new WeakMap();
|
|
1017
1083
|
_Select_instances = new WeakSet();
|
|
1018
1084
|
/**
|
|
1019
1085
|
* Processes the given item and retrieves the corresponding value from the selected options.
|
|
@@ -1032,7 +1098,7 @@ htmlSelectedItem_fn = function(item) {
|
|
|
1032
1098
|
* @returns {Array<Element>} An array of elements representing the options that are currently selected.
|
|
1033
1099
|
*/
|
|
1034
1100
|
getSelectedOptions_fn = function() {
|
|
1035
|
-
return
|
|
1101
|
+
return this.getAllOptions().filter((option) => option.hasAttribute("selected"));
|
|
1036
1102
|
};
|
|
1037
1103
|
/**
|
|
1038
1104
|
* Determines whether the select currently contains at least one visible option.
|
|
@@ -1055,7 +1121,41 @@ updateEmptyState_fn = function() {
|
|
|
1055
1121
|
this.emptyState.hidden = __privateMethod(this, _Select_instances, hasVisibleOptions_fn).call(this);
|
|
1056
1122
|
};
|
|
1057
1123
|
_applySearchFilter = new WeakMap();
|
|
1124
|
+
_handleOptionsLoad = new WeakMap();
|
|
1058
1125
|
_onMenuItemClickCapture = new WeakMap();
|
|
1126
|
+
_syncPortalStyles = new WeakMap();
|
|
1127
|
+
copyPortalCustomProperties_fn = function(container) {
|
|
1128
|
+
const style = getComputedStyle(this);
|
|
1129
|
+
for (let i = 0; i < style.length; i++) {
|
|
1130
|
+
const prop = style[i];
|
|
1131
|
+
if (prop.startsWith("--")) {
|
|
1132
|
+
container.style.setProperty(prop, style.getPropertyValue(prop));
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
syncOptionOwners_fn = function() {
|
|
1137
|
+
this.getAllOptions().forEach((option) => {
|
|
1138
|
+
option.ownerSelect = this;
|
|
1139
|
+
});
|
|
1140
|
+
};
|
|
1141
|
+
portalOptions_fn = function(container = ((_a) => (_a = this.popup) == null ? void 0 : _a._portalContainer)()) {
|
|
1142
|
+
if (!(container instanceof HTMLElement)) return;
|
|
1143
|
+
const list = container.querySelector(".list");
|
|
1144
|
+
if (!(list instanceof HTMLElement)) return;
|
|
1145
|
+
const options = this.getAllOptions();
|
|
1146
|
+
options.forEach((option) => {
|
|
1147
|
+
if (__privateGet(this, _portaledOptionRecords).some((record) => record.option === option)) return;
|
|
1148
|
+
if (!option.parentNode) return;
|
|
1149
|
+
const placeholder = document.createComment("wje-select-portaled-option");
|
|
1150
|
+
option.parentNode.insertBefore(placeholder, option);
|
|
1151
|
+
option.ownerSelect = this;
|
|
1152
|
+
option.setAttribute("data-wje-select-portaled-option", "");
|
|
1153
|
+
option.addEventListener("wje-option:change", this.optionChange);
|
|
1154
|
+
__privateGet(this, _portaledOptionRecords).push({ option, placeholder });
|
|
1155
|
+
list.insertBefore(option, this.emptyState);
|
|
1156
|
+
});
|
|
1157
|
+
};
|
|
1158
|
+
_restorePortaledOptions = new WeakMap();
|
|
1059
1159
|
syncOptionCheckbox_fn = function(option) {
|
|
1060
1160
|
const checkbox = option.querySelector('wje-checkbox[slot="check"]');
|
|
1061
1161
|
if (!checkbox) return;
|
|
@@ -1068,6 +1168,54 @@ syncOptionCheckbox_fn = function(option) {
|
|
|
1068
1168
|
}
|
|
1069
1169
|
};
|
|
1070
1170
|
__publicField(_Select, "_instanceId", 0);
|
|
1171
|
+
__publicField(_Select, "portalStyles", `
|
|
1172
|
+
[data-wje-select-portal] .options-wrapper {
|
|
1173
|
+
border-width: var(--wje-select-options-border-width, 1px);
|
|
1174
|
+
border-style: var(--wje-select-options-border-style, solid);
|
|
1175
|
+
border-color: var(--wje-select-options-border-color, var(--wje-border-color, #dcdfe3));
|
|
1176
|
+
border-radius: var(--wje-select-options-border-radius, var(--wje-border-radius, 4px));
|
|
1177
|
+
margin-top: calc(0px - var(--wje-select-border-width, 1px));
|
|
1178
|
+
background-color: var(--wje-select-options-background-color, var(--wje-color-contrast-0, #fff));
|
|
1179
|
+
overflow: hidden;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
[data-wje-select-portal] .find {
|
|
1183
|
+
margin-block: var(--wje-select-find-margin-block, .5rem);
|
|
1184
|
+
margin-inline: var(--wje-select-find-margin-inline, .5rem);
|
|
1185
|
+
width: var(--wje-select-find-width, calc(100% - 1rem));
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
[data-wje-select-portal] .list {
|
|
1189
|
+
overflow: auto;
|
|
1190
|
+
height: 100%;
|
|
1191
|
+
position: relative;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
[data-wje-select-portal] .list:has(.empty:not([hidden])) {
|
|
1195
|
+
min-height: 44px;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
[data-wje-select-portal] .empty {
|
|
1199
|
+
position: absolute;
|
|
1200
|
+
inset: 0;
|
|
1201
|
+
display: flex;
|
|
1202
|
+
align-items: center;
|
|
1203
|
+
justify-content: center;
|
|
1204
|
+
padding: var(--wje-spacing-small, 1rem);
|
|
1205
|
+
color: var(--wje-select-color, inherit);
|
|
1206
|
+
text-align: center;
|
|
1207
|
+
background-color: var(--wje-select-options-background-color, var(--wje-color-contrast-0, #fff));
|
|
1208
|
+
pointer-events: none;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
[data-wje-select-portal] .empty[hidden] {
|
|
1212
|
+
display: none;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
[data-wje-select-portal] .options-wrapper:has(.find) .list {
|
|
1216
|
+
height: calc(100% - 32px - 2 * var(--wje-select-find-margin-block, .5rem));
|
|
1217
|
+
}
|
|
1218
|
+
`);
|
|
1071
1219
|
let Select = _Select;
|
|
1072
1220
|
Select.define("wje-select", Select);
|
|
1073
1221
|
export {
|