UNPKG

flamingo-ui

Version:

火烈鸟UI组件库

289 lines (288 loc) 10.3 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var stdin_exports = {}; __export(stdin_exports, { default: () => stdin_default }); module.exports = __toCommonJS(stdin_exports); var import_Ellipsis_sfc = require("./Ellipsis-sfc.css"); var import_vue = require("vue"); var import_vue2 = require("vue"); const __vue_sfc__ = { name: "Ellipsis", props: { content: { type: String, default: "" }, direction: { type: String, default: "end" }, rows: { type: [Number, String], default: 1 }, expandText: { type: String, default: "" }, expandTextColor: { type: String, default: "#3460fa" }, collapseText: { type: String, default: "" }, collapseTextColor: { type: String, default: "#3460fa" }, symbol: { type: String, default: "..." }, lineHeight: { type: [Number, String], default: "20" } }, emits: ["click", "change"], setup(props, { emit }) { const root = (0, import_vue.ref)(null); let container = null; let maxHeight = 0; const ellipsis = (0, import_vue.ref)(); const state = (0, import_vue.reactive)({ exceeded: false, //是否超出 expanded: false //是否折叠 }); (0, import_vue.watch)( () => props.content, (newV, oldVal) => { if (newV != oldVal) { createContainer(); } } ); (0, import_vue.onMounted)(() => { createContainer(); }); const createContainer = () => { if (!root.value) return; const originStyle = window.getComputedStyle(root.value); container = document.createElement("div"); const styleNames = Array.prototype.slice.apply(originStyle); styleNames.forEach((name) => { container.style.setProperty(name, originStyle.getPropertyValue(name)); }); container.style.position = "fixed"; container.style.left = "999999px"; container.style.top = "999999px"; container.style.zIndex = "-1000"; container.style.height = "auto"; container.style.minHeight = "auto"; container.style.maxHeight = "auto"; container.style.textOverflow = "clip"; container.style.whiteSpace = "normal"; container.style.webkitLineClamp = "unset"; container.style.display = "block"; const lineHeight = pxToNumber(originStyle.lineHeight === "normal" ? props.lineHeight : originStyle.lineHeight); maxHeight = Math.floor( lineHeight * (Number(props.rows) + 0.5) + pxToNumber(originStyle.paddingTop) + pxToNumber(originStyle.paddingBottom) ); container.innerText = props.content; document.body.appendChild(container); calcEllipse(); }; const calcEllipse = () => { if (container.offsetHeight <= maxHeight) { state.exceeded = false; document.body.removeChild(container); } else { state.exceeded = true; const end = props.content.length; const middle = Math.floor((0 + end) / 2); const ellipsised = props.direction === "middle" ? tailorMiddle([0, middle], [middle, end]) : tailor(0, end); ellipsis.value = ellipsised; document.body.removeChild(container); } }; const tailor = (left, right) => { const actionText = state.expanded ? props.collapseText : props.expandText; const end = props.content.length; if (right - left <= 1) { if (props.direction === "end") { return { leading: props.content.slice(0, left) + props.symbol }; } else { return { tailing: props.symbol + props.content.slice(right, end) }; } } const middle = Math.round((left + right) / 2); if (props.direction === "end") { container.innerText = props.content.slice(0, middle) + props.symbol + actionText; } else { container.innerText = actionText + props.symbol + props.content.slice(middle, end); } if (container.offsetHeight <= maxHeight) { if (props.direction === "end") { return tailor(middle, right); } else { return tailor(left, middle); } } else { if (props.direction === "end") { return tailor(left, middle); } else { return tailor(middle, right); } } }; const tailorMiddle = (leftPart, rightPart) => { const actionText = state.expanded ? props.collapseText : props.expandText; const end = props.content.length; if (leftPart[1] - leftPart[0] <= 1 && rightPart[1] - rightPart[0] <= 1) { return { leading: props.content.slice(0, leftPart[0]) + props.symbol, tailing: props.symbol + props.content.slice(rightPart[1], end) }; } const leftPartMiddle = Math.floor((leftPart[0] + leftPart[1]) / 2); const rightPartMiddle = Math.ceil((rightPart[0] + rightPart[1]) / 2); container.innerText = props.content.slice(0, leftPartMiddle) + props.symbol + actionText + props.symbol + props.content.slice(rightPartMiddle, end); if (container.offsetHeight <= maxHeight) { return tailorMiddle([leftPartMiddle, leftPart[1]], [rightPart[0], rightPartMiddle]); } else { return tailorMiddle([leftPart[0], leftPartMiddle], [rightPartMiddle, rightPart[1]]); } }; const pxToNumber = (value) => { if (!value) return 0; const match = value.match(/^\d*(\.\d*)?/); return match ? Number(match[0]) : 0; }; const clickHandle = (type) => { if (type == 1) { state.expanded = true; emit("change", "expand"); } else { state.expanded = false; emit("change", "collapse"); } }; const handleClick = () => { emit("click"); }; return __spreadProps(__spreadValues({}, (0, import_vue.toRefs)(state)), { root, ellipsis, clickHandle, handleClick }); } }; const _hoisted_1 = { key: 0 }; const _hoisted_2 = { key: 1 }; const _hoisted_3 = { key: 2 }; function __vue_render__(_ctx, _cache) { return (0, import_vue2.openBlock)(), (0, import_vue2.createElementBlock)( "view", { class: "fmg-ellipsis", onClick: _cache[2] || (_cache[2] = (...args) => _ctx.handleClick && _ctx.handleClick(...args)), ref: "root" }, [ !_ctx.exceeded ? ((0, import_vue2.openBlock)(), (0, import_vue2.createElementBlock)( "view", _hoisted_1, (0, import_vue2.toDisplayString)(_ctx.content), 1 /* TEXT */ )) : (0, import_vue2.createCommentVNode)("v-if", true), _ctx.exceeded && !_ctx.expanded ? ((0, import_vue2.openBlock)(), (0, import_vue2.createElementBlock)("view", _hoisted_2, [ (0, import_vue2.createTextVNode)( (0, import_vue2.toDisplayString)(_ctx.ellipsis && _ctx.ellipsis.leading), 1 /* TEXT */ ), _ctx.expandText ? ((0, import_vue2.openBlock)(), (0, import_vue2.createElementBlock)( "span", { key: 0, class: "ellipsis__text", style: (0, import_vue2.normalizeStyle)({ color: _ctx.expandTextColor }), onClick: _cache[0] || (_cache[0] = (0, import_vue2.withModifiers)(($event) => _ctx.clickHandle(1), ["stop"])) }, (0, import_vue2.toDisplayString)(_ctx.expandText), 5 /* TEXT, STYLE */ )) : (0, import_vue2.createCommentVNode)("v-if", true), (0, import_vue2.createTextVNode)( (0, import_vue2.toDisplayString)(_ctx.ellipsis && _ctx.ellipsis.tailing), 1 /* TEXT */ ) ])) : (0, import_vue2.createCommentVNode)("v-if", true), _ctx.exceeded && _ctx.expanded ? ((0, import_vue2.openBlock)(), (0, import_vue2.createElementBlock)("view", _hoisted_3, [ (0, import_vue2.createTextVNode)( (0, import_vue2.toDisplayString)(_ctx.content) + " ", 1 /* TEXT */ ), _ctx.expandText ? ((0, import_vue2.openBlock)(), (0, import_vue2.createElementBlock)( "span", { key: 0, class: "ellipsis__text", style: (0, import_vue2.normalizeStyle)({ color: _ctx.collapseTextColor }), onClick: _cache[1] || (_cache[1] = (0, import_vue2.withModifiers)(($event) => _ctx.clickHandle(2), ["stop"])) }, (0, import_vue2.toDisplayString)(_ctx.collapseText), 5 /* TEXT, STYLE */ )) : (0, import_vue2.createCommentVNode)("v-if", true) ])) : (0, import_vue2.createCommentVNode)("v-if", true) ], 512 /* NEED_PATCH */ ); } __vue_sfc__.render = __vue_render__; var stdin_default = __vue_sfc__;