tailwind-to-style 2.8.4 → 2.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -8
- package/dist/index.browser.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/lib/twsx-cli.js +114 -0
- package/package.json +5 -1
- package/lib/build-twsx.js +0 -59
package/README.md
CHANGED
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
`tailwind-to-style` is a JavaScript library designed to convert Tailwind CSS utility classes into inline styles or JavaScript objects. This is especially useful when you need to dynamically apply styles to elements in frameworks like React, where inline styles or style objects are frequently used.
|
|
9
9
|
|
|
10
|
-
The library exposes two main functions:
|
|
10
|
+
The library exposes two main functions and a CLI tool:
|
|
11
11
|
|
|
12
12
|
1. **`tws`**: Converts Tailwind CSS classes into inline CSS styles or JavaScript objects (JSON).
|
|
13
13
|
2. **`twsx`**: A more advanced function that allows you to define nested and complex styles similar to SCSS, including support for responsive, state variants, and grouping.
|
|
14
|
+
3. **`twsx-cli`**: A command-line tool for generating CSS files from `twsx.*.js` files with watch mode support.
|
|
14
15
|
|
|
15
16
|
## Installation
|
|
16
17
|
|
|
@@ -547,38 +548,90 @@ import './styles/twsx.button.css';
|
|
|
547
548
|
|
|
548
549
|
In addition to using the Vite/Webpack plugin, you can also use a Node.js script to generate CSS files from `twsx.*.js` files manually or as part of your build workflow.
|
|
549
550
|
|
|
550
|
-
### Script: tailwind-to-style/lib/
|
|
551
|
+
### Script: tailwind-to-style/lib/twsx-cli.js (Legacy)
|
|
552
|
+
|
|
553
|
+
> **💡 Recommended:** Use `npx twsx-cli` instead of calling the script directly.
|
|
551
554
|
|
|
552
555
|
This script will recursively scan for all `twsx.*.js` files in your project, generate CSS using the `twsx` function, and write individual CSS files to the specified output directory.
|
|
553
556
|
|
|
554
557
|
#### How to Use
|
|
555
558
|
|
|
556
559
|
1. Create JS files with `twsx.` prefix containing style objects anywhere in your `src/` folder (e.g., `src/components/twsx.card.js`).
|
|
557
|
-
2. Run the script with the following command:
|
|
558
560
|
|
|
561
|
+
2. **One-time Build:**
|
|
562
|
+
```bash
|
|
563
|
+
node tailwind-to-style/lib/twsx-cli.js
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
3. **Watch Mode (Auto-rebuild on file changes):**
|
|
559
567
|
```bash
|
|
560
|
-
node tailwind-to-style/lib/
|
|
568
|
+
node tailwind-to-style/lib/twsx-cli.js --watch
|
|
561
569
|
```
|
|
562
570
|
|
|
563
571
|
You can configure input and output directories using environment variables:
|
|
564
572
|
```bash
|
|
565
|
-
TWSX_INPUT_DIR=src TWSX_OUTPUT_DIR=dist/styles node tailwind-to-style/lib/
|
|
573
|
+
TWSX_INPUT_DIR=src TWSX_OUTPUT_DIR=dist/styles node tailwind-to-style/lib/twsx-cli.js --watch
|
|
566
574
|
```
|
|
567
575
|
|
|
568
|
-
|
|
576
|
+
4. After running, individual CSS files will be available in the output directory (default: `src/styles/`):
|
|
569
577
|
|
|
570
578
|
```
|
|
571
579
|
src/styles/twsx.card.css
|
|
572
580
|
src/styles/twsx.button.css
|
|
573
581
|
```
|
|
574
582
|
|
|
575
|
-
|
|
583
|
+
5. Import the generated CSS files in your components:
|
|
576
584
|
|
|
577
585
|
```js
|
|
578
586
|
import './styles/twsx.card.css';
|
|
579
587
|
import './styles/twsx.button.css';
|
|
580
588
|
```
|
|
581
589
|
|
|
590
|
+
#### Usage in Different Projects
|
|
591
|
+
|
|
592
|
+
**React/Next.js/Vue/Any Project:**
|
|
593
|
+
|
|
594
|
+
1. Install the package:
|
|
595
|
+
```bash
|
|
596
|
+
npm install tailwind-to-style
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
2. Add to your `package.json`:
|
|
600
|
+
```json
|
|
601
|
+
{
|
|
602
|
+
"scripts": {
|
|
603
|
+
"twsx:build": "node node_modules/tailwind-to-style/lib/twsx-cli.js",
|
|
604
|
+
"twsx:watch": "node node_modules/tailwind-to-style/lib/twsx-cli.js --watch",
|
|
605
|
+
"dev": "npm run twsx:watch & next dev"
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
3. For development with auto-rebuild:
|
|
611
|
+
```bash
|
|
612
|
+
npm run twsx:watch
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
4. For production build:
|
|
616
|
+
```bash
|
|
617
|
+
npm run twsx:build
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
**VS Code Integration:**
|
|
621
|
+
Add to your workspace settings (`.vscode/settings.json`):
|
|
622
|
+
```json
|
|
623
|
+
{
|
|
624
|
+
"emeraldwalk.runonsave": {
|
|
625
|
+
"commands": [
|
|
626
|
+
{
|
|
627
|
+
"match": "twsx\\..*\\.js$",
|
|
628
|
+
"cmd": "npm run twsx:build"
|
|
629
|
+
}
|
|
630
|
+
]
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
```
|
|
634
|
+
|
|
582
635
|
#### Automatic Integration
|
|
583
636
|
|
|
584
637
|
You can add this script to the build section in your `package.json`:
|
|
@@ -586,7 +639,7 @@ You can add this script to the build section in your `package.json`:
|
|
|
586
639
|
```json
|
|
587
640
|
{
|
|
588
641
|
"scripts": {
|
|
589
|
-
"build-css": "node tailwind-to-style/lib/
|
|
642
|
+
"build-css": "node tailwind-to-style/lib/twsx-cli.js"
|
|
590
643
|
}
|
|
591
644
|
}
|
|
592
645
|
```
|
package/dist/index.browser.js
CHANGED
package/dist/index.cjs
CHANGED
package/dist/index.esm.js
CHANGED
package/lib/twsx-cli.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { pathToFileURL } from "url";
|
|
4
|
+
import { twsx } from "tailwind-to-style";
|
|
5
|
+
import chokidar from "chokidar";
|
|
6
|
+
|
|
7
|
+
function findTwsxFiles(dir, files = []) {
|
|
8
|
+
const items = fs.readdirSync(dir);
|
|
9
|
+
for (const item of items) {
|
|
10
|
+
const fullPath = path.join(dir, item);
|
|
11
|
+
const stat = fs.statSync(fullPath);
|
|
12
|
+
if (stat.isDirectory()) {
|
|
13
|
+
findTwsxFiles(fullPath, files);
|
|
14
|
+
} else if (item.startsWith("twsx.") && item.endsWith(".js")) {
|
|
15
|
+
files.push(fullPath);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return files;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function buildTwsx(inputDir, outputDir) {
|
|
22
|
+
try {
|
|
23
|
+
const twsxFiles = findTwsxFiles(inputDir);
|
|
24
|
+
const generatedCssFiles = [];
|
|
25
|
+
|
|
26
|
+
// Generate CSS from JS files
|
|
27
|
+
for (const filePath of twsxFiles) {
|
|
28
|
+
try {
|
|
29
|
+
const styleModule = await import(
|
|
30
|
+
pathToFileURL(filePath).href + `?update=${Date.now()}`
|
|
31
|
+
);
|
|
32
|
+
const styleObj = styleModule.default || styleModule;
|
|
33
|
+
const css = twsx(styleObj, { inject: false });
|
|
34
|
+
const fileName = path.basename(filePath).replace(/\.js$/, ".css");
|
|
35
|
+
const cssFilePath = path.join(outputDir, fileName);
|
|
36
|
+
fs.writeFileSync(cssFilePath, css);
|
|
37
|
+
generatedCssFiles.push(fileName);
|
|
38
|
+
console.log(`[twsx-cli] CSS written to ${cssFilePath}`);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error(
|
|
41
|
+
`[twsx-cli] Error importing or processing ${filePath}:`,
|
|
42
|
+
err
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Clean up orphaned CSS files
|
|
48
|
+
if (fs.existsSync(outputDir)) {
|
|
49
|
+
const existingCssFiles = fs
|
|
50
|
+
.readdirSync(outputDir)
|
|
51
|
+
.filter((file) => file.startsWith("twsx.") && file.endsWith(".css"));
|
|
52
|
+
|
|
53
|
+
for (const cssFile of existingCssFiles) {
|
|
54
|
+
if (!generatedCssFiles.includes(cssFile)) {
|
|
55
|
+
const cssFilePath = path.join(outputDir, cssFile);
|
|
56
|
+
fs.unlinkSync(cssFilePath);
|
|
57
|
+
console.log(`[twsx-cli] Removed orphaned CSS: ${cssFilePath}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} catch (err) {
|
|
62
|
+
console.error("[twsx-cli] Error scanning for twsx files:", err);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const inputDir =
|
|
67
|
+
process.env.TWSX_INPUT_DIR || path.resolve(process.cwd(), "src");
|
|
68
|
+
const outputDir =
|
|
69
|
+
process.env.TWSX_OUTPUT_DIR || path.resolve(process.cwd(), "src/styles");
|
|
70
|
+
const watchMode = process.argv.includes("--watch") || process.env.TWSX_WATCH === "true";
|
|
71
|
+
|
|
72
|
+
if (!fs.existsSync(outputDir)) {
|
|
73
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Initial build
|
|
77
|
+
(async () => {
|
|
78
|
+
try {
|
|
79
|
+
await buildTwsx(inputDir, outputDir);
|
|
80
|
+
console.log(`[twsx-cli] Initial build completed`);
|
|
81
|
+
|
|
82
|
+
if (watchMode) {
|
|
83
|
+
console.log(`[twsx-cli] Watching for changes in ${inputDir}...`);
|
|
84
|
+
|
|
85
|
+
const watcher = chokidar.watch(`${inputDir}/**/twsx.*.js`, {
|
|
86
|
+
ignored: /node_modules/,
|
|
87
|
+
persistent: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
watcher
|
|
91
|
+
.on("change", async (filePath) => {
|
|
92
|
+
console.log(`[twsx-cli] File changed: ${filePath}`);
|
|
93
|
+
await buildTwsx(inputDir, outputDir);
|
|
94
|
+
})
|
|
95
|
+
.on("add", async (filePath) => {
|
|
96
|
+
console.log(`[twsx-cli] File added: ${filePath}`);
|
|
97
|
+
await buildTwsx(inputDir, outputDir);
|
|
98
|
+
})
|
|
99
|
+
.on("unlink", async (filePath) => {
|
|
100
|
+
console.log(`[twsx-cli] File removed: ${filePath}`);
|
|
101
|
+
await buildTwsx(inputDir, outputDir);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Keep the process alive
|
|
105
|
+
process.on("SIGINT", () => {
|
|
106
|
+
console.log("\n[twsx-cli] Stopping watcher...");
|
|
107
|
+
watcher.close();
|
|
108
|
+
process.exit(0);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
} catch (err) {
|
|
112
|
+
console.error("[twsx-cli] Error writing CSS:", err);
|
|
113
|
+
}
|
|
114
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwind-to-style",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.5",
|
|
4
4
|
"description": "Convert tailwind classes to inline style",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
"lib",
|
|
16
16
|
"twsx.css"
|
|
17
17
|
],
|
|
18
|
+
"bin": {
|
|
19
|
+
"twsx-cli": "./lib/twsx-cli.js"
|
|
20
|
+
},
|
|
18
21
|
"scripts": {
|
|
19
22
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --passWithNoTests",
|
|
20
23
|
"build": "rollup -c rollup.config.js",
|
|
@@ -54,6 +57,7 @@
|
|
|
54
57
|
"@rollup/plugin-terser": "^0.4.4",
|
|
55
58
|
"babel-jest": "^28.1.0",
|
|
56
59
|
"babel-loader": "^10.0.0",
|
|
60
|
+
"chokidar": "^4.0.1",
|
|
57
61
|
"eslint": "^8.16.0",
|
|
58
62
|
"jest": "^28.1.0",
|
|
59
63
|
"prettier": "^3.5.3",
|
package/lib/build-twsx.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { pathToFileURL } from "url";
|
|
4
|
-
import { twsx } from "tailwind-to-style";
|
|
5
|
-
|
|
6
|
-
function findTwsxFiles(dir, files = []) {
|
|
7
|
-
const items = fs.readdirSync(dir);
|
|
8
|
-
for (const item of items) {
|
|
9
|
-
const fullPath = path.join(dir, item);
|
|
10
|
-
const stat = fs.statSync(fullPath);
|
|
11
|
-
if (stat.isDirectory()) {
|
|
12
|
-
findTwsxFiles(fullPath, files);
|
|
13
|
-
} else if (item.startsWith("twsx.") && item.endsWith(".js")) {
|
|
14
|
-
files.push(fullPath);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return files;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async function buildTwsx(inputDir, outputDir) {
|
|
21
|
-
try {
|
|
22
|
-
const twsxFiles = findTwsxFiles(inputDir);
|
|
23
|
-
for (const filePath of twsxFiles) {
|
|
24
|
-
try {
|
|
25
|
-
const styleModule = await import(
|
|
26
|
-
pathToFileURL(filePath).href + `?update=${Date.now()}`
|
|
27
|
-
);
|
|
28
|
-
const styleObj = styleModule.default || styleModule;
|
|
29
|
-
const css = twsx(styleObj, { inject: false });
|
|
30
|
-
const fileName = path.basename(filePath).replace(/\.js$/, ".css");
|
|
31
|
-
const cssFilePath = path.join(outputDir, fileName);
|
|
32
|
-
fs.writeFileSync(cssFilePath, css);
|
|
33
|
-
} catch (err) {
|
|
34
|
-
console.error(
|
|
35
|
-
`[build-twsx] Error importing or processing ${filePath}:`,
|
|
36
|
-
err
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
} catch (err) {
|
|
41
|
-
console.error("[build-twsx] Error scanning for twsx files:", err);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const inputDir =
|
|
46
|
-
process.env.TWSX_INPUT_DIR || path.resolve(process.cwd(), "src");
|
|
47
|
-
const outputDir =
|
|
48
|
-
process.env.TWSX_OUTPUT_DIR || path.resolve(process.cwd(), "src/styles");
|
|
49
|
-
if (!fs.existsSync(outputDir)) {
|
|
50
|
-
fs.mkdirSync(outputDir, { recursive: true });
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
(async () => {
|
|
54
|
-
try {
|
|
55
|
-
await buildTwsx(inputDir, outputDir);
|
|
56
|
-
} catch (err) {
|
|
57
|
-
console.error("[build-twsx] Error writing CSS:", err);
|
|
58
|
-
}
|
|
59
|
-
})();
|