import { makeComponentProps } from '@/composables/component' import { makeTagProps } from '@/composables/tag' import { ExtractPropTypes, computed } from 'vue' import { genericComponent, propsFactory } from '@/utils' import ColorName from '@/types/colors' import { UIcon, UAvatar } from '../../components' import Sizes from '@/types/sizes' export const makeUBadgeProps = propsFactory( { size: { type: String, default: 'sm', required: false, }, type: { type: String, default: 'default', required: false, }, color: { type: String, default: 'primary', required: false, }, avatarImagePath: { type: String, required: false, }, avatarText: { type: String, required: false, }, arrowUp: { type: Boolean, required: false, }, arrowRight: { type: Boolean, required: false, }, plus: { type: Boolean, required: false, }, ...makeComponentProps(), ...makeTagProps(), }, 'UBadge' ) export type UBadgeProps = ExtractPropTypes export type UBadgeSlots = { default: never } export const UBadge = genericComponent()({ name: 'UBadge', props: makeUBadgeProps(), emits: { click: (e: MouseEvent) => true, appendClick: (e: MouseEvent) => true, prependClick: (e: MouseEvent) => true, }, setup(props, { emit, slots }) { const bgColor = computed(() => { let color = '' if (props.color === 'gray' && props.type === 'default') { color = 'gray-100' } else if (props.color !== 'gray' && props.type === 'default') { color = props.color + '-50' } else { color = 'transparent' } return color as ColorName }) const borderColor = computed(() => { return props.type === 'outlined' ? `border-1.5 border-${textColor.value}` : '' }) const arrowColor = computed(() => { return `${props.color}-500` as ColorName }) const textSizes = computed(() => { let text = '' if (props.size === 'sm') { text = 'text-text-xs' } else if (props.size === 'md' || props.size === 'lg') { text = 'text-text-sm' } return text }) const textColor = computed(() => { return props.color + '-700' }) const avatarPaddingClasses = computed(() => ({ ['pr-px']: props.size === 'sm', ['pr-0']: props.size === 'md' || props.size === 'lg', })) const arrowUpPaddingClasses = computed(() => ({ ['pl-0.6']: props.size === 'sm', ['pl-1']: props.size === 'md' || props.size === 'lg', })) const arrowRightPaddingClasses = computed(() => ({ ['pr-0.6']: props.size === 'sm', ['pr-0.5']: props.size === 'md', ['pr-1']: props.size === 'lg', })) const plusPaddingClasses = computed(() => ({ ['py-1 px-1']: props.size === 'sm', ['py-1.5 px-1.5']: props.size === 'md', ['py-2 px-2']: props.size === 'lg', })) const labelPaddingClasses = computed(() => ({ ['px-1.3']: (props.size === 'sm' && (props.avatarText || props.avatarImagePath) && !props.arrowUp) || ((!props.avatarText || !props.avatarImagePath) && !props.arrowUp), ['px-1.5']: ((props.size === 'md' || props.size === 'lg') && (props.avatarText || props.avatarImagePath) && !props.arrowUp) || ((!props.avatarText || !props.avatarImagePath) && !props.arrowUp), ['pr-1.3 pl-1']: props.size === 'sm' && (!props.avatarText || !props.avatarImagePath) && props.arrowUp, ['pr-1.5 pl-1']: (props.size === 'md' || props.size === 'lg') && (!props.avatarText || !props.avatarImagePath) && props.arrowUp, ['pl-1.3 pr-1']: props.size === 'sm' && props.arrowRight, ['pl-1.5 pr-1']: (props.size === 'md' || props.size === 'lg') && props.arrowRight, })) const containerPaddingClasses = computed(() => ({ ['py-0.5 px-0.6']: props.size === 'sm', ['py-0.5 px-1']: props.size === 'md', ['py-1 px-1.5']: props.size === 'lg', })) const classes = computed(() => { return `bg-${bgColor.value} w-fit ${textSizes.value} text-${textColor.value} rounded-16 flex justify-center items-center ${borderColor.value} font-medium` }) const handleAppendClick = (newValue: any) => { emit('appendClick', newValue) } const handlePrependClick = (newValue: any) => { emit('prependClick', newValue) } return () => (
emit('click', e)} > {props.avatarImagePath ? (
) : null} {props.avatarText ? (
{props.avatarText}
) : null} {props.arrowUp ? (
) : null} {slots.default !== undefined && !props.plus ? (
{slots.default?.()}
) : null} {props.arrowRight ? (
) : null} {props.plus ? (
) : null}
) }, })