naive-ui
Version:
A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast
239 lines (238 loc) • 11.3 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.avatarProps = void 0;
const vue_1 = require("vue");
const vueuc_1 = require("vueuc");
const is_native_lazy_load_1 = require("../../_utils/env/is-native-lazy-load");
const utils_1 = require("../../image/src/utils");
const Tag_1 = require("../../tag/src/Tag");
const _mixins_1 = require("../../_mixins");
const _utils_1 = require("../../_utils");
const styles_1 = require("../styles");
const context_1 = require("./context");
const index_cssr_1 = __importDefault(require("./styles/index.cssr"));
exports.avatarProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { size: [String, Number], src: String, circle: {
type: Boolean,
default: undefined
}, objectFit: String, round: {
type: Boolean,
default: undefined
}, bordered: {
type: Boolean,
default: undefined
}, onError: Function, fallbackSrc: String, intersectionObserverOptions: Object, lazy: Boolean, onLoad: Function, renderPlaceholder: Function, renderFallback: Function, imgProps: Object,
/** @deprecated */
color: String });
exports.default = (0, vue_1.defineComponent)({
name: 'Avatar',
props: exports.avatarProps,
setup(props) {
const { mergedClsPrefixRef, inlineThemeDisabled } = (0, _mixins_1.useConfig)(props);
const hasLoadErrorRef = (0, vue_1.ref)(false);
let memoedTextHtml = null;
const textRef = (0, vue_1.ref)(null);
const selfRef = (0, vue_1.ref)(null);
const fitTextTransform = () => {
const { value: textEl } = textRef;
if (textEl) {
if (memoedTextHtml === null || memoedTextHtml !== textEl.innerHTML) {
memoedTextHtml = textEl.innerHTML;
const { value: selfEl } = selfRef;
if (selfEl) {
const { offsetWidth: elWidth, offsetHeight: elHeight } = selfEl;
const { offsetWidth: textWidth, offsetHeight: textHeight } = textEl;
const radix = 0.9;
const ratio = Math.min((elWidth / textWidth) * radix, (elHeight / textHeight) * radix, 1);
textEl.style.transform = `translateX(-50%) translateY(-50%) scale(${ratio})`;
}
}
}
};
const NAvatarGroup = (0, vue_1.inject)(context_1.avatarGroupInjectionKey, null);
const mergedSizeRef = (0, vue_1.computed)(() => {
const { size } = props;
if (size)
return size;
const { size: avatarGroupSize } = NAvatarGroup || {};
if (avatarGroupSize)
return avatarGroupSize;
return 'medium';
});
const themeRef = (0, _mixins_1.useTheme)('Avatar', '-avatar', index_cssr_1.default, styles_1.avatarLight, props, mergedClsPrefixRef);
const TagInjection = (0, vue_1.inject)(Tag_1.tagInjectionKey, null);
const mergedRoundRef = (0, vue_1.computed)(() => {
if (NAvatarGroup)
return true;
const { round, circle } = props;
if (round !== undefined || circle !== undefined)
return round || circle;
if (TagInjection) {
return TagInjection.roundRef.value;
}
return false;
});
const mergedBorderedRef = (0, vue_1.computed)(() => {
if (NAvatarGroup)
return true;
return props.bordered || false;
});
const cssVarsRef = (0, vue_1.computed)(() => {
const size = mergedSizeRef.value;
const round = mergedRoundRef.value;
const bordered = mergedBorderedRef.value;
const { color: propColor } = props;
const { self: { borderRadius, fontSize, color, border, colorModal, colorPopover }, common: { cubicBezierEaseInOut } } = themeRef.value;
let height;
if (typeof size === 'number') {
height = `${size}px`;
}
else {
height = themeRef.value.self[(0, _utils_1.createKey)('height', size)];
}
return {
'--n-font-size': fontSize,
'--n-border': bordered ? border : 'none',
'--n-border-radius': round ? '50%' : borderRadius,
'--n-color': propColor || color,
'--n-color-modal': propColor || colorModal,
'--n-color-popover': propColor || colorPopover,
'--n-bezier': cubicBezierEaseInOut,
'--n-merged-size': `var(--n-avatar-size-override, ${height})`
};
});
const themeClassHandle = inlineThemeDisabled
? (0, _mixins_1.useThemeClass)('avatar', (0, vue_1.computed)(() => {
const size = mergedSizeRef.value;
const round = mergedRoundRef.value;
const bordered = mergedBorderedRef.value;
const { color } = props;
let hash = '';
if (size) {
if (typeof size === 'number') {
hash += `a${size}`;
}
else {
hash += size[0];
}
}
if (round) {
hash += 'b';
}
if (bordered) {
hash += 'c';
}
if (color) {
hash += (0, _utils_1.color2Class)(color);
}
return hash;
}), cssVarsRef, props)
: undefined;
const shouldStartLoadingRef = (0, vue_1.ref)(!props.lazy);
(0, vue_1.onMounted)(() => {
// Use IntersectionObserver if lazy and intersectionObserverOptions is set
if (props.lazy && props.intersectionObserverOptions) {
let unobserve;
const stopWatchHandle = (0, vue_1.watchEffect)(() => {
unobserve === null || unobserve === void 0 ? void 0 : unobserve();
unobserve = undefined;
if (props.lazy) {
unobserve = (0, utils_1.observeIntersection)(selfRef.value, props.intersectionObserverOptions, shouldStartLoadingRef);
}
});
(0, vue_1.onBeforeUnmount)(() => {
stopWatchHandle();
unobserve === null || unobserve === void 0 ? void 0 : unobserve();
});
}
});
(0, vue_1.watch)(() => { var _a; return props.src || ((_a = props.imgProps) === null || _a === void 0 ? void 0 : _a.src); }, () => {
hasLoadErrorRef.value = false;
});
const loadedRef = (0, vue_1.ref)(!props.lazy);
return {
textRef,
selfRef,
mergedRoundRef,
mergedClsPrefix: mergedClsPrefixRef,
fitTextTransform,
cssVars: inlineThemeDisabled ? undefined : cssVarsRef,
themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass,
onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender,
hasLoadError: hasLoadErrorRef,
shouldStartLoading: shouldStartLoadingRef,
loaded: loadedRef,
mergedOnError: (e) => {
if (!shouldStartLoadingRef.value)
return;
hasLoadErrorRef.value = true;
const { onError, imgProps: { onError: imgPropsOnError } = {} } = props;
onError === null || onError === void 0 ? void 0 : onError(e);
imgPropsOnError === null || imgPropsOnError === void 0 ? void 0 : imgPropsOnError(e);
},
mergedOnLoad: (e) => {
const { onLoad, imgProps: { onLoad: imgPropsOnLoad } = {} } = props;
onLoad === null || onLoad === void 0 ? void 0 : onLoad(e);
imgPropsOnLoad === null || imgPropsOnLoad === void 0 ? void 0 : imgPropsOnLoad(e);
loadedRef.value = true;
}
};
},
render() {
var _a, _b;
const { $slots, src, mergedClsPrefix, lazy, onRender, loaded, hasLoadError, imgProps = {} } = this;
onRender === null || onRender === void 0 ? void 0 : onRender();
let img;
const placeholderNode = !loaded
&& !hasLoadError
&& (this.renderPlaceholder
? this.renderPlaceholder()
: (_b = (_a = this.$slots).placeholder) === null || _b === void 0 ? void 0 : _b.call(_a));
if (this.hasLoadError) {
img = this.renderFallback
? this.renderFallback()
: (0, _utils_1.resolveSlot)($slots.fallback, () => [
(0, vue_1.h)("img", { src: this.fallbackSrc, style: { objectFit: this.objectFit } })
]);
}
else {
img = (0, _utils_1.resolveWrappedSlot)($slots.default, (children) => {
if (children) {
return ((0, vue_1.h)(vueuc_1.VResizeObserver, { onResize: this.fitTextTransform }, {
default: () => ((0, vue_1.h)("span", { ref: "textRef", class: `${mergedClsPrefix}-avatar__text` }, children))
}));
}
else if (src || imgProps.src) {
const loadSrc = this.src || imgProps.src;
return (0, vue_1.h)('img', Object.assign(Object.assign({}, imgProps), { loading:
// If interseciton observer options is set, do not use native lazy
is_native_lazy_load_1.isImageSupportNativeLazy
&& !this.intersectionObserverOptions
&& lazy
? 'lazy'
: 'eager', src: lazy && this.intersectionObserverOptions
? this.shouldStartLoading
? loadSrc
: undefined
: loadSrc, 'data-image-src': loadSrc, onLoad: this.mergedOnLoad, onError: this.mergedOnError, style: [
imgProps.style || '',
{ objectFit: this.objectFit },
placeholderNode
? {
height: '0',
width: '0',
visibility: 'hidden',
position: 'absolute'
}
: ''
] }));
}
});
}
return ((0, vue_1.h)("span", { ref: "selfRef", class: [`${mergedClsPrefix}-avatar`, this.themeClass], style: this.cssVars },
img,
lazy && placeholderNode));
}
});
;