flamingo-ui
Version:
火烈鸟UI组件库
272 lines (271 loc) • 9.17 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
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));
import "./Ellipsis-sfc.css";
import { ref, reactive, toRefs, onMounted, watch } from "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 = ref(null);
let container = null;
let maxHeight = 0;
const ellipsis = ref();
const state = reactive({
exceeded: false,
//是否超出
expanded: false
//是否折叠
});
watch(
() => props.content,
(newV, oldVal) => {
if (newV != oldVal) {
createContainer();
}
}
);
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({}, toRefs(state)), { root, ellipsis, clickHandle, handleClick });
}
};
import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, withModifiers as _withModifiers, normalizeStyle as _normalizeStyle, createTextVNode as _createTextVNode } from "vue";
const _hoisted_1 = { key: 0 };
const _hoisted_2 = { key: 1 };
const _hoisted_3 = { key: 2 };
function __vue_render__(_ctx, _cache) {
return _openBlock(), _createElementBlock(
"view",
{
class: "fmg-ellipsis",
onClick: _cache[2] || (_cache[2] = (...args) => _ctx.handleClick && _ctx.handleClick(...args)),
ref: "root"
},
[
!_ctx.exceeded ? (_openBlock(), _createElementBlock(
"view",
_hoisted_1,
_toDisplayString(_ctx.content),
1
/* TEXT */
)) : _createCommentVNode("v-if", true),
_ctx.exceeded && !_ctx.expanded ? (_openBlock(), _createElementBlock("view", _hoisted_2, [
_createTextVNode(
_toDisplayString(_ctx.ellipsis && _ctx.ellipsis.leading),
1
/* TEXT */
),
_ctx.expandText ? (_openBlock(), _createElementBlock(
"span",
{
key: 0,
class: "ellipsis__text",
style: _normalizeStyle({ color: _ctx.expandTextColor }),
onClick: _cache[0] || (_cache[0] = _withModifiers(($event) => _ctx.clickHandle(1), ["stop"]))
},
_toDisplayString(_ctx.expandText),
5
/* TEXT, STYLE */
)) : _createCommentVNode("v-if", true),
_createTextVNode(
_toDisplayString(_ctx.ellipsis && _ctx.ellipsis.tailing),
1
/* TEXT */
)
])) : _createCommentVNode("v-if", true),
_ctx.exceeded && _ctx.expanded ? (_openBlock(), _createElementBlock("view", _hoisted_3, [
_createTextVNode(
_toDisplayString(_ctx.content) + " ",
1
/* TEXT */
),
_ctx.expandText ? (_openBlock(), _createElementBlock(
"span",
{
key: 0,
class: "ellipsis__text",
style: _normalizeStyle({ color: _ctx.collapseTextColor }),
onClick: _cache[1] || (_cache[1] = _withModifiers(($event) => _ctx.clickHandle(2), ["stop"]))
},
_toDisplayString(_ctx.collapseText),
5
/* TEXT, STYLE */
)) : _createCommentVNode("v-if", true)
])) : _createCommentVNode("v-if", true)
],
512
/* NEED_PATCH */
);
}
__vue_sfc__.render = __vue_render__;
var stdin_default = __vue_sfc__;
export {
stdin_default as default
};