UNPKG

@umbraco-ui/uui-base

Version:

This is a base dependency for Umbraco UI components. It contains mixins, animations, abstract base classes, UUIEvent base class, and universal types for properties shared by different components

892 lines (865 loc) 31.5 kB
import { css, unsafeCSS, html } from 'lit'; import { property, state } from 'lit/decorators.js'; const UUIBlinkKeyframes = css` @keyframes uui-blink { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } } `; const UUIBlinkAnimationValue = unsafeCSS("uui-blink 0.9s infinite both"); const UUIHorizontalPulseKeyframes = css` @keyframes pulse { 0% { -webkit-transform: translate(-50%, -50%) scale(0.2); transform: translate(-50%, -50%) scale(0.2); opacity: 0.9; } 80% { -webkit-transform: translate(-50%, -50%) scale(1.2); transform: translate(-50%, -50%) scale(1.2); opacity: 0; } 100% { -webkit-transform: translate(-50%, -50%) scale(2.2); transform: translate(-50%, -50%) scale(2.2); opacity: 0; } } `; const UUIHorizontalPulseAnimationValue = unsafeCSS( "pulse 0.8s ease-in-out infinite both" ); const UUIHorizontalShakeKeyframes = css` @keyframes uui-horizontal-shake { 10%, 90% { transform: translateX(-1px); } 20%, 80% { transform: translateX(1px); } 30%, 50%, 70% { transform: translateX(-2px); } 40%, 60% { transform: translateX(2px); } } `; const UUIHorizontalShakeAnimationValue = unsafeCSS( "uui-horizontal-shake 600ms ease backwards" ); class UUIEvent extends Event { constructor(evName, eventInit = {}) { super(evName, { ...eventInit }); this.detail = eventInit.detail || {}; } } class UUIFormControlEvent extends UUIEvent { constructor(evName, eventInit = {}) { super(evName, { ...{ bubbles: true }, ...eventInit }); } } UUIFormControlEvent.VALID = "valid"; UUIFormControlEvent.INVALID = "invalid"; class UUISelectableEvent extends UUIEvent { constructor(evName, eventInit = {}) { super(evName, { ...{ bubbles: true, cancelable: true }, ...eventInit }); } } UUISelectableEvent.SELECTED = "selected"; UUISelectableEvent.DESELECTED = "deselected"; var __defProp$5 = Object.defineProperty; var __decorateClass$5 = (decorators, target, key, kind) => { var result = void 0 ; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (decorator(target, key, result) ) || result; if (result) __defProp$5(target, key, result); return result; }; const ActiveMixin = (superClass) => { class ActiveMixinClass extends superClass { constructor() { super(...arguments); this.active = false; } } __decorateClass$5([ property({ type: Boolean, reflect: true }) ], ActiveMixinClass.prototype, "active"); return ActiveMixinClass; }; var __defProp$4 = Object.defineProperty; var __decorateClass$4 = (decorators, target, key, kind) => { var result = void 0 ; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (decorator(target, key, result) ) || result; if (result) __defProp$4(target, key, result); return result; }; const LabelMixin = (labelSlotName, superClass) => { class LabelMixinClass extends superClass { constructor() { super(...arguments); this._labelSlotHasContent = false; } connectedCallback() { super.connectedCallback(); if (!this.label) { console.warn(this.tagName + " needs a `label`", this); } } labelSlotChanged(e) { this._labelSlotHasContent = e.target.assignedNodes({ flatten: true }).length > 0; } /** * Call in the mixed element to render the label template. It contains a slot. This is optional. * @method renderLabel * @returns {TemplateResult} */ renderLabel() { return html` ${this._labelSlotHasContent === false ? html`<span class="label">${this.label}</span>` : ""} <slot class="label" style=${this._labelSlotHasContent ? "" : "visibility: hidden"} name=${labelSlotName ? labelSlotName : ""} @slotchange=${this.labelSlotChanged}></slot> `; } } __decorateClass$4([ property({ type: String }) ], LabelMixinClass.prototype, "label"); __decorateClass$4([ state() ], LabelMixinClass.prototype, "_labelSlotHasContent"); return LabelMixinClass; }; var __defProp$3 = Object.defineProperty; var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor; var __typeError$2 = (msg) => { throw TypeError(msg); }; var __decorateClass$3 = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp$3(target, key, result); return result; }; var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg); var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value); var __privateMethod$1 = (obj, member, method) => (__accessCheck$2(obj, member, "access private method"), method); const SelectableMixin = (superClass) => { var _selectableTarget, _onKeydown, _onClick, _SelectableMixinClass_instances, toggleSelect_fn, select_fn, deselect_fn; class SelectableMixinClass extends superClass { constructor(...args) { super(...args); __privateAdd$2(this, _SelectableMixinClass_instances); this._selectable = false; this.deselectable = true; this.selected = false; __privateAdd$2(this, _selectableTarget, this); __privateAdd$2(this, _onKeydown, (e) => { if (e.code !== "Space" && e.code !== "Enter") return; if (e.composedPath().indexOf(__privateGet$2(this, _selectableTarget)) === 0) { __privateGet$2(this, _onClick).call(this, e); } }); __privateAdd$2(this, _onClick, (e) => { const isSelectable = this._selectable || this.deselectable && this.selected; if (isSelectable === false) return; const composePath = e.composedPath(); if (__privateGet$2(this, _selectableTarget) === this) { const isActionTag = composePath.some((el) => { const elementTagName = el.tagName; return elementTagName === "A" || elementTagName === "BUTTON" || elementTagName === "INPUT" || elementTagName === "TEXTAREA" || elementTagName === "SELECT"; }); if (isActionTag) return; } if (composePath.indexOf(__privateGet$2(this, _selectableTarget)) !== -1) { if (e.type === "keydown") { e.preventDefault(); } __privateMethod$1(this, _SelectableMixinClass_instances, toggleSelect_fn).call(this); } }); this.addEventListener("click", __privateGet$2(this, _onClick)); this.addEventListener("keydown", __privateGet$2(this, _onKeydown)); } get selectable() { return this._selectable; } set selectable(newVal) { const oldVal = this._selectable; if (oldVal === newVal) return; this._selectable = newVal; if (__privateGet$2(this, _selectableTarget) === this) { __privateGet$2(this, _selectableTarget).setAttribute( "tabindex", `${newVal ? "0" : "-1"}` ); } this.requestUpdate("selectable", oldVal); } get selectableTarget() { return __privateGet$2(this, _selectableTarget); } set selectableTarget(target) { const oldTarget = __privateGet$2(this, _selectableTarget); oldTarget.removeAttribute("tabindex"); oldTarget.removeEventListener("click", __privateGet$2(this, _onClick)); oldTarget.removeEventListener( "keydown", __privateGet$2(this, _onKeydown) ); __privateSet$2(this, _selectableTarget, target); if (__privateGet$2(this, _selectableTarget) === this) { __privateGet$2(this, _selectableTarget).setAttribute( "tabindex", this._selectable ? "0" : "-1" ); } target.addEventListener("click", __privateGet$2(this, _onClick)); target.addEventListener("keydown", __privateGet$2(this, _onKeydown)); } } _selectableTarget = new WeakMap(); _onKeydown = new WeakMap(); _onClick = new WeakMap(); _SelectableMixinClass_instances = new WeakSet(); toggleSelect_fn = function() { if (!this.selectable) return; if (this.deselectable === false) { __privateMethod$1(this, _SelectableMixinClass_instances, select_fn).call(this); } else if (this.selected) { __privateMethod$1(this, _SelectableMixinClass_instances, deselect_fn).call(this); } else { __privateMethod$1(this, _SelectableMixinClass_instances, select_fn).call(this); } }; select_fn = function() { if (!this.selectable) return; const selectEvent = new UUISelectableEvent(UUISelectableEvent.SELECTED); this.dispatchEvent(selectEvent); if (selectEvent.defaultPrevented) return; this.selected = true; }; deselect_fn = function() { if (!this.deselectable) return; const selectEvent = new UUISelectableEvent(UUISelectableEvent.DESELECTED); this.dispatchEvent(selectEvent); if (selectEvent.defaultPrevented) return; this.selected = false; }; __decorateClass$3([ property({ type: Boolean, reflect: true }) ], SelectableMixinClass.prototype, "selectable", 1); __decorateClass$3([ property({ type: Boolean, reflect: true }) ], SelectableMixinClass.prototype, "selected", 2); return SelectableMixinClass; }; var __defProp$2 = Object.defineProperty; var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor; var __decorateClass$2 = (decorators, target, key, kind) => { var result = __getOwnPropDesc$1(target, key) ; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (decorator(target, key, result) ) || result; if (result) __defProp$2(target, key, result); return result; }; const SelectOnlyMixin = (superClass) => { class SelectOnlyMixinClass extends superClass { constructor() { super(...arguments); this._selectOnly = false; } get selectOnly() { return this._selectOnly; } set selectOnly(newVal) { const oldVal = this._selectOnly; this._selectOnly = newVal; this.requestUpdate("selectOnly", oldVal); } } __decorateClass$2([ property({ type: Boolean, reflect: true, attribute: "select-only" }) ], SelectOnlyMixinClass.prototype, "selectOnly"); return SelectOnlyMixinClass; }; var __defProp$1 = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __typeError$1 = (msg) => { throw TypeError(msg); }; var __decorateClass$1 = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp$1(target, key, result); return result; }; var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg); var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value); var __privateMethod = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method); const WeightedErrorFlagTypes = [ "customError", "valueMissing", "badInput", "typeMismatch", "patternMismatch", "rangeOverflow", "rangeUnderflow", "stepMismatch", "tooLong", "tooShort" ]; const UUIFormControlMixin = (superClass, defaultValue) => { var _validity, _value, _form, _validators, _formCtrlElements, _UUIFormControlMixinClass_instances, removeFormListeners_fn, dispatchValidationState_fn, _onFormSubmit; class UUIFormControlMixinClass extends superClass { constructor(...args) { super(...args); __privateAdd$1(this, _UUIFormControlMixinClass_instances); this.name = ""; // Validation __privateAdd$1(this, _validity, {}); // Will be set to true instantly to trigger the setAttribute in the setter. // This is to prevent an issue caused by using setAttribute in the constructor. this._pristine = false; this.required = false; this.requiredMessage = "This field is required"; this.error = false; this.errorMessage = "This field is invalid"; __privateAdd$1(this, _value, defaultValue); __privateAdd$1(this, _form, null); __privateAdd$1(this, _validators, []); __privateAdd$1(this, _formCtrlElements, []); __privateAdd$1(this, _onFormSubmit, () => { this.pristine = false; }); this._internals = this.attachInternals(); this.pristine = true; this.addValidator( "valueMissing", () => this.requiredMessage, () => this.hasAttribute("required") && this.hasValue() === false ); this.addValidator( "customError", () => this.errorMessage, () => this.error ); this.addEventListener("blur", () => { this.pristine = false; this.checkValidity(); }); } // Do not 'reflect' as the attribute is used as fallback. get value() { return __privateGet$1(this, _value); } set value(newValue) { const oldValue = __privateGet$1(this, _value); __privateSet$1(this, _value, newValue); if ("ElementInternals" in window && "setFormValue" in window.ElementInternals.prototype) { this._internals.setFormValue(__privateGet$1(this, _value) ?? null); } this.requestUpdate("value", oldValue); } set pristine(value) { if (this._pristine !== value) { this._pristine = value; if (value) { this.setAttribute("pristine", ""); } else { this.removeAttribute("pristine"); } __privateMethod(this, _UUIFormControlMixinClass_instances, dispatchValidationState_fn).call(this); } } get pristine() { return this._pristine; } /** * Determine wether this FormControl has a value. * @method hasValue * @returns {boolean} */ hasValue() { return this.value !== this.getDefaultValue(); } /** * Focus first element that is invalid. * @method focusFirstInvalidElement * @returns {HTMLElement | undefined} */ focusFirstInvalidElement() { const firstInvalid = __privateGet$1(this, _formCtrlElements).find( (el) => el.validity.valid === false ); if (firstInvalid) { if ("focusFirstInvalidElement" in firstInvalid) { firstInvalid.focusFirstInvalidElement(); } else { firstInvalid.focus(); } } else { this.focus(); } } disconnectedCallback() { super.disconnectedCallback(); __privateMethod(this, _UUIFormControlMixinClass_instances, removeFormListeners_fn).call(this); } /** * Add validator, to validate this Form Control. * See https://developer.mozilla.org/en-US/docs/Web/API/ValidityState for available Validator FlagTypes. * * @example * this.addValidator( * 'tooLong', * () => 'This input contains too many characters', * () => this._value.length > 10 * ); * @method hasValue * @param {FlagTypes} flagKey the type of validation. * @param {method} getMessageMethod method to retrieve relevant message. Is executed every time the validator is re-executed. * @param {method} checkMethod method to determine if this validator should invalidate this form control. Return true if this should prevent submission. */ addValidator(flagKey, getMessageMethod, checkMethod) { const validator = { flagKey, getMessageMethod, checkMethod, weight: WeightedErrorFlagTypes.indexOf(flagKey) }; __privateGet$1(this, _validators).push(validator); __privateGet$1(this, _validators).sort( (a, b) => a.weight > b.weight ? 1 : b.weight > a.weight ? -1 : 0 ); return validator; } removeValidator(validator) { const index = __privateGet$1(this, _validators).indexOf(validator); if (index !== -1) { __privateGet$1(this, _validators).splice(index, 1); } } /** * @method addFormControlElement * @description Important notice if adding a native form control then ensure that its value and thereby validity is updated when value is changed from the outside. * @param element {NativeFormControlElement} - element to validate and include as part of this form association. */ addFormControlElement(element) { __privateGet$1(this, _formCtrlElements).push(element); element.addEventListener(UUIFormControlEvent.INVALID, () => { this._runValidators(); }); element.addEventListener(UUIFormControlEvent.VALID, () => { this._runValidators(); }); if (this._pristine === false) { element.checkValidity(); this._runValidators(); } } /** * @method setCustomValidity * @description Set custom validity state, set to empty string to remove the custom message. * @param message {string} - The message to be shown * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/setCustomValidity|HTMLObjectElement:setCustomValidity} */ setCustomValidity(message) { if (this._customValidityObject) { this.removeValidator(this._customValidityObject); } if (message != null && message !== "") { this._customValidityObject = this.addValidator( "customError", () => message, () => true ); } this._runValidators(); } /** * @protected * @method _runValidators * @description Run all validators and set the validityState of this form control. * Run this method when you want to re-run all validators. * This can be relevant if you have a validators that is using values that is not triggering the Lit Updated Callback. * Such are mainly properties that are not declared as a Lit state and or Lit property. */ _runValidators() { __privateSet$1(this, _validity, {}); let message = void 0; let innerFormControlEl = void 0; __privateGet$1(this, _validators).some((validator) => { if (validator.checkMethod()) { __privateGet$1(this, _validity)[validator.flagKey] = true; message = validator.getMessageMethod(); return true; } return false; }); if (!message) { __privateGet$1(this, _formCtrlElements).some((formCtrlEl) => { let key; for (key in formCtrlEl.validity) { if (key !== "valid" && formCtrlEl.validity[key]) { __privateGet$1(this, _validity)[key] = true; message = formCtrlEl.validationMessage; innerFormControlEl ?? (innerFormControlEl = formCtrlEl); return true; } } return false; }); } const hasError = Object.values(__privateGet$1(this, _validity)).includes(true); __privateGet$1(this, _validity).valid = !hasError; this._internals.setValidity( __privateGet$1(this, _validity), // Turn messages into an array and join them with a comma. [NL]: //[...messages].join(', '), message, innerFormControlEl ?? this.getFormElement() ?? void 0 ); __privateMethod(this, _UUIFormControlMixinClass_instances, dispatchValidationState_fn).call(this); } updated(changedProperties) { super.updated(changedProperties); this._runValidators(); } submit() { __privateGet$1(this, _form)?.requestSubmit(); } formAssociatedCallback() { __privateMethod(this, _UUIFormControlMixinClass_instances, removeFormListeners_fn).call(this); __privateSet$1(this, _form, this._internals.form); if (__privateGet$1(this, _form)) { if (__privateGet$1(this, _form).hasAttribute("submit-invalid")) { this.pristine = false; } __privateGet$1(this, _form).addEventListener("submit", __privateGet$1(this, _onFormSubmit)); } } formResetCallback() { this.pristine = true; this.value = this.getInitialValue() ?? this.getDefaultValue(); } getDefaultValue() { return defaultValue; } getInitialValue() { return this.getAttribute("value"); } checkValidity() { this.pristine = false; this._runValidators(); for (const key in __privateGet$1(this, _formCtrlElements)) { if (__privateGet$1(this, _formCtrlElements)[key].checkValidity() === false) { return false; } } return this._internals?.checkValidity(); } // https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/validity get validity() { return __privateGet$1(this, _validity); } get validationMessage() { return this._internals?.validationMessage; } } _validity = new WeakMap(); _value = new WeakMap(); _form = new WeakMap(); _validators = new WeakMap(); _formCtrlElements = new WeakMap(); _UUIFormControlMixinClass_instances = new WeakSet(); removeFormListeners_fn = function() { if (__privateGet$1(this, _form)) { __privateGet$1(this, _form).removeEventListener("submit", __privateGet$1(this, _onFormSubmit)); } }; dispatchValidationState_fn = function() { if (this._pristine === true) return; if (__privateGet$1(this, _validity).valid) { this.dispatchEvent(new UUIFormControlEvent(UUIFormControlEvent.VALID)); } else { this.dispatchEvent( new UUIFormControlEvent(UUIFormControlEvent.INVALID) ); } }; _onFormSubmit = new WeakMap(); /** * This is a static class field indicating that the element is can be used inside a native form and participate in its events. * It may require a polyfill, check support here https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals. * Read more about form controls here https://web.dev/more-capable-form-controls/ * @type {boolean} */ UUIFormControlMixinClass.formAssociated = true; __decorateClass$1([ property({ type: String }) ], UUIFormControlMixinClass.prototype, "name", 2); __decorateClass$1([ property() ], UUIFormControlMixinClass.prototype, "value", 1); __decorateClass$1([ property({ type: Boolean, reflect: true, attribute: "pristine" }) ], UUIFormControlMixinClass.prototype, "pristine", 1); __decorateClass$1([ property({ type: Boolean, reflect: true }) ], UUIFormControlMixinClass.prototype, "required", 2); __decorateClass$1([ property({ type: String, attribute: "required-message" }) ], UUIFormControlMixinClass.prototype, "requiredMessage", 2); __decorateClass$1([ property({ type: Boolean, reflect: true }) ], UUIFormControlMixinClass.prototype, "error", 2); __decorateClass$1([ property({ type: String, attribute: "error-message" }) ], UUIFormControlMixinClass.prototype, "errorMessage", 2); return UUIFormControlMixinClass; }; class Timer { constructor(_callback, duration) { this._callback = _callback; this._timerId = null; this._remaining = null; this._onComplete = () => { this._remaining = null; this._callback(); }; this.setDuration(duration); } setDuration(duration) { this._duration = duration; if (this._timerId !== null) { this.restart(); } } /** starts the timer */ start() { if (this._timerId === null) { this.resume(); } } /** restarts the timer by setting remaining time to duration. */ restart() { this._remaining = this._duration; this.resume(); } pause() { if (this._timerId !== null) { window.clearTimeout(this._timerId); this._timerId = null; if (this._remaining !== null) { this._remaining -= Date.now() - this._startTime; } } } resume() { if (this._timerId !== null) { window.clearTimeout(this._timerId); } if (this._remaining === null) { this._remaining = this._duration; } this._startTime = Date.now(); this._timerId = window.setTimeout(this._onComplete, this._remaining); } destroy() { this.pause(); } } const demandCustomElement = (requester, elementName, message = `This element has to be present for ${requester.nodeName} to work appropriate.`) => { if (!customElements.get(elementName)) { console.warn( `%c ${requester.nodeName} requires ${elementName} element to be registered!`, "font-weight: bold;", message, requester ); } }; const drag = (container, options) => { function move(event) { const dims = container.getBoundingClientRect(); const defaultView = container.ownerDocument.defaultView; const offsetX = dims.left + defaultView.scrollX; const offsetY = dims.top + defaultView.scrollY; let pointerEvent; if ("TouchEvent" in window && event instanceof TouchEvent) { pointerEvent = event.touches[0]; } else if (event instanceof PointerEvent) { pointerEvent = event; } else { return; } const x = pointerEvent.pageX - offsetX; const y = pointerEvent.pageY - offsetY; if (options?.onMove) { options.onMove(x, y); } } function stop() { document.removeEventListener("pointermove", move); document.removeEventListener("pointerup", stop); if (options?.onStop) { options.onStop(); } } document.addEventListener("pointermove", move, { passive: true }); document.addEventListener("pointerup", stop); if (options?.initialEvent) { move(options.initialEvent); } }; const clamp = (value, min, max) => { return Math.min(Math.max(value, min), max); }; const reverseNumberInRange = (num, min, max) => { return max + min - num; }; const toHex = (value) => { const hex = Math.round(value).toString(16); return hex.length === 1 ? `0${hex}` : hex; }; const findAncestorByAttributeValue = (startNode, attributeName, attributeValue) => { let currentNode = startNode; while (currentNode !== null) { const elementHasAttribute = currentNode instanceof HTMLElement && currentNode.hasAttribute(attributeName) && currentNode.getAttribute(attributeName) === attributeValue; const elementContainsAttribute = currentNode.querySelector(`[${attributeName}="${attributeValue}"]`) !== null; if (elementHasAttribute) { return currentNode; } else if (elementContainsAttribute) { return currentNode.querySelector( `[${attributeName}="${attributeValue}"]` ); } currentNode = currentNode.parentElement || currentNode.parentNode || currentNode.host || null; } return null; }; function slotHasContent(target) { return target ? target.assignedNodes({ flatten: true }).length > 0 : false; } var __defProp = Object.defineProperty; var __typeError = (msg) => { throw TypeError(msg); }; var __decorateClass = (decorators, target, key, kind) => { var result = void 0 ; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (decorator(target, key, result) ) || result; if (result) __defProp(target, key, result); return result; }; var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), member.get(obj)); 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); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value); const PopoverTargetMixin = (superClass) => { var _popoverIsOpen, _popoverListener; class PopoverTargetMixinClass extends superClass { constructor(...args) { super(...args); __privateAdd(this, _popoverIsOpen, false); this._togglePopover = () => { if (!this.popoverContainerElement) return; const popoverContainerElement = findAncestorByAttributeValue( this, "id", this.popoverContainerElement ); if (!popoverContainerElement) return; if (__privateGet(this, _popoverIsOpen)) { popoverContainerElement.hidePopover(); } else { popoverContainerElement.showPopover(); } }; __privateAdd(this, _popoverListener, (event) => { requestAnimationFrame(() => { __privateSet(this, _popoverIsOpen, event.detail.newState === "open"); }); }); this.addEventListener("uui-popover-before-toggle", __privateGet(this, _popoverListener)); } } _popoverIsOpen = new WeakMap(); _popoverListener = new WeakMap(); __decorateClass([ property({ type: String, attribute: "popovertarget" }) ], PopoverTargetMixinClass.prototype, "popoverContainerElement"); return PopoverTargetMixinClass; }; function defineElement(name, options) { return (constructor) => { const isValidElementName = name.indexOf("-") > 0; if (isValidElementName === false) { console.error( `${name} is not a valid custom element name. A custom element name should consist of at least two words separated by a hyphen.` ); return; } const existingElement = window.customElements.get(name); if (!existingElement) { window.customElements.define(name, constructor, options); } }; } const UUIInterfaceLookValues = [ "default", "primary", "secondary", "outline", "placeholder" ]; const UUIInterfaceColorValues = [ "default", "positive", "warning", "danger", "invalid" ]; const UUIInterfaceHeadingValues = [ "h1", "h2", "h3", "h4", "h5", "h6" ]; export { ActiveMixin, LabelMixin, PopoverTargetMixin, SelectOnlyMixin, SelectableMixin, Timer, UUIBlinkAnimationValue, UUIBlinkKeyframes, UUIEvent, UUIFormControlEvent, UUIFormControlMixin, UUIHorizontalPulseAnimationValue, UUIHorizontalPulseKeyframes, UUIHorizontalShakeAnimationValue, UUIHorizontalShakeKeyframes, UUIInterfaceColorValues, UUIInterfaceHeadingValues, UUIInterfaceLookValues, UUISelectableEvent, clamp, defineElement, demandCustomElement, drag, findAncestorByAttributeValue, reverseNumberInRange, slotHasContent, toHex };