tailwind-to-style 2.8.5 → 2.8.6

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
@@ -506,18 +506,29 @@ export default {
506
506
  plugins: [
507
507
  twsxPlugin({
508
508
  inputDir: 'src',
509
- outputDir: 'src/styles'
509
+ outputDir: 'src/styles',
510
+ preserveStructure: false // Set to true to generate CSS next to JS files
510
511
  })
511
512
  ]
512
513
  };
513
514
  ```
514
515
 
515
- After build, individual CSS files will be created in `src/styles/` (e.g., `twsx.card.css`, `twsx.button.css`).
516
+ **Configuration Options:**
517
+ - `inputDir`: Directory to scan for `twsx.*.js` files (default: `'src'`)
518
+ - `outputDir`: Directory where CSS files will be generated (default: `'src/styles'`)
519
+ - `preserveStructure`: Whether to generate CSS files next to their JS counterparts (default: `false`)
520
+
521
+ **Default mode:** CSS files created in `src/styles/` (e.g., `twsx.card.css`, `twsx.button.css`).
522
+ **Preserve structure mode:** CSS files created next to JS files (e.g., `src/components/Card/twsx.card.css`).
523
+
516
524
  Import in your components:
517
525
  ```js
518
- // Import specific CSS files
526
+ // Default mode
519
527
  import './styles/twsx.card.css';
520
528
  import './styles/twsx.button.css';
529
+
530
+ // Preserve structure mode
531
+ import './twsx.card.css'; // If in same directory
521
532
  ```
522
533
 
523
534
  #### Webpack Plugin Usage Example
@@ -530,18 +541,29 @@ module.exports = {
530
541
  plugins: [
531
542
  new TwsxPlugin({
532
543
  inputDir: 'src',
533
- outputDir: 'src/styles'
544
+ outputDir: 'src/styles',
545
+ preserveStructure: false // Set to true to generate CSS next to JS files
534
546
  })
535
547
  ]
536
548
  };
537
549
  ```
538
550
 
539
- After build, individual CSS files will be created in `src/styles/` (e.g., `twsx.card.css`, `twsx.button.css`).
551
+ **Configuration Options:**
552
+ - `inputDir`: Directory to scan for `twsx.*.js` files (default: `'src'`)
553
+ - `outputDir`: Directory where CSS files will be generated (default: `'src/styles'`)
554
+ - `preserveStructure`: Whether to generate CSS files next to their JS counterparts (default: `false`)
555
+
556
+ **Default mode:** CSS files created in `src/styles/` (e.g., `twsx.card.css`, `twsx.button.css`).
557
+ **Preserve structure mode:** CSS files created next to JS files (e.g., `src/components/Card/twsx.card.css`).
558
+
540
559
  Import in your components:
541
560
  ```js
542
- // Import specific CSS files
561
+ // Default mode
543
562
  import './styles/twsx.card.css';
544
563
  import './styles/twsx.button.css';
564
+
565
+ // Preserve structure mode
566
+ import './twsx.card.css'; // If in same directory
545
567
  ```
546
568
 
547
569
  ## Build-Time CSS Generation via Script
@@ -568,25 +590,56 @@ node tailwind-to-style/lib/twsx-cli.js
568
590
  node tailwind-to-style/lib/twsx-cli.js --watch
569
591
  ```
570
592
 
593
+ 4. **Preserve Structure Mode (Generate CSS next to JS files):**
594
+ ```bash
595
+ # One-time build with preserve structure
596
+ node tailwind-to-style/lib/twsx-cli.js --preserve-structure
597
+
598
+ # Watch mode with preserve structure
599
+ node tailwind-to-style/lib/twsx-cli.js --watch --preserve-structure
600
+ ```
601
+
571
602
  You can configure input and output directories using environment variables:
572
603
  ```bash
573
604
  TWSX_INPUT_DIR=src TWSX_OUTPUT_DIR=dist/styles node tailwind-to-style/lib/twsx-cli.js --watch
574
605
  ```
575
606
 
576
- 4. After running, individual CSS files will be available in the output directory (default: `src/styles/`):
607
+ Or use environment variables for preserve structure:
608
+ ```bash
609
+ TWSX_PRESERVE_STRUCTURE=true node tailwind-to-style/lib/twsx-cli.js --watch
610
+ ```
611
+
612
+ 5. **Output locations:**
577
613
 
614
+ **Default mode:** CSS files will be in the output directory (default: `src/styles/`):
578
615
  ```
