@arco-design/web-vue
Version:
Arco Design Vue 2.0: A Vue.js 3 UI Library
250 lines (249 loc) • 8.71 kB
JavaScript
import { defineComponent, toRefs, inject, computed, ref, onMounted, watch, nextTick, resolveComponent, openBlock, createElementBlock, normalizeStyle, normalizeClass, createVNode, withCtx, createElementVNode, Fragment, renderSlot, createCommentVNode } from "vue";
import { getPrefixCls } from "../_utils/global-config.js";
import { useIndex } from "../_hooks/use-index.js";
import ResizeObserver from "../_components/resize-observer-v2.js";
import { avatarGroupInjectionKey } from "./context.js";
import { isNumber } from "../_utils/is.js";
import IconImageClose from "../icon/icon-image-close/index.js";
import IconLoading from "../icon/icon-loading/index.js";
import { configProviderInjectionKey } from "../config-provider/context.js";
import _export_sfc from "../_virtual/plugin-vue_export-helper.js";
const _sfc_main = defineComponent({
name: "Avatar",
components: {
ResizeObserver,
IconImageClose,
IconLoading
},
props: {
shape: {
type: String,
default: "circle"
},
imageUrl: String,
size: Number,
autoFixFontSize: {
type: Boolean,
default: true
},
triggerType: {
type: String,
default: "button"
},
triggerIconStyle: {
type: Object
},
objectFit: {
type: String
}
},
emits: {
click: (ev) => true,
error: () => true,
load: () => true
},
setup(props, { slots, emit, attrs }) {
const { shape, size, autoFixFontSize, triggerType, triggerIconStyle } = toRefs(props);
const prefixCls = getPrefixCls("avatar");
const groupCtx = inject(avatarGroupInjectionKey, void 0);
const configCtx = inject(configProviderInjectionKey, void 0);
const rtl = computed(() => {
var _a;
return (_a = configCtx == null ? void 0 : configCtx.rtl) != null ? _a : false;
});
const itemRef = ref();
const wrapperRef = ref();
const mergedShape = computed(() => {
var _a;
return (_a = groupCtx == null ? void 0 : groupCtx.shape) != null ? _a : shape.value;
});
const mergedSize = computed(() => {
var _a;
return (_a = groupCtx == null ? void 0 : groupCtx.size) != null ? _a : size.value;
});
const mergedAutoFixFontSize = computed(
() => {
var _a;
return (_a = groupCtx == null ? void 0 : groupCtx.autoFixFontSize) != null ? _a : autoFixFontSize.value;
}
);
const isImage = ref(false);
const hasError = ref(false);
const shouldLoad = ref(true);
const isLoaded = ref(false);
const index = groupCtx ? useIndex({
itemRef,
selector: `.${prefixCls}`
}).computedIndex : ref(-1);
const outerStyle = computed(() => {
var _a;
const style = isNumber(mergedSize.value) ? {
width: `${mergedSize.value}px`,
height: `${mergedSize.value}px`,
fontSize: `${mergedSize.value / 2}px`
} : {};
if (groupCtx) {
style.zIndex = groupCtx.zIndexAscend ? index.value + 1 : groupCtx.total - index.value;
style.marginLeft = index.value !== 0 ? `-${((_a = mergedSize.value) != null ? _a : 40) / 4}px` : "0";
}
return style;
});
const computedTriggerIconStyle = useTriggerIconStyle({
triggerIconStyle: triggerIconStyle == null ? void 0 : triggerIconStyle.value,
inlineStyle: attrs.style,
triggerType: triggerType.value
});
const autoFixFontSizeHandler = () => {
if (!isImage.value && !props.imageUrl) {
nextTick(() => {
var _a;
if (!wrapperRef.value || !itemRef.value) {
return;
}
const textWidth = wrapperRef.value.clientWidth;
const avatarWidth = (_a = mergedSize.value) != null ? _a : itemRef.value.offsetWidth;
const scale = avatarWidth / (textWidth + 8);
if (avatarWidth && scale < 1) {
wrapperRef.value.style.transform = `scale(${scale}) translateX(-50%)`;
}
shouldLoad.value = true;
});
}
};
onMounted(() => {
var _a;
if (((_a = wrapperRef.value) == null ? void 0 : _a.firstElementChild) && ["IMG", "PICTURE"].includes(wrapperRef.value.firstElementChild.tagName)) {
isImage.value = true;
}
if (mergedAutoFixFontSize.value) {
autoFixFontSizeHandler();
}
});
watch(size, () => {
if (mergedAutoFixFontSize.value) {
autoFixFontSizeHandler();
}
});
const cls = computed(() => [
prefixCls,
`${prefixCls}-${mergedShape.value}`
]);
const wrapperCls = computed(
() => isImage.value || props.imageUrl ? `${prefixCls}-image` : `${prefixCls}-text`
);
const onClick = (e) => {
emit("click", e);
};
const handleResize = () => {
if (mergedAutoFixFontSize.value) {
autoFixFontSizeHandler();
}
};
const handleImgLoad = () => {
isLoaded.value = true;
emit("load");
};
const handleImgError = () => {
hasError.value = true;
emit("error");
};
return {
prefixCls,
rtl,
itemRef,
cls,
outerStyle,
wrapperRef,
wrapperCls,
computedTriggerIconStyle,
isImage,
shouldLoad,
isLoaded,
hasError,
onClick,
handleResize,
handleImgLoad,
handleImgError
};
}
});
const useTriggerIconStyle = ({
triggerType,
inlineStyle = {},
triggerIconStyle = {}
}) => {
let addon = {};
if (triggerType === "button" && (!triggerIconStyle || triggerIconStyle && !triggerIconStyle.color) && inlineStyle && inlineStyle.backgroundColor) {
addon = { color: inlineStyle.backgroundColor };
}
return {
...triggerIconStyle,
...addon
};
};
const _hoisted_1 = ["src"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_IconImageClose = resolveComponent("IconImageClose");
const _component_IconLoading = resolveComponent("IconLoading");
const _component_resize_observer = resolveComponent("resize-observer");
return openBlock(), createElementBlock("div", {
ref: "itemRef",
style: normalizeStyle(_ctx.outerStyle),
class: normalizeClass([
_ctx.cls,
{
[`${_ctx.prefixCls}-with-trigger-icon`]: Boolean(_ctx.$slots["trigger-icon"]),
[`${_ctx.prefixCls}-rtl`]: _ctx.rtl
}
]),
onClick: _cache[2] || (_cache[2] = (...args) => _ctx.onClick && _ctx.onClick(...args))
}, [
createVNode(_component_resize_observer, { onResize: _ctx.handleResize }, {
default: withCtx(() => [
createElementVNode("span", {
ref: "wrapperRef",
class: normalizeClass(_ctx.wrapperCls)
}, [
_ctx.imageUrl ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
_ctx.hasError ? renderSlot(_ctx.$slots, "error", { key: 0 }, () => [
createElementVNode("div", {
class: normalizeClass(`${_ctx.prefixCls}-image-icon`)
}, [
createVNode(_component_IconImageClose)
], 2)
]) : createCommentVNode("v-if", true),
!(_ctx.hasError || !_ctx.shouldLoad) && !_ctx.isLoaded ? renderSlot(_ctx.$slots, "default", { key: 1 }, () => [
createElementVNode("div", {
class: normalizeClass(`${_ctx.prefixCls}-image-icon`)
}, [
createVNode(_component_IconLoading)
], 2)
]) : createCommentVNode("v-if", true),
!(_ctx.hasError || !_ctx.shouldLoad) ? (openBlock(), createElementBlock("img", {
key: 2,
src: _ctx.imageUrl,
style: normalizeStyle({
width: _ctx.size + "px",
height: _ctx.size + "px",
objectFit: _ctx.objectFit
}),
alt: "avatar",
onLoad: _cache[0] || (_cache[0] = (...args) => _ctx.handleImgLoad && _ctx.handleImgLoad(...args)),
onError: _cache[1] || (_cache[1] = (...args) => _ctx.handleImgError && _ctx.handleImgError(...args))
}, null, 44, _hoisted_1)) : createCommentVNode("v-if", true)
], 64)) : renderSlot(_ctx.$slots, "default", { key: 1 })
], 2)
]),
_: 3
}, 8, ["onResize"]),
_ctx.$slots["trigger-icon"] ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(`${_ctx.prefixCls}-trigger-icon-${_ctx.triggerType}`),
style: normalizeStyle(_ctx.computedTriggerIconStyle)
}, [
renderSlot(_ctx.$slots, "trigger-icon")
], 6)) : createCommentVNode("v-if", true)
], 6);
}
var _Avatar = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export { _Avatar as default };