diff --git a/.gitignore b/.gitignore
index b3e819f18..db5315411 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,3 +75,4 @@ vite.config.mts.timestamp-*.mjs
*storybook.log
storybook-static
+
diff --git a/.storybook/main.ts b/.storybook/main.ts
index 3a24b68d4..a799ec143 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -1,63 +1,96 @@
import type { StorybookConfig } from '@storybook/vue3-vite'
-import vue from '@vitejs/plugin-vue'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
import IconsResolver from 'unplugin-icons/resolver'
import Icons from 'unplugin-icons/vite'
import Components from 'unplugin-vue-components/vite'
+import type { InlineConfig } from 'vite'
const config: StorybookConfig = {
- stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
- addons: [
- '@storybook/addon-docs',
- '@storybook/addon-controls',
- '@storybook/addon-actions',
- '@storybook/addon-viewport',
- '@storybook/addon-backgrounds'
- ],
+ stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ addons: ['@storybook/addon-docs'],
framework: {
name: '@storybook/vue3-vite',
options: {}
},
- viteFinal: async (config) => {
+ async viteFinal(config) {
+ // Use dynamic import to avoid CJS deprecation warning
const { mergeConfig } = await import('vite')
+ // Filter out any plugins that might generate import maps
+ if (config.plugins) {
+ config.plugins = config.plugins.filter((plugin: any) => {
+ if (plugin && plugin.name && plugin.name.includes('import-map')) {
+ return false
+ }
+ return true
+ })
+ }
+
return mergeConfig(config, {
+ // Replace plugins entirely to avoid inheritance issues
plugins: [
- vue(),
+ // Only include plugins we explicitly need for Storybook
Icons({
compiler: 'vue3',
customCollections: {
- comfy: FileSystemIconLoader('../src/assets/icons/custom')
+ comfy: FileSystemIconLoader(
+ process.cwd() + '/src/assets/icons/custom'
+ )
}
}),
Components({
- dts: false, // Disable DTS generation for Storybook
+ dts: false, // Disable dts generation in Storybook
resolvers: [
IconsResolver({
customCollections: ['comfy']
})
],
- dirs: ['../src/components', '../src/layout', '../src/views'],
+ dirs: [
+ process.cwd() + '/src/components',
+ process.cwd() + '/src/layout',
+ process.cwd() + '/src/views'
+ ],
deep: true,
extensions: ['vue']
})
+ // Note: Explicitly NOT including generateImportMapPlugin to avoid externalization
],
+ server: {
+ allowedHosts: true
+ },
resolve: {
alias: {
- '@': new URL('../src', import.meta.url).pathname
+ '@': process.cwd() + '/src'
}
},
- define: {
- ...config.define,
- global: 'globalThis',
- __COMFYUI_FRONTEND_VERSION__: JSON.stringify('1.26.4'),
- __SENTRY_ENABLED__: JSON.stringify(false),
- __SENTRY_DSN__: JSON.stringify(''),
- __ALGOLIA_APP_ID__: JSON.stringify(''),
- __ALGOLIA_API_KEY__: JSON.stringify(''),
- __USE_PROD_CONFIG__: JSON.stringify(false)
+ build: {
+ rollupOptions: {
+ external: () => {
+ // Don't externalize any modules in Storybook build
+ // This ensures PrimeVue and other dependencies are bundled
+ return false
+ },
+ onwarn: (warning, warn) => {
+ // Suppress specific warnings
+ if (
+ warning.code === 'UNUSED_EXTERNAL_IMPORT' &&
+ warning.message?.includes('resolveComponent')
+ ) {
+ return
+ }
+ // Suppress Storybook font asset warnings
+ if (
+ warning.code === 'UNRESOLVED_IMPORT' &&
+ warning.message?.includes('nunito-sans')
+ ) {
+ return
+ }
+ warn(warning)
+ }
+ },
+ chunkSizeWarningLimit: 1000
}
- })
+ } satisfies InlineConfig)
}
}
export default config
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index b8b43aa2f..747bbe802 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -1,57 +1,53 @@
+import { definePreset } from '@primevue/themes'
+import Aura from '@primevue/themes/aura'
import { setup } from '@storybook/vue3'
import type { Preview } from '@storybook/vue3-vite'
import { createPinia } from 'pinia'
+import 'primeicons/primeicons.css'
import PrimeVue from 'primevue/config'
+import ConfirmationService from 'primevue/confirmationservice'
import ToastService from 'primevue/toastservice'
import Tooltip from 'primevue/tooltip'
-import { createI18n } from 'vue-i18n'
-import '../public/materialdesignicons.min.css'
-// Import styles
import '../src/assets/css/style.css'
+import { i18n } from '../src/i18n'
+import '../src/lib/litegraph/public/css/litegraph.css'
+import { useWidgetStore } from '../src/stores/widgetStore'
+import { useColorPaletteStore } from '../src/stores/workspace/colorPaletteStore'
-// Mock Firebase for Storybook
-const mockFirebase = {
- auth: () => ({
- currentUser: null,
- onAuthStateChanged: () => () => {}
- }),
- firestore: () => ({})
-}
+const ComfyUIPreset = definePreset(Aura, {
+ semantic: {
+ // @ts-expect-error fix me
+ primary: Aura['primitive'].blue
+ }
+})
-// Setup Vue plugins for Storybook
+// Setup Vue app for Storybook
setup((app) => {
+ app.directive('tooltip', Tooltip)
const pinia = createPinia()
- const i18n = createI18n({
- locale: 'en',
- fallbackLocale: 'en',
- messages: {
- en: {
- g: {
- searchSettings: 'Search Settings',
- noResultsFound: 'No Results Found',
- searchFailedMessage: 'Try adjusting your search terms',
- experimental: 'Experimental',
- loadingPanel: 'Loading {panel}...'
- },
- settings: {},
- settingsCategories: {}
- }
- }
- })
-
app.use(pinia)
+
+ // Initialize stores
+ useColorPaletteStore(pinia)
+ useWidgetStore(pinia)
+
app.use(i18n)
app.use(PrimeVue, {
theme: {
- preset: null // Will use CSS for theming
+ preset: ComfyUIPreset,
+ options: {
+ prefix: 'p',
+ cssLayer: {
+ name: 'primevue',
+ order: 'primevue, tailwind-utilities'
+ },
+ darkModeSelector: '.dark-theme, :root:has(.dark-theme)'
+ }
}
})
+ app.use(ConfirmationService)
app.use(ToastService)
- app.directive('tooltip', Tooltip)
-
- // Provide mock services
- app.provide('firebase', mockFirebase)
})
// Dark theme decorator
@@ -81,40 +77,9 @@ const preview: Preview = {
backgrounds: {
default: 'light',
values: [
- {
- name: 'light',
- value: '#ffffff'
- },
- {
- name: 'dark',
- value: '#1a1a1a'
- }
+ { name: 'light', value: '#ffffff' },
+ { name: 'dark', value: '#0a0a0a' }
]
- },
- viewport: {
- viewports: {
- small: {
- name: 'Small',
- styles: {
- width: '640px',
- height: '480px'
- }
- },
- medium: {
- name: 'Medium',
- styles: {
- width: '768px',
- height: '1024px'
- }
- },
- large: {
- name: 'Large',
- styles: {
- width: '1024px',
- height: '768px'
- }
- }
- }
}
},
globalTypes: {
diff --git a/knip.config.ts b/knip.config.ts
index 4d102262a..81333a2c3 100644
--- a/knip.config.ts
+++ b/knip.config.ts
@@ -42,7 +42,14 @@ const config: KnipConfig = {
'vite.electron.config.mts',
'vite.types.config.mts',
// Auto generated manager types
- 'src/types/generatedManagerTypes.ts'
+ 'src/types/generatedManagerTypes.ts',
+ // Design system components (may not be used immediately)
+ 'src/components/button/IconGroup.vue',
+ 'src/components/button/MoreButton.vue',
+ 'src/components/button/TextButton.vue',
+ 'src/components/card/CardTitle.vue',
+ 'src/components/card/CardDescription.vue',
+ 'src/components/input/SingleSelect.vue'
],
ignoreExportsUsedInFile: true,
// Vue-specific configuration
diff --git a/package-lock.json b/package-lock.json
index dd01527b3..d7f9173f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -59,13 +59,8 @@
"@lobehub/i18n-cli": "^1.20.0",
"@pinia/testing": "^0.1.5",
"@playwright/test": "^1.52.0",
- "@storybook/addon-actions": "^9.0.8",
- "@storybook/addon-backgrounds": "^9.0.8",
- "@storybook/addon-controls": "^9.0.8",
- "@storybook/addon-docs": "^9.1.2",
- "@storybook/addon-onboarding": "^9.1.2",
- "@storybook/addon-viewport": "^9.0.8",
- "@storybook/vue3-vite": "^9.1.2",
+ "@storybook/addon-docs": "^9.1.1",
+ "@storybook/vue3-vite": "^9.1.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
"@types/dompurify": "^3.0.5",
"@types/fs-extra": "^11.0.4",
@@ -79,7 +74,7 @@
"eslint": "^9.12.0",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-prettier": "^5.2.6",
- "eslint-plugin-storybook": "^9.1.2",
+ "eslint-plugin-storybook": "^9.1.1",
"eslint-plugin-unused-imports": "^4.1.4",
"eslint-plugin-vue": "^9.27.0",
"fs-extra": "^11.2.0",
@@ -91,7 +86,7 @@
"lint-staged": "^15.2.7",
"postcss": "^8.4.39",
"prettier": "^3.3.2",
- "storybook": "^9.1.2",
+ "storybook": "^9.1.1",
"tailwindcss": "^3.4.4",
"tsx": "^4.15.6",
"typescript": "^5.4.5",
@@ -144,9 +139,9 @@
"dev": true
},
"node_modules/@adobe/css-tools": {
- "version": "4.4.4",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
- "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.3.tgz",
+ "integrity": "sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==",
"dev": true,
"license": "MIT"
},
@@ -4330,50 +4325,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@storybook/addon-actions": {
- "version": "9.0.8",
- "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-9.0.8.tgz",
- "integrity": "sha512-LFePu7PPnWN0Il/uoUpmA5T0J0C7d6haJIbg0pXrjxW2MQVSYXE4S4LSUz8fOImltBDV3xAl6tLPYHFj6VcrOA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
- "node_modules/@storybook/addon-backgrounds": {
- "version": "9.0.8",
- "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-9.0.8.tgz",
- "integrity": "sha512-4Vvr4wYHtiZ8UVWdCahK0XEMU4zNgInnNcVQ31YkUg41MVSY+aoZqtNuxOuRbFzUtjL9/aVsbY0Sg9Lp1/EJ4g==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
- "node_modules/@storybook/addon-controls": {
- "version": "9.0.8",
- "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-9.0.8.tgz",
- "integrity": "sha512-6MY9QeBv2vNmBXH+ONmbpp/Gu/odSxriN1+BAY+il9OyXZBMq3OiDsjoH7xY5V7PGr+0XhZfOLkamvx3q+lQTg==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
"node_modules/@storybook/addon-docs": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-9.1.2.tgz",
- "integrity": "sha512-U3eHJ8lQFfEZ/OcgdKkUBbW2Y2tpAsHfy8lQOBgs5Pgj9biHEJcUmq+drOS/sJhle673eoBcUFmspXulI4KP1w==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-9.1.1.tgz",
+ "integrity": "sha512-CzgvTy3V5X4fe+VPkiZVwPKARlpEBDAKte8ajLAlHJQLFpADdYrBRQ0se6I+kcxva7rZQzdhuH7qjXMDRVcfnw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@mdx-js/react": "^3.0.0",
- "@storybook/csf-plugin": "9.1.2",
+ "@storybook/csf-plugin": "9.1.1",
"@storybook/icons": "^1.4.0",
- "@storybook/react-dom-shim": "9.1.2",
+ "@storybook/react-dom-shim": "9.1.1",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"ts-dedent": "^2.0.0"
@@ -4383,7 +4345,7 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^9.1.2"
+ "storybook": "^9.1.1"
}
},
"node_modules/@storybook/addon-docs/node_modules/@storybook/icons": {
@@ -4401,9 +4363,9 @@
}
},
"node_modules/@storybook/addon-docs/node_modules/@storybook/react-dom-shim": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-9.1.2.tgz",
- "integrity": "sha512-nw7BLAHCJswPZGsuL0Gs2AvFUWriusCTgPBmcHppSw/AqvT4XRFRDE+5q3j04/XKuZBrAA2sC4L+HuC0uzEChQ==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-9.1.1.tgz",
+ "integrity": "sha512-L+HCOXvOP+PwKrVS8od9aF+F4hO7zA0Nt1vnpbg2LeAHCxYghrjFVtioe7gSlzrlYdozQrPLY98a4OkDB7KGrw==",
"dev": true,
"license": "MIT",
"funding": {
@@ -4413,7 +4375,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "storybook": "^9.1.2"
+ "storybook": "^9.1.1"
}
},
"node_modules/@storybook/addon-docs/node_modules/react": {
@@ -4446,39 +4408,14 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@storybook/addon-onboarding": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-9.1.2.tgz",
- "integrity": "sha512-WfYIBmRtwUF13Hcu6BdsqATsAuBK0dwsz7O4tL0FGrIwY/vdzZ5jNzYvzzgilzlu9QiPvzEIBvs6X4BVulN3LQ==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- },
- "peerDependencies": {
- "storybook": "^9.1.2"
- }
- },
- "node_modules/@storybook/addon-viewport": {
- "version": "9.0.8",
- "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-9.0.8.tgz",
- "integrity": "sha512-HgIFDzNXvMx0zQBM5mhwBoAJlrF9KRlxNCZnJbqrFLCJO4Ps2PMtB0HRGHcg0gm3RLcqyps0DpiF7wll3udb7Q==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
"node_modules/@storybook/builder-vite": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-9.1.2.tgz",
- "integrity": "sha512-5Y7e5wnSzFxCGP63UNRRZVoxHe1znU4dYXazJBobAlEcUPBk7A0sH2716tA6bS4oz92oG9tgvn1g996hRrw4ow==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-9.1.1.tgz",
+ "integrity": "sha512-rM0QOfykr39SFBRQnoAa5PU3xTHnJE1R5tigvjved1o7sumcfjrhqmEyAgNZv1SoRztOO92jwkTi7En6yheOKg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@storybook/csf-plugin": "9.1.2",
+ "@storybook/csf-plugin": "9.1.1",
"ts-dedent": "^2.0.0"
},
"funding": {
@@ -4486,14 +4423,14 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^9.1.2",
+ "storybook": "^9.1.1",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
"node_modules/@storybook/csf-plugin": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-9.1.2.tgz",
- "integrity": "sha512-bfMh6r+RieBLPWtqqYN70le2uTE4JzOYPMYSCagHykUti3uM/1vRFaZNkZtUsRy5GwEzE5jLdDXioG1lOEeT2Q==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-9.1.1.tgz",
+ "integrity": "sha512-MwdtvzzFpkard06pCfDrgRXZiBfWAQICdKh7kzpv1L8SwewsRgUr5WZQuEAVfYdSvCFJbWnNN4KirzPhe5ENCg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4504,7 +4441,7 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^9.1.2"
+ "storybook": "^9.1.1"
}
},
"node_modules/@storybook/csf-plugin/node_modules/unplugin": {
@@ -4529,9 +4466,9 @@
"license": "MIT"
},
"node_modules/@storybook/vue3": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@storybook/vue3/-/vue3-9.1.2.tgz",
- "integrity": "sha512-aYLh6/DZEuoOtsn/qePb9I/kuzwZGy+mS/ELlFoj72vpJc4d21hKZfiepO5bZ3z73XK7nLmdMVQ2tIwvsin4Vw==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@storybook/vue3/-/vue3-9.1.1.tgz",
+ "integrity": "sha512-eKY1wKKmFrO8IpgHIV7XAyv7WRvI9rdvni4niy0bcho7QLD27trmJ9lJ3mAwZ8rEpUjgYOSDi6i5/jangbZc4w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4547,19 +4484,19 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^9.1.2",
+ "storybook": "^9.1.1",
"vue": "^3.0.0"
}
},
"node_modules/@storybook/vue3-vite": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@storybook/vue3-vite/-/vue3-vite-9.1.2.tgz",
- "integrity": "sha512-MSXNtSbY8dnlcSzmbjkzJs1gAmDVRH1b4lBYU8TPHb8YmFz9vdYi8JNjOFztEjcnFe6VPVeCys69MpzZqGF31g==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@storybook/vue3-vite/-/vue3-vite-9.1.1.tgz",
+ "integrity": "sha512-JdQPPYCVxvw+hXEd27JH5ESmP7o86/dwNGiWvFUZLUp1utjrtXfr68QiFWRWjWRCe/4RvNgypX3tKoZMZ3ay6w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@storybook/builder-vite": "9.1.2",
- "@storybook/vue3": "9.1.2",
+ "@storybook/builder-vite": "9.1.1",
+ "@storybook/vue3": "9.1.1",
"find-package-json": "^1.2.0",
"magic-string": "^0.30.0",
"typescript": "^5.8.3",
@@ -4574,7 +4511,7 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^9.1.2",
+ "storybook": "^9.1.1",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
@@ -4624,9 +4561,9 @@
"peer": true
},
"node_modules/@testing-library/jest-dom": {
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.7.0.tgz",
- "integrity": "sha512-RI2e97YZ7MRa+vxP4UUnMuMFL2buSsf0ollxUbTgrbPLKhMn8KVTx7raS6DYjC7v1NDVrioOvaShxsguLNISCA==",
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.4.tgz",
+ "integrity": "sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4634,6 +4571,7 @@
"aria-query": "^5.0.0",
"css.escape": "^1.5.1",
"dom-accessibility-api": "^0.6.3",
+ "lodash": "^4.17.21",
"picocolors": "^1.1.1",
"redent": "^3.0.0"
},
@@ -5273,9 +5211,9 @@
}
},
"node_modules/@types/react": {
- "version": "19.1.10",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.10.tgz",
- "integrity": "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==",
+ "version": "19.1.9",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz",
+ "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==",
"dev": true,
"license": "MIT",
"peer": true,
@@ -5416,14 +5354,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.1.tgz",
- "integrity": "sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz",
+ "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.39.1",
- "@typescript-eslint/types": "^8.39.1",
+ "@typescript-eslint/tsconfig-utils": "^8.39.0",
+ "@typescript-eslint/types": "^8.39.0",
"debug": "^4.3.4"
},
"engines": {
@@ -5438,9 +5376,9 @@
}
},
"node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.1.tgz",
- "integrity": "sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz",
+ "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5470,9 +5408,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.1.tgz",
- "integrity": "sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz",
+ "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8484,6 +8422,7 @@
"version": "1.39.9",
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.9.tgz",
"integrity": "sha512-9OtbkZmTA2Qc9groyA1PUNeb6knVTkvB2RSdr/LcJXDL8IdEakaxwXLHXa7VX/Wj0GmdMJPR3WhnPGhiP3E+qg==",
+ "license": "MIT",
"workspaces": [
"docs",
"benchmarks"
@@ -8688,9 +8627,9 @@
}
},
"node_modules/eslint-plugin-storybook": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-9.1.2.tgz",
- "integrity": "sha512-EQa/kChrYrekxv36q3pvW57anqxMlAP4EdPXEDyA/EDrCQJaaTbWEdsMnVZtD744RjPP0M5wzaUjHbMhNooAwQ==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-9.1.1.tgz",
+ "integrity": "sha512-g4/i9yW6cl4TCEMzYyALNvO3d/jB6TDvSs/Pmye7dHDrra2B7dgZJGzmEWILD62brVrLVHNoXgy2dNPtx80kmw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8701,18 +8640,18 @@
},
"peerDependencies": {
"eslint": ">=8",
- "storybook": "^9.1.2"
+ "storybook": "^9.1.1"
}
},
"node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/scope-manager": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.1.tgz",
- "integrity": "sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz",
+ "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.39.1",
- "@typescript-eslint/visitor-keys": "8.39.1"
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -8723,9 +8662,9 @@
}
},
"node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/types": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.1.tgz",
- "integrity": "sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz",
+ "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8737,16 +8676,16 @@
}
},
"node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.1.tgz",
- "integrity": "sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz",
+ "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/project-service": "8.39.1",
- "@typescript-eslint/tsconfig-utils": "8.39.1",
- "@typescript-eslint/types": "8.39.1",
- "@typescript-eslint/visitor-keys": "8.39.1",
+ "@typescript-eslint/project-service": "8.39.0",
+ "@typescript-eslint/tsconfig-utils": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -8766,16 +8705,16 @@
}
},
"node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/utils": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.1.tgz",
- "integrity": "sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz",
+ "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
- "@typescript-eslint/scope-manager": "8.39.1",
- "@typescript-eslint/types": "8.39.1",
- "@typescript-eslint/typescript-estree": "8.39.1"
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -8790,13 +8729,13 @@
}
},
"node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.39.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.1.tgz",
- "integrity": "sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz",
+ "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.39.1",
+ "@typescript-eslint/types": "8.39.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -16224,9 +16163,9 @@
"license": "MIT"
},
"node_modules/storybook": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/storybook/-/storybook-9.1.2.tgz",
- "integrity": "sha512-TYcq7WmgfVCAQge/KueGkVlM/+g33sQcmbATlC3X6y/g2FEeSSLGrb6E6d3iemht8oio+aY6ld3YOdAnMwx45Q==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/storybook/-/storybook-9.1.1.tgz",
+ "integrity": "sha512-q6GaGZdVZh6rjOdGnc+4hGTu8ECyhyjQDw4EZNxKtQjDO8kqtuxbFm8l/IP2l+zLVJAatGWKkaX9Qcd7QZxz+Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -19484,4 +19423,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index aa31ac88e..7a934cbda 100644
--- a/package.json
+++ b/package.json
@@ -40,13 +40,8 @@
"@lobehub/i18n-cli": "^1.20.0",
"@pinia/testing": "^0.1.5",
"@playwright/test": "^1.52.0",
- "@storybook/addon-actions": "^9.0.8",
- "@storybook/addon-backgrounds": "^9.0.8",
- "@storybook/addon-controls": "^9.0.8",
- "@storybook/addon-docs": "^9.1.2",
- "@storybook/addon-onboarding": "^9.1.2",
- "@storybook/addon-viewport": "^9.0.8",
- "@storybook/vue3-vite": "^9.1.2",
+ "@storybook/addon-docs": "^9.1.1",
+ "@storybook/vue3-vite": "^9.1.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
"@types/dompurify": "^3.0.5",
"@types/fs-extra": "^11.0.4",
@@ -60,7 +55,7 @@
"eslint": "^9.12.0",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-prettier": "^5.2.6",
- "eslint-plugin-storybook": "^9.1.2",
+ "eslint-plugin-storybook": "^9.1.1",
"eslint-plugin-unused-imports": "^4.1.4",
"eslint-plugin-vue": "^9.27.0",
"fs-extra": "^11.2.0",
@@ -72,7 +67,7 @@
"lint-staged": "^15.2.7",
"postcss": "^8.4.39",
"prettier": "^3.3.2",
- "storybook": "^9.1.2",
+ "storybook": "^9.1.1",
"tailwindcss": "^3.4.4",
"tsx": "^4.15.6",
"typescript": "^5.4.5",
@@ -131,4 +126,4 @@
"zod": "^3.23.8",
"zod-validation-error": "^3.3.0"
}
-}
+}
\ No newline at end of file
diff --git a/playwright.config.ts b/playwright.config.ts
index e259c74ac..92c2d11fd 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -16,8 +16,8 @@ export default defineConfig({
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
- /* Retry on CI only */
- retries: process.env.CI ? 2 : 0,
+ /* Retry on CI only - increased for better flaky test handling */
+ retries: process.env.CI ? 3 : 0,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
diff --git a/src/components/button/IconButton.vue b/src/components/button/IconButton.vue
new file mode 100644
index 000000000..1a38866f7
--- /dev/null
+++ b/src/components/button/IconButton.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
diff --git a/src/components/button/IconGroup.vue b/src/components/button/IconGroup.vue
new file mode 100644
index 000000000..082da5a76
--- /dev/null
+++ b/src/components/button/IconGroup.vue
@@ -0,0 +1,7 @@
+
+