ranui
Version:
UI Component library based on `Web Component`
561 lines (560 loc) • 21.5 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);
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
};