rabbit-design
Version:
A lightweight UI plugin library written in TypeScript and based on JavaScript
143 lines (107 loc) • 4.39 kB
text/typescript
import { warn } from '../../mixins';
import { $el, createElem, removeAttrs, setCss, setHtml } from '../../dom-utils';
import PREFIX from '../prefix';
class Avatar {
readonly VERSION: string;
readonly COMPONENTS: NodeListOf<Element>;
constructor() {
this.VERSION = 'v1.0';
this.COMPONENTS = $el('r-avatar', { all: true });
this._create(this.COMPONENTS);
}
private _create(COMPONENTS: NodeListOf<Element>): void {
COMPONENTS.forEach((node) => {
this._setIcon(node);
this._setImage(node);
this._setSize(node);
this._setCustomContent(node);
removeAttrs(node, ['icon', 'src', 'custom-icon']);
});
}
private _setIcon(node: Element): void {
const hasIcon = this._getIcon(node);
const customIcon = this._getCustmIcon(node);
if (!hasIcon) return;
if (hasIcon || customIcon) {
setHtml(node, '');
node.classList.add(`${PREFIX.avatar}-icon`);
}
if (customIcon) {
setHtml(node, customIcon);
} else {
const AvatarIcon = createElem('i');
AvatarIcon.className = `rab-icon rab-icon-${hasIcon}`;
node.appendChild(AvatarIcon);
}
}
private _setImage(node: Element): void {
const hasSrc = this._getSrc(node);
if (!hasSrc) return;
const AvatarImage = createElem('img');
// @ts-ignore
AvatarImage.src = hasSrc;
setHtml(node, '');
node.classList.add(`${PREFIX.avatar}-image`);
node.appendChild(AvatarImage);
}
// 自定义头像内容
private _setCustomContent(node: Element): void {
if (node.getAttribute('rb-icon') || node.getAttribute('rb-src')) return;
if (setHtml(node)) {
const AvatarStrBox = createElem('span');
AvatarStrBox.className = `${PREFIX.avatar}-string`;
setHtml(AvatarStrBox, node.innerHTML);
setHtml(node, '');
node.appendChild(AvatarStrBox);
this._setScale(node, AvatarStrBox);
}
}
// 使文本容器大写适应头像容器并且不超出范围
private _setScale(node: Element, children: HTMLSpanElement) {
const avatarWidth: number = node.getBoundingClientRect().width;
const childrenWidth: number = children.offsetWidth;
if (avatarWidth - 8 < childrenWidth) {
const newScale = `scale(${(avatarWidth - 8) / childrenWidth}) translateX(-50%)`;
setCss(children, 'transform', `scale(${newScale}) translateX(-50%)`);
} else {
setCss(children, 'transform', 'scale(1) translateX(-50%)');
}
}
// 设置头像尺寸
private _setSize(node: any): void {
const size = this._getSize(node);
if (!size) return;
setCss(node, 'width', `${size}px`);
setCss(node, 'height', `${size}px`);
setCss(node, 'lineHeight', `${size}px`);
// 如果设置的尺寸超过40,且在有图标的情况下将其字体大写设为头像尺寸的一半
if (size >= 40) {
if (node.querySelector('.rab-icon')) {
const newFontSize = `${Math.floor(size / 2)}px`;
setCss(node, 'fontSize', newFontSize);
}
}
}
private _getIcon(node: Element): string {
return node.getAttribute('rb-icon') || '';
}
private _getCustmIcon(node: Element): string {
return node.getAttribute('rb-custom-icon') || '';
}
private _getSrc(node: Element): string {
return node.getAttribute('rb-src') || '';
}
private _getSize(node: Element): number | undefined {
const size = node.getAttribute('rb-size') || '';
// 不获取这两个
if (size === 'large' || size === 'small') return;
// 尺寸设置为数值,则将字符串数值转换为数字
const toNum = Number(size);
if (toNum) return toNum;
// 打印错误不包括设置了数值为0
else if (toNum !== 0) {
warn(`You have set an invalid size value for the Avatar component --> "${size}"`);
}
}
}
export default Avatar;