From 1221756e059bbbe068004c663c70d1391185a1ad Mon Sep 17 00:00:00 2001 From: Christian Byrne Date: Thu, 5 Mar 2026 17:07:46 -0800 Subject: [PATCH] fix: enable enforce-canonical-classes tailwind lint rule (#9427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Enable `better-tailwindcss/enforce-canonical-classes` lint rule and auto-fix all 611 violations across 173 files. Stacked on #9417. ## Changes - **What**: Simplify Tailwind classes to canonical forms via `eslint --fix`: - `h-X w-X` → `size-X` - `overflow-x-hidden overflow-y-hidden` → `overflow-hidden` - and other canonical simplifications - Enable `enforce-canonical-classes` as `'error'` in eslint config ## Review Focus Mechanical auto-fix PR — all changes produced by `eslint --fix`. No visual or behavioral changes; canonical forms are functionally identical. **Stack:** #9417 → **this PR** → PR 3 (class order) Fixes #9300 (partial — 2 of 3 rules) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9427-fix-enable-enforce-canonical-classes-tailwind-lint-rule-31a6d73d365081a49340d7d4640ede45) by [Unito](https://www.unito.io) --- eslint.config.ts | 4 +-- .../LiteGraphCanvasSplitterOverlay.vue | 6 ++-- src/components/TopMenuSection.vue | 2 +- .../tabs/terminal/BaseTerminal.vue | 7 ++--- .../tabs/terminal/LogsTerminal.vue | 2 +- .../breadcrumb/SubgraphBreadcrumb.vue | 2 +- .../breadcrumb/SubgraphBreadcrumbItem.vue | 2 +- src/components/builder/AppBuilder.vue | 2 +- src/components/builder/BuilderDialog.vue | 4 +-- .../builder/ConnectOutputPopover.vue | 6 ++-- src/components/card/CardTop.vue | 2 +- src/components/common/DropdownItem.vue | 2 +- src/components/common/DropdownMenu.vue | 2 +- src/components/common/FormImageUpload.vue | 2 +- src/components/common/LazyImage.vue | 2 +- src/components/common/MarqueeLine.vue | 4 +-- src/components/common/TreeExplorerV2.vue | 2 +- src/components/common/WorkflowActionsList.vue | 6 ++-- .../widget/WorkflowTemplateSelectorDialog.vue | 16 ++++------- src/components/dialog/confirm/ConfirmBody.vue | 2 +- .../content/ConfirmationDialogContent.vue | 6 ++-- .../dialog/content/ErrorDialogContent.vue | 4 ++- .../content/MissingCoreNodesMessage.vue | 2 +- .../dialog/content/MissingModelsContent.vue | 16 ++++------- .../dialog/content/MissingModelsFooter.vue | 2 +- .../dialog/content/MissingNodesContent.vue | 12 ++++---- .../dialog/content/MissingNodesFooter.vue | 2 +- .../dialog/content/SignInContent.vue | 4 +-- .../TopUpCreditsDialogContentLegacy.vue | 4 +-- .../dialog/content/setting/UserPanel.vue | 2 +- .../dialog/content/signin/ApiKeyForm.vue | 2 +- .../dialog/content/signin/SignInForm.vue | 2 +- .../dialog/content/signin/SignUpForm.vue | 2 +- .../CancelSubscriptionDialogContent.vue | 4 +-- src/components/error/ErrorOverlay.vue | 4 +-- .../gradientslider/GradientSlider.vue | 2 +- src/components/graph/CanvasModeSelector.vue | 8 +++--- src/components/graph/GraphCanvas.vue | 4 +-- src/components/graph/GraphCanvasMenu.vue | 16 +++++------ .../selectionToolbox/ColorPickerMenu.vue | 2 +- src/components/graph/widgets/DomWidget.vue | 4 +-- .../helpcenter/HelpCenterMenuContent.vue | 4 +-- src/components/imagecrop/WidgetImageCrop.vue | 4 +-- src/components/input/MultiSelect.vue | 4 +-- src/components/load3d/Load3DScene.vue | 2 +- src/components/load3d/Load3dViewerContent.vue | 2 +- .../load3d/controls/SceneControls.vue | 4 +-- .../maskeditor/BrushSettingsPanel.vue | 4 +-- .../maskeditor/ColorSelectSettingsPanel.vue | 4 +-- .../maskeditor/ImageLayerSettingsPanel.vue | 12 ++++---- .../maskeditor/MaskEditorContent.vue | 12 ++++---- .../maskeditor/PaintBucketSettingsPanel.vue | 4 +-- src/components/maskeditor/SidePanel.vue | 4 +-- .../maskeditor/controls/DropdownControl.vue | 2 +- .../maskeditor/controls/SliderControl.vue | 2 +- .../maskeditor/controls/ToggleControl.vue | 2 +- .../maskeditor/dialog/TopBarHeader.vue | 12 ++++---- src/components/painter/WidgetPainter.vue | 4 +-- .../queue/JobHistoryActionsMenu.vue | 4 +-- src/components/queue/QueueOverlayActive.vue | 2 +- .../queue/dialogs/QueueClearHistoryDialog.vue | 6 ++-- src/components/queue/job/JobContextMenu.vue | 2 +- .../queue/job/JobDetailsPopover.vue | 28 ++++++++----------- src/components/queue/job/JobFilterActions.vue | 4 +-- .../queue/job/QueueAssetPreview.vue | 6 ++-- src/components/queue/job/QueueJobItem.vue | 6 ++-- .../rightSidePanel/errors/ErrorNodeCard.vue | 4 +-- .../rightSidePanel/errors/MissingNodeCard.vue | 4 +-- .../errors/MissingPackGroupRow.vue | 8 +++--- .../rightSidePanel/errors/TabErrors.vue | 2 +- .../rightSidePanel/parameters/WidgetItem.vue | 4 +-- .../rightSidePanel/settings/LayoutField.vue | 2 +- .../subgraph/SubgraphNodeWidget.vue | 2 +- src/components/sidebar/ComfyMenuButton.vue | 2 +- src/components/sidebar/SideToolbar.vue | 2 +- .../sidebar/tabs/AssetsSidebarGridView.vue | 2 +- .../sidebar/tabs/AssetsSidebarListView.vue | 2 +- .../sidebar/tabs/NodeLibrarySidebarTabV2.vue | 4 +-- .../sidebar/tabs/SidebarTabTemplate.vue | 2 +- .../tabs/modelLibrary/ModelTreeLeaf.vue | 2 +- .../tabs/nodeLibrary/EssentialNodeCard.vue | 2 +- .../tabs/nodeLibrary/NodeDragPreview.vue | 2 +- .../sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue | 2 +- .../templates/thumbnails/AudioThumbnail.vue | 2 +- .../templates/thumbnails/BaseThumbnail.vue | 6 ++-- .../thumbnails/HoverDissolveThumbnail.vue | 2 +- .../templates/thumbnails/LogoOverlay.vue | 2 +- .../ui/search-input/searchInput.variants.ts | 4 +-- src/components/ui/select/SelectItem.vue | 2 +- src/components/ui/select/SelectTrigger.vue | 2 +- src/components/ui/slider/Slider.vue | 2 +- .../ui/tags-input/TagsInputItemDelete.vue | 2 +- src/components/widget/SampleModelSelector.vue | 4 +-- .../widget/layout/BaseModalLayout.vue | 2 +- .../assets/components/AssetBrowserModal.vue | 2 +- src/platform/assets/components/AssetCard.vue | 2 +- .../components/AssetExportProgressDialog.vue | 2 +- .../components/MediaAssetFilterMenu.vue | 2 +- src/platform/assets/components/MediaTitle.vue | 2 +- .../components/ModelImportProgressDialog.vue | 2 +- .../assets/components/UploadModelUrlInput.vue | 4 +-- .../onboarding/CloudForgotPasswordView.vue | 4 +-- .../cloud/onboarding/CloudLoginView.vue | 4 +-- .../cloud/onboarding/CloudSignupView.vue | 4 +-- .../CloudSubscriptionRedirectView.vue | 12 +++----- .../cloud/onboarding/UserCheckView.vue | 2 +- .../onboarding/components/CloudSignInForm.vue | 2 +- .../onboarding/components/CloudTemplate.vue | 4 +-- .../skeletons/CloudLoginViewSkeleton.vue | 2 +- .../components/FreeTierDialogContent.vue | 4 +-- .../subscription/components/PricingTable.vue | 20 ++++++------- .../components/SubscriptionPanel.vue | 2 +- .../SubscriptionRequiredDialogContent.vue | 4 +-- .../components/SwapNodeGroupRow.vue | 6 ++-- .../components/SwapNodesCard.vue | 2 +- .../secrets/components/SecretListItem.vue | 2 +- .../secrets/components/SecretsPanel.vue | 2 +- src/platform/surveys/NightlySurveyPopover.vue | 2 +- .../components/ReleaseNotificationToast.vue | 4 +-- .../updates/components/WhatsNewPopup.vue | 2 +- .../workspace/auth/WorkspaceAuthGate.vue | 2 +- .../components/PricingTableWorkspace.vue | 20 ++++++------- ...criptionRequiredDialogContentWorkspace.vue | 2 +- ...SubscriptionTransitionPreviewWorkspace.vue | 4 +-- .../TopUpCreditsDialogContentWorkspace.vue | 4 +-- .../components/WorkspaceSwitcherPopover.vue | 4 +-- .../dialogs/CreateWorkspaceDialogContent.vue | 4 +-- .../dialogs/DeleteWorkspaceDialogContent.vue | 4 +-- .../dialogs/EditWorkspaceDialogContent.vue | 4 +-- .../dialogs/InviteMemberDialogContent.vue | 8 +++--- .../InviteMemberUpsellDialogContent.vue | 4 +-- .../dialogs/LeaveWorkspaceDialogContent.vue | 4 +-- .../dialogs/RemoveMemberDialogContent.vue | 4 +-- .../dialogs/RevokeInviteDialogContent.vue | 4 +-- .../settings/WorkspacePanelContent.vue | 4 +-- .../core/layout/transform/TransformPane.vue | 2 +- .../extensions/linearMode/AppOutput.vue | 2 +- .../extensions/linearMode/ImagePreview.vue | 4 +-- .../extensions/linearMode/LinearControls.vue | 8 +++--- .../extensions/linearMode/LinearPreview.vue | 2 +- .../extensions/linearMode/MobileDisplay.vue | 8 +++--- .../extensions/linearMode/Preview3d.vue | 2 +- .../extensions/vueNodes/VideoPreview.vue | 10 +++---- .../vueNodes/components/ImagePreview.vue | 10 +++---- .../vueNodes/components/LGraphNode.vue | 6 ++-- .../vueNodes/components/LGraphNodePreview.vue | 2 +- .../vueNodes/components/LivePreview.vue | 2 +- .../vueNodes/components/NodeHeader.vue | 4 +-- .../vueNodes/components/NodeSlots.vue | 2 +- .../components/ValueControlPopover.vue | 10 +++---- .../widgets/components/WidgetChart.vue | 2 +- .../widgets/components/WidgetColorPicker.vue | 2 +- .../vueNodes/widgets/components/WidgetDOM.vue | 2 +- .../widgets/components/WidgetGalleria.vue | 4 +-- .../form/dropdown/FormDropdownMenu.vue | 2 +- .../form/dropdown/FormDropdownMenuFilter.vue | 2 +- .../form/dropdown/FormDropdownMenuItem.vue | 8 +++--- src/views/GraphView.vue | 2 +- src/views/LinearView.vue | 2 +- src/views/layouts/LayoutDefault.vue | 2 +- .../components/ManagerProgressToast.vue | 4 +-- .../manager/ImportFailedNodeContent.vue | 4 +-- .../components/manager/ManagerDialog.vue | 4 +-- .../manager/NodeConflictDialogContent.vue | 4 +-- .../components/manager/PackStatusMessage.vue | 2 +- .../manager/PackVersionSelectorPopover.vue | 2 +- .../manager/button/PackEnableToggle.vue | 2 +- .../manager/infoPanel/MarkdownText.vue | 4 +-- .../infoPanel/tabs/DescriptionTabPanel.vue | 2 +- .../infoPanel/tabs/WarningTabPanel.vue | 2 +- .../manager/packBanner/PackBanner.vue | 10 +++---- .../components/manager/packCard/PackCard.vue | 8 +++--- .../manager/packCard/PackCardFooter.vue | 2 +- .../manager/skeleton/PackCardSkeleton.vue | 2 +- 174 files changed, 344 insertions(+), 385 deletions(-) diff --git a/eslint.config.ts b/eslint.config.ts index 199c7d91b7..892a94ab9c 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -128,9 +128,7 @@ export default defineConfig([ 'better-tailwindcss/enforce-consistent-line-wrapping': 'off', // Off: large batch change, enable and apply with `eslint --fix` 'better-tailwindcss/enforce-consistent-class-order': 'off', - // Off: large batch change (v3→v4 renames like rounded→rounded-sm), - // enable and apply with `eslint --fix` in a follow-up PR - 'better-tailwindcss/enforce-canonical-classes': 'off', + 'better-tailwindcss/enforce-canonical-classes': 'error', 'better-tailwindcss/no-deprecated-classes': 'error' } }, diff --git a/src/components/LiteGraphCanvasSplitterOverlay.vue b/src/components/LiteGraphCanvasSplitterOverlay.vue index 7de233850b..498dc680bd 100644 --- a/src/components/LiteGraphCanvasSplitterOverlay.vue +++ b/src/components/LiteGraphCanvasSplitterOverlay.vue @@ -1,6 +1,6 @@