UNPKG

ranui

Version:

UI Component library based on `Web Component`

561 lines (560 loc) 21.5 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import "./index-CWcQDopI.js"; import "./index-C6fbgi_U.js"; import { a as addClassToElement, r as removeClassToElement, i as isMobile, h as generateThrottle } from "./plus-BQnIzzvi.js"; import { c as createCustomError, i as isDisabled, H as HTMLElementSSR } from "./index-9tJmVuyv.js"; function Custom$1() { if (typeof document !== "undefined" && !customElements.get("ra-option")) { class Option extends HTMLElement { constructor() { super(); __publicField(this, "_option"); __publicField(this, "_optionContent"); __publicField(this, "_shadowDom"); __publicField(this, "_slot"); this._slot = document.createElement("slot"); this._option = document.createElement("div"); this._option.setAttribute("class", "ran-option"); this._optionContent = document.createElement("div"); this._optionContent.setAttribute("class", "ran-option-content"); this._optionContent.appendChild(this._slot); this._option.appendChild(this._optionContent); const shadowRoot = this.attachShadow({ mode: "closed" }); this._shadowDom = shadowRoot; shadowRoot.appendChild(this._option); } static get observedAttributes() { return ["disabled", "sheet", "value"]; } get value() { return this.getAttribute("value"); } set value(value) { this.setAttribute("value", value || ""); } get sheet() { return this.getAttribute("sheet"); } set sheet(value) { this.setAttribute("sheet", value || ""); } get disabled() { return isDisabled(this); } set disabled(value) { if (!value || value === "false") { this.removeAttribute("disabled"); } else { this.setAttribute("disabled", ""); } } handlerExternalCss() { if (this.sheet) { try { const sheet = new CSSStyleSheet(); sheet.insertRule(this.sheet); this._shadowDom.adoptedStyleSheets = [sheet]; } catch (error) { console.error(`Failed to parse the rule in CSSStyleSheet: ${this.sheet},error:${error}`); } } } attributeChangedCallback(name, oldValue, newValue) { if (name === "disabled" && this._option) { if (!newValue || newValue === "false") { this._option.setAttribute("disabled", ""); } else { this._option.removeAttribute("disabled"); } } if (name === "sheet" && this._shadowDom && oldValue !== newValue) this.handlerExternalCss(); } } return Option; } else { return createCustomError("document is undefined or ra-option is exist"); } } Custom$1(); const placementDirection = { bottom: { add: "ran-select-dropdown-down-in", remove: "ran-select-dropdown-down-out" }, top: { add: "ran-select-dropdown-up-in", remove: "ran-select-dropdown-up-out" } }; const searchThrottle = generateThrottle(); class Select extends HTMLElementSSR() { constructor() { super(); __publicField(this, "removeTimeId"); __publicField(this, "_select"); __publicField(this, "_selection"); __publicField(this, "_search"); __publicField(this, "_icon"); __publicField(this, "_selectDropdown"); __publicField(this, "_selectionDropdown"); __publicField(this, "_selectDropDownInTimeId"); __publicField(this, "_selectDropDownOutTimeId"); __publicField(this, "_optionList"); __publicField(this, "_optionLabelMapValue"); __publicField(this, "_optionValueMapLabel"); __publicField(this, "_activeOption"); __publicField(this, "_text"); __publicField(this, "_selector"); __publicField(this, "onSearch"); /** * @description: 移除 select dropdown * @return {*} */ __publicField(this, "setSelectDropdownDisplayNone", () => { if (this._selectDropDownOutTimeId) return; if (this._selectionDropdown && this._selectionDropdown.style.display !== "none") { addClassToElement(this._selectionDropdown, placementDirection[this.placement].remove); this._selectDropDownOutTimeId = setTimeout(() => { var _a; (_a = this._selectionDropdown) == null ? void 0 : _a.style.setProperty("display", "none"); this._selectionDropdown && removeClassToElement(this._selectionDropdown, placementDirection[this.placement].remove); clearTimeout(this._selectDropDownOutTimeId); this._selectDropDownOutTimeId = void 0; }, 300); } }); /** * @description: 添加 select dropdown * @return {*} */ __publicField(this, "setSelectDropdownDisplayBlock", () => { var _a; if (this._selectDropDownInTimeId) return; if (this._selectionDropdown && this._selectionDropdown.style.display !== "block") { addClassToElement(this._selectionDropdown, placementDirection[this.placement].add); (_a = this._selectionDropdown) == null ? void 0 : _a.style.setProperty("display", "block"); this._selectDropDownInTimeId = setTimeout(() => { this._selectionDropdown && removeClassToElement(this._selectionDropdown, placementDirection[this.placement].add); clearTimeout(this._selectDropDownInTimeId); this._selectDropDownInTimeId = void 0; }, 200); } }); __publicField(this, "placementPosition", () => { if (!this._selectionDropdown || !this._selectDropdown) return; const rect = this.getBoundingClientRect(); const { top, left, bottom, width } = rect; const root = document.getElementById(this.getPopupContainerId); this._selectionDropdown.style.setProperty("--ran-x", `${top + window.scrollX}`); this._selectionDropdown.style.setProperty("--ran-y", `${left + window.scrollY}`); let selectTop = bottom + window.scrollY; let selectLeft = left + window.scrollX; this._selectionDropdown.style.setProperty("width", `${width}px`); if (this.placement === "top") { selectTop = top + window.scrollY - this._selectionDropdown.clientHeight; } if (this.getPopupContainerId && root) { if (this.placement === "top") { selectTop = top - root.getBoundingClientRect().top - this._selectionDropdown.clientHeight; } else { selectTop = root.getBoundingClientRect().height; } selectLeft = 0; } this._selectionDropdown.style.setProperty("inset", `${selectTop}px auto auto ${selectLeft}px`); }); /** * @description: 设置下拉框 * @return {*} */ __publicField(this, "selectMouseDown", (e) => { e.stopPropagation(); if (isDisabled(this)) return; this.removeDropDownTimeId(); this.setSelectDropdownDisplayNone(); this.setSelectDropdownDisplayBlock(); this.placementPosition(); }); __publicField(this, "removeDropDownTimeId", () => { this._search.setAttribute("value", ""); if (this.trigger.includes("hover") && !isMobile()) { clearTimeout(this.removeTimeId); this.removeTimeId = void 0; } }); /** * @description: 焦点移除的情况,需要移除 select 下拉框 * @return {*} */ __publicField(this, "selectBlur", () => { if (this.removeTimeId) { this.removeDropDownTimeId(); } this.removeTimeId = setTimeout(() => { this.removeDropDownTimeId(); this.setSelectDropdownDisplayNone(); }, 100); }); /** * @description: 选中一个选项的情况 * @param {MouseEvent} e * @return {*} */ __publicField(this, "clickOption", (e) => { var _a, _b; e.stopPropagation(); let element = e.target; if ((_a = element.classList) == null ? void 0 : _a.contains("ranui-select-dropdown-option-item")) { element = element.children[0]; } if (!((_b = element.classList) == null ? void 0 : _b.contains("ranui-select-dropdown-option-item-content"))) return; const label = element.innerHTML; const value = this._optionLabelMapValue.get(label); if (value) { this.setAttribute("value", value); this._text.innerHTML = label; this._text.setAttribute("title", label); this._search.setAttribute("placeholder", label); } const rect = this.getBoundingClientRect(); const { height } = rect; this._text.style.setProperty("line-height", `${height}px`); if (this._activeOption) { removeClassToElement(this._activeOption, "ranui-select-dropdown-option-active"); } setTimeout(() => { this._activeOption = (element == null ? void 0 : element.parentElement) || void 0; if (this._activeOption) { addClassToElement(this._activeOption, "ranui-select-dropdown-option-active"); } }, 200); this.setSelectDropdownDisplayNone(); this.dispatchEvent(new CustomEvent("change", { detail: { value, label } })); this.removeDropDownTimeId(); }); /** * @description: 初始化创建选项下拉框 * @return {*} */ __publicField(this, "createOption", () => { if (!this._selectDropdown) { this.appendChild(this._select); const container = document.getElementById(this.getPopupContainerId) || document.body; this._selectDropdown = document.createElement("div"); this._selectDropdown.style.setProperty("-webkit-tap-highlight-color", "transparent"); this._selectDropdown.style.setProperty("outline", "0"); this._selectDropdown.addEventListener("click", this.clickOption); this._selectionDropdown = document.createElement("div"); this._selectionDropdown.style.setProperty("-webkit-tap-highlight-color", "transparent"); this._selectionDropdown.style.setProperty("outline", "0"); if (this.dropdownclass) { this._selectionDropdown.setAttribute("class", `${this.dropdownclass} ranui-select-dropdown`); } else { this._selectionDropdown.setAttribute("class", "ranui-select-dropdown"); } if (this.trigger.includes("hover") && !isMobile()) { this._selectDropdown.addEventListener("mouseleave", this.selectBlur); this._selectDropdown.addEventListener("mouseenter", this.removeDropDownTimeId); } this._selectDropdown.appendChild(this._selectionDropdown); this._selectionDropdown.style.setProperty("display", "none"); container.appendChild(this._selectDropdown); } this.addOptionToSlot(); }); /** * @description: 移除选项下拉框 * @return {*} */ __publicField(this, "removeSelectDropdown", () => { try { if (this._selectDropdown) { const container = document.getElementById(this.getPopupContainerId) || document.body; container.removeChild(this._selectDropdown); } } catch (error) { } }); /** * @description: 当 select 中有 option 元素的时候,给 dropdown 添加元素 * @return {*} */ __publicField(this, "addOptionToSlot", () => { var _a; const child = this.children || []; this._optionList = []; for (const item of child) { if (item.tagName === "R-OPTION") { const label = item.innerHTML; const value = item.getAttribute("value") || ""; (_a = this._optionList) == null ? void 0 : _a.push({ label, value }); this._optionLabelMapValue.set(label, value); this._optionValueMapLabel.set(value, label); } } this.createSelectDropdownContent(this._optionList); }); __publicField(this, "createSelectDropdownContent", (options = []) => { var _a, _b; if (options.length === 0) { (_a = this._selectDropdown) == null ? void 0 : _a.style.setProperty("display", "none"); } else { (_b = this._selectDropdown) == null ? void 0 : _b.style.setProperty("display", "block"); } if (this._selectionDropdown) { this._selectionDropdown.innerHTML = ""; } options.forEach((item) => { if (this._selectionDropdown) { const { label, value } = item; const selectOptionItem = document.createElement("div"); const defaultValue = this.getAttribute("defaultValue") || this.getAttribute("value"); if (defaultValue === value) { selectOptionItem.setAttribute( "class", "ranui-select-dropdown-option-active ranui-select-dropdown-option-item" ); this._activeOption = selectOptionItem; } else { selectOptionItem.setAttribute("class", "ranui-select-dropdown-option-item"); } const selectOptionItemContent = document.createElement("div"); selectOptionItemContent.setAttribute("class", "ranui-select-dropdown-option-item-content"); selectOptionItemContent.innerHTML = `${label}`; selectOptionItemContent.setAttribute("value", `${value}`); selectOptionItemContent.setAttribute("title", `${label}`); selectOptionItem.appendChild(selectOptionItemContent); this._selectionDropdown.appendChild(selectOptionItem); } }); this.setDefaultValue(); }); __publicField(this, "setDefaultValue", () => { const defaultValue = this.getAttribute("defaultValue") || this.getAttribute("value"); if (!defaultValue) return; const label = this._optionValueMapLabel.get(defaultValue); if (!label) return; this.setAttribute("value", defaultValue); const rect = this.getBoundingClientRect(); const { height } = rect; this._text.style.setProperty("line-height", `${height}px`); this._text.innerHTML = label; this._text.setAttribute("title", label); }); __publicField(this, "changeSearch", (e) => { const value = e.detail.value || ""; this.dispatchEvent( new CustomEvent("search", { detail: { value } }) ); if (this._selectionDropdown) { this._selectionDropdown.innerHTML = ""; } if (value.length > 0) { const options = this._optionList.map((item) => { const { label } = item; if (`${label}`.toLowerCase().includes(value)) { return { label, value: item.value }; } return void 0; }).filter((item) => item); this.createSelectDropdownContent(options); } else { this.createSelectDropdownContent(this._optionList); } }); __publicField(this, "setShowSearch", () => { this.onSearch = searchThrottle(this.changeSearch); this.onSearch && this._search.addEventListener("change", this.onSearch); this.onSearch && this._search.addEventListener("click", this.onSearch); }); __publicField(this, "removeShowSearch", () => { this.onSearch && this._search.removeEventListener("change", this.onSearch); this.onSearch && this._search.removeEventListener("click", this.onSearch); }); __publicField(this, "listenActionEvent", () => { this.removeEventListener("mouseenter", this.selectMouseDown); this.removeEventListener("mouseleave", this.selectBlur); this.removeEventListener("click", this.selectMouseDown); this.removeEventListener("blur", this.selectBlur); if (this.trigger.includes("hover") && !isMobile()) { this.addEventListener("mouseenter", this.selectMouseDown); this.addEventListener("mouseleave", this.selectBlur); } if (this.trigger.includes("click")) { this.addEventListener("click", this.selectMouseDown); this.addEventListener("blur", this.selectBlur); } }); __publicField(this, "clickRemoveSelect", (e) => { e.stopPropagation(); this.setSelectDropdownDisplayNone(); }); this._select = document.createElement("div"); this._select.setAttribute("class", "ran-select"); this._select.setAttribute("part", "select"); this._selection = document.createElement("div"); this._selection.setAttribute("class", "selection"); this._selection.setAttribute("part", "selection"); this._selector = document.createElement("div"); this._search = document.createElement("ra-input"); this._search.setAttribute("class", "selection-search"); this._search.setAttribute("part", "search"); this._search.setAttribute("type", "search"); this._search.setAttribute("autocomplete", "off"); this._text = document.createElement("span"); this._text.setAttribute("class", "selection-item"); this._text.setAttribute("part", "selection-item"); this._icon = document.createElement("ra-icon"); this._icon.setAttribute("class", "icon"); this._icon.setAttribute("part", "icon"); this._icon.setAttribute("name", "arrow-down"); this._icon.setAttribute("color", "#d9d9d9"); this._icon.setAttribute("size", "16"); this._selector.appendChild(this._text); this._selector.appendChild(this._search); this._selection.appendChild(this._icon); this._selection.appendChild(this._selector); this._select.appendChild(this._selection); this._optionList = []; this._optionLabelMapValue = /* @__PURE__ */ new Map(); this._optionValueMapLabel = /* @__PURE__ */ new Map(); } static get observedAttributes() { return [ "disabled", "sheet", "clear", "type", "defaultValue", "showSearch", "placement", // 弹窗的方向 "getPopupContainerId", // 挂载的节点 "dropdownclass", // 弹窗的类名 "trigger" // 触发下拉框的行为,click 还是 hover,hover 在 isMobile 移动端无效 ]; } get value() { return this.getAttribute("value") || ""; } set value(value) { if (!isDisabled(this) && value) { this.setAttribute("value", value); } else { this.removeAttribute("value"); } } get defaultValue() { return this.getAttribute("defaultValue") || ""; } set defaultValue(value) { this.setAttribute("defaultValue", value || ""); } get showSearch() { return this.getAttribute("showSearch") || ""; } set showSearch(value) { this.setAttribute("showSearch", value || ""); } get type() { return this.getAttribute("type") || ""; } set type(value) { this.setAttribute("type", value || ""); } get placement() { return this.getAttribute("placement") || "bottom"; } set placement(value) { this.setAttribute("placement", value || ""); } get sheet() { return this.getAttribute("sheet") || ""; } set sheet(value) { this.setAttribute("sheet", value || ""); } get getPopupContainerId() { return this.getAttribute("getPopupContainerId") || ""; } set getPopupContainerId(value) { this.setAttribute("getPopupContainerId", value || ""); } get dropdownclass() { return this.getAttribute("dropdownclass") || ""; } set dropdownclass(value) { this.setAttribute("dropdownclass", value || ""); } get trigger() { return this.getAttribute("trigger") || "click"; } set trigger(value) { this.setAttribute("trigger", value || ""); } get disabled() { return isDisabled(this); } set disabled(value) { if (!value || value === "false") { this.removeAttribute("disabled"); this._selection.removeAttribute("disabled"); } else { this.setAttribute("disabled", ""); this._selection.setAttribute("disabled", ""); } } connectedCallback() { this.createOption(); this.listenActionEvent(); this.setShowSearch(); document.addEventListener("click", this.clickRemoveSelect); } disconnectCallback() { var _a; this.removeEventListener("mouseenter", this.selectMouseDown); this.removeEventListener("mouseleave", this.selectBlur); this.removeEventListener("click", this.selectMouseDown); this.removeEventListener("blur", this.selectBlur); this.removeSelectDropdown(); (_a = this._selectDropdown) == null ? void 0 : _a.removeEventListener("click", this.clickOption); document.removeEventListener("click", this.clickRemoveSelect); } attributeChangedCallback(name, _, newValue) { if (name === "disabled" && this._select) { if (!newValue || newValue === "false") { this._select.setAttribute("disabled", ""); this._selection.setAttribute("disabled", ""); } else { this._select.removeAttribute("disabled"); this._selection.removeAttribute("disabled"); } } } } function Custom() { if (typeof document !== "undefined" && !customElements.get("ra-select")) { customElements.define("ra-select", Select); return Select; } else { return createCustomError("document is undefined or ra-select is exist"); } } const index = Custom(); const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, Select, default: index }, Symbol.toStringTag, { value: "Module" })); export { Select, index as default, index$1 as i };