Spaces:
No application file
No application file
FORGE-X: Upload source (chrome_extension.zip)
Browse files- README.md +62 -7
- background/service-worker.js +15 -0
- content/content.js +18 -0
- icons/icon128.png +0 -0
- icons/icon16.png +0 -0
- icons/icon32.png +0 -0
- icons/icon48.png +0 -0
- manifest.json +54 -0
- popup/popup.css +11 -0
- popup/popup.html +23 -0
- popup/popup.js +19 -0
README.md
CHANGED
|
@@ -1,13 +1,68 @@
|
|
| 1 |
---
|
| 2 |
-
title: Tailwind
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version:
|
| 8 |
-
python_version: '3.13'
|
| 9 |
app_file: app.py
|
| 10 |
pinned: false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
---
|
|
|
|
| 12 |
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: "Tailwind CSS Component Preview Extension"
|
| 3 |
+
emoji: 🎨
|
| 4 |
+
colorFrom: yellow
|
| 5 |
+
colorTo: blue
|
| 6 |
sdk: gradio
|
| 7 |
+
sdk_version: 4.44.0
|
|
|
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
+
license: mit
|
| 11 |
+
tags:
|
| 12 |
+
- frontend
|
| 13 |
+
- web-development
|
| 14 |
+
- javascript
|
| 15 |
+
- react
|
| 16 |
+
- development
|
| 17 |
+
- extension
|
| 18 |
+
- tailwind
|
| 19 |
+
- component
|
| 20 |
---
|
| 21 |
+
# Tailwind CSS Component Preview Extension
|
| 22 |
|
| 23 |
+
Analyzes any webpage for Tailwind CSS utility class usage. Detects Tailwind components, counts utility classes by category, and shows which design patterns are used on the page.
|
| 24 |
+
|
| 25 |
+
## Key Features
|
| 26 |
+
|
| 27 |
+
- Detects whether a page uses Tailwind CSS
|
| 28 |
+
- Counts utility classes by category: colors, spacing, layout, typography
|
| 29 |
+
- Shows the most frequently used Tailwind classes on any page
|
| 30 |
+
- Identifies how many elements use Tailwind utilities vs plain CSS
|
| 31 |
+
- Helps developers learn Tailwind patterns from live sites
|
| 32 |
+
|
| 33 |
+
## How It Works
|
| 34 |
+
|
| 35 |
+
Click the extension icon on any webpage. The extension scans all DOM elements, identifies Tailwind CSS utility classes, and categorizes them by function (color, spacing, layout, typography). Results display instantly in the popup — no page reload needed.
|
| 36 |
+
|
| 37 |
+
## What You Get
|
| 38 |
+
|
| 39 |
+
- One-click Tailwind CSS detection and analysis
|
| 40 |
+
- Class categorization by utility type
|
| 41 |
+
- Works on any website — inspect any site's Tailwind usage
|
| 42 |
+
- Privacy-first — all analysis runs locally in your browser
|
| 43 |
+
|
| 44 |
+
## 🚀 Usage
|
| 45 |
+
|
| 46 |
+
1. Click **Use in Spaces** above to run the demo directly
|
| 47 |
+
2. Or clone the repository and run locally:
|
| 48 |
+
|
| 49 |
+
```bash
|
| 50 |
+
git clone https://huggingface.co/spaces/WealthFromAI/tailwind-css-component-preview-extension-10c0
|
| 51 |
+
cd tailwind-css-component-preview-extension-10c0
|
| 52 |
+
pip install -r requirements.txt
|
| 53 |
+
python app.py
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
## 💰 Pricing
|
| 57 |
+
|
| 58 |
+
- **Demo**: Free on Hugging Face Spaces
|
| 59 |
+
- **Full Source Code**: $14.99
|
| 60 |
+
- Available on [Gumroad](https://gumroad.com) and [Whop](https://whop.com)
|
| 61 |
+
|
| 62 |
+
## 📄 License
|
| 63 |
+
|
| 64 |
+
MIT License — free to use, modify, and distribute.
|
| 65 |
+
|
| 66 |
+
---
|
| 67 |
+
|
| 68 |
+
*Built with [FORGE-X](https://github.com/WealthFromAI) — automated digital product engine*
|
background/service-worker.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
chrome.runtime.onInstalled.addListener((details) => {
|
| 2 |
+
if (details.reason === 'install') {
|
| 3 |
+
console.log('Tailwind CSS Component Preview Extension installed');
|
| 4 |
+
chrome.storage.local.set({ installDate: Date.now(), version: '1.0.0' });
|
| 5 |
+
}
|
| 6 |
+
});
|
| 7 |
+
|
| 8 |
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
| 9 |
+
if (message.type === 'getState') {
|
| 10 |
+
chrome.storage.local.get(null, (data) => {
|
| 11 |
+
sendResponse(data);
|
| 12 |
+
});
|
| 13 |
+
return true;
|
| 14 |
+
}
|
| 15 |
+
});
|
content/content.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
| 2 |
+
if (request.action === 'analyze') {
|
| 3 |
+
try {
|
| 4 |
+
var data = {
|
| 5 |
+
status: 'ok',
|
| 6 |
+
title: document.title,
|
| 7 |
+
url: window.location.href,
|
| 8 |
+
headings: document.querySelectorAll('h1,h2,h3').length,
|
| 9 |
+
links: document.querySelectorAll('a[href]').length,
|
| 10 |
+
images: document.querySelectorAll('img').length
|
| 11 |
+
};
|
| 12 |
+
sendResponse(data);
|
| 13 |
+
} catch (e) {
|
| 14 |
+
sendResponse({ status: 'error', message: e.message });
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
return true;
|
| 18 |
+
});
|
icons/icon128.png
ADDED
|
|
icons/icon16.png
ADDED
|
|
icons/icon32.png
ADDED
|
|
icons/icon48.png
ADDED
|
|
manifest.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"manifest_version": 3,
|
| 3 |
+
"name": "Tailwind CSS Component Preview Extension",
|
| 4 |
+
"short_name": "Tailwind CSS",
|
| 5 |
+
"version": "1.0.0",
|
| 6 |
+
"description": "",
|
| 7 |
+
"author": "ForgeX Empire",
|
| 8 |
+
"homepage_url": "https://gumroad.com",
|
| 9 |
+
"permissions": [
|
| 10 |
+
"activeTab",
|
| 11 |
+
"storage",
|
| 12 |
+
"scripting"
|
| 13 |
+
],
|
| 14 |
+
"host_permissions": [
|
| 15 |
+
"http://*/*",
|
| 16 |
+
"https://*/*"
|
| 17 |
+
],
|
| 18 |
+
"background": {
|
| 19 |
+
"service_worker": "background/service-worker.js",
|
| 20 |
+
"type": "module"
|
| 21 |
+
},
|
| 22 |
+
"action": {
|
| 23 |
+
"default_popup": "popup/popup.html",
|
| 24 |
+
"default_title": "Tailwind CSS Component Preview Extension",
|
| 25 |
+
"default_icon": {
|
| 26 |
+
"16": "icons/icon16.png",
|
| 27 |
+
"32": "icons/icon32.png",
|
| 28 |
+
"48": "icons/icon48.png",
|
| 29 |
+
"128": "icons/icon128.png"
|
| 30 |
+
}
|
| 31 |
+
},
|
| 32 |
+
"content_scripts": [
|
| 33 |
+
{
|
| 34 |
+
"matches": [
|
| 35 |
+
"http://*/*",
|
| 36 |
+
"https://*/*"
|
| 37 |
+
],
|
| 38 |
+
"js": [
|
| 39 |
+
"content/content.js"
|
| 40 |
+
],
|
| 41 |
+
"run_at": "document_idle",
|
| 42 |
+
"all_frames": false
|
| 43 |
+
}
|
| 44 |
+
],
|
| 45 |
+
"icons": {
|
| 46 |
+
"16": "icons/icon16.png",
|
| 47 |
+
"32": "icons/icon32.png",
|
| 48 |
+
"48": "icons/icon48.png",
|
| 49 |
+
"128": "icons/icon128.png"
|
| 50 |
+
},
|
| 51 |
+
"content_security_policy": {
|
| 52 |
+
"extension_pages": "script-src 'self'; object-src 'self'"
|
| 53 |
+
}
|
| 54 |
+
}
|
popup/popup.css
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
| 3 |
+
body { width: 350px; min-height: 200px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #fff; color: #1a1a1a; }
|
| 4 |
+
header { background: #2d5be3; color: #fff; padding: 12px 16px; }
|
| 5 |
+
header h1 { font-size: 14px; font-weight: 600; }
|
| 6 |
+
.content { padding: 16px; }
|
| 7 |
+
.btn { display: inline-block; background: #2d5be3; color: #fff; border: none; border-radius: 6px; padding: 8px 16px; font-size: 13px; cursor: pointer; width: 100%; text-align: center; }
|
| 8 |
+
.btn:hover { background: #1a3fa8; }
|
| 9 |
+
.result { margin-top: 12px; padding: 10px; background: #f5f7ff; border-radius: 6px; font-size: 12px; }
|
| 10 |
+
.upgrade { display: block; text-align: center; margin-top: 10px; font-size: 11px; color: #888; text-decoration: none; }
|
| 11 |
+
.upgrade:hover { color: #2d5be3; }
|
popup/popup.html
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
```html
|
| 2 |
+
<!DOCTYPE html>
|
| 3 |
+
<html lang="en">
|
| 4 |
+
<head>
|
| 5 |
+
<meta charset="UTF-8">
|
| 6 |
+
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'self';">
|
| 7 |
+
<meta name="viewport" content="width=350, initial-scale=1.0">
|
| 8 |
+
<title>Tailwind CSS Component Preview Extension</title>
|
| 9 |
+
<link rel="stylesheet" href="popup.css">
|
| 10 |
+
</head>
|
| 11 |
+
<body>
|
| 12 |
+
<div class="container">
|
| 13 |
+
<h1>Tailwind CSS Component Preview Extension</h1>
|
| 14 |
+
<p>Easily preview and inspect Tailwind CSS components in your browser.</p>
|
| 15 |
+
<h2>Main Feature</h2>
|
| 16 |
+
<p>Click on any Tailwind CSS class in a web page to see a preview of the component.</p>
|
| 17 |
+
<button>Get Started</button>
|
| 18 |
+
<a href="#" class="upgrade-btn">Upgrade to Pro</a>
|
| 19 |
+
</div>
|
| 20 |
+
<script src="popup.js"></script>
|
| 21 |
+
</body>
|
| 22 |
+
</html>
|
| 23 |
+
```
|
popup/popup.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 2 |
+
const btn = document.getElementById('analyze');
|
| 3 |
+
const result = document.getElementById('result');
|
| 4 |
+
if (btn) {
|
| 5 |
+
btn.addEventListener('click', () => {
|
| 6 |
+
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
| 7 |
+
if (tabs[0]) {
|
| 8 |
+
chrome.tabs.sendMessage(tabs[0].id, { action: 'analyze' }, (response) => {
|
| 9 |
+
if (chrome.runtime.lastError) {
|
| 10 |
+
result.textContent = 'Could not connect to page. Try refreshing.';
|
| 11 |
+
return;
|
| 12 |
+
}
|
| 13 |
+
result.textContent = response ? JSON.stringify(response, null, 2) : 'No data';
|
| 14 |
+
});
|
| 15 |
+
}
|
| 16 |
+
});
|
| 17 |
+
});
|
| 18 |
+
}
|
| 19 |
+
});
|