@aplus-frontend/antdv
Version:
Vue basic component library maintained based on ant-design-vue
204 lines • 6.46 kB
JavaScript
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _extends from "@babel/runtime/helpers/esm/extends";
import { computed, defineComponent, nextTick, onMounted, shallowRef, watch, createVNode as _createVNode } from 'vue';
import { getPropsSlot } from '../_util/props-util';
import PropTypes from '../_util/vue-types';
import useBreakpoint from '../_util/hooks/useBreakpoint';
import { responsiveArray } from '../_util/responsiveObserve';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import ResizeObserver from '../vc-resize-observer';
import eagerComputed from '../_util/eagerComputed';
import useStyle from './style';
import { useAvatarInjectContext } from './AvatarContext';
export const avatarProps = () => ({
prefixCls: String,
shape: {
type: String,
default: 'circle'
},
size: {
type: [Number, String, Object],
default: () => 'default'
},
src: String,
/** Srcset of image avatar */
srcset: String,
icon: PropTypes.any,
alt: String,
gap: Number,
draggable: {
type: Boolean,
default: undefined
},
crossOrigin: String,
loadError: {
type: Function
}
});
const Avatar = defineComponent({
compatConfig: {
MODE: 3
},
name: 'AAvatar',
inheritAttrs: false,
props: avatarProps(),
slots: Object,
setup(props, _ref) {
let {
slots,
attrs
} = _ref;
const isImgExist = shallowRef(true);
const isMounted = shallowRef(false);
const scale = shallowRef(1);
const avatarChildrenRef = shallowRef(null);
const avatarNodeRef = shallowRef(null);
const {
prefixCls
} = useConfigInject('avatar', props);
const [wrapSSR, hashId] = useStyle(prefixCls);
const avatarCtx = useAvatarInjectContext();
const size = computed(() => {
return props.size === 'default' ? avatarCtx.size : props.size;
});
const screens = useBreakpoint();
const responsiveSize = eagerComputed(() => {
if (typeof props.size !== 'object') {
return undefined;
}
const currentBreakpoint = responsiveArray.find(screen => screens.value[screen]);
const currentSize = props.size[currentBreakpoint];
return currentSize;
});
const responsiveSizeStyle = hasIcon => {
if (responsiveSize.value) {
return {
width: `${responsiveSize.value}px`,
height: `${responsiveSize.value}px`,
lineHeight: `${responsiveSize.value}px`,
fontSize: `${hasIcon ? responsiveSize.value / 2 : 18}px`
};
}
return {};
};
const setScaleParam = () => {
if (!avatarChildrenRef.value || !avatarNodeRef.value) {
return;
}
const childrenWidth = avatarChildrenRef.value.offsetWidth; // offsetWidth avoid affecting be transform scale
const nodeWidth = avatarNodeRef.value.offsetWidth;
// denominator is 0 is no meaning
if (childrenWidth !== 0 && nodeWidth !== 0) {
const {
gap = 4
} = props;
if (gap * 2 < nodeWidth) {
scale.value = nodeWidth - gap * 2 < childrenWidth ? (nodeWidth - gap * 2) / childrenWidth : 1;
}
}
};
const handleImgLoadError = () => {
const {
loadError
} = props;
const errorFlag = loadError === null || loadError === void 0 ? void 0 : loadError();
if (errorFlag !== false) {
isImgExist.value = false;
}
};
watch(() => props.src, () => {
nextTick(() => {
isImgExist.value = true;
scale.value = 1;
});
});
watch(() => props.gap, () => {
nextTick(() => {
setScaleParam();
});
});
onMounted(() => {
nextTick(() => {
setScaleParam();
isMounted.value = true;
});
});
return () => {
var _a, _b;
const {
shape,
src,
alt,
srcset,
draggable,
crossOrigin
} = props;
const mergeShape = (_a = avatarCtx.shape) !== null && _a !== void 0 ? _a : shape;
const icon = getPropsSlot(slots, props, 'icon');
const pre = prefixCls.value;
const classString = {
[`${attrs.class}`]: !!attrs.class,
[pre]: true,
[`${pre}-lg`]: size.value === 'large',
[`${pre}-sm`]: size.value === 'small',
[`${pre}-${mergeShape}`]: true,
[`${pre}-image`]: src && isImgExist.value,
[`${pre}-icon`]: icon,
[hashId.value]: true
};
const sizeStyle = typeof size.value === 'number' ? {
width: `${size.value}px`,
height: `${size.value}px`,
lineHeight: `${size.value}px`,
fontSize: icon ? `${size.value / 2}px` : '18px'
} : {};
const children = (_b = slots.default) === null || _b === void 0 ? void 0 : _b.call(slots);
let childrenToRender;
if (src && isImgExist.value) {
childrenToRender = _createVNode("img", {
"draggable": draggable,
"src": src,
"srcset": srcset,
"onError": handleImgLoadError,
"alt": alt,
"crossorigin": crossOrigin
}, null);
} else if (icon) {
childrenToRender = icon;
} else if (isMounted.value || scale.value !== 1) {
const transformString = `scale(${scale.value}) translateX(-50%)`;
const childrenStyle = {
msTransform: transformString,
WebkitTransform: transformString,
transform: transformString
};
const sizeChildrenStyle = typeof size.value === 'number' ? {
lineHeight: `${size.value}px`
} : {};
childrenToRender = _createVNode(ResizeObserver, {
"onResize": setScaleParam
}, {
default: () => [_createVNode("span", {
"class": `${pre}-string`,
"ref": avatarChildrenRef,
"style": _extends(_extends({}, sizeChildrenStyle), childrenStyle)
}, [children])]
});
} else {
childrenToRender = _createVNode("span", {
"class": `${pre}-string`,
"ref": avatarChildrenRef,
"style": {
opacity: 0
}
}, [children]);
}
return wrapSSR(_createVNode("span", _objectSpread(_objectSpread({}, attrs), {}, {
"ref": avatarNodeRef,
"class": classString,
"style": [sizeStyle, responsiveSizeStyle(!!icon), attrs.style]
}), [childrenToRender]));
};
}
});
export default Avatar;