Skip to content
Open
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
740 changes: 432 additions & 308 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "next lint --fix",
"lint:check": "next lint"
"lint:check": "next lint",
"postinstall": "node scripts/patch-plasmo-with-tailwind-4.js"
},
"dependencies": {
"@emotion/react": "^11.14.0",
Expand All @@ -33,12 +34,12 @@
"react-dom": "^19.1.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.14",
"@types/chrome": "^0.0.318",
"@types/node": "^22.15.3",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.3",
"@typescript-eslint/eslint-plugin": "^8.31.1",
"autoprefixer": "^10.4.21",
"cross-env": "^7.0.3",
"eslint": "^9.26.0",
"eslint-config-next": "^15.3.1",
Expand All @@ -49,7 +50,7 @@
"eslint-plugin-simple-import-sort": "^12.1.1",
"postcss": "^8.5.3",
"prettier": "^3.5.3",
"tailwindcss": "^3.4.17",
"tailwindcss": "^4.1.14",
"typescript": "^5.8.3"
},
"eslintConfig": {
Expand Down
3 changes: 1 addition & 2 deletions postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
'@tailwindcss/postcss': {},
},
};
173 changes: 173 additions & 0 deletions scripts/patch-plasmo-with-tailwind-4.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#!/usr/bin/env node

/**
* Plasmo + Tailwind v4 Compatibility Patch
*
* Automatically fixes "node:" import issues in jiti and @tailwindcss/oxide
* that cause Plasmo builds to fail when using Tailwind CSS v4.
*
* @see https://github.com/PlasmoHQ/plasmo/issues/1188
*/

const fs = require('fs');
const path = require('path');

// Console colors
const c = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
cyan: '\x1b[36m',
};

const log = (msg, color = 'reset') =>
console.log(`${c[color]}${msg}${c.reset}`);

/**
* Find package files that need patching
*/
const findPackageFiles = () => {
const nodeModules = path.resolve('node_modules');
if (!fs.existsSync(nodeModules)) return [];

const files = [];
const pnpmPath = path.join(nodeModules, '.pnpm');

// Helper to safely read directory
const readDir = (dir) => {
try {
return fs.existsSync(dir) ? fs.readdirSync(dir) : [];
} catch {
return [];
}
};

// Helper to check file exists
const fileExists = (filePath) => {
try {
return fs.existsSync(filePath);
} catch {
return false;
}
};

// Find jiti files
const findJitiFiles = (basePath) => {
const jitiPath = path.join(basePath, 'jiti');
if (!fileExists(jitiPath)) return [];

const targets = ['dist/jiti.cjs', 'dist/babel.cjs', 'lib/jiti.cjs'];

return targets
.map((target) => path.join(jitiPath, target))
.filter(fileExists);
};

// Find oxide files
const findOxideFiles = (basePath) => {
const oxidePath = path.join(basePath, '@tailwindcss', 'oxide', 'index.js');
return fileExists(oxidePath) ? [oxidePath] : [];
};

// Search pnpm structure
if (fileExists(pnpmPath)) {
readDir(pnpmPath).forEach((entry) => {
if (entry.startsWith('jiti@')) {
const packagePath = path.join(pnpmPath, entry, 'node_modules');
files.push(...findJitiFiles(packagePath));
}

if (
entry.startsWith('@tailwindcss+oxide@') ||
entry.startsWith('%40tailwindcss+oxide@')
) {
const packagePath = path.join(pnpmPath, entry, 'node_modules');
files.push(...findOxideFiles(packagePath));
}
});
}

// Search regular node_modules
files.push(...findJitiFiles(nodeModules));
files.push(...findOxideFiles(nodeModules));

return [...new Set(files)]; // Remove duplicates
};

/**
* Patch a single file
*/
const patchFile = (filePath) => {
try {
if (!fs.existsSync(filePath)) {
log(`⚠️ File not found: ${path.basename(filePath)}`, 'yellow');
return false;
}

const content = fs.readFileSync(filePath, 'utf8');
const hasNodeImports =
content.includes('require("node:') || content.includes("require('node:");

if (!hasNodeImports) {
log(`✅ ${path.basename(filePath)} - already patched`, 'green');
return true;
}

// Apply patches for both quote styles
const patched = content
.replace(/require\("node:([^"]+)"\)/g, 'require("$1")')
.replace(/require\('node:([^']+)'\)/g, "require('$1')");

fs.writeFileSync(filePath, patched, 'utf8');
log(`✅ ${path.basename(filePath)} - patched successfully`, 'green');
return true;
} catch (error) {
log(`❌ ${path.basename(filePath)} - error: ${error.message}`, 'red');
return false;
}
};

