tailwind-to-style 2.8.3 → 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
 
@@ -490,82 +491,145 @@ This will automatically log warnings for operations taking longer than 5ms and p
490
491
 
491
492
  ### Automated Modular CSS Generation
492
493
 
493
- 1. Save your modular styles in the `src/twsx/` folder as JS files (e.g., `card.js`, `button.js`).
494
+ 1. Create JS files with `twsx.` prefix in your project (e.g., `twsx.card.js`, `twsx.button.js`) anywhere in your `src/` folder.
494
495
  2. Use the Vite/Webpack plugin from the `plugins/` folder to automatically generate CSS on every build/rebuild.
495
- 3. All generated CSS files will be merged into a single `twsx.css` file inside `node_modules/tailwind-to-style/`.
496
- 4. In React, simply import this file in your entry point: `import 'tailwind-to-style/twsx.css'`.
496
+ 3. Each JS file will generate its own CSS file in the specified output directory (default: `src/styles/`).
497
+ 4. Import the generated CSS files directly in your components or bundle them as needed.
497
498
 
498
499
  #### Vite Plugin Usage Example
499
500
 
500
501
  Add the plugin to your `vite.config.js`:
501
502
  ```js
502
- import twsxPlugin from './plugins/vite-twsx';
503
+ import twsxPlugin from 'tailwind-to-style/plugins/vite-twsx';
503
504
 
504
505
  export default {
505
506
  plugins: [
506
507
  twsxPlugin({
507
- twsxDir: 'src/twsx',
508
- outDir: 'dist'
508
+ inputDir: 'src',
509
+ outputDir: 'src/styles'
509
510
  })
510
511
  ]
511
512
  };
512
513
  ```
513
514
 
514
- After build, the merged CSS file will be automatically created at `node_modules/tailwind-to-style/twsx.css`.
515
- Import in React:
515
+ After build, individual CSS files will be created in `src/styles/` (e.g., `twsx.card.css`, `twsx.button.css`).
516
+ Import in your components:
516
517
  ```js
517
- // src/index.js
518
- import 'tailwind-to-style/twsx.css';
518
+ // Import specific CSS files
519
+ import './styles/twsx.card.css';
520
+ import './styles/twsx.button.css';
519
521
  ```
520
522
 
521
523
  #### Webpack Plugin Usage Example
522
524
 
523
525
  Add the plugin to your `webpack.config.js`:
524
526
  ```js
525
- import TwsxPlugin from './plugins/webpack-twsx';
527
+ import TwsxPlugin from 'tailwind-to-style/plugins/webpack-twsx';
526
528
 
527
529
  module.exports = {
528
530
  plugins: [
529
531
  new TwsxPlugin({
530
- twsxDir: 'src/twsx',
531
- outDir: 'dist'
532
+ inputDir: 'src',
533
+ outputDir: 'src/styles'
532
534
  })
533
535
  ]
534
536
  };
535
537
  ```
536
538
 
537
- After build, the merged CSS file will be automatically created at `node_modules/tailwind-to-style/twsx.css`.
538
- Import in React:
539
+ After build, individual CSS files will be created in `src/styles/` (e.g., `twsx.card.css`, `twsx.button.css`).
540
+ Import in your components:
539
541
  ```js
540
- // src/index.js
541
- import 'tailwind-to-style/twsx.css';
542
+ // Import specific CSS files
543
+ import './styles/twsx.card.css';
544
+ import './styles/twsx.button.css';
542
545
  ```
543
546
 
544
547
  ## Build-Time CSS Generation via Script
545
548
 
546
- In addition to using the Vite/Webpack plugin, you can also use a Node.js script to generate a CSS file from the `src/twsx` folder manually or as part of your build workflow.
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.
547
550
 
548
- ### Script: lib/build-twsx.js
551
+ ### Script: tailwind-to-style/lib/twsx-cli.js (Legacy)
549
552
 
550
- This script will read all JS files in `src/twsx`, generate CSS using the `twsx` function, and write the result to `node_modules/tailwind-to-style/twsx.css`.
553
+ > **💡 Recommended:** Use `npx twsx-cli` instead of calling the script directly.
554
+
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.
551
556
 
552
557
  #### How to Use
553
558
 
554
- 1. Make sure your JS files containing style objects are in `src/twsx`.
555
- 2. Run the script with the following command:
559
+ 1. Create JS files with `twsx.` prefix containing style objects anywhere in your `src/` folder (e.g., `src/components/twsx.card.js`).
556
560
 
561
+ 2. **One-time Build:**
557
562
  ```bash
558
- node lib/build-twsx.js
563
+ node tailwind-to-style/lib/twsx-cli.js
559
564
  ```
560
- 3. After running, the combined CSS file will be available at:
561
565
 
566
+ 3. **Watch Mode (Auto-rebuild on file changes):**
567
+ ```bash
568
+ node tailwind-to-style/lib/twsx-cli.js --watch
562
569
  ```
563
- node_modules/tailwind-to-style/twsx.css
570
+
571
+ You can configure input and output directories using environment variables:
572
+ ```bash
573
+ TWSX_INPUT_DIR=src TWSX_OUTPUT_DIR=dist/styles node tailwind-to-style/lib/twsx-cli.js --watch
564
574
  ```
