react-avatar
Version:
Universal React avatar component makes it possible to generate avatars based on user information.
150 lines (142 loc) • 5.37 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: 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 _wrapper = _interopRequireDefault(require("./wrapper"));
var _utils = require("../utils");
class AvatarText extends _react.default.PureComponent {
constructor() {
var _this;
super(...arguments);
_this = this;
(0, _defineProperty2.default)(this, "_scaleTextNode", function (node) {
let retryTTL = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 16;
const {
unstyled,
textSizeRatio,
textMarginRatio,
avatar
} = _this.props;
_this._node = node;
if (!node || !node.parentNode || unstyled || avatar.src || !_this._mounted) return;
const spanNode = node.parentNode;
const tableNode = spanNode.parentNode;
const {
width: containerWidth,
height: containerHeight
} = spanNode.getBoundingClientRect();
// Whenever the avatar element is not visible due to some CSS
// (such as display: none) on any parent component we will check
// whether the component has become visible.
//
// The time between checks grows up to half a second in an attempt
// to reduce flicker / performance issues.
if (containerWidth == 0 && containerHeight == 0) {
const ttl = Math.min(retryTTL * 1.5, 500);
(0, _utils.setGroupedTimeout)(() => _this._scaleTextNode(node, ttl), ttl);
return;
}
// If the tableNode (outer-container) does not have its fontSize set yet,
// we'll set it according to "textSizeRatio"
if (!tableNode.style.fontSize) {
const baseFontSize = containerHeight / textSizeRatio;
tableNode.style.fontSize = "".concat(baseFontSize, "px");
}
// Reset font-size such that scaling works correctly (#133)
spanNode.style.fontSize = null;
// Measure the actual width of the text after setting the container size
const {
width: textWidth
} = node.getBoundingClientRect();
if (textWidth < 0) return;
// Calculate the maximum width for the text based on "textMarginRatio"
const maxTextWidth = containerWidth * (1 - 2 * textMarginRatio);
// If the text is too wide, scale it down by (maxWidth / actualWidth)
if (textWidth > maxTextWidth) spanNode.style.fontSize = "calc(1em * ".concat(maxTextWidth / textWidth, ")");
});
}
componentDidMount() {
this._mounted = true;
this._scaleTextNode(this._node);
}
componentWillUnmount() {
this._mounted = false;
}
render() {
const {
className,
round,
unstyled,
title,
name,
value,
avatar
} = this.props;
const size = (0, _utils.parseSize)(this.props.size);
const initialsStyle = unstyled ? null : {
width: size.str,
height: size.str,
lineHeight: 'initial',
textAlign: 'center',
color: this.props.fgColor,
background: avatar.color,
borderRadius: (0, _utils.calculateBorderRadius)(round)
};
const tableStyle = unstyled ? null : {
display: 'table',
tableLayout: 'fixed',
width: '100%',
height: '100%'
};
const spanStyle = unstyled ? null : {
display: 'table-cell',
verticalAlign: 'middle',
fontSize: '100%',
whiteSpace: 'nowrap'
};
// Ensure the text node is updated and scaled when any of these
// values changed by calling the `_scaleTextNode` method using
// the correct `ref`.
const key = [avatar.value, this.props.size].join('');
return /*#__PURE__*/_react.default.createElement(_wrapper.default, this.props, /*#__PURE__*/_react.default.createElement("div", {
className: className + ' sb-avatar__text',
style: initialsStyle,
title: (0, _utils.getNullableText)(title, name || value)
}, /*#__PURE__*/_react.default.createElement("div", {
style: tableStyle
}, /*#__PURE__*/_react.default.createElement("span", {
style: spanStyle
}, /*#__PURE__*/_react.default.createElement("span", {
ref: this._scaleTextNode,
key: key
}, avatar.value)))));
}
}
exports.default = AvatarText;
(0, _defineProperty2.default)(AvatarText, "propTypes", {
name: _propTypes.default.string,
value: _propTypes.default.string,
avatar: _propTypes.default.object,
title: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]),
className: _propTypes.default.string,
unstyled: _propTypes.default.bool,
fgColor: _propTypes.default.string,
textSizeRatio: _propTypes.default.number,
textMarginRatio: _propTypes.default.number,
round: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.string, _propTypes.default.number]),
size: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])
});
(0, _defineProperty2.default)(AvatarText, "defaultProps", {
className: '',
fgColor: '#FFF',
round: false,
size: 100,
textSizeRatio: 3,
textMarginRatio: .15,
unstyled: false
});