173 lines
9.4 KiB
JavaScript
173 lines
9.4 KiB
JavaScript
define(["require", "exports", "tslib", "react", "../../Utilities", "@fluentui/utilities", "./DocumentCard.base", "@fluentui/react-window-provider", "../../utilities/dom"], function (require, exports, tslib_1, React, Utilities_1, utilities_1, DocumentCard_base_1, react_window_provider_1, dom_1) {
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.DocumentCardTitleBase = void 0;
|
|
var getClassNames = (0, Utilities_1.classNamesFunction)();
|
|
var TRUNCATION_VERTICAL_OVERFLOW_THRESHOLD = 5;
|
|
/**
|
|
* {@docCategory DocumentCard}
|
|
*/
|
|
var DocumentCardTitleBase = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DocumentCardTitleBase, _super);
|
|
function DocumentCardTitleBase(props) {
|
|
var _this = _super.call(this, props) || this;
|
|
_this._titleElement = React.createRef();
|
|
// Truncate logic here way can't handle the case that chars with different widths are mixed very well.
|
|
// Let _shrinkTitle take care of that.
|
|
_this._truncateTitle = function () {
|
|
if (!_this._needMeasurement) {
|
|
return;
|
|
}
|
|
_this._async.requestAnimationFrame(_this._truncateWhenInAnimation);
|
|
};
|
|
_this._truncateWhenInAnimation = function () {
|
|
var originalTitle = _this.props.title;
|
|
var element = _this._titleElement.current;
|
|
if (element) {
|
|
var style = getComputedStyle(element);
|
|
if (style.width && style.lineHeight && style.height) {
|
|
var clientWidth = element.clientWidth, scrollWidth = element.scrollWidth;
|
|
_this._clientWidth = clientWidth;
|
|
var lines = Math.floor((parseInt(style.height, 10) + TRUNCATION_VERTICAL_OVERFLOW_THRESHOLD) / parseInt(style.lineHeight, 10));
|
|
element.style.whiteSpace = '';
|
|
// Use overflow to predict truncated length.
|
|
// Take an example.The text is: A text with A very long text that need to be truncated.ppt
|
|
// if container is like
|
|
// |A text with A very| long text that need to be truncated.ppt
|
|
// The scroll width is 58, (take two | out of length)
|
|
// The client width is 18
|
|
// the overflow rate is scrollWidth/clientWidth which should be close to length(overflowText)/length(visualText)
|
|
// And the length of remaining text should be truncated is (original Length)/(58/18) -3 = 15.
|
|
// So that the logic can predict truncated text well.
|
|
// first piece will be `A text `, * second piece will be `ated.ppt`
|
|
// |A text ...ated.ppt|
|
|
var overFlowRate = scrollWidth / (parseInt(style.width, 10) * lines);
|
|
if (overFlowRate > 1) {
|
|
var truncatedLength = originalTitle.length / overFlowRate - 3; /** Saved for separator */
|
|
return _this.setState({
|
|
truncatedTitleFirstPiece: originalTitle.slice(0, truncatedLength / 2),
|
|
truncatedTitleSecondPiece: originalTitle.slice(originalTitle.length - truncatedLength / 2),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
_this._shrinkTitle = function () {
|
|
var _a = _this.state, truncatedTitleFirstPiece = _a.truncatedTitleFirstPiece, truncatedTitleSecondPiece = _a.truncatedTitleSecondPiece;
|
|
if (truncatedTitleFirstPiece && truncatedTitleSecondPiece) {
|
|
var titleElement = _this._titleElement.current;
|
|
if (!titleElement) {
|
|
return;
|
|
}
|
|
if (titleElement.scrollHeight > titleElement.clientHeight + TRUNCATION_VERTICAL_OVERFLOW_THRESHOLD ||
|
|
titleElement.scrollWidth > titleElement.clientWidth) {
|
|
_this.setState({
|
|
truncatedTitleFirstPiece: truncatedTitleFirstPiece.slice(0, truncatedTitleFirstPiece.length - 1),
|
|
truncatedTitleSecondPiece: truncatedTitleSecondPiece.slice(1),
|
|
});
|
|
}
|
|
}
|
|
};
|
|
(0, utilities_1.initializeComponentRef)(_this);
|
|
_this._async = new Utilities_1.Async(_this);
|
|
_this._events = new Utilities_1.EventGroup(_this);
|
|
_this._clientWidth = undefined;
|
|
_this.state = {
|
|
truncatedTitleFirstPiece: undefined,
|
|
truncatedTitleSecondPiece: undefined,
|
|
};
|
|
return _this;
|
|
}
|
|
DocumentCardTitleBase.prototype.componentDidUpdate = function (prevProps) {
|
|
var _this = this;
|
|
if (this.props.title !== prevProps.title) {
|
|
this.setState({
|
|
truncatedTitleFirstPiece: undefined,
|
|
truncatedTitleSecondPiece: undefined,
|
|
});
|
|
}
|
|
if (prevProps.shouldTruncate !== this.props.shouldTruncate) {
|
|
var win = (0, dom_1.getWindowEx)(this.context);
|
|
if (this.props.shouldTruncate) {
|
|
this._truncateTitle();
|
|
this._async.requestAnimationFrame(this._shrinkTitle);
|
|
this._events.on(win, 'resize', this._updateTruncation);
|
|
}
|
|
else {
|
|
this._events.off(win, 'resize', this._updateTruncation);
|
|
}
|
|
}
|
|
else if (this._needMeasurement) {
|
|
this._async.requestAnimationFrame(function () {
|
|
_this._truncateWhenInAnimation();
|
|
_this._shrinkTitle();
|
|
});
|
|
}
|
|
};
|
|
DocumentCardTitleBase.prototype.componentDidMount = function () {
|
|
if (this.props.shouldTruncate) {
|
|
this._truncateTitle();
|
|
var win = (0, dom_1.getWindowEx)(this.context);
|
|
this._events.on(win, 'resize', this._updateTruncation);
|
|
}
|
|
};
|
|
DocumentCardTitleBase.prototype.componentWillUnmount = function () {
|
|
this._events.dispose();
|
|
this._async.dispose();
|
|
};
|
|
DocumentCardTitleBase.prototype.render = function () {
|
|
var _this = this;
|
|
var _a = this.props, title = _a.title, shouldTruncate = _a.shouldTruncate, showAsSecondaryTitle = _a.showAsSecondaryTitle, styles = _a.styles, theme = _a.theme, className = _a.className;
|
|
var _b = this.state, truncatedTitleFirstPiece = _b.truncatedTitleFirstPiece, truncatedTitleSecondPiece = _b.truncatedTitleSecondPiece;
|
|
this._classNames = getClassNames(styles, {
|
|
theme: theme,
|
|
className: className,
|
|
showAsSecondaryTitle: showAsSecondaryTitle,
|
|
});
|
|
if (shouldTruncate && truncatedTitleFirstPiece && truncatedTitleSecondPiece) {
|
|
return (React.createElement(DocumentCard_base_1.DocumentCardContext.Consumer, null, function (_a) {
|
|
var role = _a.role, tabIndex = _a.tabIndex;
|
|
return (React.createElement("div", { className: _this._classNames.root, ref: _this._titleElement, title: title, tabIndex: tabIndex, role: role },
|
|
truncatedTitleFirstPiece,
|
|
"\u2026",
|
|
truncatedTitleSecondPiece));
|
|
}));
|
|
}
|
|
else {
|
|
return (React.createElement(DocumentCard_base_1.DocumentCardContext.Consumer, null, function (_a) {
|
|
var role = _a.role, tabIndex = _a.tabIndex;
|
|
return (React.createElement("div", { className: _this._classNames.root, ref: _this._titleElement, title: title, tabIndex: tabIndex, role: role, style: _this._needMeasurement ? { whiteSpace: 'nowrap' } : undefined }, title));
|
|
}));
|
|
}
|
|
};
|
|
Object.defineProperty(DocumentCardTitleBase.prototype, "_needMeasurement", {
|
|
/**
|
|
* In measuring, it will render a same style text with whiteSpace: 'nowrap', to get overflow rate.
|
|
* So that the logic can predict truncated text well.
|
|
*/
|
|
get: function () {
|
|
return !!this.props.shouldTruncate && this._clientWidth === undefined;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
DocumentCardTitleBase.prototype._updateTruncation = function () {
|
|
var _this = this;
|
|
if (this._timerId) {
|
|
return;
|
|
}
|
|
this._timerId = this._async.setTimeout(function () {
|
|
delete _this._timerId;
|
|
_this._clientWidth = undefined;
|
|
_this.setState({
|
|
truncatedTitleFirstPiece: undefined,
|
|
truncatedTitleSecondPiece: undefined,
|
|
});
|
|
}, 250);
|
|
};
|
|
DocumentCardTitleBase.contextType = react_window_provider_1.WindowContext;
|
|
return DocumentCardTitleBase;
|
|
}(React.Component));
|
|
exports.DocumentCardTitleBase = DocumentCardTitleBase;
|
|
});
|
|
//# sourceMappingURL=DocumentCardTitle.base.js.map
|