Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7be97b3
[feat] Add Storybook setup and NodePreview story
snomiao Aug 9, 2025
308b3cd
[feat] Improve Storybook configuration and setup
snomiao Aug 10, 2025
6244caf
[docs] Add comprehensive Storybook documentation
snomiao Aug 10, 2025
2b86f41
[refactor] Remove ts-expect-error comment from Storybook preview
snomiao Aug 11, 2025
88baf87
[bugfix] Fix TypeScript errors in Load3D components and GLTF test
snomiao Aug 12, 2025
799b760
[feat] Add Chromatic GitHub Action for Storybook visual testing
snomiao Aug 12, 2025
1411481
[docs] Add Chromatic documentation to Storybook README
snomiao Aug 12, 2025
1e93567
chore(chromatic.yaml): restrict push branches to main only for better…
snomiao Aug 12, 2025
ac37a5e
[feat] Rebase branch onto main and update Storybook configuration
snomiao Aug 13, 2025
cd787c5
[bugfix] Fix TypeScript errors in SubgraphNode type checking
snomiao Aug 13, 2025
cf4ab95
fix(vite.config.mts): correct path alias for src directory to ensure …
snomiao Aug 13, 2025
ceec83b
[feat] Remove bun.lock as it's now ignored
snomiao Aug 14, 2025
b2a97ee
[bugfix] Fix Storybook builder require() error by converting main.ts …
snomiao Aug 14, 2025
62747ec
chore(storybook): replace main.mjs with main.ts for improved type saf…
snomiao Aug 15, 2025
205f455
[feat] Optimize Chromatic workflow with automated PR status comments
snomiao Aug 15, 2025
a89b9e8
chore(chromatic.yaml): move permissions section inside the chromatic-…
snomiao Aug 15, 2025
74a83fa
[fix] Resolve Vite CJS deprecation warning in Storybook config
snomiao Aug 15, 2025
171d096
fix(chromatic.yaml): change edit-mode from replace to append to prese…
snomiao Aug 15, 2025
c877223
[fix] Replace __dirname with process.cwd() in Storybook config
snomiao Aug 16, 2025
26dbbb1
feature: storybook-setting (#5088)
viva-jinyi Aug 19, 2025
945e8e9
[feat] Add Storybook configuration and settings panel stories
snomiao Aug 16, 2025
de0130d
[bugfix] Fix TypeScript error in Rectangle.ts - remove invalid generi…
snomiao Aug 16, 2025
8167021
[bugfix] Fix TypeScript error in Rectangle subarray method
snomiao Aug 16, 2025
84ce478
Revert "[bugfix] Fix TypeScript error in Rectangle subarray method"
snomiao Aug 16, 2025
4947da3
Revert "[bugfix] Fix TypeScript error in Rectangle.ts - remove invali…
snomiao Aug 16, 2025
f989b05
[auto-fix] Fix TypeScript error in Rectangle.ts - remove generic type…
snomiao Aug 16, 2025
2cc7ae2
[revert] Remove litegraph infrastructure changes unrelated to PR
snomiao Aug 16, 2025
13a6a20
restore rectangle.ts
snomiao Aug 17, 2025
b9e0186
[merge] Merge origin/main
snomiao Aug 19, 2025
2c9a1f1
Merge remote-tracking branch 'origin/main' into sno-storybook--settin…
snomiao Aug 19, 2025
b388bcc
[feat] Improve Storybook configuration and fix store coupling
snomiao Aug 21, 2025
0f06f75
Merge remote-tracking branch 'origin/main' into sno-storybook--settin…
snomiao Aug 22, 2025
257ca95
Merge remote-tracking branch 'origin/main' into sno-storybook--settin…
snomiao Aug 23, 2025
3b95dac
Merge remote-tracking branch 'origin/main' into sno-storybook--settin…
snomiao Aug 26, 2025
24ce3fa
[fix] Add missing @iconify/tailwind dependency for tests
snomiao Aug 26, 2025
2e2e1aa
Merge origin/main into sno-storybook--settings-panel
snomiao Aug 29, 2025
b5e106e
[fix] Replace non-existent toBeOneOf test assertions with standard to…
snomiao Aug 29, 2025
6acb1b2
Merge branch 'main' into sno-storybook--settings-panel
snomiao Sep 7, 2025
3aec59a
Merge branch 'main' into sno-storybook--settings-panel
snomiao Sep 16, 2025
e930184
Merge branch 'main' into sno-storybook--settings-panel
snomiao Sep 30, 2025
a249d20
fix: Update import path for useSettingStore in Storybook preview
snomiao Sep 30, 2025
d08c408
chore: Remove incomplete story files causing import errors
snomiao Sep 30, 2025
dc5ab71
Merge branch 'main' into sno-storybook--settings-panel
snomiao Oct 1, 2025
6b08839
Merge branch 'main' into sno-storybook--settings-panel
snomiao Oct 2, 2025
af20722
Merge origin/main into sno-storybook--settings-panel
snomiao Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import Tooltip from 'primevue/tooltip'
import '@/assets/css/style.css'
import { i18n } from '@/i18n'
import '@/lib/litegraph/public/css/litegraph.css'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useWidgetStore } from '@/stores/widgetStore'
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'

