@randevcx/ranui
Version:
UI Component library based on `Web Component`
533 lines (532 loc) • 24.2 kB
JavaScript
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
};