mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-06 21:50:05 +00:00
[feat] Add Storybook configuration and settings panel stories
- Set up Storybook 9.1.2 with Vue 3, PrimeVue, and Tailwind CSS support - Created comprehensive stories for settings panel components: - SettingItem: Various input types (boolean, text, number, slider, combo, color) - SettingGroup: Grouped settings with dividers and different categories - SettingsPanel: Multiple setting groups and empty states - PanelTemplate: Reusable panel layout with header/footer slots - AboutPanel: System information and project badges - SettingDialogContent: Complete dialog with responsive layouts - Updated TypeScript configuration to include Storybook files 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
108
src/components/dialog/content/SettingDialogContent.stories.ts
Normal file
108
src/components/dialog/content/SettingDialogContent.stories.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
|
||||
import SettingDialogContent from './SettingDialogContent.vue'
|
||||
|
||||
const meta: Meta<typeof SettingDialogContent> = {
|
||||
title: 'Components/Dialog/SettingDialogContent',
|
||||
component: SettingDialogContent,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
'The complete settings dialog content with sidebar navigation and tabbed panels.'
|
||||
}
|
||||
}
|
||||
},
|
||||
argTypes: {
|
||||
defaultPanel: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'about',
|
||||
'keybinding',
|
||||
'extension',
|
||||
'server-config',
|
||||
'user',
|
||||
'credits'
|
||||
],
|
||||
description: 'The default panel to show when the dialog opens'
|
||||
}
|
||||
},
|
||||
decorators: [
|
||||
() => ({
|
||||
template:
|
||||
'<div style="width: 100vw; height: 100vh; padding: 20px; background: #f5f5f5;"><story /></div>'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {}
|
||||
}
|
||||
|
||||
export const AboutPanel: Story = {
|
||||
args: {
|
||||
defaultPanel: 'about'
|
||||
}
|
||||
}
|
||||
|
||||
export const KeybindingPanel: Story = {
|
||||
args: {
|
||||
defaultPanel: 'keybinding'
|
||||
}
|
||||
}
|
||||
|
||||
export const ExtensionPanel: Story = {
|
||||
args: {
|
||||
defaultPanel: 'extension'
|
||||
}
|
||||
}
|
||||
|
||||
export const ServerConfigPanel: Story = {
|
||||
args: {
|
||||
defaultPanel: 'server-config'
|
||||
}
|
||||
}
|
||||
|
||||
export const UserPanel: Story = {
|
||||
args: {
|
||||
defaultPanel: 'user'
|
||||
}
|
||||
}
|
||||
|
||||
export const CreditsPanel: Story = {
|
||||
args: {
|
||||
defaultPanel: 'credits'
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive variants
|
||||
export const Mobile: Story = {
|
||||
args: {},
|
||||
parameters: {
|
||||
viewport: {
|
||||
defaultViewport: 'mobile1'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const Tablet: Story = {
|
||||
args: {},
|
||||
parameters: {
|
||||
viewport: {
|
||||
defaultViewport: 'tablet'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const Desktop: Story = {
|
||||
args: {},
|
||||
parameters: {
|
||||
viewport: {
|
||||
defaultViewport: 'desktop'
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/components/dialog/content/setting/AboutPanel.stories.ts
Normal file
63
src/components/dialog/content/setting/AboutPanel.stories.ts
Normal file
@@ -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
src/components/dialog/content/setting/PanelTemplate.stories.ts
Normal file
197
src/components/dialog/content/setting/PanelTemplate.stories.ts
Normal file
@@ -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>
|
||||
`
|
||||
})
|
||||
}
|
||||
150
src/components/dialog/content/setting/SettingGroup.stories.ts
Normal file
150
src/components/dialog/content/setting/SettingGroup.stories.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
|
||||
import type { SettingParams } from '@/types/settingTypes'
|
||||
|
||||
import SettingGroup from './SettingGroup.vue'
|
||||
|
||||
const meta: Meta<typeof SettingGroup> = {
|
||||
title: 'Components/Setting/SettingGroup',
|
||||
component: SettingGroup,
|
||||
parameters: {
|
||||
layout: 'padded'
|
||||
},
|
||||
argTypes: {
|
||||
group: {
|
||||
control: 'object',
|
||||
description: 'The setting group configuration'
|
||||
},
|
||||
divider: {
|
||||
control: 'boolean',
|
||||
description: 'Show divider above the group'
|
||||
}
|
||||
},
|
||||
decorators: [
|
||||
() => ({
|
||||
template: '<div style="max-width: 500px; padding: 16px;"><story /></div>'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
const createMockSetting = (
|
||||
overrides: Partial<SettingParams> = {}
|
||||
): SettingParams => ({
|
||||
id: 'test.setting' as any,
|
||||
name: 'Test Setting',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
...overrides
|
||||
})
|
||||
|
||||
export const BasicGroup: Story = {
|
||||
args: {
|
||||
group: {
|
||||
label: 'Basic Settings',
|
||||
settings: [
|
||||
createMockSetting({
|
||||
id: 'basic.enable' as any,
|
||||
name: 'Enable Feature',
|
||||
type: 'boolean',
|
||||
defaultValue: true,
|
||||
tooltip: 'Enable or disable this feature'
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'basic.name' as any,
|
||||
name: 'Display Name',
|
||||
type: 'text',
|
||||
defaultValue: 'My App',
|
||||
tooltip: 'The name to display in the title bar'
|
||||
})
|
||||
]
|
||||
},
|
||||
divider: false
|
||||
}
|
||||
}
|
||||
|
||||
export const GroupWithDivider: Story = {
|
||||
args: {
|
||||
group: {
|
||||
label: 'Advanced Settings',
|
||||
settings: [
|
||||
createMockSetting({
|
||||
id: 'advanced.debug' as any,
|
||||
name: 'Debug Mode',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
experimental: true,
|
||||
tooltip: 'Enable debug logging and developer tools'
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'advanced.timeout' as any,
|
||||
name: 'Request Timeout (ms)',
|
||||
type: 'number',
|
||||
defaultValue: 5000,
|
||||
tooltip: 'How long to wait for requests',
|
||||
attrs: {
|
||||
min: 1000,
|
||||
max: 30000,
|
||||
step: 500
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
divider: true
|
||||
}
|
||||
}
|
||||
|
||||
export const PerformanceGroup: Story = {
|
||||
args: {
|
||||
group: {
|
||||
label: 'Performance',
|
||||
settings: [
|
||||
createMockSetting({
|
||||
id: 'perf.threads' as any,
|
||||
name: 'Worker Threads',
|
||||
type: 'slider',
|
||||
defaultValue: 4,
|
||||
tooltip: 'Number of worker threads to use',
|
||||
attrs: {
|
||||
min: 1,
|
||||
max: 16,
|
||||
step: 1
|
||||
}
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'perf.quality' as any,
|
||||
name: 'Render Quality',
|
||||
type: 'combo',
|
||||
defaultValue: 'high',
|
||||
tooltip: 'Rendering quality level',
|
||||
options: [
|
||||
{ text: 'Low', value: 'low' },
|
||||
{ text: 'Medium', value: 'medium' },
|
||||
{ text: 'High', value: 'high' },
|
||||
{ text: 'Ultra', value: 'ultra' }
|
||||
]
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'perf.vsync' as any,
|
||||
name: 'V-Sync',
|
||||
type: 'boolean',
|
||||
defaultValue: true,
|
||||
tooltip: 'Enable vertical synchronization'
|
||||
})
|
||||
]
|
||||
},
|
||||
divider: false
|
||||
}
|
||||
}
|
||||
|
||||
export const EmptyGroup: Story = {
|
||||
args: {
|
||||
group: {
|
||||
label: 'Empty Group',
|
||||
settings: []
|
||||
},
|
||||
divider: false
|
||||
}
|
||||
}
|
||||
159
src/components/dialog/content/setting/SettingItem.stories.ts
Normal file
159
src/components/dialog/content/setting/SettingItem.stories.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
|
||||
import type { SettingParams } from '@/types/settingTypes'
|
||||
|
||||
import SettingItem from './SettingItem.vue'
|
||||
|
||||
const meta: Meta<typeof SettingItem> = {
|
||||
title: 'Components/Setting/SettingItem',
|
||||
component: SettingItem,
|
||||
parameters: {
|
||||
layout: 'padded'
|
||||
},
|
||||
argTypes: {
|
||||
setting: {
|
||||
control: 'object',
|
||||
description: 'The setting configuration object'
|
||||
}
|
||||
},
|
||||
decorators: [
|
||||
() => ({
|
||||
template: '<div style="max-width: 500px; padding: 16px;"><story /></div>'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
const createMockSetting = (
|
||||
overrides: Partial<SettingParams> = {}
|
||||
): SettingParams => ({
|
||||
id: 'test.setting' as any,
|
||||
name: 'Test Setting',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
tooltip: 'This is a test setting for demonstration purposes',
|
||||
...overrides
|
||||
})
|
||||
|
||||
export const BooleanSetting: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'Enable Feature',
|
||||
type: 'boolean',
|
||||
defaultValue: true,
|
||||
tooltip: 'Toggle this feature on or off'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const TextSetting: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'API Endpoint',
|
||||
type: 'text',
|
||||
defaultValue: 'https://api.example.com',
|
||||
tooltip: 'The API endpoint to connect to'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const NumberSetting: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'Max Connections',
|
||||
type: 'number',
|
||||
defaultValue: 10,
|
||||
tooltip: 'Maximum number of concurrent connections',
|
||||
attrs: {
|
||||
min: 1,
|
||||
max: 100,
|
||||
step: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const SliderSetting: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'Volume Level',
|
||||
type: 'slider',
|
||||
defaultValue: 50,
|
||||
tooltip: 'Adjust the volume level',
|
||||
attrs: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 5
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const ComboSetting: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'Theme',
|
||||
type: 'combo',
|
||||
defaultValue: 'dark',
|
||||
tooltip: 'Select your preferred theme',
|
||||
options: [
|
||||
{ text: 'Light', value: 'light' },
|
||||
{ text: 'Dark', value: 'dark' },
|
||||
{ text: 'Auto', value: 'auto' }
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const ColorSetting: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'Accent Color',
|
||||
type: 'color',
|
||||
defaultValue: '#007bff',
|
||||
tooltip: 'Choose your accent color'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const ExperimentalSetting: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'Experimental Feature',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
experimental: true,
|
||||
tooltip: 'This feature is experimental and may change'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const WithLanguageTag: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
id: 'Comfy.Locale' as any,
|
||||
name: 'Language',
|
||||
type: 'combo',
|
||||
defaultValue: 'en',
|
||||
tooltip: 'Select your preferred language',
|
||||
options: [
|
||||
{ text: 'English', value: 'en' },
|
||||
{ text: 'Spanish', value: 'es' },
|
||||
{ text: 'French', value: 'fr' }
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const InteractiveBoolean: Story = {
|
||||
args: {
|
||||
setting: createMockSetting({
|
||||
name: 'Interactive Boolean',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
tooltip: 'Click to toggle this setting'
|
||||
})
|
||||
}
|
||||
}
|
||||
238
src/components/dialog/content/setting/SettingsPanel.stories.ts
Normal file
238
src/components/dialog/content/setting/SettingsPanel.stories.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
|
||||
import type { ISettingGroup, SettingParams } from '@/types/settingTypes'
|
||||
|
||||
import SettingsPanel from './SettingsPanel.vue'
|
||||
|
||||
const meta: Meta<typeof SettingsPanel> = {
|
||||
title: 'Components/Setting/SettingsPanel',
|
||||
component: SettingsPanel,
|
||||
parameters: {
|
||||
layout: 'padded'
|
||||
},
|
||||
argTypes: {
|
||||
settingGroups: {
|
||||
control: 'object',
|
||||
description: 'Array of setting groups to display'
|
||||
}
|
||||
},
|
||||
decorators: [
|
||||
() => ({
|
||||
template: '<div style="max-width: 600px; padding: 16px;"><story /></div>'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
const createMockSetting = (
|
||||
overrides: Partial<SettingParams> = {}
|
||||
): SettingParams => ({
|
||||
id: 'test.setting' as any,
|
||||
name: 'Test Setting',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
...overrides
|
||||
})
|
||||
|
||||
const mockGeneralSettings: ISettingGroup = {
|
||||
label: 'General',
|
||||
settings: [
|
||||
createMockSetting({
|
||||
id: 'Comfy.Locale' as any,
|
||||
name: 'Language',
|
||||
type: 'combo',
|
||||
defaultValue: 'en',
|
||||
tooltip: 'Select your preferred language',
|
||||
options: [
|
||||
{ text: 'English', value: 'en' },
|
||||
{ text: 'Spanish', value: 'es' },
|
||||
{ text: 'French', value: 'fr' },
|
||||
{ text: 'German', value: 'de' }
|
||||
]
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'Comfy.AutoSave' as any,
|
||||
name: 'Auto Save',
|
||||
type: 'boolean',
|
||||
defaultValue: true,
|
||||
tooltip: 'Automatically save your work'
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'Comfy.AutoSaveInterval' as any,
|
||||
name: 'Auto Save Interval (seconds)',
|
||||
type: 'number',
|
||||
defaultValue: 30,
|
||||
tooltip: 'How often to auto save in seconds',
|
||||
attrs: {
|
||||
min: 10,
|
||||
max: 300,
|
||||
step: 5
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
const mockAppearanceSettings: ISettingGroup = {
|
||||
label: 'Appearance',
|
||||
settings: [
|
||||
createMockSetting({
|
||||
id: 'Comfy.ColorPalette' as any,
|
||||
name: 'Color Palette',
|
||||
type: 'combo',
|
||||
defaultValue: 'dark',
|
||||
tooltip: 'Choose your color theme',
|
||||
options: [
|
||||
{ text: 'Dark', value: 'dark' },
|
||||
{ text: 'Light', value: 'light' },
|
||||
{ text: 'Arc', value: 'arc' },
|
||||
{ text: 'Nord', value: 'nord' }
|
||||
]
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'Comfy.AccentColor' as any,
|
||||
name: 'Accent Color',
|
||||
type: 'color',
|
||||
defaultValue: '#007bff',
|
||||
tooltip: 'Choose your accent color'
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'Comfy.NodeOpacity' as any,
|
||||
name: 'Node Opacity',
|
||||
type: 'slider',
|
||||
defaultValue: 80,
|
||||
tooltip: 'Adjust node transparency',
|
||||
attrs: {
|
||||
min: 10,
|
||||
max: 100,
|
||||
step: 10
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
const mockPerformanceSettings: ISettingGroup = {
|
||||
label: 'Performance',
|
||||
settings: [
|
||||
createMockSetting({
|
||||
id: 'Comfy.MaxConcurrentTasks' as any,
|
||||
name: 'Max Concurrent Tasks',
|
||||
type: 'number',
|
||||
defaultValue: 4,
|
||||
tooltip: 'Maximum number of tasks to run simultaneously',
|
||||
attrs: {
|
||||
min: 1,
|
||||
max: 16
|
||||
}
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'Comfy.EnableGPUAcceleration' as any,
|
||||
name: 'GPU Acceleration',
|
||||
type: 'boolean',
|
||||
defaultValue: true,
|
||||
tooltip: 'Enable GPU acceleration for better performance',
|
||||
experimental: true
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'Comfy.CacheSize' as any,
|
||||
name: 'Cache Size (MB)',
|
||||
type: 'slider',
|
||||
defaultValue: 512,
|
||||
tooltip: 'Amount of memory to use for caching',
|
||||
attrs: {
|
||||
min: 128,
|
||||
max: 2048,
|
||||
step: 128
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export const EmptyPanel: Story = {
|
||||
args: {
|
||||
settingGroups: []
|
||||
}
|
||||
}
|
||||
|
||||
export const SingleGroup: Story = {
|
||||
args: {
|
||||
settingGroups: [mockGeneralSettings]
|
||||
}
|
||||
}
|
||||
|
||||
export const MultipleGroups: Story = {
|
||||
args: {
|
||||
settingGroups: [
|
||||
mockGeneralSettings,
|
||||
mockAppearanceSettings,
|
||||
mockPerformanceSettings
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export const AppearanceOnly: Story = {
|
||||
args: {
|
||||
settingGroups: [mockAppearanceSettings]
|
||||
}
|
||||
}
|
||||
|
||||
export const PerformanceOnly: Story = {
|
||||
args: {
|
||||
settingGroups: [mockPerformanceSettings]
|
||||
}
|
||||
}
|
||||
|
||||
export const MixedInputTypes: Story = {
|
||||
args: {
|
||||
settingGroups: [
|
||||
{
|
||||
label: 'Mixed Settings',
|
||||
settings: [
|
||||
createMockSetting({
|
||||
id: 'mixed.boolean' as any,
|
||||
name: 'Boolean Setting',
|
||||
type: 'boolean',
|
||||
defaultValue: true
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'mixed.text' as any,
|
||||
name: 'Text Setting',
|
||||
type: 'text',
|
||||
defaultValue: 'Default text'
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'mixed.number' as any,
|
||||
name: 'Number Setting',
|
||||
type: 'number',
|
||||
defaultValue: 42
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'mixed.slider' as any,
|
||||
name: 'Slider Setting',
|
||||
type: 'slider',
|
||||
defaultValue: 75,
|
||||
attrs: { min: 0, max: 100 }
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'mixed.combo' as any,
|
||||
name: 'Combo Setting',
|
||||
type: 'combo',
|
||||
defaultValue: 'option2',
|
||||
options: [
|
||||
{ text: 'Option 1', value: 'option1' },
|
||||
{ text: 'Option 2', value: 'option2' },
|
||||
{ text: 'Option 3', value: 'option3' }
|
||||
]
|
||||
}),
|
||||
createMockSetting({
|
||||
id: 'mixed.color' as any,
|
||||
name: 'Color Setting',
|
||||
type: 'color',
|
||||
defaultValue: '#ff6b35'
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user