const ComfyUIPreset = definePreset(Aura, {
semantic: {
Expand All @@ -28,6 +31,122 @@ setup((app) => {
const pinia = createPinia()

app.use(pinia)

// Initialize stores
useColorPaletteStore(pinia)
useWidgetStore(pinia)

// Initialize setting store and mock settings for Storybook
const settingStore = useSettingStore(pinia)

// Initialize setting values manually for Storybook (since loadSettingValues might fail)
settingStore.$patch({
settingValues: {} // Start with empty settings values
})

// Mock common setting definitions for Storybook
const mockSettings = [
{ id: 'Comfy.Locale', name: 'Language', type: 'combo', defaultValue: 'en' },
{
id: 'Comfy.AutoSave',
name: 'Auto Save',
type: 'boolean',
defaultValue: true
},
{
id: 'Comfy.AutoSaveInterval',
name: 'Auto Save Interval',
type: 'number',
defaultValue: 30
},
{
id: 'Comfy.ColorPalette',
name: 'Color Palette',
type: 'combo',
defaultValue: 'dark'
},
{
id: 'Comfy.AccentColor',
name: 'Accent Color',
type: 'color',
defaultValue: '#007bff'
},
{
id: 'Comfy.NodeOpacity',
name: 'Node Opacity',
type: 'slider',
defaultValue: 80
},
{
id: 'Comfy.MaxConcurrentTasks',
name: 'Max Concurrent Tasks',
type: 'number',
defaultValue: 4
},
{
id: 'Comfy.EnableGPUAcceleration',
name: 'GPU Acceleration',
type: 'boolean',
defaultValue: true
},
{
id: 'Comfy.CacheSize',
name: 'Cache Size',
type: 'slider',
defaultValue: 512
},
// Mock settings used in stories
{
id: 'test.setting',
name: 'Test Setting',
type: 'boolean',
defaultValue: false
},
{
id: 'mixed.boolean',
name: 'Boolean Setting',
type: 'boolean',
defaultValue: true
},
{
id: 'mixed.text',
name: 'Text Setting',
type: 'text',
defaultValue: 'Default text'
},
{
id: 'mixed.number',
name: 'Number Setting',
type: 'number',
defaultValue: 42
},
{
id: 'mixed.slider',
name: 'Slider Setting',
type: 'slider',
defaultValue: 75
},
{
id: 'mixed.combo',
name: 'Combo Setting',
type: 'combo',
defaultValue: 'option2'
},
{
id: 'mixed.color',
name: 'Color Setting',
type: 'color',
defaultValue: '#ff6b35'
}
]

// Register mock settings
try {
mockSettings.forEach((setting) => settingStore.addSetting(setting as any))
} catch (error) {
console.warn('Failed to add settings, they might already exist:', error)
}

app.use(i18n)
app.use(PrimeVue, {
theme: {
Expand Down
63 changes: 63 additions & 0 deletions src/components/dialog/content/setting/AboutPanel.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { Meta, StoryObj } from '@storybook/vue3-vite'

import AboutPanel from './AboutPanel.vue'

const meta: Meta<typeof AboutPanel> = {
title: 'Components/Setting/AboutPanel',
component: AboutPanel,
parameters: {
layout: 'padded',
docs: {
description: {
component:
'The About panel displays project information, badges, and system statistics.'
}
}
},
decorators: [
() => ({
template:
'<div style="max-width: 600px; min-height: 400px; padding: 16px;"><story /></div>'
})
]
}

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {
args: {},
parameters: {
docs: {
description: {
story:
'The default About panel showing project badges and system information.'
}
}
}
}

export const WithSystemStats: Story = {
args: {},
parameters: {
docs: {
description: {
story: 'About panel with system statistics visible.'
}
}
}
}

export const Mobile: Story = {
args: {},
parameters: {
viewport: {
defaultViewport: 'mobile1'
},
docs: {
description: {
story: 'About panel optimized for mobile devices.'
}
}
}
}
197 changes: 197 additions & 0 deletions src/components/dialog/content/setting/PanelTemplate.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import type { Meta, StoryObj } from '@storybook/vue3-vite'

import PanelTemplate from './PanelTemplate.vue'

const meta: Meta<typeof PanelTemplate> = {
title: 'Components/Setting/PanelTemplate',
component: PanelTemplate,
parameters: {
layout: 'padded',
docs: {
description: {
component:
'A template component for settings panels that provides consistent layout with header, content, and footer slots.'
}
}
},
argTypes: {
value: {
control: 'text',
description: 'The value identifier for the tab panel'
},
class: {
control: 'text',
description: 'Additional CSS classes to apply'
}
},
decorators: [
() => ({
template:
'<div style="width: 600px; height: 400px; border: 1px solid #ddd;"><story /></div>'
})
]
}

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {
args: {
value: 'example-panel'
},
render: (args) => ({
components: { PanelTemplate },
setup() {
return { args }
},
template: `
<PanelTemplate v-bind="args">
<div class="p-4">
<h3 class="text-lg font-semibold mb-4">Panel Content</h3>
<p class="mb-4">This is the main content area of the panel.</p>
<div class="space-y-2">
<div class="p-2 bg-gray-100 rounded">Setting Item 1</div>
<div class="p-2 bg-gray-100 rounded">Setting Item 2</div>
<div class="p-2 bg-gray-100 rounded">Setting Item 3</div>
</div>
</div>
</PanelTemplate>
`
})
}

export const WithHeader: Story = {
args: {
value: 'header-panel'
},
render: (args) => ({
components: { PanelTemplate },
setup() {
return { args }
},
template: `
<PanelTemplate v-bind="args">
<template #header>
<div class="p-3 bg-blue-50 border border-blue-200 rounded mb-4">
<h4 class="text-blue-800 font-medium">Panel Header</h4>
<p class="text-blue-600 text-sm">This is a header message for the panel.</p>
</div>
</template>
<div class="p-4">
<h3 class="text-lg font-semibold mb-4">Panel Content</h3>
<p>Content with a header message above.</p>
</div>
</PanelTemplate>
`
})
}

export const WithFooter: Story = {
args: {
value: 'footer-panel'
},
render: (args) => ({
components: { PanelTemplate },
setup() {
return { args }
},
template: `
<PanelTemplate v-bind="args">
<div class="p-4">
<h3 class="text-lg font-semibold mb-4">Panel Content</h3>
<p>Content with a footer below.</p>
</div>
<template #footer>
<div class="p-3 bg-gray-50 border-t">
<div class="flex justify-end space-x-2">
<button class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600">
Cancel
</button>
<button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
Save
</button>
</div>
</div>
</template>
</PanelTemplate>
`
})
}

export const WithHeaderAndFooter: Story = {
args: {
value: 'full-panel'
},
render: (args) => ({
components: { PanelTemplate },
setup() {
return { args }
},
template: `
<PanelTemplate v-bind="args">
<template #header>
<div class="p-3 bg-green-50 border border-green-200 rounded mb-4">
<h4 class="text-green-800 font-medium">Important Notice</h4>
<p class="text-green-600 text-sm">Please review all settings before saving.</p>
</div>
</template>
<div class="p-4">
<h3 class="text-lg font-semibold mb-4">Settings Content</h3>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium mb-1">Setting 1</label>
<input type="text" class="w-full p-2 border rounded" value="Default value" />
</div>
<div>
<label class="block text-sm font-medium mb-1">Setting 2</label>
<select class="w-full p-2 border rounded">
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
</div>
</div>
<template #footer>
<div class="p-3 bg-gray-50 border-t">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Changes will be saved automatically</span>
<button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
Apply Changes
</button>
</div>
</div>
</template>
</PanelTemplate>
`
})
}

export const LongContent: Story = {
args: {
value: 'long-panel'
},
render: (args) => ({
components: { PanelTemplate },
setup() {
return { args }
},
template: `
<PanelTemplate v-bind="args">
<div class="p-4">
<h3 class="text-lg font-semibold mb-4">Scrollable Content</h3>
<div class="space-y-4">
${Array.from(
{ length: 20 },
(_, i) => `
<div class="p-3 bg-gray-100 rounded">
<h4 class="font-medium">Setting Group ${i + 1}</h4>
<p class="text-sm text-gray-600">This is setting group ${i + 1} with some description text.</p>
</div>
`
).join('')}
</div>
</div>
</PanelTemplate>
`
})
}