UNPKG

ranui

Version:

UI Component library based on `Web Component`

309 lines (308 loc) 14.3 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 { d as createDocumentFragment, a as addClassToElement } from "./plus-BQnIzzvi.js"; import { i as isDisabled, r as removeClassToElementChild } from "./index-9tJmVuyv.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}.ran-tab ::slotted(r-tab){box-sizing:border-box;width:100%;height:100%;padding:10px;flex-shrink:0;overflow:auto;text-align:start}.ran-tab-header{position:relative;overflow:hidden;scroll-behavior:smooth}.ran-tab-header-nav{display:flex;flex-flow:row nowrap;justify-content:flex-start;align-items:center}.ran-tab-header-nav::-webkit-scrollbar{display:none}.ran-tab-header-nav-item{flex-shrink:0}.ran-tab-header-nav .active{color:var(--active-color, #1890ff)}.ran-tab-header-line{position:absolute;width:0;margin-top:-2px;height:2px;border-radius:2px;background:var(--line-color, #1890ff);transition:.2s}.ran-tab-content{overflow:hidden}.ran-tab-content-wrap{display:flex;width:100%;height:100%;transition:.2s}:host([type="line"]) .ran-tab-header-nav-item{border:solid 1px transparent}:host([type="line"]) .ran-tab-header-nav .active{color:var(--line-color, #1890ff);border:solid 1px transparent;border-color:var(--border-color, rgba(0, 0, 0, .2)) var(--border-color, rgba(0, 0, 0, .2)) transparent;border-radius:var(--border-radius, .25em) var(--border-radius, .25em) 0 0}:host([type="line"]) .ran-tab-header-line{transition:none;visibility:hidden}:host([type="line"]) .ran-tab-header-line:after,:host([type="line"]) .ran-tab-header-line:before{content:"";position:absolute;visibility:visible;width:9999px;height:1px;bottom:0;background:var(--border-color, rgba(0, 0, 0, .2))}:host([type="line"]) .ran-tab-header-line:after{left:100%}:host([type="line"]) .ran-tab-header-line:before{right:100%}:host([align="center"]) .ran-tab-header-nav{justify-content:center}:host([align="center"]) .ran-tab-header-line{left:50%}:host([align="end"]) .ran-tab-header-nav{justify-content:flex-end}'; function CustomElement() { if (typeof window !== "undefined" && !customElements.get("r-tabs")) { class Tabs extends HTMLElement { constructor() { super(); __publicField(this, "_container"); __publicField(this, "_header"); __publicField(this, "_nav"); __publicField(this, "_line"); __publicField(this, "_content"); __publicField(this, "_wrap"); __publicField(this, "_slot"); __publicField(this, "tabHeaderKeyMapIndex"); /** * @description: 构建 tabPane 组件 key 值和 index 的映射,同时判断一个 tabs 下的 tabPane key 值不能重复 * @param {string} key * @param {number} index */ __publicField(this, "initTabHeaderKeyMapIndex", (key, index2) => { const value = this.tabHeaderKeyMapIndex[key]; if (value) { throw new Error("tab 组件的 key 值存在重复,或者某个 tab 组件缺少 key 属性"); } else { this.tabHeaderKeyMapIndex[key] = index2; } }); /** * @description: 初始化 tabLine 的位置,主要是当 tabs 的 align 属性为 center 时需要处理 */ __publicField(this, "initTabLineAlignCenter", () => { const { length } = this._nav.children; let left = 0; for (let i = 0; i < length; i++) { const { width = 0 } = this._nav.children[i].getBoundingClientRect(); left += width; } this._line.style.setProperty("left", `calc(50% - ${left / 2}px)`); }); /** * @description: 初始化tabLine的位置,主要是当tabs的align属性为end时需要处理 */ __publicField(this, "initTabLineAlignEnd", () => { const { length } = this._nav.children; let left = 0; for (let i = 0; i < length; i++) { const { width = 0 } = this._nav.children[i].getBoundingClientRect(); left += width; } this._line.style.setProperty("left", `calc(100% - ${left}px)`); }); /** * @description: 通过key值设置tabLine的位置 * @param {string} key */ __publicField(this, "setTabLine", (key) => { if (key) { const index2 = this.tabHeaderKeyMapIndex[key]; const TabHeader = this._nav.children[index2]; const { width = 0 } = TabHeader.getBoundingClientRect(); this._line.style.setProperty("width", `${width}px`); let distance = 0; for (let i = 0; i < index2; i++) { const item = this._nav.children[i]; const { width: width2 = 0 } = item.getBoundingClientRect(); distance += width2; } this._line.style.setProperty("transform", `translateX(${distance}px)`); } }); /** * @description: 通过传入的key值设置tabContent */ __publicField(this, "setTabContent", (key) => { if (key) { const index2 = this.tabHeaderKeyMapIndex[key]; this._wrap.style.setProperty("transform", `translateX(${index2 * -100}%)`); } }); /** * @description: 根据点击设置 tabLine 的位置 * @param {Event} e * @param {number} index * @param {number} width */ __publicField(this, "clickTabHead", (e) => { const tabHeader = e.target; const key = tabHeader.getAttribute("r-key"); const disabled = isDisabled(tabHeader); if (!disabled && key) { this.setAttribute("active", key); this.setTabLine(key); this.setTabContent(key); removeClassToElementChild(this._nav, "active"); addClassToElement(tabHeader, "active"); } }); /** * @description: tabPane 设置属性,需要在 tabs 上展示时触发 * @param {string} key * @param {string} value */ __publicField(this, "updateAttribute", (key, attribute, value = "") => { var _a, _b; const index2 = this.tabHeaderKeyMapIndex[key]; if (key && value && this._nav.children[index2]) { (_a = this._nav.children[index2]) == null ? void 0 : _a.setAttribute(attribute, value); } else { (_b = this._nav.children[index2]) == null ? void 0 : _b.removeAttribute(attribute); } }); /** * @description: 初始化 tabs 的 active 属性和 tabLine,tabContent */ __publicField(this, "initActive", () => { const tabHeaderList = [...this._nav.children]; const initTabList = tabHeaderList.filter((item) => !isDisabled(item)); let initTabHeader; if (this.active != null) { initTabHeader = initTabList.find((item) => item.getAttribute("r-key") === this.active); initTabHeader == null ? void 0 : initTabHeader.setAttribute("r-key", this.active); } if (!initTabHeader) { initTabHeader = initTabList.shift(); } if (!initTabHeader) return; const index2 = tabHeaderList.findIndex((item) => item === initTabHeader); const key = (initTabHeader == null ? void 0 : initTabHeader.getAttribute("r-key")) || `${index2}`; if (key != null) { this.setAttribute("active", `${key}`); addClassToElement(initTabHeader, "active"); this.setTabContent(key); setTimeout(() => { this.setTabLine(key); }, 200); } }); /** * @description: 监听 slot 组件的添加/删除/替换操作,进行 tabs 初始化 * @return {*} */ __publicField(this, "listenSlotChange", () => { const slots = this._slot.assignedElements(); slots.forEach((item, index2) => { const tabPane = this.createTabHeader(item, index2); this._nav.appendChild(tabPane); tabPane.addEventListener("click", this.clickTabHead); }); this.initActive(); if (this.align) { if (this.align === "center") this.initTabLineAlignCenter(); if (this.align === "end") this.initTabLineAlignEnd(); } }); /** * @description: 初始化 tab */ __publicField(this, "initTab", () => { this._slot.addEventListener("slotchange", this.listenSlotChange); }); /** * @description: 卸载 tab */ __publicField(this, "unloadTab", () => { this._slot.removeEventListener("slotchange", this.listenSlotChange); }); this._container = document.createElement("div"); this._container.setAttribute("class", "ran-tab"); this._header = document.createElement("div"); this._header.setAttribute("class", "ran-tab-header"); this._nav = document.createElement("div"); this._nav.setAttribute("class", "ran-tab-header-nav"); this._line = document.createElement("div"); this._line.setAttribute("class", "ran-tab-header-line"); this._content = document.createElement("div"); this._content.setAttribute("class", "ran-tab-content"); this._wrap = document.createElement("div"); this._wrap.setAttribute("class", "ran-tab-content-wrap"); this._slot = document.createElement("slot"); this._wrap.appendChild(this._slot); this._content.appendChild(this._wrap); this._header.appendChild(createDocumentFragment([this._nav, this._line])); this._container.appendChild(createDocumentFragment([this._header, this._content])); this.tabHeaderKeyMapIndex = {}; const shadowRoot = this.attachShadow({ mode: "closed" }); const F7170EE498E0DD32CBDCB63FBA8F75CC = document.createElement("style"); F7170EE498E0DD32CBDCB63FBA8F75CC.textContent = f7170ee498e0dd32cbdcb63fba8f75cc; shadowRoot.appendChild(F7170EE498E0DD32CBDCB63FBA8F75CC); shadowRoot.appendChild(this._container); } static get observedAttributes() { return ["active", "forceRender", "type", "align", "effect"]; } get align() { return this.getAttribute("align") || "start"; } set align(value) { this.setAttribute("align", value); } set type(value) { this.setAttribute("type", value); } get type() { return this.getAttribute("type") || "flat"; } get active() { return this.getAttribute("active"); } set active(value) { if (value) { this.setAttribute("active", value); this.setTabLine(value); this.setTabContent(value); } else { this.removeAttribute("active"); } } get effect() { return this.getAttribute("effect"); } set effect(value) { if (!value || value === "false") { this.removeAttribute("effect"); } else { this.setAttribute("effect", value); } } /** * @description: 根据传入的 tabPane 生成 tabs 的头部 * @param {Element} tabPane * @param {number} index * @return {Element} */ createTabHeader(tabPane, index2) { const label = tabPane.getAttribute("label") || ""; const icon = tabPane.getAttribute("icon") || ""; const iconSize = tabPane.getAttribute("iconSize") || ""; const key = tabPane.getAttribute("r-key") || `${index2}`; const type = tabPane.getAttribute("type") || "text"; this.initTabHeaderKeyMapIndex(key, index2); const tabHeader = document.createElement("r-button"); tabHeader.setAttribute("class", "tab-header-nav-item"); tabHeader.setAttribute("type", type); icon && tabHeader.setAttribute("icon", icon); iconSize && tabHeader.setAttribute("iconSize", iconSize); isDisabled(tabPane) && tabHeader.setAttribute("disabled", ""); tabHeader.setAttribute("r-key", key); if (this.effect) { tabPane.setAttribute("effect", this.effect); this._line.style.setProperty("display", "none"); } tabPane.setAttribute("r-key", key); tabHeader.innerHTML = label; return tabHeader; } connectedCallback() { this.initTab(); } disconnectCallback() { this.unloadTab(); } attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { this.dispatchEvent( new CustomEvent("change", { detail: { active: this.active } }) ); if (name === "align") { if (newValue === "center") this.initTabLineAlignCenter(); if (newValue === "end") this.initTabLineAlignEnd(); } if (name === "effect") { const tabHeaderList = [...this._nav.children]; tabHeaderList.forEach((item) => { if (!this.effect || this.effect === "false") { item.removeAttribute("effect"); } else { item.setAttribute("effect", newValue); } }); } if (name === "active") { this.setAttribute(name, newValue); } } } } customElements.define("r-tabs", Tabs); return Tabs; } } const index = CustomElement(); const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: index }, Symbol.toStringTag, { value: "Module" })); export { index as a, index$1 as i };