/*! * All material copyright ESRI, All Rights Reserved, unless otherwise specified. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details. * v1.0.0-beta.97 */ import { q as queryElementRoots, o as closestElementCrossShadowBoundary } from './dom.js'; /** * Exported for testing purposes only * * @internal */ const labelClickEvent = "calciteInternalLabelClick"; const labelConnectedEvent = "calciteInternalLabelConnected"; const labelDisconnectedEvent = "calciteInternaLabelDisconnected"; const labelTagName = "calcite-label"; const onLabelClickMap = new WeakMap(); const onLabelConnectedMap = new WeakMap(); const onLabelDisconnectedMap = new WeakMap(); const unlabeledComponents = new Set(); const findLabelForComponent = (componentEl) => { const { id } = componentEl; const forLabel = id && queryElementRoots(componentEl, { selector: `${labelTagName}[for="${id}"]` }); if (forLabel) { return forLabel; } const parentLabel = closestElementCrossShadowBoundary(componentEl, labelTagName); if (!parentLabel || // labelable components within other custom elements are not considered labelable hasAncestorCustomElements(parentLabel, componentEl)) { return null; } return parentLabel; }; function hasAncestorCustomElements(label, componentEl) { let traversedElements; const customElementAncestorCheckEventType = "custom-element-ancestor-check"; const listener = (event) => { event.stopImmediatePropagation(); const composedPath = event.composedPath(); traversedElements = composedPath.slice(composedPath.indexOf(componentEl), composedPath.indexOf(label)); }; label.addEventListener(customElementAncestorCheckEventType, listener, { once: true }); componentEl.dispatchEvent(new CustomEvent(customElementAncestorCheckEventType, { composed: true, bubbles: true })); label.removeEventListener(customElementAncestorCheckEventType, listener); const ancestorCustomElements = traversedElements .filter((el) => el !== componentEl && el !== label) .filter((el) => { var _a; return (_a = el.tagName) === null || _a === void 0 ? void 0 : _a.includes("-"); }); return ancestorCustomElements.length > 0; } /** * Helper to set up label interactions on connectedCallback. * * @param component */ function connectLabel(component) { const labelEl = findLabelForComponent(component.el); if (onLabelClickMap.has(labelEl) || (!labelEl && unlabeledComponents.has(component))) { return; } const boundOnLabelDisconnected = onLabelDisconnected.bind(component); if (labelEl) { component.labelEl = labelEl; const boundOnLabelClick = onLabelClick.bind(component); onLabelClickMap.set(component.labelEl, boundOnLabelClick); component.labelEl.addEventListener(labelClickEvent, boundOnLabelClick); unlabeledComponents.delete(component); document.removeEventListener(labelConnectedEvent, onLabelConnectedMap.get(component)); onLabelDisconnectedMap.set(component, boundOnLabelDisconnected); document.addEventListener(labelDisconnectedEvent, boundOnLabelDisconnected); } else if (!unlabeledComponents.has(component)) { boundOnLabelDisconnected(); document.removeEventListener(labelDisconnectedEvent, onLabelDisconnectedMap.get(component)); } } /** * Helper to tear down label interactions on disconnectedCallback on labelable components. * * @param component */ function disconnectLabel(component) { unlabeledComponents.delete(component); document.removeEventListener(labelConnectedEvent, onLabelConnectedMap.get(component)); document.removeEventListener(labelDisconnectedEvent, onLabelDisconnectedMap.get(component)); onLabelConnectedMap.delete(component); onLabelDisconnectedMap.delete(component); if (!component.labelEl) { return; } const boundOnLabelClick = onLabelClickMap.get(component.labelEl); component.labelEl.removeEventListener(labelClickEvent, boundOnLabelClick); onLabelClickMap.delete(component.labelEl); } /** * Helper to get the label text from a component. * * @param component */ function getLabelText(component) { var _a, _b; return component.label || ((_b = (_a = component.labelEl) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || ""; } function onLabelClick(event) { if (this.disabled) { return; } const containedLabelableChildClicked = this.el.contains(event.detail.sourceEvent.target); if (containedLabelableChildClicked) { return; } this.onLabelClick(event); } function onLabelConnected() { if (unlabeledComponents.has(this)) { connectLabel(this); } } function onLabelDisconnected() { unlabeledComponents.add(this); const boundOnLabelConnected = onLabelConnectedMap.get(this) || onLabelConnected.bind(this); onLabelConnectedMap.set(this, boundOnLabelConnected); document.addEventListener(labelConnectedEvent, boundOnLabelConnected); } export { labelDisconnectedEvent as a, connectLabel as c, disconnectLabel as d, getLabelText as g, labelConnectedEvent as l };