565
- 4. Import this CSS file in your React entry point:
575
+
576
+ 4. After running, individual CSS files will be available in the output directory (default: `src/styles/`):
577
+
578
+ ```
579
+ src/styles/twsx.card.css
580
+ src/styles/twsx.button.css
581
+ ```
582
+
583
+ 5. Import the generated CSS files in your components:
566
584
 
567
585
  ```js
568
- import 'tailwind-to-style/twsx.css';
586
+ import './styles/twsx.card.css';
587
+ import './styles/twsx.button.css';
588
+ ```
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
+ }
569
633
  ```
570
634
 
571
635
  #### Automatic Integration
@@ -575,7 +639,7 @@ You can add this script to the build section in your `package.json`:
575
639
  ```json
576
640
  {
577
641
  "scripts": {
578
- "build-css": "node lib/build-twsx.js"
642
+ "build-css": "node tailwind-to-style/lib/twsx-cli.js"
579
643
  }
580
644
  }
581
645
  ```
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.3
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.3
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.3
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.3",
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",
@@ -21,7 +21,7 @@ async function buildTwsx(inputDir, outputDir) {
21
21
  try {
22
22
  const twsxFiles = findTwsxFiles(inputDir);
23
23
  const generatedCssFiles = [];
24
-
24
+
25
25
  // Generate CSS from JS files
26
26
  for (const filePath of twsxFiles) {
27
27
  try {
@@ -41,20 +41,17 @@ async function buildTwsx(inputDir, outputDir) {
41
41
  );
42
42
  }
43
43
  }
44
-
44
+
45
45
  // Clean up orphaned CSS files
46
46
  if (fs.existsSync(outputDir)) {
47
- const existingCssFiles = fs.readdirSync(outputDir)
48
- .filter(file => file.startsWith('twsx.') && file.endsWith('.css'));
49
-
50
- console.log(`[vite-twsx] Found ${existingCssFiles.length} existing CSS files:`, existingCssFiles);
51
- console.log(`[vite-twsx] Generated ${generatedCssFiles.length} CSS files:`, generatedCssFiles);
52
-
47
+ const existingCssFiles = fs
48
+ .readdirSync(outputDir)
49
+ .filter((file) => file.startsWith("twsx.") && file.endsWith(".css"));
50
+
53
51
  for (const cssFile of existingCssFiles) {
54
52
  if (!generatedCssFiles.includes(cssFile)) {
55
53
  const cssFilePath = path.join(outputDir, cssFile);
56
54
  fs.unlinkSync(cssFilePath);
57
- console.log(`[vite-twsx] Removed orphaned CSS: ${cssFilePath}`);
58
55
  }
59
56
  }
60
57
  }
@@ -34,7 +34,6 @@ async function buildTwsx(inputDir, outputDir) {
34
34
  const cssFilePath = path.join(outputDir, fileName);
35
35
  fs.writeFileSync(cssFilePath, css);
36
36
  generatedCssFiles.push(fileName);
37
- console.log(`[webpack-twsx] CSS written to ${cssFilePath}`);
38
37
  } catch (err) {
39
38
  console.error(
40
39
  `[webpack-twsx] Error importing or processing ${filePath}:`,
@@ -49,24 +48,11 @@ async function buildTwsx(inputDir, outputDir) {
49
48
  return file.startsWith("twsx.") && file.endsWith(".css");
50
49
  });
51
50
 
52
- if (
53
- Array.isArray(existingCssFiles) &&
54
- Array.isArray(generatedCssFiles)
55
- ) {
56
- console.log(
57
- `[webpack-twsx] Found ${existingCssFiles.length} existing CSS files:`,
58
- existingCssFiles
59
- );
60
- console.log(
61
- `[webpack-twsx] Generated ${generatedCssFiles.length} CSS files:`,
62
- generatedCssFiles
63
- );
64
-
51
+ if (Array.isArray(existingCssFiles) && Array.isArray(generatedCssFiles)) {
65
52
  for (const cssFile of existingCssFiles) {
66
53
  if (!generatedCssFiles.includes(cssFile)) {
67
54
  const cssFilePath = path.join(outputDir, cssFile);
68
55
  fs.unlinkSync(cssFilePath);
69
- console.log(`[webpack-twsx] Removed orphaned CSS: ${cssFilePath}`);
70
56
  }
71
57
  }
72
58
  }
package/lib/build-twsx.js DELETED
@@ -1,60 +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
- console.log(`[build-twsx] CSS written to ${cssFilePath}`);
34
- } catch (err) {
35
- console.error(
36
- `[build-twsx] Error importing or processing ${filePath}:`,
37
- err
38
- );
39
- }
40
- }
41
- } catch (err) {
42
- console.error("[build-twsx] Error scanning for twsx files:", err);
43
- }
44
- }
45
-
46
- const inputDir =
47
- process.env.TWSX_INPUT_DIR || path.resolve(process.cwd(), "src");
48
- const outputDir =
49
- process.env.TWSX_OUTPUT_DIR || path.resolve(process.cwd(), "src/styles");
50
- if (!fs.existsSync(outputDir)) {
51
- fs.mkdirSync(outputDir, { recursive: true });
52
- }
53
-
54
- (async () => {
55
- try {
56
- await buildTwsx(inputDir, outputDir);
57
- } catch (err) {
58
- console.error("[build-twsx] Error writing CSS:", err);
59
- }
60
- })();