UNPKG

antd-mobile

Version:

<img src="https://gw.alipayobjects.com/mdn/rms_ee68a8/afts/img/A*hjjDS5Yy-ooAAAAAAAAAAAAAARQnAQ" alt="logo" width="100%" />

172 lines (145 loc) 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Ellipsis = void 0; var _react = _interopRequireWildcard(require("react")); var _withDefaultProps = require("../../utils/with-default-props"); var _nativeProps = require("../../utils/native-props"); var _useResizeEffect = require("../../utils/use-resize-effect"); var _ahooks = require("ahooks"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const classPrefix = `adm-ellipsis`; const defaultProps = { direction: 'end', rows: 1, expandText: '', collapseText: '' }; const Ellipsis = p => { const props = (0, _withDefaultProps.mergeProps)(defaultProps, p); const rootRef = (0, _react.useRef)(null); const [ellipsised, setEllipsised] = (0, _react.useState)({}); const [expanded, setExpanded] = (0, _react.useState)(false); const [exceeded, setExceeded] = (0, _react.useState)(false); function calcEllipsised() { const root = rootRef.current; if (!root) return; const originStyle = window.getComputedStyle(root); const 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.webkitBoxOrient = 'unset'; container.style.display = 'block'; const lineHeight = pxToNumber(originStyle.lineHeight); const maxHeight = Math.floor(lineHeight * (props.rows + 0.5) + pxToNumber(originStyle.paddingTop) + pxToNumber(originStyle.paddingBottom)); container.innerText = props.content; document.body.appendChild(container); if (container.offsetHeight <= maxHeight) { setExceeded(false); } else { setExceeded(true); const end = props.content.length; const actionText = expanded ? props.collapseText : props.expandText; function check(left, right) { if (right - left <= 1) { if (props.direction === 'end') { return { leading: props.content.slice(0, left) + '...' }; } else { return { tailing: '...' + props.content.slice(right, end) }; } } const middle = Math.round((left + right) / 2); if (props.direction === 'end') { container.innerText = props.content.slice(0, middle) + '...' + actionText; } else { container.innerText = actionText + '...' + props.content.slice(middle, end); } if (container.offsetHeight <= maxHeight) { if (props.direction === 'end') { return check(middle, right); } else { return check(left, middle); } } else { if (props.direction === 'end') { return check(left, middle); } else { return check(middle, right); } } } function checkMiddle(leftPart, rightPart) { if (leftPart[1] - leftPart[0] <= 1 && rightPart[1] - rightPart[0] <= 1) { return { leading: props.content.slice(0, leftPart[0]) + '...', tailing: '...' + props.content.slice(rightPart[1], end) }; } const leftPartMiddle = Math.floor((leftPart[0] + leftPart[1]) / 2); const rightPartMiddle = Math.floor((rightPart[0] + rightPart[1]) / 2); container.innerText = props.content.slice(0, leftPartMiddle) + '...' + actionText + '...' + props.content.slice(rightPartMiddle, end); if (container.offsetHeight <= maxHeight) { return checkMiddle([leftPartMiddle, leftPart[1]], [rightPart[0], rightPartMiddle]); } else { return checkMiddle([leftPart[0], leftPartMiddle], [rightPartMiddle, rightPart[1]]); } } const middle = Math.floor((0 + end) / 2); const ellipsised = props.direction === 'middle' ? checkMiddle([0, middle], [middle, end]) : check(0, end); setEllipsised(ellipsised); } document.body.removeChild(container); } (0, _useResizeEffect.useResizeEffect)(calcEllipsised, rootRef); (0, _ahooks.useIsomorphicLayoutEffect)(() => { calcEllipsised(); }, [props.content, props.direction, props.rows, props.expandText, props.collapseText]); const expandActionElement = exceeded && props.expandText ? _react.default.createElement("a", { onClick: () => { setExpanded(true); } }, props.expandText) : null; const collapseActionElement = exceeded && props.expandText ? _react.default.createElement("a", { onClick: () => { setExpanded(false); } }, props.collapseText) : null; const renderContent = () => { if (!exceeded) { return props.content; } if (expanded) { return _react.default.createElement(_react.default.Fragment, null, props.content, collapseActionElement); } else { return _react.default.createElement(_react.default.Fragment, null, ellipsised.leading, expandActionElement, ellipsised.tailing); } }; return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", { ref: rootRef, className: classPrefix }, renderContent())); }; exports.Ellipsis = Ellipsis; function pxToNumber(value) { if (!value) return 0; const match = value.match(/^\d*(\.\d*)?/); return match ? Number(match[0]) : 0; }