UNPKG

@wix/design-system

Version:

@wix/design-system

250 lines (248 loc) 8.72 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _debounce = _interopRequireDefault(require("lodash/debounce")); var _shallowequal = _interopRequireDefault(require("shallowequal")); var _EllipsisSt = require("./Ellipsis.st.css.js"); var _Tooltip = _interopRequireDefault(require("../../Tooltip")); var _ZIndex = require("../ZIndex"); var _TooltipCommon = require("../PropTypes/TooltipCommon"); var _TextComponent = _interopRequireDefault(require("./components/TextComponent")); var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/common/Ellipsis/Ellipsis.tsx"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } class Ellipsis extends _react.default.PureComponent { constructor(props) { super(props); this.ref = void 0; this.tooltipRef = void 0; /** * Once text component has rendered, * Update text content and tooltip active state * @private */ this._onTextRendered = () => { var { isActive, textContent } = this.state; var newTextContent = this._getTextContent(); var shouldBeActive = this._checkShouldBeActive(); var newState = _objectSpread(_objectSpread({ textRendered: true }, newTextContent !== textContent ? { textContent: newTextContent } : {}), shouldBeActive !== isActive ? { isActive: shouldBeActive } : {}); this.setState(oldState => _objectSpread(_objectSpread({}, oldState), newState)); }; /** * An ellipsis is considered active when either the text's scroll width/height is wider than it's container or itself. * @private */ this._updateIsActive = () => { var { isActive } = this.state; var shouldBeActive = this._checkShouldBeActive(); if (shouldBeActive !== isActive) { this.setState({ isActive: shouldBeActive }); } }; this._getTextContent = () => { var { current: textElement } = this.ref; return textElement && textElement.textContent; }; this._checkShouldBeActive = () => this._isOverflowingHorizontally() || this._isOverflowingVertically(); this._isOverflowingHorizontally = () => { var _textElement$parentEl; var { current: textElement } = this.ref; var { ellipsis } = this.props; var parentWidth = textElement == null || (_textElement$parentEl = textElement.parentElement) == null ? void 0 : _textElement$parentEl.offsetWidth; return !!(ellipsis && textElement && (parentWidth && textElement.scrollWidth - parentWidth > 1 || textElement.offsetWidth < textElement.scrollWidth)); }; this._isOverflowingVertically = () => { var _textElement$parentEl2; var { current: textElement } = this.ref; var { ellipsis, maxLines } = this.props; var parentHeight = textElement == null || (_textElement$parentEl2 = textElement.parentElement) == null ? void 0 : _textElement$parentEl2.offsetHeight; return !!(maxLines && maxLines > 1 && ellipsis && textElement && (parentHeight && textElement.scrollHeight - parentHeight > 1 || textElement.offsetHeight < textElement.scrollHeight)); }; /** * A callback for resizing the window, must be debounced in order to improve performance. * @private */ this._debouncedUpdate = (0, _debounce.default)(this._updateIsActive, 100); this.state = { isActive: false, textContent: null, textRendered: false }; this.ref = /*#__PURE__*/_react.default.createRef(); this.tooltipRef = /*#__PURE__*/_react.default.createRef(); } componentDidMount() { var _this$props$onEllipsi, _this$props; window.addEventListener('resize', this._debouncedUpdate); (_this$props$onEllipsi = (_this$props = this.props).onEllipsisStateChange) == null || _this$props$onEllipsi.call(_this$props, this.state.isActive); } _renderText() { var { render, ellipsis, maxLines } = this.props; var { textRendered, isActive } = this.state; return /*#__PURE__*/_react.default.createElement(_TextComponent.default, { render, ellipsis, maxLines, textRendered, onTextRendered: this._onTextRendered, textElementRef: this.ref, isEllipsisActive: isActive, tooltipRef: this.tooltipRef, __self: this, __source: { fileName: _jsxFileName, lineNumber: 167, columnNumber: 7 } }); } render() { var { appendTo, wrapperClassName, disabled, enterDelay, exitDelay, fixed, flip, maxWidth, moveArrowTo, moveBy, onHide, onShow, placement, showTooltip, textAlign, zIndex, size, interactive } = this.props; var { isActive, textContent } = this.state; return showTooltip && isActive ? /*#__PURE__*/_react.default.createElement(_Tooltip.default, { ref: this.tooltipRef, className: (0, _EllipsisSt.st)(_EllipsisSt.classes.tooltip, wrapperClassName), content: textContent, appendTo, disabled, enterDelay, exitDelay, fixed, flip, maxWidth, moveArrowTo, moveBy, onHide, onShow, placement, textAlign, zIndex, size, interactive, __self: this, __source: { fileName: _jsxFileName, lineNumber: 201, columnNumber: 7 } }, this._renderText()) : this._renderText(); } static getDerivedStateFromProps(props, state) { var { render, ellipsis, maxLines } = props; var textPropsChanged = state.prevRender !== render || state.prevEllipsis !== ellipsis || state.prevMaxLines !== maxLines; if (!textPropsChanged) { return null; } // Text changed, initialize textRendered state return { textRendered: false, prevRender: render, prevEllipsis: ellipsis, prevMaxLines: maxLines }; } componentDidUpdate(prevProps, prevState) { var { textRendered, isActive } = this.state; if (textRendered && !(0, _shallowequal.default)(prevProps, this.props)) { this._updateIsActive(); } if (prevState.isActive !== isActive && this.props.onEllipsisStateChange) { this.props.onEllipsisStateChange(this.state.isActive); } } componentWillUnmount() { this._debouncedUpdate.cancel(); window.removeEventListener('resize', this._debouncedUpdate); } } Ellipsis.propTypes = _objectSpread({ /** When true, text that is longer than it's container will be truncated to a single line followed by ellipsis. Otherwise the text will break into several lines. */ ellipsis: _propTypes.default.bool, /** True by default, set it to false in order to show ellipsis without a tooltip. */ showTooltip: _propTypes.default.bool, /** A className to be applied to the Ellipsis wrapper. */ wrapperClassName: _propTypes.default.string, /** The render function, use it to render a text you want to truncate with ellipsis. */ render: _propTypes.default.func, /** maxLines truncates text at a specific number of lines. */ maxLines: _propTypes.default.number, /** A callback fired when ellipsis state changes. */ onEllipsisStateChange: _propTypes.default.func }, _TooltipCommon.TooltipCommonProps); Ellipsis.defaultProps = { ellipsis: false, appendTo: 'window', flip: false, fixed: false, placement: 'top', zIndex: _ZIndex.ZIndex.tooltip, enterDelay: 0, exitDelay: 0, showTooltip: true }; var _default = exports.default = Ellipsis; //# sourceMappingURL=Ellipsis.js.map