Split Tailwind utility functions out to a shared package (#5777)

## Summary

Split tailwind utils out to a shared package within the monorepo.

## Changes

- Creates `@comfyorg/tailwind-utils` package
- Does not require export, publishing, etc
- Uses `export` to ensure this change does not impact other PRs (many
imports to update)
- If we _want_ to update all imports, there are two commits ready to be
re-applied
  - e.g. `git revert 80960c2a82c0d1ac06eee1bb83ac333216b2b376`

## Review Focus

- Is this pattern desirable?
- Should we just include this in a broader design-system split? I kind
of vote yes, but also it's a good small, first step.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5777-Split-Tailwind-utility-functions-out-to-a-shared-package-2796d73d3650815f976fc73b4fb86ef3)
by [Unito](https://www.unito.io)
This commit is contained in:
filtered
2025-09-26 09:55:21 +10:00
committed by GitHub
parent 703de3e669
commit 961af8731e
7 changed files with 104 additions and 20 deletions

View File

@@ -107,6 +107,7 @@
"@alloc/quick-lru": "^5.2.0",
"@atlaskit/pragmatic-drag-and-drop": "^1.3.1",
"@comfyorg/comfyui-electron-types": "0.4.73-0",
"@comfyorg/tailwind-utils": "workspace:*",
"@iconify/json": "^2.2.380",
"@primeuix/forms": "0.0.2",
"@primeuix/styled": "0.3.2",
@@ -130,7 +131,6 @@
"algoliasearch": "^5.21.0",
"axios": "^1.8.2",
"chart.js": "^4.5.0",
"clsx": "^2.1.1",
"dompurify": "^3.2.5",
"dotenv": "^16.4.5",
"es-toolkit": "^1.39.9",
@@ -148,7 +148,6 @@
"primevue": "^4.2.5",
"reka-ui": "^2.5.0",
"semver": "^7.7.2",
"tailwind-merge": "^3.3.1",
"three": "^0.170.0",
"tiptap-markdown": "^0.8.10",
"vue": "^3.5.13",

View File

@@ -0,0 +1,31 @@
# @comfyorg/tailwind-utils
Shared Tailwind CSS utility functions for the ComfyUI Frontend monorepo.
## Usage
The `cn` function combines `clsx` and `tailwind-merge` to handle conditional classes and resolve Tailwind conflicts.
```typescript
import { cn } from '@comfyorg/tailwind-utils'
// Use with conditional classes (object)
<div :class="cn('transition-opacity', { 'opacity-75': !isHovered })" />
// Use with conditional classes (ternary)
<button
:class="cn('px-4 py-2', isActive ? 'bg-blue-500' : 'bg-gray-500')"
/>
```
## Installation
This package is part of the ComfyUI Frontend monorepo and is automatically available to all workspace packages.
```json
{
"dependencies": {
"@comfyorg/tailwind-utils": "workspace:*"
}
}
```

View File

@@ -0,0 +1,30 @@
{
"name": "@comfyorg/tailwind-utils",
"version": "1.0.0",
"type": "module",
"description": "Shared Tailwind CSS utilities for ComfyUI Frontend",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"import": "./src/index.ts",
"types": "./src/index.ts"
}
},
"scripts": {
"typecheck": "tsc --noEmit"
},
"nx": {
"tags": [
"scope:shared",
"type:util"
]
},
"dependencies": {
"clsx": "^2.1.1",
"tailwind-merge": "^2.2.0"
},
"devDependencies": {
"typescript": "^5.4.5"
}
}

View File

@@ -0,0 +1,8 @@
import clsx, { type ClassArray } from 'clsx'
import { twMerge } from 'tailwind-merge'
export type { ClassValue } from 'clsx'
export function cn(...inputs: ClassArray) {
return twMerge(clsx(inputs))
}

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"
},
"include": ["src/**/*"]
}

35
pnpm-lock.yaml generated
View File

@@ -17,6 +17,9 @@ importers:
'@comfyorg/comfyui-electron-types':
specifier: 0.4.73-0
version: 0.4.73-0
'@comfyorg/tailwind-utils':
specifier: workspace:*
version: link:packages/tailwind-utils
'@iconify/json':
specifier: ^2.2.380
version: 2.2.380
@@ -86,9 +89,6 @@ importers:
chart.js:
specifier: ^4.5.0
version: 4.5.0
clsx:
specifier: ^2.1.1
version: 2.1.1
dompurify:
specifier: ^3.2.5
version: 3.2.5
@@ -140,9 +140,6 @@ importers:
semver:
specifier: ^7.7.2
version: 7.7.2
tailwind-merge:
specifier: ^3.3.1
version: 3.3.1
three:
specifier: ^0.170.0
version: 0.170.0
@@ -355,6 +352,19 @@ importers:
specifier: ^3.24.1
version: 3.24.1(zod@3.24.1)
packages/tailwind-utils:
dependencies:
clsx:
specifier: ^2.1.1
version: 2.1.1
tailwind-merge:
specifier: ^2.2.0
version: 2.6.0
devDependencies:
typescript:
specifier: ^5.4.5
version: 5.9.2
packages:
'@adobe/css-tools@4.4.3':
@@ -5888,8 +5898,8 @@ packages:
resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==}
engines: {node: ^14.18.0 || >=16.0.0}
tailwind-merge@3.3.1:
resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==}
tailwind-merge@2.6.0:
resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==}
tailwindcss-primeui@0.6.1:
resolution: {integrity: sha512-T69Rylcrmnt8zy9ik+qZvsLuRIrS9/k6rYJSIgZ1trnbEzGDDQSCIdmfyZknevqiHwpSJHSmQ9XT2C+S/hJY4A==}
@@ -6323,6 +6333,9 @@ packages:
vue-component-type-helpers@3.0.7:
resolution: {integrity: sha512-TvyUcFXmjZcXUvU+r1MOyn4/vv4iF+tPwg5Ig33l/FJ3myZkxeQpzzQMLMFWcQAjr6Xs7BRwVy/TwbmNZUA/4w==}
vue-component-type-helpers@3.0.8:
resolution: {integrity: sha512-WyR30Eq15Y/+odrUUMax6FmPbZwAp/HnC7qgR1r3lVFAcqwQ4wUoV79Mbh4SxDy3NiqDa+G4TOKD5xXSgBHo5A==}
vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
@@ -8879,7 +8892,7 @@ snapshots:
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))
type-fest: 2.19.0
vue: 3.5.13(typescript@5.9.2)
vue-component-type-helpers: 3.0.7
vue-component-type-helpers: 3.0.8
'@swc/helpers@0.5.17':
dependencies:
@@ -13075,7 +13088,7 @@ snapshots:
dependencies:
'@pkgr/core': 0.2.9
tailwind-merge@3.3.1: {}
tailwind-merge@2.6.0: {}
tailwindcss-primeui@0.6.1(tailwindcss@4.1.12):
dependencies:
@@ -13545,6 +13558,8 @@ snapshots:
vue-component-type-helpers@3.0.7: {}
vue-component-type-helpers@3.0.8: {}
vue-demi@0.14.10(vue@3.5.13(typescript@5.9.2)):
dependencies:
vue: 3.5.13(typescript@5.9.2)

View File

@@ -1,8 +1 @@
import clsx, { type ClassArray } from 'clsx'
import { twMerge } from 'tailwind-merge'
export type { ClassValue } from 'clsx'
export function cn(...inputs: ClassArray) {
return twMerge(clsx(inputs))
}
export { cn, type ClassValue } from '@comfyorg/tailwind-utils'