@elastic/eui
Version:
Elastic UI Component Library
177 lines (174 loc) • 7.11 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["width", "onResize"],
_excluded2 = ["width", "children", "text", "truncation", "truncationOffset", "truncationPosition", "ellipsis", "calculationDelayMs", "containerRef", "className"],
_excluded3 = ["onResize"];
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useState, useMemo, useCallback, useEffect } from 'react';
import classNames from 'classnames';
import { useCombinedRefs, useEuiMemoizedStyles } from '../../services';
import { EuiResizeObserver } from '../observer/resize_observer';
import { EuiToolTip } from '../tool_tip';
import { TruncationUtils } from './utils';
import { euiTextTruncateStyles } from './text_truncate.styles';
import { jsx as ___EmotionJSX } from "@emotion/react";
var TRUNCATION_TYPES = ['end', 'start', 'startEnd', 'middle'];
export var EuiTextTruncate = function EuiTextTruncate(_ref) {
var width = _ref.width,
onResize = _ref.onResize,
props = _objectWithoutProperties(_ref, _excluded);
return width != null ? ___EmotionJSX(EuiTextTruncateWithWidth, _extends({
width: width
}, props)) : ___EmotionJSX(EuiTextTruncateWithResizeObserver, _extends({
onResize: onResize
}, props));
};
var EuiTextTruncateWithWidth = function EuiTextTruncateWithWidth(_ref2) {
var width = _ref2.width,
children = _ref2.children,
text = _ref2.text,
_ref2$truncation = _ref2.truncation,
_truncation = _ref2$truncation === void 0 ? 'end' : _ref2$truncation,
_ref2$truncationOffse = _ref2.truncationOffset,
_truncationOffset = _ref2$truncationOffse === void 0 ? 0 : _ref2$truncationOffse,
truncationPosition = _ref2.truncationPosition,
_ref2$ellipsis = _ref2.ellipsis,
ellipsis = _ref2$ellipsis === void 0 ? '…' : _ref2$ellipsis,
calculationDelayMs = _ref2.calculationDelayMs,
containerRef = _ref2.containerRef,
className = _ref2.className,
rest = _objectWithoutProperties(_ref2, _excluded2);
// Note: This needs to be a state and not a ref to trigger a rerender on mount
var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
containerEl = _useState2[0],
setContainerEl = _useState2[1];
var refs = useCombinedRefs([setContainerEl, containerRef]);
// If necessary, wait a tick on mount before truncating
var _useState3 = useState(!calculationDelayMs),
_useState4 = _slicedToArray(_useState3, 2),
ready = _useState4[0],
setReady = _useState4[1];
useEffect(function () {
if (calculationDelayMs) {
var timerId = setTimeout(function () {
return setReady(true);
}, calculationDelayMs);
return function () {
return clearTimeout(timerId);
};
}
}, [calculationDelayMs]);
// Handle exceptions where we need to override the passed props
var _useMemo = useMemo(function () {
var truncation = _truncation;
var truncationOffset = 0;
if (_truncation === 'end' || _truncation === 'start') {
if (0 < _truncationOffset && _truncationOffset < text.length) {
truncationOffset = _truncationOffset;
}
} else if (_truncation === 'startEnd' && truncationPosition != null) {
if (truncationPosition <= 0) {
truncation = 'end';
} else if (truncationPosition >= text.length) {
truncation = 'start';
}
}
return {
truncation: truncation,
truncationOffset: truncationOffset
};
}, [_truncation, _truncationOffset, truncationPosition, text.length]),
truncation = _useMemo.truncation,
truncationOffset = _useMemo.truncationOffset;
var truncatedText = useMemo(function () {
var truncatedText = '';
if (!ready || !containerEl) return text;
if (!width) return truncatedText;
var utils = new TruncationUtils({
fullText: text,
ellipsis: ellipsis,
container: containerEl,
availableWidth: width
});
if (utils.checkIfTruncationIsNeeded() === false) {
truncatedText = text;
} else if (utils.checkSufficientEllipsisWidth(truncation) === false) {
truncatedText = '';
} else {
switch (truncation) {
case 'end':
truncatedText = utils.truncateEnd(truncationOffset);
break;
case 'start':
truncatedText = utils.truncateStart(truncationOffset);
break;
case 'startEnd':
if (truncationPosition == null) {
truncatedText = utils.truncateStartEndAtMiddle();
} else {
truncatedText = utils.truncateStartEndAtPosition(truncationPosition);
}
break;
case 'middle':
truncatedText = utils.truncateMiddle();
break;
}
}
return truncatedText;
}, [ready, width, text, truncation, truncationOffset, truncationPosition, ellipsis, containerEl]);
var isTruncating = truncatedText !== text;
var styles = useEuiMemoizedStyles(euiTextTruncateStyles);
var content = ___EmotionJSX("div", _extends({
className: classNames('euiTextTruncate', className),
css: styles.euiTextTruncate,
ref: refs
}, rest), isTruncating ? ___EmotionJSX(React.Fragment, null, ___EmotionJSX("span", {
className: "euiTextTruncate__truncatedText",
css: styles.euiTextTruncate__truncatedText,
"aria-hidden": true,
"data-test-subj": "truncatedText"
}, children ? children(truncatedText) : truncatedText), ___EmotionJSX("span", {
className: "euiTextTruncate__fullText",
css: styles.euiTextTruncate__fullText,
"data-test-subj": "fullText"
}, text)) : ___EmotionJSX("span", {
className: "euiTextTruncate__fullText",
"data-test-subj": "fullText"
}, children ? children(text) : text));
return isTruncating ? ___EmotionJSX(EuiToolTip, {
content: text,
disableScreenReaderOutput: true,
display: "block"
}, content) : content;
};
var EuiTextTruncateWithResizeObserver = function EuiTextTruncateWithResizeObserver(_ref3) {
var _onResize = _ref3.onResize,
props = _objectWithoutProperties(_ref3, _excluded3);
var _useState5 = useState(0),
_useState6 = _slicedToArray(_useState5, 2),
width = _useState6[0],
setWidth = _useState6[1];
var onResize = useCallback(function (_ref4) {
var width = _ref4.width;
setWidth(width);
_onResize === null || _onResize === void 0 || _onResize(width);
}, [_onResize]);
return ___EmotionJSX(EuiResizeObserver, {
onResize: onResize
}, function (ref) {
return ___EmotionJSX(EuiTextTruncateWithWidth, _extends({
width: width,
containerRef: ref
}, props, {
"data-resize-observer": "true"
}));
});
};