579
616
  src/styles/twsx.card.css
580
617
  src/styles/twsx.button.css
581
618
  ```
582
619
 
620
+ **Preserve structure mode:** CSS files will be generated next to their JS counterparts:
621
+ ```
622
+ src/components/Button/twsx.button.js → src/components/Button/twsx.button.css
623
+ src/components/Card/twsx.card.js → src/components/Card/twsx.card.css
624
+ ```
625
+
583
626
  5. Import the generated CSS files in your components:
584
627
 
628
+ **Default mode:**
585
629
  ```js
586
630
  import './styles/twsx.card.css';
587
631
  import './styles/twsx.button.css';
588
632
  ```
589
633
 
634
+ **Preserve structure mode:**
635
+ ```js
636
+ // In src/components/Button/Button.jsx
637
+ import './twsx.button.css';
638
+
639
+ // In src/components/Card/Card.jsx
640
+ import './twsx.card.css';
641
+ ```
642
+
590
643
  #### Usage in Different Projects
591
644
 
592
645
  **React/Next.js/Vue/Any Project:**
@@ -602,6 +655,8 @@ npm install tailwind-to-style
602
655
  "scripts": {
603
656
  "twsx:build": "node node_modules/tailwind-to-style/lib/twsx-cli.js",
604
657
  "twsx:watch": "node node_modules/tailwind-to-style/lib/twsx-cli.js --watch",
658
+ "twsx:preserve": "node node_modules/tailwind-to-style/lib/twsx-cli.js --preserve-structure",
659
+ "twsx:dev": "node node_modules/tailwind-to-style/lib/twsx-cli.js --watch --preserve-structure",
605
660
  "dev": "npm run twsx:watch & next dev"
606
661
  }
607
662
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.8.5
2
+ * tailwind-to-style v2.8.6
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.5
2
+ * tailwind-to-style v2.8.6
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.5
2
+ * tailwind-to-style v2.8.6
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
package/lib/twsx-cli.js CHANGED
@@ -18,7 +18,7 @@ function findTwsxFiles(dir, files = []) {
18
18
  return files;
19
19
  }
20
20
 
21
- async function buildTwsx(inputDir, outputDir) {
21
+ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
22
22
  try {
23
23
  const twsxFiles = findTwsxFiles(inputDir);
24
24
  const generatedCssFiles = [];
@@ -32,9 +32,18 @@ async function buildTwsx(inputDir, outputDir) {
32
32
  const styleObj = styleModule.default || styleModule;
33
33
  const css = twsx(styleObj, { inject: false });
34
34
  const fileName = path.basename(filePath).replace(/\.js$/, ".css");
35
- const cssFilePath = path.join(outputDir, fileName);
35
+
36
+ let cssFilePath;
37
+ if (preserveStructure) {
38
+ // Generate CSS in the same directory as the JS file
39
+ cssFilePath = filePath.replace(/\.js$/, ".css");
40
+ } else {
41
+ // Generate CSS in the output directory
42
+ cssFilePath = path.join(outputDir, fileName);
43
+ }
44
+
36
45
  fs.writeFileSync(cssFilePath, css);
37
- generatedCssFiles.push(fileName);
46
+ generatedCssFiles.push(preserveStructure ? cssFilePath : fileName);
38
47
  console.log(`[twsx-cli] CSS written to ${cssFilePath}`);
39
48
  } catch (err) {
40
49
  console.error(
@@ -45,7 +54,7 @@ async function buildTwsx(inputDir, outputDir) {
45
54
  }
46
55
 
47
56
  // Clean up orphaned CSS files
48
- if (fs.existsSync(outputDir)) {
57
+ if (!preserveStructure && fs.existsSync(outputDir)) {
49
58
  const existingCssFiles = fs
50
59
  .readdirSync(outputDir)
51
60
  .filter((file) => file.startsWith("twsx.") && file.endsWith(".css"));
@@ -57,6 +66,31 @@ async function buildTwsx(inputDir, outputDir) {
57
66
  console.log(`[twsx-cli] Removed orphaned CSS: ${cssFilePath}`);
58
67
  }
59
68
  }
69
+ } else if (preserveStructure) {
70
+ // Clean up orphaned CSS files in preserve structure mode
71
+ const twsxFiles = findTwsxFiles(inputDir);
72
+ const expectedCssFiles = twsxFiles.map(file => file.replace(/\.js$/, ".css"));
73
+
74
+ // Find and remove orphaned CSS files
75
+ function cleanupOrphanedCss(dir) {
76
+ if (!fs.existsSync(dir)) return;
77
+
78
+ const items = fs.readdirSync(dir);
79
+ for (const item of items) {
80
+ const fullPath = path.join(dir, item);
81
+ const stat = fs.statSync(fullPath);
82
+ if (stat.isDirectory()) {
83
+ cleanupOrphanedCss(fullPath);
84
+ } else if (item.startsWith("twsx.") && item.endsWith(".css")) {
85
+ if (!expectedCssFiles.includes(fullPath)) {
86
+ fs.unlinkSync(fullPath);
87
+ console.log(`[twsx-cli] Removed orphaned CSS: ${fullPath}`);
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ cleanupOrphanedCss(inputDir);
60
94
  }
61
95
  } catch (err) {
62
96
  console.error("[twsx-cli] Error scanning for twsx files:", err);
@@ -68,15 +102,16 @@ const inputDir =
68
102
  const outputDir =
69
103
  process.env.TWSX_OUTPUT_DIR || path.resolve(process.cwd(), "src/styles");
70
104
  const watchMode = process.argv.includes("--watch") || process.env.TWSX_WATCH === "true";
105
+ const preserveStructure = process.argv.includes("--preserve-structure") || process.env.TWSX_PRESERVE_STRUCTURE === "true";
71
106
 
72
- if (!fs.existsSync(outputDir)) {
107
+ if (!preserveStructure && !fs.existsSync(outputDir)) {
73
108
  fs.mkdirSync(outputDir, { recursive: true });
74
109
  }
75
110
 
76
111
  // Initial build
77
112
  (async () => {
78
113
  try {
79
- await buildTwsx(inputDir, outputDir);
114
+ await buildTwsx(inputDir, outputDir, preserveStructure);
80
115
  console.log(`[twsx-cli] Initial build completed`);
81
116
 
82
117
  if (watchMode) {
@@ -90,15 +125,15 @@ if (!fs.existsSync(outputDir)) {
90
125
  watcher
91
126
  .on("change", async (filePath) => {
92
127
  console.log(`[twsx-cli] File changed: ${filePath}`);
93
- await buildTwsx(inputDir, outputDir);
128
+ await buildTwsx(inputDir, outputDir, preserveStructure);
94
129
  })
95
130
  .on("add", async (filePath) => {
96
131
  console.log(`[twsx-cli] File added: ${filePath}`);
97
- await buildTwsx(inputDir, outputDir);
132
+ await buildTwsx(inputDir, outputDir, preserveStructure);
98
133
  })
99
134
  .on("unlink", async (filePath) => {
100
135
  console.log(`[twsx-cli] File removed: ${filePath}`);
101
- await buildTwsx(inputDir, outputDir);
136
+ await buildTwsx(inputDir, outputDir, preserveStructure);
102
137
  });
103
138
 
104
139
  // Keep the process alive
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwind-to-style",
3
- "version": "2.8.5",
3
+ "version": "2.8.6",
4
4
  "description": "Convert tailwind classes to inline style",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -12,8 +12,7 @@
12
12
  "README.md",
13
13
  "LICENSE",
14
14
  "plugins",
15
- "lib",
16
- "twsx.css"
15
+ "lib"
17
16
  ],
18
17
  "bin": {
19
18
  "twsx-cli": "./lib/twsx-cli.js"
@@ -17,7 +17,7 @@ function findTwsxFiles(dir, files = []) {
17
17
  return files;
18
18
  }
19
19
 
20
- async function buildTwsx(inputDir, outputDir) {
20
+ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
21
21
  try {
22
22
  const twsxFiles = findTwsxFiles(inputDir);
23
23
  const generatedCssFiles = [];
@@ -31,9 +31,24 @@ async function buildTwsx(inputDir, outputDir) {
31
31
  const styleObj = styleModule.default || styleModule;
32
32
  const css = twsx(styleObj, { inject: false });
33
33
  const fileName = path.basename(filePath).replace(/\.js$/, ".css");
34
- const cssFilePath = path.join(outputDir, fileName);
34
+
35
+ let cssFilePath;
36
+ if (preserveStructure) {
37
+ // Generate CSS file next to the JS file
38
+ cssFilePath = filePath.replace(/\.js$/, ".css");
39
+ } else {
40
+ // Generate CSS file in the output directory
41
+ cssFilePath = path.join(outputDir, fileName);
42
+ }
43
+
44
+ // Ensure the directory exists
45
+ const cssDir = path.dirname(cssFilePath);
46
+ if (!fs.existsSync(cssDir)) {
47
+ fs.mkdirSync(cssDir, { recursive: true });
48
+ }
49
+
35
50
  fs.writeFileSync(cssFilePath, css);
36
- generatedCssFiles.push(fileName);
51
+ generatedCssFiles.push(preserveStructure ? cssFilePath : fileName);
37
52
  } catch (err) {
38
53
  console.error(
39
54
  `[vite-twsx] Error importing or processing ${filePath}:`,
@@ -43,15 +58,27 @@ async function buildTwsx(inputDir, outputDir) {
43
58
  }
44
59
 
45
60
  // Clean up orphaned CSS files
46
- if (fs.existsSync(outputDir)) {
47
- const existingCssFiles = fs
48
- .readdirSync(outputDir)
49
- .filter((file) => file.startsWith("twsx.") && file.endsWith(".css"));
61
+ if (preserveStructure) {
62
+ // For preserve structure mode, clean up next to JS files
63
+ const allJsFiles = findTwsxFiles(inputDir);
64
+ for (const jsFile of allJsFiles) {
65
+ const cssFile = jsFile.replace(/\.js$/, ".css");
66
+ if (fs.existsSync(cssFile) && !generatedCssFiles.includes(cssFile)) {
67
+ fs.unlinkSync(cssFile);
68
+ }
69
+ }
70
+ } else {
71
+ // For normal mode, clean up in output directory
72
+ if (fs.existsSync(outputDir)) {
73
+ const existingCssFiles = fs
74
+ .readdirSync(outputDir)
75
+ .filter((file) => file.startsWith("twsx.") && file.endsWith(".css"));
50
76
 
51
- for (const cssFile of existingCssFiles) {
52
- if (!generatedCssFiles.includes(cssFile)) {
53
- const cssFilePath = path.join(outputDir, cssFile);
54
- fs.unlinkSync(cssFilePath);
77
+ for (const cssFile of existingCssFiles) {
78
+ if (!generatedCssFiles.includes(cssFile)) {
79
+ const cssFilePath = path.join(outputDir, cssFile);
80
+ fs.unlinkSync(cssFilePath);
81
+ }
55
82
  }
56
83
  }
57
84
  }
@@ -65,8 +92,9 @@ export default function twsxPlugin(options = {}) {
65
92
  const inputDir = options.inputDir || path.resolve(process.cwd(), "src");
66
93
  const outputDir =
67
94
  options.outputDir || path.resolve(process.cwd(), "src/styles");
95
+ const preserveStructure = options.preserveStructure || false;
68
96
 
69
- if (!fs.existsSync(outputDir)) {
97
+ if (!preserveStructure && !fs.existsSync(outputDir)) {
70
98
  fs.mkdirSync(outputDir, { recursive: true });
71
99
  }
72
100
 
@@ -74,14 +102,14 @@ export default function twsxPlugin(options = {}) {
74
102
  name: "vite-twsx",
75
103
  async buildStart() {
76
104
  try {
77
- await buildTwsx(inputDir, outputDir);
105
+ await buildTwsx(inputDir, outputDir, preserveStructure);
78
106
  } catch (err) {
79
107
  console.error("[vite-twsx] Error writing CSS:", err);
80
108
  }
81
109
  },
82
110
  async handleHotUpdate() {
83
111
  try {
84
- await buildTwsx(inputDir, outputDir);
112
+ await buildTwsx(inputDir, outputDir, preserveStructure);
85
113
  } catch (err) {
86
114
  console.error("[vite-twsx] Error updating CSS:", err);
87
115
  }
@@ -17,7 +17,7 @@ function findTwsxFiles(dir, files = []) {
17
17
  return files;
18
18
  }
19
19
 
20
- async function buildTwsx(inputDir, outputDir) {
20
+ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
21
21
  try {
22
22
  const twsxFiles = findTwsxFiles(inputDir);
23
23
  const generatedCssFiles = [];
@@ -31,9 +31,24 @@ async function buildTwsx(inputDir, outputDir) {
31
31
  const styleObj = styleModule.default || styleModule;
32
32
  const css = twsx(styleObj, { inject: false });
33
33
  const fileName = path.basename(filePath).replace(/\.js$/, ".css");
34
- const cssFilePath = path.join(outputDir, fileName);
34
+
35
+ let cssFilePath;
36
+ if (preserveStructure) {
37
+ // Generate CSS file next to the JS file
38
+ cssFilePath = filePath.replace(/\.js$/, ".css");
39
+ } else {
40
+ // Generate CSS file in the output directory
41
+ cssFilePath = path.join(outputDir, fileName);
42
+ }
43
+
44
+ // Ensure the directory exists
45
+ const cssDir = path.dirname(cssFilePath);
46
+ if (!fs.existsSync(cssDir)) {
47
+ fs.mkdirSync(cssDir, { recursive: true });
48
+ }
49
+
35
50
  fs.writeFileSync(cssFilePath, css);
36
- generatedCssFiles.push(fileName);
51
+ generatedCssFiles.push(preserveStructure ? cssFilePath : fileName);
37
52
  } catch (err) {
38
53
  console.error(
39
54
  `[webpack-twsx] Error importing or processing ${filePath}:`,
@@ -43,16 +58,28 @@ async function buildTwsx(inputDir, outputDir) {
43
58
  }
44
59
 
45
60
  // Clean up orphaned CSS files
46
- if (fs.existsSync(outputDir)) {
47
- const existingCssFiles = fs.readdirSync(outputDir).filter((file) => {
48
- return file.startsWith("twsx.") && file.endsWith(".css");
49
- });
61
+ if (preserveStructure) {
62
+ // For preserve structure mode, clean up next to JS files
63
+ const allJsFiles = findTwsxFiles(inputDir);
64
+ for (const jsFile of allJsFiles) {
65
+ const cssFile = jsFile.replace(/\.js$/, ".css");
66
+ if (fs.existsSync(cssFile) && !generatedCssFiles.includes(cssFile)) {
67
+ fs.unlinkSync(cssFile);
68
+ }
69
+ }
70
+ } else {
71
+ // For normal mode, clean up in output directory
72
+ if (fs.existsSync(outputDir)) {
73
+ const existingCssFiles = fs.readdirSync(outputDir).filter((file) => {
74
+ return file.startsWith("twsx.") && file.endsWith(".css");
75
+ });
50
76
 
51
- if (Array.isArray(existingCssFiles) && Array.isArray(generatedCssFiles)) {
52
- for (const cssFile of existingCssFiles) {
53
- if (!generatedCssFiles.includes(cssFile)) {
54
- const cssFilePath = path.join(outputDir, cssFile);
55
- fs.unlinkSync(cssFilePath);
77
+ if (Array.isArray(existingCssFiles) && Array.isArray(generatedCssFiles)) {
78
+ for (const cssFile of existingCssFiles) {
79
+ if (!generatedCssFiles.includes(cssFile)) {
80
+ const cssFilePath = path.join(outputDir, cssFile);
81
+ fs.unlinkSync(cssFilePath);
82
+ }
56
83
  }
57
84
  }
58
85
  }
@@ -67,7 +94,9 @@ class TwsxPlugin {
67
94
  this.inputDir = options.inputDir || path.resolve(process.cwd(), "src");
68
95
  this.outputDir =
69
96
  options.outputDir || path.resolve(process.cwd(), "src/styles");
70
- if (!fs.existsSync(this.outputDir)) {
97
+ this.preserveStructure = options.preserveStructure || false;
98
+
99
+ if (!this.preserveStructure && !fs.existsSync(this.outputDir)) {
71
100
  fs.mkdirSync(this.outputDir, { recursive: true });
72
101
  }
73
102
  }
@@ -75,14 +104,14 @@ class TwsxPlugin {
75
104
  apply(compiler) {
76
105
  compiler.hooks.beforeCompile.tapPromise("TwsxPlugin", async () => {
77
106
  try {
78
- await buildTwsx(this.inputDir, this.outputDir);
107
+ await buildTwsx(this.inputDir, this.outputDir, this.preserveStructure);
79
108
  } catch (err) {
80
109
  console.error("[webpack-twsx] Error writing CSS:", err);
81
110
  }
82
111
  });
83
112
  compiler.hooks.watchRun.tapPromise("TwsxPlugin", async () => {
84
113
  try {
85
- await buildTwsx(this.inputDir, this.outputDir);
114
+ await buildTwsx(this.inputDir, this.outputDir, this.preserveStructure);
86
115
  } catch (err) {
87
116
  console.error("[webpack-twsx] Error updating CSS:", err);
88
117
  }
package/twsx.css DELETED
File without changes