Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support browser runtime for tw plugin #1072

Merged
merged 8 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lazy-dodos-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"uploadthing": minor
---

feat: add conditional `browser` export to support importing of tailwind config in the browser
2 changes: 1 addition & 1 deletion packages/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@types/react": "18.3.3",
"@uploadthing/eslint-config": "workspace:*",
"@uploadthing/tsconfig": "workspace:*",
"bunchee": "^5.2.1",
"bunchee": "^5.6.2",
"eslint": "^8.57.0",
"expo-constants": "^15.4.5",
"expo-document-picker": "^12.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/mime-types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"devDependencies": {
"@uploadthing/eslint-config": "workspace:*",
"@uploadthing/tsconfig": "workspace:*",
"bunchee": "^5.2.1",
"bunchee": "^5.6.2",
"eslint": "^8.57.0",
"typescript": "^5.5.2"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"@uploadthing/eslint-config": "workspace:*",
"@uploadthing/tsconfig": "workspace:*",
"@vitest/browser": "2.1.2",
"bunchee": "^5.2.1",
"bunchee": "^5.6.2",
"concurrently": "^8.2.2",
"eslint": "^8.57.0",
"next": "14.2.11",
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"@types/react": "18.3.3",
"@uploadthing/eslint-config": "workspace:",
"@uploadthing/tsconfig": "workspace:",
"bunchee": "^5.2.1",
"bunchee": "^5.6.2",
"eslint": "^8.57.0",
"react": "18.3.1",
"solid-js": "^1.8.23",
Expand Down
3 changes: 2 additions & 1 deletion packages/uploadthing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
}
},
"./tw": {
"browser": "./tw/index.browser.js",
juliusmarminge marked this conversation as resolved.
Show resolved Hide resolved
"import": {
"types": "./tw/index.d.ts",
"default": "./tw/index.js"
Expand Down Expand Up @@ -165,7 +166,7 @@
"@uploadthing/eslint-config": "workspace:*",
"@uploadthing/tsconfig": "workspace:*",
"body-parser": "^1.20.2",
"bunchee": "^5.2.1",
"bunchee": "^5.6.2",
"eslint": "^8.57.0",
"express": "^4.18.2",
"fastify": "^4.26.1",
Expand Down
79 changes: 0 additions & 79 deletions packages/uploadthing/src/tw.ts

This file was deleted.

15 changes: 15 additions & 0 deletions packages/uploadthing/src/tw/index.browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Config } from "tailwindcss";

import { uploadthingPlugin } from "./plugin";

export { uploadthingPlugin };

export function withUt(twConfig: Config) {
if (!twConfig.plugins) {
twConfig.plugins = [];
}

twConfig.plugins.push(uploadthingPlugin);

return twConfig;
}
juliusmarminge marked this conversation as resolved.
Show resolved Hide resolved
60 changes: 60 additions & 0 deletions packages/uploadthing/src/tw/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { dirname, sep } from "node:path";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Consider browser compatibility for Node.js imports

The node:path import will cause issues in browser environments. Given the PR's objective to support browser runtime, this needs to be addressed.

Consider creating a browser-specific version without Node.js dependencies:

- import { dirname, sep } from "node:path";
+ // For browser version:
+ const sep = '/';
+ const dirname = (path: string) => path.substring(0, path.lastIndexOf(sep));

Committable suggestion skipped: line range outside the PR's diff.

import type { Config } from "tailwindcss";

import { uploadthingPlugin } from "./plugin";

export { uploadthingPlugin };

/**
* Add more here when additional UI packages are added
*/
const PACKAGES = ["react", "solid", "svelte", "vue"];

/**
* HOF for Tailwind config that adds the
* {@link uploadthingPlugin} to the Tailwind config
* as well as adds content paths to detect the necessary
* classnames
*/
export function withUt(twConfig: Config) {
const contentPaths = PACKAGES.map((pkg) => {
try {
const resolved = require.resolve(`@uploadthing/${pkg}`, {
paths: [...module.paths, process.cwd()],
});

return dirname(resolved) + sep + "**";
} catch {
return null;
}
}).filter((s) => s != null);

if (contentPaths.length === 0) {
// eslint-disable-next-line no-console
console.warn(`
[uploadthing]: Unable to resolve path for uploadthing UI packages. As a workaround, you can manually add the paths to your content paths:
- Find where your package manager has installed the distribution files, e.g. './node_modules/@uploadthing/react'.
Note: If you have a monorepo, you may need to look up the tree to find the correct path.
- Add the path to the 'content' field in your Tailwind configuration:
content: [
// your other content paths
'./node_modules/@uploadthing/react/dist**' // <-- add this line
]
`);
}

if (Array.isArray(twConfig.content)) {
twConfig.content.push(...contentPaths);
} else {
// content can be an object too with `files` property
twConfig.content.files.push(...contentPaths);
}
Comment on lines +46 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add type checking for content object structure

The code assumes the content object has a files property without type checking.

Add type checking to prevent runtime errors:

  } else {
    // content can be an object too with `files` property
+   if (!twConfig.content || !Array.isArray(twConfig.content.files)) {
+     twConfig.content = { files: [] };
+   }
    twConfig.content.files.push(...contentPaths);
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (Array.isArray(twConfig.content)) {
twConfig.content.push(...contentPaths);
} else {
// content can be an object too with `files` property
twConfig.content.files.push(...contentPaths);
}
if (Array.isArray(twConfig.content)) {
twConfig.content.push(...contentPaths);
} else {
// content can be an object too with `files` property
if (!twConfig.content || !Array.isArray(twConfig.content.files)) {
twConfig.content = { files: [] };
}
twConfig.content.files.push(...contentPaths);
}


if (!twConfig.plugins) {
twConfig.plugins = [];
}

twConfig.plugins.push(uploadthingPlugin);

return twConfig;
}
23 changes: 23 additions & 0 deletions packages/uploadthing/src/tw/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import plugin from "tailwindcss/plugin";

/**
* UploadThing Tailwind plugin which injects custom variants
* for the built-in UI components
* @see https://docs.uploadthing.com/concepts/theming#theming-with-tailwind-css
*
* When using this, you need to specify `content` manually. For automatic
* detection, see {@link withUt}.
*/
export const uploadthingPlugin = plugin(({ addVariant }) => {
// Variants to select specific underlying element
addVariant("ut-button", '&>*[data-ut-element="button"]');
addVariant("ut-allowed-content", '&>*[data-ut-element="allowed-content"]');
addVariant("ut-label", '&>*[data-ut-element="label"]');
addVariant("ut-upload-icon", '&>*[data-ut-element="upload-icon"]');
addVariant("ut-clear-btn", '&>*[data-ut-element="clear-btn"]');

// Variants to select specific state
addVariant("ut-readying", '&[data-state="readying"]');
addVariant("ut-ready", '&[data-state="ready"]');
addVariant("ut-uploading", '&[data-state="uploading"]');
});
2 changes: 1 addition & 1 deletion packages/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"devDependencies": {
"@uploadthing/eslint-config": "workspace:*",
"@uploadthing/tsconfig": "workspace:*",
"bunchee": "^5.2.1",
"bunchee": "^5.6.2",
"concurrently": "^8.2.2",
"tailwindcss": "^3.4.1",
"typescript": "^5.5.2",
Expand Down
Loading
Loading