@extclp/vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 7.04 kB
Source Map (JSON)
{"version":3,"file":"avatar.vue2.mjs","sources":["../../../components/avatar/avatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Icon } from '@/components/icon'\nimport { ResizeObserver } from '@/components/resize-observer'\nimport { Renderer } from '@/components/renderer'\n\nimport { computed, inject, ref, watch } from 'vue'\n\nimport { createIconProp, emitEvent, useNameHelper, useProps } from '@vexip-ui/config'\nimport { useDisplay } from '@vexip-ui/hooks'\nimport { avatarProps } from './props'\nimport { GROUP_STATE, objectFitValues } from './symbol'\n\nimport type { ComponentSize, StyleType } from '@vexip-ui/config'\n\ndefineOptions({ name: 'Avatar' })\n\nconst _props = defineProps(avatarProps)\nconst props = useProps('avatar', _props, {\n size: 'default',\n src: {\n default: '',\n static: true\n },\n icon: createIconProp(),\n circle: false,\n alt: '',\n fit: {\n default: 'cover',\n validator: value => objectFitValues.includes(value)\n },\n srcSet: '',\n gap: 4,\n iconScale: 1.4,\n fallbackSrc: '',\n color: null,\n background: null,\n slots: () => ({})\n})\n\nconst slots = defineSlots<{\n default?: () => any,\n icon?: () => any\n}>()\n\nconst groupState = inject(GROUP_STATE, null)\n\nconst nh = useNameHelper('avatar')\n\nconst loadFail = ref(false)\nconst fallbackFail = ref(false)\n\nconst wrapper = ref<HTMLElement>()\nconst text = useDisplay(() => scaleText(true))\n\nconst size = computed(() => {\n return groupState?.size ?? props.size\n})\nconst className = computed(() => {\n return {\n [nh.b()]: true,\n [nh.bs('vars')]: true,\n [nh.bm('inherit')]: props.inherit,\n [nh.bm(size.value as ComponentSize)]:\n typeof size.value !== 'number' && size.value !== 'default',\n [nh.bm('circle')]: props.circle\n }\n})\nconst style = computed(() => {\n const style: StyleType = {\n [nh.cv('color')]: props.color,\n [nh.cv('bg-color')]: props.background,\n [nh.cv('image-fit')]: props.fit\n }\n\n if (typeof size.value === 'number') {\n style[nh.cv('size')] = `${size.value}px`\n }\n\n return style\n})\n\nwatch(\n () => props.src,\n () => {\n loadFail.value = false\n fallbackFail.value = false\n scaleText()\n }\n)\nwatch(\n () => props.fallbackSrc,\n () => {\n fallbackFail.value = false\n scaleText()\n }\n)\nwatch(\n () => props.gap,\n () => scaleText()\n)\n\ndefineExpose({ loadFail, fallbackFail })\n\nfunction handleError(event: Event) {\n loadFail.value = true\n emitEvent(props.onError, event)\n}\n\nlet lastText: string | null = null\n\nfunction scaleText(force = false) {\n const avatarEl = wrapper.value\n const textEl = text.value\n\n if (avatarEl && textEl && (force || lastText === null || lastText !== textEl.textContent)) {\n lastText = textEl.textContent\n\n const { offsetWidth: avatarWidth, offsetHeight: avatarHeight } = avatarEl\n const { offsetWidth: textWidth, offsetHeight: textHeight } = textEl\n const padding = props.gap * 2\n\n const ratio = Math.min(\n (avatarWidth - padding) / (textWidth || 1),\n (avatarHeight - padding) / (textHeight || 1),\n 1\n )\n\n textEl.style.transform = `scale(${ratio})`\n }\n}\n\nfunction handleClick(event: MouseEvent) {\n emitEvent(props.onClick, event)\n}\n</script>\n\n<template>\n <div\n ref=\"wrapper\"\n :class=\"className\"\n :style=\"style\"\n @click=\"handleClick\"\n >\n <img\n v-if=\"(props.src || props.srcSet) && !loadFail\"\n :class=\"nh.be('image')\"\n :src=\"props.src\"\n :alt=\"props.alt\"\n :srcset=\"props.srcSet\"\n @error=\"handleError\"\n />\n <img\n v-else-if=\"loadFail && props.fallbackSrc && !fallbackFail\"\n :class=\"nh.be('image')\"\n :src=\"props.fallbackSrc\"\n :alt=\"props.alt\"\n @error=\"fallbackFail = true\"\n />\n <template v-else-if=\"icon || slots.icon\">\n <slot name=\"icon\">\n <Renderer :renderer=\"props.slots.icon\">\n <Icon :class=\"nh.be('icon')\" :icon=\"icon\" :scale=\"props.iconScale\"></Icon>\n </Renderer>\n </slot>\n </template>\n <ResizeObserver v-else :on-resize=\"scaleText\">\n <span ref=\"text\" :class=\"nh.be('text')\">\n <slot>\n <Renderer :renderer=\"props.slots.default\"></Renderer>\n </slot>\n </span>\n </ResizeObserver>\n </div>\n</template>\n"],"names":["props","useProps","__props","createIconProp","value","objectFitValues","slots","_useSlots","groupState","inject","GROUP_STATE","nh","useNameHelper","loadFail","ref","fallbackFail","wrapper","text","useDisplay","scaleText","size","computed","className","style","watch","__expose","handleError","event","emitEvent","lastText","force","avatarEl","textEl","avatarWidth","avatarHeight","textWidth","textHeight","padding","ratio","handleClick"],"mappings":"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"}