refactor: Replaced classNames with tailwind merge in badge component
This commit is contained in:
@@ -1,33 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<component :is="wrapperType" :class="badgeClasses" :href="href">
|
<component :is="wrapperType" :class="badgeClasses" :href="href">
|
||||||
<slot name="icon"/>
|
<slot name="icon" />
|
||||||
<slot name="default" />
|
<slot name="default" />
|
||||||
</component>
|
</component>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, toRefs, useSlots } from 'vue'
|
import { computed, useSlots } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type { BadgeType, BadgeSize } from './types'
|
import type { BadgeType, BadgeSize } from './types'
|
||||||
import { useBadgeClasses } from '@/components/Badge/composables/useBadgeClasses'
|
import { useBadgeClasses } from '@/components/Badge/composables/useBadgeClasses'
|
||||||
|
|
||||||
const props = defineProps({
|
interface IBadgeProps {
|
||||||
type: {
|
type?: BadgeType
|
||||||
type: String as PropType<BadgeType>,
|
size?: BadgeSize
|
||||||
default: 'default',
|
href?: string | null
|
||||||
},
|
}
|
||||||
size: {
|
const props = withDefaults(defineProps<IBadgeProps>(), {
|
||||||
type: String as PropType<BadgeSize>,
|
type: 'default',
|
||||||
default: 'xs',
|
size: 'xs',
|
||||||
},
|
href: null,
|
||||||
href: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const slots = useSlots()
|
const slots = useSlots()
|
||||||
const isContentEmpty = computed(() => !slots.default)
|
const isContentEmpty = computed(() => !slots.default)
|
||||||
const wrapperType = computed(() => props.href ? 'a' : 'span')
|
const wrapperType = computed(() => (props.href ? 'a' : 'span'))
|
||||||
|
|
||||||
const { badgeClasses } = useBadgeClasses(toRefs(props), { isContentEmpty })
|
const { badgeClasses } = useBadgeClasses(props, { isContentEmpty })
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,61 +1,65 @@
|
|||||||
import type { BadgeType, BadgeSize } from '../types'
|
import type { BadgeType, BadgeSize } from '../types'
|
||||||
import { computed } from 'vue'
|
import { computed, type Ref, useAttrs } from 'vue'
|
||||||
import type { Ref } from 'vue'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import classNames from 'classnames'
|
|
||||||
|
|
||||||
const defaultBadgeClasses = 'mr-2 px-2.5 py-0.5 rounded flex items-center justify-center'
|
const defaultBadgeClasses = 'mr-2 px-2.5 py-0.5 rounded flex items-center justify-center'
|
||||||
const badgeLinkClasses = 'bg-blue-100 hover:bg-blue-200 text-blue-800 dark:text-blue-800 dark:hover:bg-blue-300'
|
const badgeLinkClasses = 'bg-blue-100 hover:bg-blue-200 text-blue-800 dark:text-blue-800 dark:hover:bg-blue-300'
|
||||||
const onlyIconClasses = 'p-1 rounded-full mr-2'
|
const onlyIconClasses = 'p-1 rounded-full mr-2'
|
||||||
|
|
||||||
const badgeTextClasses: Record<BadgeType, string> = {
|
const badgeTextClasses: Record<BadgeType, string> = {
|
||||||
default: 'text-blue-800 dark:text-blue-800',
|
default: 'text-blue-800 dark:text-blue-800',
|
||||||
dark: 'text-gray-800 dark:bg-gray-700',
|
dark: 'text-gray-800 dark:bg-gray-700',
|
||||||
red: 'text-red-800 dark:text-red-900',
|
red: 'text-red-800 dark:text-red-900',
|
||||||
green: 'text-green-800 dark:text-green-900',
|
green: 'text-green-800 dark:text-green-900',
|
||||||
yellow: 'text-yellow-800 dark:text-yellow-900',
|
yellow: 'text-yellow-800 dark:text-yellow-900',
|
||||||
indigo: 'text-indigo-800 dark:text-indigo-900',
|
indigo: 'text-indigo-800 dark:text-indigo-900',
|
||||||
purple: 'text-purple-800 dark:text-purple-900',
|
purple: 'text-purple-800 dark:text-purple-900',
|
||||||
pink: 'text-pink-800 dark:text-pink-900',
|
pink: 'text-pink-800 dark:text-pink-900',
|
||||||
}
|
}
|
||||||
|
|
||||||
const badgeTypeClasses: Record<BadgeType, string> = {
|
const badgeTypeClasses: Record<BadgeType, string> = {
|
||||||
default: 'bg-blue-100 dark:bg-blue-200',
|
default: 'bg-blue-100 dark:bg-blue-200',
|
||||||
dark: 'bg-gray-100 dark:bg-gray-700',
|
dark: 'bg-gray-100 dark:bg-gray-700',
|
||||||
red: 'bg-red-100 dark:bg-red-200',
|
red: 'bg-red-100 dark:bg-red-200',
|
||||||
green: 'bg-green-100 dark:bg-green-200',
|
green: 'bg-green-100 dark:bg-green-200',
|
||||||
yellow: 'bg-yellow-100 dark:bg-yellow-200',
|
yellow: 'bg-yellow-100 dark:bg-yellow-200',
|
||||||
indigo: 'bg-indigo-100 dark:bg-indigo-200',
|
indigo: 'bg-indigo-100 dark:bg-indigo-200',
|
||||||
purple: 'bg-purple-100 dark:bg-purple-200',
|
purple: 'bg-purple-100 dark:bg-purple-200',
|
||||||
pink: 'bg-pink-100 dark:bg-pink-200',
|
pink: 'bg-pink-100 dark:bg-pink-200',
|
||||||
}
|
}
|
||||||
|
|
||||||
const badgeSizeClasses: Record<BadgeSize, string> = {
|
const badgeSizeClasses: Record<BadgeSize, string> = {
|
||||||
xs: 'text-xs font-semibold',
|
xs: 'text-xs font-semibold',
|
||||||
sm: 'text-sm font-medium',
|
sm: 'text-sm font-medium',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UseBadgeClassesProps = {
|
export type UseBadgeClassesProps = {
|
||||||
type: Ref<BadgeType>
|
type: BadgeType
|
||||||
size: Ref<BadgeSize>
|
size: BadgeSize
|
||||||
href: Ref<string>
|
href: string | null
|
||||||
}
|
}
|
||||||
export type UseBadgeClassesOptions = {
|
export type UseBadgeClassesOptions = {
|
||||||
isContentEmpty: Ref<boolean>
|
isContentEmpty: Ref<boolean>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useBadgeClasses(props: UseBadgeClassesProps, options: UseBadgeClassesOptions): {
|
export function useBadgeClasses(
|
||||||
badgeClasses: Ref<string>
|
props: UseBadgeClassesProps,
|
||||||
|
options: UseBadgeClassesOptions,
|
||||||
|
): {
|
||||||
|
badgeClasses: Ref<string>
|
||||||
} {
|
} {
|
||||||
const badgeClasses = computed<string>(() => {
|
const attrs = useAttrs()
|
||||||
return classNames(
|
const badgeClasses = computed<string>(() => {
|
||||||
badgeSizeClasses[props.size.value],
|
return twMerge(
|
||||||
props.href.value ? '' : badgeTypeClasses[props.type.value],
|
badgeSizeClasses[props.size],
|
||||||
props.href.value ? '' : badgeTextClasses[props.type.value],
|
props.href ? '' : badgeTypeClasses[props.type],
|
||||||
props.href.value ? badgeLinkClasses : '',
|
props.href ? '' : badgeTextClasses[props.type],
|
||||||
options.isContentEmpty.value ? onlyIconClasses : defaultBadgeClasses,
|
props.href ? badgeLinkClasses : '',
|
||||||
)
|
options.isContentEmpty.value ? onlyIconClasses : defaultBadgeClasses,
|
||||||
})
|
attrs.class as string,
|
||||||
return {
|
)
|
||||||
badgeClasses,
|
})
|
||||||
}
|
return {
|
||||||
|
badgeClasses,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user