Files
ComfyUI_frontend/src/platform/assets/components/AssetCard.stories.ts
Alexander Brown 471ccca1dd Style: Design System use across more components (#6705)
## Summary

Only remaining use is in `buttonTypes.ts` which @viva-jinyi is going to
be working on to consolidate our different buttons soon.

## Changes

- **What**: Replace light/dark colors with theme aware design system
tokens.

## Review Focus

Double check the chosen colors for the components

## Screenshots

| Before | After |
| ------ | ----- |
| <img width="607" height="432" alt="image"
src="https://github.com/user-attachments/assets/6c0ee6d6-819f-40b1-b775-f8b25dd18104"
/> | <img width="646" height="488" alt="image"
src="https://github.com/user-attachments/assets/9c8532de-8ac6-4b48-9021-3fd0b3e0bc63"
/> |

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6705-Style-WIP-Design-System-use-across-more-components-2ab6d73d365081619115fc5f87a46341)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
2025-11-17 12:27:10 -08:00

222 lines
5.5 KiB
TypeScript

import type { Meta, StoryObj } from '@storybook/vue3-vite'
import AssetCard from '@/platform/assets/components/AssetCard.vue'
import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser'
import { mockAssets } from '@/platform/assets/fixtures/ui-mock-assets'
// Use the first mock asset as base and transform it to display format
const baseAsset = mockAssets[0]
const createAssetData = (
overrides: Partial<AssetDisplayItem> = {}
): AssetDisplayItem => ({
...baseAsset,
description:
'High-quality realistic images with perfect detail and natural lighting effects for professional photography',
badges: [
{ label: 'checkpoints', type: 'type' },
{ label: '2.1 GB', type: 'size' }
],
stats: {
formattedDate: '3/15/25',
downloadCount: '1.8k',
stars: '4.2k'
},
...overrides
})
const meta: Meta<typeof AssetCard> = {
title: 'Platform/Assets/AssetCard',
component: AssetCard,
parameters: {
layout: 'centered'
},
decorators: [
() => ({
template: '<div class="p-8 bg-base-background"><story /></div>'
})
]
}
export default meta
type Story = StoryObj<typeof meta>
export const Interactive: Story = {
args: {
asset: createAssetData(),
interactive: true
},
decorators: [
() => ({
template: '<div class="p-8 bg-base-background max-w-96"><story /></div>'
})
],
parameters: {
docs: {
description: {
story:
'Default AssetCard with complete data including badges and all stats.'
}
}
}
}
export const NonInteractive: Story = {
args: {
asset: createAssetData(),
interactive: false
},
decorators: [
() => ({
template: '<div class="p-8 bg-base-background max-w-96"><story /></div>'
})
],
parameters: {
docs: {
description: {
story:
'AssetCard in non-interactive mode - renders as div without button semantics.'
}
}
}
}
export const WithPreviewImage: Story = {
args: {
asset: createAssetData({
preview_url: '/assets/images/comfy-logo-single.svg'
}),
interactive: true
},
decorators: [
() => ({
template: '<div class="p-8 bg-base-background max-w-96"><story /></div>'
})
],
parameters: {
docs: {
description: {
story: 'AssetCard with a preview image displayed.'
}
}
}
}
export const FallbackGradient: Story = {
args: {
asset: createAssetData({
preview_url: undefined
}),
interactive: true
},
decorators: [
() => ({
template: '<div class="p-8 bg-base-background max-w-96"><story /></div>'
})
],
parameters: {
docs: {
description: {
story:
'AssetCard showing fallback gradient when no preview image is available.'
}
}
}
}
export const EdgeCases: Story = {
render: () => ({
components: { AssetCard },
setup() {
const edgeCases = [
// Default case for comparison
createAssetData({
name: 'Complete Data',
description: 'Asset with all data present for comparison'
}),
// No badges
createAssetData({
id: 'no-badges',
name: 'No Badges',
description: 'Testing graceful handling when badges are not provided',
badges: []
}),
// No stars
createAssetData({
id: 'no-stars',
name: 'No Stars',
description: 'Testing missing stars data gracefully',
stats: {
downloadCount: '1.8k',
formattedDate: '3/15/25'
}
}),
// No downloads
createAssetData({
id: 'no-downloads',
name: 'No Downloads',
description: 'Testing missing downloads data gracefully',
stats: {
stars: '4.2k',
formattedDate: '3/15/25'
}
}),
// No date
createAssetData({
id: 'no-date',
name: 'No Date',
description: 'Testing missing date data gracefully',
stats: {
stars: '4.2k',
downloadCount: '1.8k'
}
}),
// No stats at all
createAssetData({
id: 'no-stats',
name: 'No Stats',
description: 'Testing when all stats are missing',
stats: {}
}),
// Long description
createAssetData({
id: 'long-desc',
name: 'Long Description',
description:
'This is a very long description that should demonstrate how the component handles text overflow and truncation with ellipsis. The description continues with even more content to ensure we test the 2-line clamp behavior properly and see how it renders when there is significantly more text than can fit in the allocated space.'
}),
// Minimal data
createAssetData({
id: 'minimal',
name: 'Minimal',
description: 'Basic model',
tags: ['models'],
badges: [],
stats: {}
})
]
return { edgeCases }
},
template: `
<div class="grid grid-cols-4 gap-6 p-8 bg-base-background">
<AssetCard
v-for="asset in edgeCases"
:key="asset.id"
:asset="asset"
:interactive="true"
@select="(asset) => console.log('Selected:', asset)"
/>
</div>
`
}),
parameters: {
layout: 'fullscreen',
docs: {
description: {
story:
'All AssetCard edge cases in a grid layout to test graceful handling of missing data, badges, stats, and long descriptions.'
}
}
}
}