From 9f0fa7202d9d8f5ae8041bcdc1b1b1edb1dbb4d1 Mon Sep 17 00:00:00 2001 From: Alexander Brown Date: Wed, 8 Oct 2025 18:59:36 -0700 Subject: [PATCH 1/5] Docs: Update agent instructions about style classes (#5990) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Very small change to help the LLMs follow the new patterns. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5990-Docs-Update-agent-instructions-about-style-classes-2876d73d365081339dbddf22d22947e7) by [Unito](https://www.unito.io) --- AGENTS.md | 2 +- CLAUDE.md | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 59c9af1cd..0d060af1f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,7 +5,7 @@ - Routing/i18n/entry: `src/router.ts`, `src/i18n.ts`, `src/main.ts`. - Tests: unit/component in `tests-ui/` and `src/components/**/*.{test,spec}.ts`; E2E in `browser_tests/`. - Public assets: `public/`. Build output: `dist/`. -- Config: `vite.config.mts`, `vitest.config.ts`, `playwright.config.ts`, `eslint.config.js`, `.prettierrc`. +- Config: `vite.config.mts`, `vitest.config.ts`, `playwright.config.ts`, `eslint.config.ts`, `.prettierrc`. ## Build, Test, and Development Commands - `pnpm dev`: Start Vite dev server. diff --git a/CLAUDE.md b/CLAUDE.md index 74e656f00..0b187fbfc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -126,6 +126,5 @@ const value = api.getServerFeature('config_name', defaultValue) // Get config - NEVER use `--no-verify` flag when committing - NEVER delete or disable tests to make them pass - NEVER circumvent quality checks -- NEVER use `dark:` prefix - always use `dark-theme:` for dark mode styles, for example: `dark-theme:text-white dark-theme:bg-black` -- NEVER use `:class="[]"` to merge class names - always use `import { cn } from '@/utils/tailwindUtil'`, for example: `
` - +- NEVER use `dark:` or `dark-theme:` tailwind variants. Instead use a semantic value from the `style.css` theme, e.g. `bg-node-component-surface` +- NEVER use `:class="[]"` to merge class names - always use `import { cn } from '@/utils/tailwindUtil'`, for example: `
` From c9da8b200dac4d257801bca0f704ba560c99f80f Mon Sep 17 00:00:00 2001 From: Alexander Brown Date: Wed, 8 Oct 2025 19:32:32 -0700 Subject: [PATCH 2/5] Fix: Allow uncoloring Vue Nodes (#5991) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes an issue where trying to uncolor a node broke the vue color syncing. ## Changes - **What**: Changes litegraph property removal from `delete` to `= undefined` ## Screenshots ### Before https://github.com/user-attachments/assets/81a1ad40-ba5d-4dec-8f90-5b61eb804a16 ### After https://github.com/user-attachments/assets/459d2d15-c728-49d2-abd9-6e255e5383e5 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5991-Fix-Allow-uncoloring-Vue-Nodes-2876d73d365081f4a74fc9fa423aae1c) by [Unito](https://www.unito.io) --- src/lib/litegraph/src/LGraphNode.ts | 14 +++++++------- src/lib/litegraph/src/LGraphNodeProperties.ts | 14 ++++++-------- .../litegraph/core/LGraphNodeProperties.test.ts | 4 ++-- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/lib/litegraph/src/LGraphNode.ts b/src/lib/litegraph/src/LGraphNode.ts index b17d46d77..29e31a942 100644 --- a/src/lib/litegraph/src/LGraphNode.ts +++ b/src/lib/litegraph/src/LGraphNode.ts @@ -344,8 +344,8 @@ export class LGraphNode /** @inheritdoc {@link IColorable.setColorOption} */ setColorOption(colorOption: ColorOption | null): void { if (colorOption == null) { - delete this.color - delete this.bgcolor + this.color = undefined + this.bgcolor = undefined } else { this.color = colorOption.color this.bgcolor = colorOption.bgcolor @@ -495,7 +495,7 @@ export class LGraphNode set shape(v: RenderShape | 'default' | 'box' | 'round' | 'circle' | 'card') { switch (v) { case 'default': - delete this._shape + this._shape = undefined break case 'box': this._shape = RenderShape.BOX @@ -943,7 +943,7 @@ export class LGraphNode } // @ts-expect-error Exceptional case: id is removed so that the graph can assign a new one on add. - delete data.id + data.id = undefined if (LiteGraph.use_uuids) data.id = LiteGraph.uuidv4() @@ -1948,7 +1948,7 @@ export class LGraphNode for (const input of this.inputs) { if (input._widget === widget) { input._widget = undefined - delete input.widget + input.widget = undefined } } } @@ -2857,7 +2857,7 @@ export class LGraphNode const reroutes = LLink.getReroutes(graph, link) for (const reroute of reroutes) { reroute.linkIds.add(link.id) - if (reroute.floating) delete reroute.floating + if (reroute.floating) reroute.floating = undefined reroute._dragging = undefined } @@ -2947,7 +2947,7 @@ export class LGraphNode reroute.floatingLinkIds.add(link.id) link.parentId = reroute.id - delete parentReroute.floating + parentReroute.floating = undefined return reroute } diff --git a/src/lib/litegraph/src/LGraphNodeProperties.ts b/src/lib/litegraph/src/LGraphNodeProperties.ts index f4a5d0c13..6e635e228 100644 --- a/src/lib/litegraph/src/LGraphNodeProperties.ts +++ b/src/lib/litegraph/src/LGraphNodeProperties.ts @@ -132,14 +132,12 @@ export class LGraphNodeProperties { oldValue: any, newValue: any ): void { - if (oldValue !== newValue && this.node.graph) { - this.node.graph.trigger('node:property:changed', { - nodeId: this.node.id, - property: propertyPath, - oldValue, - newValue - }) - } + this.node.graph?.trigger('node:property:changed', { + nodeId: this.node.id, + property: propertyPath, + oldValue, + newValue + }) } /** diff --git a/tests-ui/tests/litegraph/core/LGraphNodeProperties.test.ts b/tests-ui/tests/litegraph/core/LGraphNodeProperties.test.ts index 35c36b677..aca6fe391 100644 --- a/tests-ui/tests/litegraph/core/LGraphNodeProperties.test.ts +++ b/tests-ui/tests/litegraph/core/LGraphNodeProperties.test.ts @@ -46,12 +46,12 @@ describe('LGraphNodeProperties', () => { }) }) - it("should not emit events when value doesn't change", () => { + it('should emit event when value is set to the same value', () => { new LGraphNodeProperties(mockNode) mockNode.title = 'Test Node' // Same value as original - expect(mockGraph.trigger).toHaveBeenCalledTimes(0) + expect(mockGraph.trigger).toHaveBeenCalledTimes(1) }) it('should not emit events when node has no graph', () => { From b943c0fa75f1db361b4362941f69489adac05176 Mon Sep 17 00:00:00 2001 From: Alexander Brown Date: Wed, 8 Oct 2025 19:39:14 -0700 Subject: [PATCH 3/5] Lint: Add tailwind linter (#5984) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Adds the [tailwind lint plugin](https://github.com/francoismassart/eslint-plugin-tailwindcss/?tab=readme-ov-file#eslint-plugin-tailwindcss) and fixes the currently fixable rules ([v4 is still in beta](https://github.com/francoismassart/eslint-plugin-tailwindcss/?tab=readme-ov-file#about-tailwind-css-4-support)). ## Changes - **What**: Enforces things like consistent class order, and eventually can prohibit extra classes that could be utilities instead - **Dependencies**: The plugin and its types ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5984-Lint-Add-tailwind-linter-2866d73d365081d89db0d998232533bb) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action --- eslint.config.ts | 97 +++++++++++-------- package.json | 2 + pnpm-lock.yaml | 50 +++++++++- pnpm-workspace.yaml | 5 + src/App.vue | 2 +- src/components/bottomPanel/BottomPanel.vue | 8 +- .../tabs/shortcuts/EssentialsPanel.vue | 4 +- .../tabs/shortcuts/ShortcutsList.vue | 8 +- .../tabs/shortcuts/ViewControlsPanel.vue | 4 +- .../tabs/terminal/BaseTerminal.vue | 6 +- .../tabs/terminal/LogsTerminal.vue | 4 +- .../breadcrumb/SubgraphBreadcrumbItem.vue | 4 +- src/components/button/MoreButton.vue | 2 +- src/components/card/CardDescription.vue | 2 +- src/components/card/CardTop.vue | 10 +- src/components/chip/SquareChip.vue | 2 +- src/components/common/FileDownload.vue | 2 +- src/components/common/FormImageUpload.vue | 8 +- src/components/common/LazyImage.vue | 4 +- .../common/NoResultsPlaceholder.vue | 4 +- src/components/common/SearchBox.vue | 2 +- src/components/common/SystemStatsPanel.vue | 4 +- src/components/common/TreeExplorer.vue | 2 +- src/components/common/UrlInput.vue | 4 +- src/components/common/UserCredit.vue | 2 +- .../widget/WorkflowTemplateSelectorDialog.vue | 34 +++---- .../dialog/content/ApiNodesSignInContent.vue | 8 +- .../content/ConfirmationDialogContent.vue | 10 +- .../dialog/content/ErrorDialogContent.vue | 8 +- .../dialog/content/LoadWorkflowWarning.vue | 2 +- .../content/MissingCoreNodesMessage.vue | 2 +- .../dialog/content/MissingModelsWarning.vue | 2 +- .../dialog/content/SignInContent.vue | 22 ++--- .../content/TopUpCreditsDialogContent.vue | 16 +-- .../dialog/content/UpdatePasswordContent.vue | 4 +- .../content/credit/CreditTopUpOption.vue | 4 +- .../dialog/content/setting/AboutPanel.vue | 2 +- .../dialog/content/setting/CreditsPanel.vue | 10 +- .../content/setting/KeybindingPanel.vue | 5 +- .../dialog/content/setting/PanelTemplate.vue | 4 +- .../dialog/content/setting/UsageLogsTable.vue | 2 +- .../dialog/content/setting/UserPanel.vue | 8 +- .../dialog/content/signin/ApiKeyForm.vue | 16 +-- .../dialog/content/signin/PasswordFields.vue | 6 +- .../dialog/content/signin/SignInForm.vue | 12 +-- .../dialog/content/signin/SignUpForm.vue | 8 +- src/components/graph/GraphCanvas.vue | 2 +- src/components/graph/GraphCanvasMenu.vue | 8 +- src/components/graph/SelectionToolbox.vue | 4 +- .../graph/modals/ZoomControlsModal.vue | 28 +++--- .../graph/selectionToolbox/BypassButton.vue | 4 +- .../selectionToolbox/ColorPickerButton.vue | 4 +- .../ConvertToSubgraphButton.vue | 2 +- .../graph/selectionToolbox/ExecuteButton.vue | 4 +- .../graph/selectionToolbox/FrameNodes.vue | 2 +- .../graph/selectionToolbox/InfoButton.vue | 2 +- .../selectionToolbox/MaskEditorButton.vue | 2 +- .../graph/selectionToolbox/MenuOptionItem.vue | 12 +-- .../graph/selectionToolbox/NodeOptions.vue | 2 +- .../selectionToolbox/NodeOptionsButton.vue | 2 +- .../RefreshSelectionButton.vue | 2 +- .../graph/selectionToolbox/SubmenuPopover.vue | 4 +- .../selectionToolbox/VerticalDivider.vue | 2 +- .../graph/widgets/ChatHistoryWidget.vue | 16 +-- .../graph/widgets/TextPreviewWidget.vue | 6 +- .../graph/widgets/chatHistory/CopyButton.vue | 2 +- .../widgets/chatHistory/ResponseBlurb.vue | 8 +- src/components/input/MultiSelect.vue | 12 +-- src/components/input/SingleSelect.vue | 2 +- src/components/load3d/Load3D.vue | 6 +- src/components/load3d/Load3DAnimation.vue | 6 +- .../load3d/Load3DAnimationControls.vue | 4 +- src/components/load3d/Load3DControls.vue | 14 +-- src/components/load3d/Load3DScene.vue | 2 +- src/components/load3d/Load3dViewerContent.vue | 16 +-- src/components/load3d/LoadingOverlay.vue | 4 +- .../load3d/controls/CameraControls.vue | 8 +- .../load3d/controls/ExportControls.vue | 6 +- .../load3d/controls/LightControls.vue | 6 +- .../load3d/controls/ModelControls.vue | 20 ++-- .../load3d/controls/RecordingControls.vue | 12 +-- .../load3d/controls/SceneControls.vue | 12 +-- .../load3d/controls/ViewerControls.vue | 4 +- src/components/node/NodePreview.vue | 2 +- src/components/searchbox/NodeSearchBox.vue | 4 +- src/components/searchbox/NodeSearchItem.vue | 8 +- src/components/sidebar/SideToolbar.vue | 2 +- .../sidebar/tabs/SidebarTabTemplate.vue | 10 +- .../tabs/modelLibrary/DownloadItem.vue | 8 +- .../modelLibrary/ElectronDownloadItems.vue | 2 +- .../sidebar/tabs/nodeLibrary/NodeHelpPage.vue | 8 +- .../templates/thumbnails/AudioThumbnail.vue | 4 +- .../templates/thumbnails/BaseThumbnail.vue | 8 +- .../thumbnails/CompareSliderThumbnail.vue | 2 +- .../thumbnails/HoverDissolveThumbnail.vue | 2 +- .../toast/RerouteMigrationToast.vue | 4 +- src/components/topbar/CommandMenubar.vue | 6 +- src/components/topbar/CurrentUserPopover.vue | 10 +- src/components/topbar/TopMenubar.vue | 6 +- src/components/topbar/WorkflowTab.vue | 8 +- src/components/topbar/WorkflowTabPopover.vue | 2 +- src/components/topbar/WorkflowTabs.vue | 8 +- src/components/ui/slider/Slider.vue | 2 +- src/components/widget/SampleModelSelector.vue | 6 +- .../widget/layout/BaseModalLayout.vue | 10 +- src/components/widget/nav/NavIcon.vue | 2 +- src/components/widget/nav/NavItem.vue | 4 +- src/components/widget/nav/NavTitle.vue | 2 +- src/components/widget/panel/LeftSidePanel.vue | 4 +- src/components/widget/panel/PanelHeader.vue | 6 +- .../widget/panel/RightSidePanel.vue | 2 +- src/core/graph/subgraph/SubgraphNode.vue | 18 ++-- .../graph/subgraph/SubgraphNodeWidget.vue | 4 +- .../assets/components/AssetBadgeGroup.vue | 2 +- src/platform/assets/components/AssetCard.vue | 4 +- src/platform/assets/components/AssetGrid.vue | 4 +- .../components/SettingDialogContent.vue | 8 +- src/renderer/extensions/minimap/MiniMap.vue | 6 +- .../extensions/minimap/MiniMapPanel.vue | 2 +- .../extensions/vueNodes/VideoPreview.vue | 26 ++--- .../vueNodes/components/ImagePreview.vue | 30 +++--- .../vueNodes/components/InputSlot.vue | 2 +- .../vueNodes/components/LGraphNode.vue | 8 +- .../vueNodes/components/LGraphNodePreview.vue | 4 +- .../vueNodes/components/LODFallback.vue | 2 +- .../vueNodes/components/NodeContent.vue | 2 +- .../vueNodes/components/NodeHeader.vue | 10 +- .../vueNodes/components/NodeSlots.vue | 4 +- .../vueNodes/components/NodeWidgets.vue | 6 +- .../vueNodes/components/OutputSlot.vue | 4 +- .../widgets/components/WidgetChart.vue | 2 +- .../widgets/components/WidgetColorPicker.vue | 2 +- .../widgets/components/WidgetFileUpload.vue | 48 ++++----- .../widgets/components/WidgetGalleria.vue | 6 +- .../widgets/components/WidgetImageCompare.vue | 4 +- .../widgets/components/WidgetMarkdown.vue | 4 +- .../form/dropdown/FormDropdownInput.vue | 4 +- .../form/dropdown/FormDropdownMenu.vue | 8 +- .../form/dropdown/FormDropdownMenuActions.vue | 8 +- .../form/dropdown/FormDropdownMenuFilter.vue | 2 +- .../form/dropdown/FormDropdownMenuItem.vue | 4 +- .../components/layout/WidgetLayoutField.vue | 8 +- src/views/UserSelectView.vue | 2 +- src/views/layouts/LayoutDefault.vue | 2 +- src/views/templates/BaseViewTemplate.vue | 10 +- .../ManagerProgressDialogContent.vue | 14 +-- .../components/ManagerProgressFooter.vue | 4 +- .../components/ManagerProgressHeader.vue | 2 +- .../manager/ManagerDialogContent.vue | 28 +++--- .../components/manager/ManagerHeader.vue | 2 +- .../components/manager/ManagerNavSidebar.vue | 6 +- .../manager/NodeConflictDialogContent.vue | 54 ++++++----- .../components/manager/NodeConflictFooter.vue | 4 +- .../components/manager/NodeConflictHeader.vue | 2 +- .../components/manager/PackStatusMessage.vue | 4 +- .../components/manager/PackVersionBadge.vue | 4 +- .../manager/PackVersionSelectorPopover.vue | 14 +-- .../manager/button/PackEnableToggle.vue | 4 +- .../manager/infoPanel/InfoPanel.vue | 8 +- .../manager/infoPanel/InfoPanelHeader.vue | 4 +- .../manager/infoPanel/InfoPanelMultiItem.vue | 8 +- .../components/manager/infoPanel/InfoTabs.vue | 8 +- .../manager/infoPanel/InfoTextSection.vue | 2 +- .../manager/infoPanel/MarkdownText.vue | 2 +- .../infoPanel/tabs/DescriptionTabPanel.vue | 4 +- .../manager/infoPanel/tabs/NodesTabPanel.vue | 6 +- .../infoPanel/tabs/WarningTabPanel.vue | 10 +- .../manager/packBanner/PackBanner.vue | 8 +- .../components/manager/packCard/PackCard.vue | 16 +-- .../manager/packCard/PackCardFooter.vue | 2 +- .../components/manager/packIcon/PackIcon.vue | 8 +- .../manager/packIcon/PackIconStacked.vue | 6 +- .../registrySearchBar/RegistrySearchBar.vue | 10 +- .../manager/skeleton/PackCardSkeleton.vue | 14 +-- .../manager/NodeConflictDialogContent.test.ts | 34 ++++--- tsconfig.json | 7 +- vite.config.mts | 3 +- 177 files changed, 731 insertions(+), 652 deletions(-) diff --git a/eslint.config.ts b/eslint.config.ts index 131c63ace..4e19eba2e 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -4,36 +4,67 @@ import pluginI18n from '@intlify/eslint-plugin-vue-i18n' import { importX } from 'eslint-plugin-import-x' import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' import storybook from 'eslint-plugin-storybook' +import tailwind from 'eslint-plugin-tailwindcss' import unusedImports from 'eslint-plugin-unused-imports' import pluginVue from 'eslint-plugin-vue' import { defineConfig } from 'eslint/config' import globals from 'globals' -import tseslint from 'typescript-eslint' +import { + configs as tseslintConfigs, + parser as tseslintParser +} from 'typescript-eslint' import vueParser from 'vue-eslint-parser' const extraFileExtensions = ['.vue'] +const commonGlobals = { + ...globals.browser, + __COMFYUI_FRONTEND_VERSION__: 'readonly' +} as const + +const settings = { + 'import/resolver': { + typescript: true, + node: true + }, + tailwindcss: { + config: `${import.meta.dirname}/packages/design-system/src/css/style.css`, + functions: ['cn', 'clsx', 'tw'] + } +} as const + +const commonParserOptions = { + parser: tseslintParser, + projectService: true, + tsConfigRootDir: import.meta.dirname, + ecmaVersion: 2020, + sourceType: 'module', + extraFileExtensions +} as const + export default defineConfig([ { ignores: [ - 'src/scripts/*', - 'src/extensions/core/*', - 'src/types/vue-shim.d.ts', - 'packages/registry-types/src/comfyRegistryTypes.ts', - 'src/types/generatedManagerTypes.ts', + '.i18nrc.cjs', + 'components.d.ts', + 'lint-staged.config.js', + 'vitest.setup.ts', '**/vite.config.*.timestamp*', - '**/vitest.config.*.timestamp*' + '**/vitest.config.*.timestamp*', + 'packages/registry-types/src/comfyRegistryTypes.ts', + 'src/extensions/core/*', + 'src/scripts/*', + 'src/types/generatedManagerTypes.ts', + 'src/types/vue-shim.d.ts' ] }, { files: ['./**/*.{ts,mts}'], + settings, languageOptions: { - globals: { - ...globals.browser, - __COMFYUI_FRONTEND_VERSION__: 'readonly' - }, + globals: commonGlobals, parserOptions: { - parser: tseslint.parser, + ...commonParserOptions, projectService: { allowDefaultProject: [ 'vite.config.mts', @@ -42,47 +73,26 @@ export default defineConfig([ 'playwright.config.ts', 'playwright.i18n.config.ts' ] - }, - tsConfigRootDir: import.meta.dirname, - ecmaVersion: 2020, - sourceType: 'module', - extraFileExtensions - } - }, - settings: { - 'import/resolver': { - typescript: true, - node: true + } } } }, { files: ['./**/*.vue'], + settings, languageOptions: { - globals: { - ...globals.browser, - __COMFYUI_FRONTEND_VERSION__: 'readonly' - }, + globals: commonGlobals, parser: vueParser, - parserOptions: { - parser: tseslint.parser, - projectService: true, - tsConfigRootDir: import.meta.dirname, - ecmaVersion: 2020, - sourceType: 'module', - extraFileExtensions - } - }, - settings: { - 'import/resolver': { - typescript: true, - node: true - } + parserOptions: commonParserOptions } }, pluginJs.configs.recommended, - // eslint-disable-next-line import-x/no-named-as-default-member - tseslint.configs.recommended, + + tseslintConfigs.recommended, + // Difference in typecheck on CI vs Local + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore Bad types in the plugin + tailwind.configs['flat/recommended'], pluginVue.configs['flat/recommended'], eslintPluginPrettierRecommended, storybook.configs['flat/recommended'], @@ -114,6 +124,7 @@ export default defineConfig([ 'import-x/no-relative-packages': 'error', 'unused-imports/no-unused-imports': 'error', 'no-console': ['error', { allow: ['warn', 'error'] }], + 'tailwindcss/no-custom-classname': 'off', // TODO: fix 'vue/no-v-html': 'off', // Enforce dark-theme: instead of dark: prefix 'vue/no-restricted-class': ['error', '/^dark:/'], diff --git a/package.json b/package.json index 43ce2d1fb..b631ab224 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "@storybook/vue3-vite": "catalog:", "@tailwindcss/vite": "catalog:", "@trivago/prettier-plugin-sort-imports": "catalog:", + "@types/eslint-plugin-tailwindcss": "catalog:", "@types/fs-extra": "catalog:", "@types/jsdom": "catalog:", "@types/node": "catalog:", @@ -73,6 +74,7 @@ "eslint-plugin-import-x": "catalog:", "eslint-plugin-prettier": "catalog:", "eslint-plugin-storybook": "catalog:", + "eslint-plugin-tailwindcss": "catalog:", "eslint-plugin-unused-imports": "catalog:", "eslint-plugin-vue": "catalog:", "fs-extra": "^11.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8bb996c7d..3b362bc15 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,6 +84,9 @@ catalogs: '@trivago/prettier-plugin-sort-imports': specifier: ^5.2.0 version: 5.2.2 + '@types/eslint-plugin-tailwindcss': + specifier: ^3.17.0 + version: 3.17.0 '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 @@ -147,6 +150,9 @@ catalogs: eslint-plugin-storybook: specifier: ^9.1.6 version: 9.1.6 + eslint-plugin-tailwindcss: + specifier: 4.0.0-beta.0 + version: 4.0.0-beta.0 eslint-plugin-unused-imports: specifier: ^4.2.0 version: 4.2.0 @@ -274,6 +280,9 @@ catalogs: specifier: ^3.3.0 version: 3.3.0 +overrides: + '@types/eslint': '-' + importers: .: @@ -489,6 +498,9 @@ importers: '@trivago/prettier-plugin-sort-imports': specifier: 'catalog:' version: 5.2.2(@vue/compiler-sfc@3.5.13)(prettier@3.3.2) + '@types/eslint-plugin-tailwindcss': + specifier: 'catalog:' + version: 3.17.0 '@types/fs-extra': specifier: 'catalog:' version: 11.0.4 @@ -537,6 +549,9 @@ importers: eslint-plugin-storybook: specifier: 'catalog:' version: 9.1.6(eslint@9.35.0(jiti@2.4.2))(storybook@9.1.6(@testing-library/dom@10.4.1)(prettier@3.3.2)(vite@5.4.19(@types/node@20.14.10)(lightningcss@1.30.1)(terser@5.39.2)))(typescript@5.9.2) + eslint-plugin-tailwindcss: + specifier: 'catalog:' + version: 4.0.0-beta.0(tailwindcss@4.1.12) eslint-plugin-unused-imports: specifier: 'catalog:' version: 4.2.0(@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2)) @@ -2990,6 +3005,9 @@ packages: '@types/diff-match-patch@1.0.36': resolution: {integrity: sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==} + '@types/eslint-plugin-tailwindcss@3.17.0': + resolution: {integrity: sha512-ucQGf2YIdTcndYcxRU3UdZgmhUHsOlbIF4BaRtl0op+7k2JmqM2i3aXZ6XIcfZgVq1ZKov7VM5c/BR81ukmkyg==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -4508,7 +4526,7 @@ packages: resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - '@types/eslint': '>=8.0.0' + '@types/eslint': '*' eslint: '>=8.0.0' eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' prettier: '>=3.0.0' @@ -4525,6 +4543,12 @@ packages: eslint: '>=8' storybook: ^9.1.6 + eslint-plugin-tailwindcss@4.0.0-beta.0: + resolution: {integrity: sha512-WWCajZgQu38Sd67ZCl2W6i3MRzqB0d+H8s4qV9iB6lBJbsDOIpIlj6R1Fj2FXkoWErbo05pZnZYbCGIU9o/DsA==} + engines: {node: '>=18.12.0'} + peerDependencies: + tailwindcss: ^3.4.0 || ^4.0.0 + eslint-plugin-unused-imports@4.2.0: resolution: {integrity: sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==} peerDependencies: @@ -6966,6 +6990,11 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} + tailwind-api-utils@1.0.3: + resolution: {integrity: sha512-KpzUHkH1ug1sq4394SLJX38ZtpeTiqQ1RVyFTTSY2XuHsNSTWUkRo108KmyyrMWdDbQrLYkSHaNKj/a3bmA4sQ==} + peerDependencies: + tailwindcss: ^3.3.0 || ^4.0.0 || ^4.0.0-beta + tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} @@ -10336,6 +10365,8 @@ snapshots: '@types/diff-match-patch@1.0.36': {} + '@types/eslint-plugin-tailwindcss@3.17.0': {} + '@types/estree@1.0.5': {} '@types/estree@1.0.8': {} @@ -10748,7 +10779,7 @@ snapshots: '@vue/shared': 3.5.13 estree-walker: 2.0.2 magic-string: 0.30.19 - postcss: 8.5.1 + postcss: 8.5.6 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.13': @@ -12097,6 +12128,14 @@ snapshots: - supports-color - typescript + eslint-plugin-tailwindcss@4.0.0-beta.0(tailwindcss@4.1.12): + dependencies: + fast-glob: 3.3.3 + postcss: 8.5.6 + synckit: 0.11.11 + tailwind-api-utils: 1.0.3(tailwindcss@4.1.12) + tailwindcss: 4.1.12 + eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2)): dependencies: eslint: 9.35.0(jiti@2.4.2) @@ -15115,6 +15154,13 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + tailwind-api-utils@1.0.3(tailwindcss@4.1.12): + dependencies: + enhanced-resolve: 5.18.3 + jiti: 2.5.1 + local-pkg: 1.1.2 + tailwindcss: 4.1.12 + tailwind-merge@2.6.0: {} tailwindcss-primeui@0.6.1(tailwindcss@4.1.12): diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 936e0ce8b..f3b1ce376 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -29,6 +29,7 @@ catalog: '@storybook/vue3-vite': ^9.1.1 '@tailwindcss/vite': ^4.1.12 '@trivago/prettier-plugin-sort-imports': ^5.2.0 + '@types/eslint-plugin-tailwindcss': ^3.17.0 '@types/fs-extra': ^11.0.4 '@types/jsdom': ^21.1.7 '@types/node': ^20.14.8 @@ -50,6 +51,7 @@ catalog: eslint-plugin-import-x: ^4.16.1 eslint-plugin-prettier: ^5.5.4 eslint-plugin-storybook: ^9.1.6 + eslint-plugin-tailwindcss: 4.0.0-beta.0 eslint-plugin-unused-imports: ^4.2.0 eslint-plugin-vue: ^10.4.0 firebase: ^11.6.0 @@ -95,6 +97,9 @@ catalog: cleanupUnusedCatalogs: true +overrides: + '@types/eslint': '-' + ignoredBuiltDependencies: - '@firebase/util' - protobufjs diff --git a/src/App.vue b/src/App.vue index 6f6f10a1e..c0c9fdd20 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,7 +2,7 @@ diff --git a/src/components/bottomPanel/BottomPanel.vue b/src/components/bottomPanel/BottomPanel.vue index 0ed71bffa..cffa74f76 100644 --- a/src/components/bottomPanel/BottomPanel.vue +++ b/src/components/bottomPanel/BottomPanel.vue @@ -1,17 +1,17 @@