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 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/build-twsx.js
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/build-twsx.js
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/build-twsx.js
573
+ TWSX_INPUT_DIR=src TWSX_OUTPUT_DIR=dist/styles node tailwind-to-style/lib/twsx-cli.js --watch
566
574
  ```
567
575
 
568
- 3. After running, individual CSS files will be available in the output directory (default: `src/styles/`):
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
- 4. Import the generated CSS files in your components:
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/build-twsx.js"
642
+ "build-css": "node tailwind-to-style/lib/twsx-cli.js"
590
643
  }
591
644
  }
592
645
  ```
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.4
2
+ * tailwind-to-style v2.8.5
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.4
2
+ * tailwind-to-style v2.8.5
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.4
2
+ * tailwind-to-style v2.8.5
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
@@ -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.4",
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
- })();