/**
* Main execution
*/
const main = () => {
log('🔧 Plasmo + Tailwind v4 compatibility patch', 'cyan');

const files = findPackageFiles();

if (files.length === 0) {
log('⚠️ No files found to patch', 'yellow');
log(
' This might mean packages are not installed or using different structure',
'yellow',
);
return;
}

log(` Found ${files.length} files to check`, 'blue');

const results = files.map(patchFile);
const successful = results.filter(Boolean).length;

log(''); // Empty line

if (successful === files.length) {
log('🎉 All files patched successfully!', 'green');
log(' Tailwind v4 should now work with Plasmo', 'green');
} else {
log(`⚠️ ${successful}/${files.length} files patched`, 'yellow');
}

if (successful === 0) {
log('💡 Try running: pnpm install && node scripts/patch-jiti.js', 'blue');
}
};

// Execute if run directly
if (require.main === module) {
main();
}

module.exports = { main, patchFile, findPackageFiles };
2 changes: 1 addition & 1 deletion src/popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function IndexPopup() {
},
breakpoints: {
values: {
//copied from tailwind.config.js
//copied from globals.css
xs: 0,
sm: 640,
md: 768,
Expand Down
62 changes: 47 additions & 15 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
@@ -1,25 +1,57 @@
@import url('https://fonts.googleapis.com/css2?family=Bai+Jamjuree:wght@500;600;700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Bai+Jamjuree:wght@500;600;700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap')
layer(base);

@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'tailwindcss';

* {
box-sizing: border-box;
/*If changing be sure to update in popup.tsx too*/
@theme {
--color-haiti: #090b2c;
--color-persimmon-50: #ffe5de;
--color-persimmon-100: #ffcabd;
--color-persimmon-200: #ffb09d;
--color-persimmon-300: #ff947e;
--color-persimmon-400: #ff7760;
--color-persimmon-500: #ff5743; /* brand accent, danger*/
--color-persimmon-600: #d14a39;
--color-persimmon-700: #a43d2e;
--color-persimmon-800: #793025;
--color-persimmon-900: #51231b;
--color-royal: #573dff; /* brand secondary (dark)*/
--color-royal-dark: #3c2ab2;
--color-cornflower-50: #eae4ff;
--color-cornflower-100: #d3caff; /* ~periwinkle*/
--color-cornflower-200: #bcb0fe;
--color-cornflower-300: #a297fd;
--color-cornflower-400: #857efc;
--color-cornflower-500: #6266fa; /* brand primary*/
--color-cornflower-600: #5455cc;
--color-cornflower-700: #45449f; /* ~royal*/
--color-cornflower-800: #363475;
--color-cornflower-900: #28254d;
--color-periwinkle: #c2c8ff; /* brand secondary (light)*/
--color-shade: #101828; /* drop shadow color from shipfaster ui*/

--font-display: Bai Jamjuree, Roboto, sans-serif;
--font-main: Inter, Roboto, sans-serif;
}

@layer base {
html,
body {
@apply font-main;
}
@utility bg-lighten {
background-color: rgba(255, 255, 255, 0.6);
}

@utility bg-darken {
background-color: rgba(0, 0, 0, 0.6);
}

@layer utilities {
.bg-lighten {
background-color: rgba(255, 255, 255, 0.6);
* {
box-sizing: border-box;
}
.bg-darken {
background-color: rgba(0, 0, 0, 0.6);
}

@layer base {
html,
body {
@apply font-main;
}
}
2 changes: 1 addition & 1 deletion src/tabs/permissions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function PermissionsPls() {
variant="contained"
disableElevation
size="large"
className="normal-case bg-royal hover:bg-royalDark"
className="normal-case bg-royal hover:bg-royal-dark"
onClick={async () => {
const response = await realBrowser.permissions.request({
origins: neededOrigins,
Expand Down
47 changes: 0 additions & 47 deletions tailwind.config.js

This file was deleted.