UNPKG

@randevcx/ranui

Version:

UI Component library based on `Web Component`

533 lines (532 loc) 24.2 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); return value; }; import { a as addClassToElement, r as removeClassToElement, i as isMobile, d as generateThrottle } from "./utils-74Icp-PI.js"; import { H as HTMLElementSSR, i as isDisabled, c as createCustomError } from "./index-CSnBqUsQ.js"; import "./option.js"; import "./index-Cwo9RI60.js"; import "./index-C01KPJ2U.js"; const f7170ee498e0dd32cbdcb63fba8f75cc = '.remove-wap-active-focus{outline:0;-webkit-tap-highlight-color:transparent}.remove-wap-active-focus:active,.remove-wap-active-focus:focus{outline:0;-webkit-tap-highlight-color:transparent}html.dark .r-preview-mask .r-preview-contain{background-color:#191919!important}r-select{position:relative;width:120px;height:40px}:host{position:relative;display:inline-block;cursor:pointer;height:32px;outline:0;-webkit-tap-highlight-color:transparent}:host,:host(:focus),:host(:active){outline:0;-webkit-tap-highlight-color:transparent}:host ::slotted(r-option){display:none}:host([disabled]){cursor:not-allowed;pointer-events:all;opacity:.6}:host([type="text"])::part(selection){border:none}:host([type="text"])::part(icon){display:none}:host(:not([disabled]):hover) .select{cursor:pointer}:host(:not([disabled]):hover) .selection{border:1px solid #1890ff}:host(:not([disabled]):hover) .selection-search{cursor:pointer}:host(:not([disabled]):hover) .selection-item{cursor:pointer;color:#bfbfbf}:host(:not([disabled]):focus) .selection{border:1px solid #1890ff}:host(:not([disabled]):focus) .selection-search{cursor:pointer}:host(:not([disabled]):focus) .selection-item{cursor:pointer;color:#bfbfbf}:host .selection-search{display:none}:host([showSearch]:not([disabled])) .selection-search{cursor:text;display:block}:host([showSearch]:not([disabled])) .selection-item{cursor:pointer}:host([showSearch]:not([disabled]):focus) .selection-search{display:block;cursor:text;opacity:1}.ran-select{width:100%;height:100%;box-sizing:border-box;margin:0;padding:0;color:#000000e0;font-size:14px;line-height:1.57142857;list-style:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";position:relative;display:inline-block}.ran-select .selection{position:relative;background-color:#fff;border:1px solid #d9d9d9;transition:all .2s cubic-bezier(.645,.045,.355,1);width:100%;height:100%;padding:0 11px;box-sizing:border-box;margin:0;color:#000000e0;font-size:14px;line-height:1.57142857;list-style:none;font-family:inherit;display:flex;border-radius:6px}.ran-select .selection-search{position:absolute;top:0;left:0;height:100%;inset-inline-start:11px;inset-inline-end:11px;opacity:0;margin:0;padding:0;background:transparent;border:none;outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-family:inherit;cursor:not-allowed}.ran-select .selection-search::-webkit-search-cancel-button{display:none;-webkit-appearance:none}.ran-select .selection-search::part(ran-input){border:none;padding:0;height:100%;outline:none}.ran-select .selection-search::part(ran-input):active{border:none;padding:0;height:100%;outline:none;border-color:transparent;box-shadow:none;border-right-width:0px}.ran-select .selection-item{position:absolute;top:0;left:12px;margin:0;padding:0;background:transparent;border:none;outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-family:inherit;height:100%;-webkit-user-select:none;user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.ran-select .selection-select{color:#00000040}.ran-select .selection .icon{display:flex;align-items:center;color:#00000040;font-style:normal;text-align:center;text-transform:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:absolute;top:50%;inset-inline-start:auto;inset-inline-end:8px;height:12px;margin-top:-3px;font-size:12px;pointer-events:none}'; 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, "_slot"); __publicField(this, "_shadowDom"); __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, height, x, y, right } = 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; const 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; } } 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) { 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); } }); /** * @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", () => { const slots = this._slot.assignedElements(); slots.forEach((item) => { var _a; if (item.tagName !== "R-OPTION") return; const label = item.innerHTML; const value = item.getAttribute("value") || ""; (_a = this._optionList) == null ? void 0 : _a.push({ label, value }); if (this._optionLabelMapValue.get(label)) { console.warn(`${label} is repeat option`); } if (this._optionValueMapLabel.get(value)) { console.warn(`${value} is repeat option`); } 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"); } 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, "listenSlotChange", () => { this._slot.addEventListener("slotchange", this.addOptionToSlot); }); __publicField(this, "removeListenSlotChange", () => { this._slot.removeEventListener("slotchange", this.addOptionToSlot); }); __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._slot = document.createElement("slot"); 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("r-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._slot.setAttribute("class", "slot"); this._select.appendChild(this._selection); this._select.appendChild(this._slot); this._optionList = []; this._optionLabelMapValue = /* @__PURE__ */ new Map(); this._optionValueMapLabel = /* @__PURE__ */ new Map(); const shadowRoot = this.attachShadow({ mode: "closed" }); const F7170EE498E0DD32CBDCB63FBA8F75CC = document.createElement("style"); F7170EE498E0DD32CBDCB63FBA8F75CC.textContent = f7170ee498e0dd32cbdcb63fba8f75cc; shadowRoot.appendChild(F7170EE498E0DD32CBDCB63FBA8F75CC); this._shadowDom = shadowRoot; this._shadowDom.appendChild(this._select); } 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", ""); } } 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}`); } } } connectedCallback() { this.handlerExternalCss(); this.createOption(); this.listenActionEvent(); this.listenSlotChange(); 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); this.removeListenSlotChange(); document.removeEventListener("click", this.clickRemoveSelect); } attributeChangedCallback(name, oldValue, 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"); } } if (name === "sheet" && this._shadowDom && oldValue !== newValue) { this.handlerExternalCss(); } } } function Custom() { if (typeof document !== "undefined" && !customElements.get("r-select")) { customElements.define("r-select", Select); return Select; } else { return createCustomError("document is undefined or r-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 as S, index as a, index$1 as i };