mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-27 01:39:47 +00:00
[backport cloud/1.37] feat(StatusBadge): add dot mode with CVA variants (#8231)
Backport of #8202 to `cloud/1.37` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8231-backport-cloud-1-37-feat-StatusBadge-add-dot-mode-with-CVA-variants-2f06d73d365081438b3ee0121ef4f239) by [Unito](https://www.unito.io) Co-authored-by: Alexander Brown <drjkl@comfy.org> Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
95
src/components/common/StatusBadge.stories.ts
Normal file
95
src/components/common/StatusBadge.stories.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||||
|
|
||||||
|
import StatusBadge from './StatusBadge.vue'
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Common/StatusBadge',
|
||||||
|
component: StatusBadge,
|
||||||
|
tags: ['autodocs'],
|
||||||
|
argTypes: {
|
||||||
|
label: { control: 'text' },
|
||||||
|
severity: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['default', 'secondary', 'warn', 'danger', 'contrast']
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['label', 'dot', 'circle']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
label: 'Status',
|
||||||
|
severity: 'default'
|
||||||
|
}
|
||||||
|
} satisfies Meta<typeof StatusBadge>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
export const Default: Story = {}
|
||||||
|
|
||||||
|
export const Failed: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Failed',
|
||||||
|
severity: 'danger'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Finished: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Finished',
|
||||||
|
severity: 'contrast'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Dot: Story = {
|
||||||
|
args: {
|
||||||
|
label: undefined,
|
||||||
|
variant: 'dot',
|
||||||
|
severity: 'danger'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Circle: Story = {
|
||||||
|
args: {
|
||||||
|
label: '3',
|
||||||
|
variant: 'circle'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AllSeverities: Story = {
|
||||||
|
render: () => ({
|
||||||
|
components: { StatusBadge },
|
||||||
|
template: `
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<StatusBadge label="Default" severity="default" />
|
||||||
|
<StatusBadge label="Secondary" severity="secondary" />
|
||||||
|
<StatusBadge label="Warn" severity="warn" />
|
||||||
|
<StatusBadge label="Danger" severity="danger" />
|
||||||
|
<StatusBadge label="Contrast" severity="contrast" />
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AllVariants: Story = {
|
||||||
|
render: () => ({
|
||||||
|
components: { StatusBadge },
|
||||||
|
template: `
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<div class="flex flex-col items-center gap-1">
|
||||||
|
<StatusBadge label="Label" variant="label" />
|
||||||
|
<span class="text-xs text-muted">label</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col items-center gap-1">
|
||||||
|
<StatusBadge variant="dot" severity="danger" />
|
||||||
|
<span class="text-xs text-muted">dot</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col items-center gap-1">
|
||||||
|
<StatusBadge label="5" variant="circle" />
|
||||||
|
<span class="text-xs text-muted">circle</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,30 +1,27 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
type Severity = 'default' | 'secondary' | 'warn' | 'danger' | 'contrast'
|
import { statusBadgeVariants } from './statusBadge.variants'
|
||||||
|
import type { StatusBadgeVariants } from './statusBadge.variants'
|
||||||
|
|
||||||
const { label, severity = 'default' } = defineProps<{
|
const {
|
||||||
label: string
|
label,
|
||||||
severity?: Severity
|
severity = 'default',
|
||||||
|
variant
|
||||||
|
} = defineProps<{
|
||||||
|
label?: string | number
|
||||||
|
severity?: StatusBadgeVariants['severity']
|
||||||
|
variant?: StatusBadgeVariants['variant']
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
function badgeClasses(sev: Severity): string {
|
|
||||||
const baseClasses =
|
|
||||||
'inline-flex h-3.5 items-center justify-center rounded-full px-1 text-xxxs font-semibold uppercase'
|
|
||||||
|
|
||||||
switch (sev) {
|
|
||||||
case 'danger':
|
|
||||||
return `${baseClasses} bg-destructive-background text-white`
|
|
||||||
case 'contrast':
|
|
||||||
return `${baseClasses} bg-base-foreground text-base-background`
|
|
||||||
case 'warn':
|
|
||||||
return `${baseClasses} bg-warning-background text-base-background`
|
|
||||||
case 'secondary':
|
|
||||||
return `${baseClasses} bg-secondary-background text-base-foreground`
|
|
||||||
default:
|
|
||||||
return `${baseClasses} bg-primary-background text-base-foreground`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<span :class="badgeClasses(severity)">{{ label }}</span>
|
<span
|
||||||
|
:class="
|
||||||
|
statusBadgeVariants({
|
||||||
|
severity,
|
||||||
|
variant: variant ?? (label == null ? 'dot' : 'label')
|
||||||
|
})
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
26
src/components/common/statusBadge.variants.ts
Normal file
26
src/components/common/statusBadge.variants.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import type { VariantProps } from 'cva'
|
||||||
|
import { cva } from 'cva'
|
||||||
|
|
||||||
|
export const statusBadgeVariants = cva({
|
||||||
|
base: 'inline-flex items-center justify-center rounded-full',
|
||||||
|
variants: {
|
||||||
|
severity: {
|
||||||
|
default: 'bg-primary-background text-base-foreground',
|
||||||
|
secondary: 'bg-secondary-background text-base-foreground',
|
||||||
|
warn: 'bg-warning-background text-base-background',
|
||||||
|
danger: 'bg-destructive-background text-white',
|
||||||
|
contrast: 'bg-base-foreground text-base-background'
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
label: 'h-3.5 px-1 text-xxxs font-semibold uppercase',
|
||||||
|
dot: 'size-2',
|
||||||
|
circle: 'size-3.5 text-xxxs font-semibold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
severity: 'default',
|
||||||
|
variant: 'label'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export type StatusBadgeVariants = VariantProps<typeof statusBadgeVariants>
|
||||||
Reference in New Issue
Block a user