Hwandji's picture
feat: initial HuggingFace Space deployment
4343907
raw
history blame
4.32 kB
<template>
<span :class="badgeClasses" v-bind="$attrs">
<!-- Dot indicator -->
<span v-if="dot" class="saap-badge__dot" aria-hidden="true" />
<!-- Icon -->
<component
v-if="icon"
:is="iconComponent"
class="saap-badge__icon"
aria-hidden="true"
/>
<!-- Content -->
<span class="saap-badge__content">
<slot />
</span>
</span>
</template>
<script setup lang="ts">
import { computed, defineProps, withDefaults } from 'vue'
import type { BadgeProps } from '@/types'
interface Props extends BadgeProps {
icon?: string
}
const props = withDefaults(defineProps<Props>(), {
variant: 'neutral',
size: 'md',
dot: false,
outline: false
})
// Computed
const badgeClasses = computed(() => [
'saap-badge',
`saap-badge--${props.variant}`,
`saap-badge--${props.size}`,
{
'saap-badge--outline': props.outline,
'saap-badge--with-dot': props.dot,
'saap-badge--with-icon': props.icon
}
])
const iconComponent = computed(() => {
if (props.icon) {
return resolveIconComponent(props.icon)
}
return null
})
// Methods
function resolveIconComponent(iconName: string) {
try {
return () => import(`lucide-vue-next/dist/esm/icons/${iconName}.js`)
} catch {
return null
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/mixins.scss';
.saap-badge {
@include badge-base;
// Variants - Solid
&--success:not(&--outline) {
@include badge-success;
}
&--warning:not(&--outline) {
@include badge-warning;
}
&--error:not(&--outline) {
@include badge-error;
}
&--info:not(&--outline) {
@include badge-info;
}
&--neutral:not(&--outline) {
background: var(--saap-neutral-200);
color: var(--saap-neutral-800);
}
// Variants - Outline
&--success#{&--outline} {
background: transparent;
color: var(--saap-success);
border: 1px solid var(--saap-success);
}
&--warning#{&--outline} {
background: transparent;
color: var(--saap-warning);
border: 1px solid var(--saap-warning);
}
&--error#{&--outline} {
background: transparent;
color: var(--saap-error);
border: 1px solid var(--saap-error);
}
&--info#{&--outline} {
background: transparent;
color: var(--saap-info);
border: 1px solid var(--saap-info);
}
&--neutral#{&--outline} {
background: transparent;
color: var(--saap-neutral-600);
border: 1px solid var(--saap-neutral-300);
}
// Sizes
&--sm {
padding: var(--saap-space-1) var(--saap-space-2);
font-size: 0.625rem; // 10px
gap: var(--saap-space-1);
}
&--md {
padding: var(--saap-space-1) var(--saap-space-3);
font-size: var(--saap-text-xs);
gap: var(--saap-space-1);
}
&--lg {
padding: var(--saap-space-2) var(--saap-space-4);
font-size: var(--saap-text-sm);
gap: var(--saap-space-2);
}
}
.saap-badge__dot {
width: 0.375rem; // 6px
height: 0.375rem;
border-radius: 50%;
background: currentColor;
flex-shrink: 0;
.saap-badge--sm & {
width: 0.25rem; // 4px
height: 0.25rem;
}
.saap-badge--lg & {
width: 0.5rem; // 8px
height: 0.5rem;
}
}
.saap-badge__icon {
width: 0.75rem; // 12px
height: 0.75rem;
flex-shrink: 0;
.saap-badge--sm & {
width: 0.625rem; // 10px
height: 0.625rem;
}
.saap-badge--lg & {
width: 1rem; // 16px
height: 1rem;
}
}
.saap-badge__content {
line-height: 1;
}
// Special agent status badges
.saap-badge {
&--agent-active {
background: var(--saap-success);
color: white;
}
&--agent-inactive {
background: var(--saap-neutral-400);
color: white;
}
&--agent-processing {
background: var(--saap-warning);
color: white;
&::after {
content: '';
display: inline-block;
width: 0.5rem;
height: 0.5rem;
margin-left: var(--saap-space-1);
border: 1px solid currentColor;
border-top-color: transparent;
border-radius: 50%;
animation: spin 1s linear infinite;
}
}
&--agent-error {
background: var(--saap-error);
color: white;
}
&--agent-idle {
background: var(--saap-neutral-500);
color: white;
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>