UNPKG

vui-design

Version:

A high quality UI Toolkit based on Vue.js

174 lines (150 loc) 3.69 kB
import VuiIcon from "../icon"; import PropTypes from "../../utils/prop-types"; import getClassNamePrefix from "../../utils/getClassNamePrefix"; const shapes = ["circle", "square"]; const sizes = ["small", "medium", "large"]; export const createProps = () => { return { classNamePrefix: PropTypes.string, src: PropTypes.string, replacement: PropTypes.string, alt: PropTypes.string, icon: PropTypes.string, shape: PropTypes.oneOf(shapes), size: PropTypes.oneOfType([PropTypes.oneOf(sizes), PropTypes.number]) }; }; export default { name: "vui-avatar", inject: { vuiAvatarGroup: { default: undefined } }, components: { VuiIcon }, props: createProps(), data() { const state = { scale: 1 }; return { state }; }, methods: { response() { const { $el: el, $refs: references } = this; if (!references.children) { return; } const boundary = el.getBoundingClientRect().width; const width = references.children.offsetWidth; const isOverflowed = boundary - 8 < width; this.state.scale = isOverflowed ? ((boundary - 8) / width) : 1; }, handleError(e) { this.$emit("error", e); } }, mounted() { this.response(); }, updated() { this.response(); }, render() { const { vuiAvatarGroup, $slots: slots, $props: props, state, $listeners: listeners } = this; const { handleError } = this; // src const src = props.src || props.replacement; // type let type; if (src) { type = "image"; } else if (slots.icon || props.icon) { type = "icon"; } else if (slots.default) { type = "children"; } // shape let shape; if (vuiAvatarGroup && vuiAvatarGroup.shape) { shape = vuiAvatarGroup.shape; } else if (props.shape) { shape = props.shape; } else { shape = "circle"; } // size let size; if (vuiAvatarGroup && vuiAvatarGroup.size) { size = vuiAvatarGroup.size; } else if (props.size) { size = props.size; } else { size = "medium"; } const isPresetSize = sizes.indexOf(size) > -1; // class const classNamePrefix = getClassNamePrefix(props.classNamePrefix, "avatar"); let classes = {}; classes.el = { [`${classNamePrefix}`]: true, [`${classNamePrefix}-with-${type}`]: type, [`${classNamePrefix}-${shape}`]: shape, [`${classNamePrefix}-${size}`]: size && isPresetSize }; classes.elChildren = `${classNamePrefix}-${type}`; // style let styles = {}; if (size && !isPresetSize) { styles.el = { width: `${size}px`, height: `${size}px`, lineHeight: `${size}px`, fontSize: `${size / 2}px` }; } if (type === "children") { styles.elChildren = { transform: `scale(${state.scale}) translateX(-50%)` }; } // attributes const attributes = { class: classes.el, style: styles.el, on: { ...listeners } }; // render let children; if (type === "image") { children = ( <img class={classes.elChildren} src={src} alt={props.alt} onError={handleError} /> ); } else if (type === "icon") { children = slots.icon || ( <VuiIcon type={props.icon} class={classes.elChildren} /> ); } else if (type === "children") { children = ( <div ref="children" class={classes.elChildren} style={styles.elChildren}>{slots.default}</div> ); } return ( <div {...attributes}>{children}</div> ); } };