Files
ComfyUI_frontend/src/components/common/WorkflowActionsList.vue
Dante 82242f1b00 refactor: add Badge component and fix twMerge font-size detection (#10580)
## Summary
- Rename `text-xxxs`/`text-xxs` to `text-3xs`/`text-2xs` in design
system CSS — fixes `tailwind-merge` incorrectly classifying custom
font-size utilities as color classes, which clobbered text color
- Add `Badge` component with updated severity colors matching Figma
design (white text on colored backgrounds)
- Add Badge stories under `Components/Badges/Badge`
- Add unit tests including twMerge regression coverage

Split from #10438 per review feedback — this PR contains the
foundational Badge component; migration of consumers follows in a
separate PR.

## Test plan
- [x] Unit tests pass (`Badge.test.ts` — 12 tests)
- [x] Typecheck passes
- [x] Lint passes
- [ ] Verify Badge stories render correctly in Storybook
- [ ] Verify existing components using `text-2xs`/`text-3xs` render
unchanged

Fixes #10438 (partial)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10580-refactor-add-Badge-component-and-fix-twMerge-font-size-detection-32f6d73d3650810dae7cd0d4af67fd1c)
by [Unito](https://www.unito.io)
2026-03-27 19:23:59 -07:00

54 lines
1.7 KiB
Vue

<script setup lang="ts">
import { DropdownMenuItem, DropdownMenuSeparator } from 'reka-ui'
import type { Component } from 'vue'
import OverlayIcon from '@/components/common/OverlayIcon.vue'
import type { WorkflowMenuItem } from '@/types/workflowMenuItem'
import { cn } from '@/utils/tailwindUtil'
const {
items,
itemComponent = DropdownMenuItem,
separatorComponent = DropdownMenuSeparator
} = defineProps<{
items: WorkflowMenuItem[]
itemComponent?: Component
separatorComponent?: Component
}>()
</script>
<template>
<template v-for="(item, index) in items" :key="index">
<component
:is="separatorComponent"
v-if="item.separator"
class="my-1 w-full border-b border-border-subtle"
/>
<component
:is="itemComponent"
v-else-if="item.visible !== false"
:disabled="item.disabled"
:class="
cn(
'flex min-h-6 items-center gap-2 self-stretch rounded-sm p-2 outline-none',
!item.disabled && item.command && 'cursor-pointer',
'data-highlighted:bg-secondary-background-hover',
!item.disabled && 'hover:bg-secondary-background-hover',
'data-disabled:cursor-default data-disabled:opacity-50'
)
"
@select="() => item.command?.()"
>
<OverlayIcon v-if="item.overlayIcon" v-bind="item.overlayIcon" />
<i v-else-if="item.icon" :class="item.icon" />
<span class="flex-1">{{ item.label }}</span>
<span
v-if="item.badge"
class="ml-3 flex items-center gap-1 rounded-full bg-(--primary-background) px-1.5 py-0.5 text-2xs text-base-foreground uppercase"
>
{{ item.badge }}
</span>
</component>
</template>
</template>