@melcanz85/chaincss 1.5.3 → 1.5.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 +192 -172
- package/chaincss.js +5 -6
- package/package.json +1 -1
- package/transpiler.js +1 -1
package/README.md
CHANGED
|
@@ -1,193 +1,213 @@
|
|
|
1
1
|
# @melcanz85/chaincss
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://badge.fury.io/js/@melcanz85%2Fchaincss)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
A simple JavaScript-to-CSS transpiler that converts JS objects into optimized CSS.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
npm install @melcanz85/chaincss
|
|
9
|
-
```
|
|
8
|
+
## 🚀 Installation
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
```bash
|
|
11
|
+
npm install @melcanz85/chaincss
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
13
|
+
📦 Usage (Node.js)
|
|
14
|
+
Quick Setup
|
|
15
|
+
|
|
16
|
+
Install development dependencies:
|
|
17
|
+
|
|
18
|
+
bash
|
|
19
|
+
|
|
20
|
+
npm install --save-dev nodemon concurrently
|
|
21
|
+
|
|
22
|
+
Update your package.json scripts:
|
|
23
|
+
|
|
24
|
+
json
|
|
25
|
+
|
|
26
|
+
"scripts": {
|
|
27
|
+
"start": "concurrently \"nodemon server.js\" \"nodemon --watch chaincss/*.jcss --watch processor.js --exec 'node processor.js'\""
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Project Structure
|
|
31
|
+
|
|
32
|
+
Create this folder structure in your project:
|
|
33
|
+
text
|
|
34
|
+
|
|
35
|
+
your-project/
|
|
36
|
+
├── chaincss/ # ChainCSS source files
|
|
37
|
+
│ ├── chaincss.jcss # Main entry file
|
|
38
|
+
│ ├── chain.jcss # Chaining definitions
|
|
39
|
+
│ └── processor.js # Processing script
|
|
40
|
+
├── public/ # Output files
|
|
41
|
+
│ ├── index.html
|
|
42
|
+
│ └── chainstyle.css # Generated CSS
|
|
43
|
+
├── node_modules/
|
|
44
|
+
├── package.json
|
|
45
|
+
└── package-lock.json
|
|
46
|
+
|
|
47
|
+
Processor Setup
|
|
48
|
+
|
|
49
|
+
In chaincss/processor.js:
|
|
50
|
+
javascript
|
|
51
|
+
|
|
52
|
+
const jss = require("@melcanz85/chaincss");
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
// Process main file and output CSS
|
|
56
|
+
jss.processJSS('./chaincss/chaincss.jcss', './public/chainstyle.css');
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error('Error processing JSS file:', err.stack);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
💻 Code Examples
|
|
63
|
+
Main File (chaincss/chaincss.jcss)
|
|
64
|
+
javascript
|
|
65
|
+
|
|
66
|
+
<@
|
|
67
|
+
// Import chaining definitions
|
|
68
|
+
const style = get('./chain.jcss');
|
|
69
|
+
|
|
70
|
+
// Override specific styles
|
|
71
|
+
style.navA.color = 'red';
|
|
72
|
+
|
|
73
|
+
// Compile to CSS
|
|
74
|
+
compile(style);
|
|
75
|
+
@>
|
|
76
|
+
|
|
77
|
+
@media (max-width: 768px) {
|
|
78
|
+
<@
|
|
79
|
+
run(
|
|
80
|
+
chaincss.flexDirection('column').alignItems('flex-start').block('header'),
|
|
81
|
+
chaincss.order(1).block('.logo'),
|
|
82
|
+
chaincss.order(2).block('.search-bar'),
|
|
83
|
+
chaincss.order(3).block('h1'),
|
|
84
|
+
chaincss.order(5).block('nav'),
|
|
85
|
+
chaincss.order(4).display('flex').width('100%').justifyContent('flex-end').block('.burgerWrapper')
|
|
86
|
+
);
|
|
87
|
+
@>
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Chaining File (chaincss/chain.jcss)
|
|
91
|
+
javascript
|
|
92
|
+
|
|
93
|
+
// Variables for consistent styling
|
|
94
|
+
const bodyBgColor = '#f0f0f0';
|
|
95
|
+
const headerBgColor = '#333';
|
|
96
|
+
const bodyFontFamily = 'Arial, sans-serif';
|
|
97
|
+
const headerAlignItems = 'center';
|
|
98
|
+
const logoHeight = '50px';
|
|
99
|
+
|
|
100
|
+
// Reset browser defaults
|
|
101
|
+
const resetDefaultBrowStyle = chaincss
|
|
102
|
+
.margin('0')
|
|
103
|
+
.padding('0')
|
|
104
|
+
.block('body', 'h1', 'h2', 'h3', 'p', 'ul');
|
|
105
|
+
|
|
106
|
+
// Body styles
|
|
107
|
+
const bodyStyle = chaincss
|
|
108
|
+
.fontFamily(bodyFontFamily)
|
|
109
|
+
.lineHeight('1.6')
|
|
110
|
+
.bgColor(bodyBgColor)
|
|
111
|
+
.block('body');
|
|
112
|
+
|
|
113
|
+
// Header styles
|
|
114
|
+
const header = chaincss
|
|
115
|
+
.display('flex')
|
|
116
|
+
.alignItems(headerAlignItems)
|
|
117
|
+
.justifyContent('space-between')
|
|
118
|
+
.bgColor(headerBgColor)
|
|
119
|
+
.color('#fff')
|
|
120
|
+
.padding('10px 20px')
|
|
121
|
+
.block('header');
|
|
122
|
+
|
|
123
|
+
// Logo
|
|
124
|
+
const logoImgHeight = chaincss
|
|
125
|
+
.height(logoHeight)
|
|
126
|
+
.block('.logo img');
|
|
127
|
+
|
|
128
|
+
module.exports = {
|
|
129
|
+
resetDefaultBrowStyle,
|
|
130
|
+
bodyStyle,
|
|
131
|
+
header,
|
|
132
|
+
logoImgHeight
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
📝 Notes
|
|
136
|
+
|
|
137
|
+
CSS syntax can be written directly in .jcss files
|
|
138
|
+
|
|
139
|
+
ChainCSS syntax must be wrapped in <@ @> delimiters
|
|
140
|
+
|
|
141
|
+
The get() function imports chaining definitions from other files
|
|
142
|
+
|
|
143
|
+
Style modifications between get() and compile() will override existing styles
|
|
144
|
+
|
|
145
|
+
🎨 Editor Support
|
|
146
|
+
|
|
147
|
+
Since .jcss files are just JavaScript files with ChainCSS syntax, you can easily enable proper syntax highlighting in your editor:
|
|
148
|
+
VS Code
|
|
149
|
+
|
|
150
|
+
Add this to your project's .vscode/settings.json:
|
|
151
|
+
json
|
|
152
|
+
|
|
153
|
+
{
|
|
154
|
+
"files.associations": {
|
|
155
|
+
"*.jcss": "javascript"
|
|
55
156
|
}
|
|
157
|
+
}
|
|
56
158
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
//main (chaincss.jcss)
|
|
60
|
-
<@
|
|
61
|
-
const style = get('../../chaincss.jcss/chain.jcss');
|
|
62
|
-
|
|
63
|
-
// STYLE MODIFICATION HAPPENS HERE
|
|
64
|
-
style.navA.color = 'red';
|
|
65
|
-
|
|
66
|
-
// COMPILING THE STYLE JS TO PURE CSS OR THE STYLE.CSS FILE
|
|
67
|
-
compile(style);
|
|
68
|
-
@>
|
|
69
|
-
|
|
70
|
-
@media (max-width: 768px) {
|
|
71
|
-
<@
|
|
72
|
-
run(
|
|
73
|
-
chaincss.flexDirection('column').alignItems('flex-start').block('header'),
|
|
74
|
-
chaincss.order(1).block('.logo'),
|
|
75
|
-
chaincss.order(2).block('.search-bar'),
|
|
76
|
-
chaincss.order(3).block('h1'),
|
|
77
|
-
chaincss.order(5).block('nav'),
|
|
78
|
-
chaincss.order(4).display('flex').width('100%').justifyContent('flex-end').block('.burgerWrapper'),
|
|
79
|
-
chaincss.display('flex').flexDirection('column').justifyContent('space-around').padding('4px').margin('5px 1px').width('30px').height('30px').cursor('pointer').block('.burger'),
|
|
80
|
-
chaincss.display('none').flexDirection('column').block('nav ul'),
|
|
81
|
-
chaincss.margin('10px 1px').block('nav ul li'),
|
|
82
|
-
chaincss.display('flex').block('nav ul.active'),
|
|
83
|
-
chaincss.width('100px').marginTop('10px').block('.search-bar'),
|
|
84
|
-
chaincss.width('100%').block('.search-bar input'),
|
|
85
|
-
chaincss.flex('1 1 100%').padding('50px').block('.box'),
|
|
86
|
-
chaincss.position('static').block('footer')
|
|
87
|
-
);
|
|
88
|
-
@>
|
|
89
|
-
}
|
|
159
|
+
WebStorm / IntelliJ IDEA
|
|
90
160
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Note: you can write css syntax code directly in the main jcss as you can see in the example the @media css syntax for mobile rendering but anything that is jcss syntax you have to put it inside <@ @> delimiters.
|
|
94
|
-
|
|
95
|
-
//Chaining (chain.jcss) example:
|
|
96
|
-
|
|
97
|
-
const bodyBgColor = '#f0f0f0';
|
|
98
|
-
const headerBgCOlor = '#333';
|
|
99
|
-
const bodyLineHeight = '1.6';
|
|
100
|
-
const bodyFontFamily = 'Arial, sans-serif';
|
|
101
|
-
const headerAlignItems = 'center';
|
|
102
|
-
const searchBarFontSize = '16px';
|
|
103
|
-
|
|
104
|
-
const resetDefaultBrowStyle = chaincss
|
|
105
|
-
.margin('0')
|
|
106
|
-
.padding('0')
|
|
107
|
-
.block('body', 'h1', 'h2', 'h3', 'p', 'ul');
|
|
108
|
-
|
|
109
|
-
const bodyStyle = chaincss
|
|
110
|
-
.fontFamily(bodyFontFamily)
|
|
111
|
-
.lineHeight(bodyLineHeight)
|
|
112
|
-
.bgColor(bodyBgColor)
|
|
113
|
-
.block('body');
|
|
114
|
-
|
|
115
|
-
// Site Header
|
|
116
|
-
const header = chaincss
|
|
117
|
-
.display('flex')
|
|
118
|
-
.alignItems(headerAlignItems)
|
|
119
|
-
.justifyContent('space-between')
|
|
120
|
-
.bgColor(headerBgCOlor)
|
|
121
|
-
.color(texcolor)
|
|
122
|
-
.padding('10px 20px')
|
|
123
|
-
.flexWrap('wrap')
|
|
124
|
-
.block('header');
|
|
125
|
-
|
|
126
|
-
const logoImgHeigth = chaincss
|
|
127
|
-
.height(logoHeight)
|
|
128
|
-
.block('.logo img');
|
|
129
|
-
|
|
130
|
-
// Burger button
|
|
131
|
-
const burgerWrapper = chaincss
|
|
132
|
-
.display('none')
|
|
133
|
-
.block('.burgerWrapper');
|
|
134
|
-
|
|
135
|
-
const burgerLine = chaincss
|
|
136
|
-
.width('100%')
|
|
137
|
-
.height('3px')
|
|
138
|
-
.bgColor('white')
|
|
139
|
-
.block('.line');
|
|
140
|
-
|
|
141
|
-
// search Bar
|
|
142
|
-
const divSearchBar = chaincss
|
|
143
|
-
.display('flex')
|
|
144
|
-
.flexGrow('1')
|
|
145
|
-
.justifyContent('flex-end')
|
|
146
|
-
.block('.search-bar');
|
|
147
|
-
|
|
148
|
-
const inputSearchBar = chaincss
|
|
149
|
-
.padding('5px')
|
|
150
|
-
.fontSize(searchBarFontSize)
|
|
151
|
-
.border('none')
|
|
152
|
-
.borderRadius('4px')
|
|
153
|
-
.width('200px')
|
|
154
|
-
.transition('w 0.4s ease-in-out')
|
|
155
|
-
.block('.search-bar input');
|
|
156
|
-
|
|
157
|
-
module.exports = {
|
|
158
|
-
resetDefaultBrowStyle,
|
|
159
|
-
bodyStyle,
|
|
160
|
-
header,
|
|
161
|
-
logoImgHeigth,
|
|
162
|
-
burgerWrapper,
|
|
163
|
-
burgerLine,
|
|
164
|
-
divSearchBar,
|
|
165
|
-
inputSearchBar
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
## In this example you can see the chaining pattern of code its like writing css code but in javascript fashion where you can manipulate its values through variables. In css you have to scroll down and find each block to change it. In this case you just find it through variables.
|
|
161
|
+
Go to Settings/Preferences → Editor → File Types
|
|
169
162
|
|
|
170
|
-
|
|
163
|
+
Select JavaScript in the list
|
|
164
|
+
|
|
165
|
+
Click + and add *.jcss to the registered patterns
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
✅ Basic JS → CSS Convert plain JS objects to CSS
|
|
167
|
+
Vim / Neovim
|
|
174
168
|
|
|
175
|
-
|
|
169
|
+
Add to your .vimrc or init.vim:
|
|
170
|
+
vim
|
|
176
171
|
|
|
177
|
-
|
|
172
|
+
au BufRead,BufNewFile *.jcss setfiletype javascript
|
|
178
173
|
|
|
179
|
-
|
|
174
|
+
Sublime Text
|
|
180
175
|
|
|
181
|
-
|
|
176
|
+
Create or edit ~/Library/Application Support/Sublime Text/Packages/User/JCSS.sublime-settings:
|
|
177
|
+
json
|
|
182
178
|
|
|
183
|
-
|
|
179
|
+
{
|
|
180
|
+
"extensions": ["jcss"],
|
|
181
|
+
"syntax": "Packages/JavaScript/JavaScript.sublime-syntax"
|
|
182
|
+
}
|
|
184
183
|
|
|
185
|
-
|
|
184
|
+
Atom
|
|
186
185
|
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
Add to your config.cson:
|
|
187
|
+
coffeescript
|
|
188
|
+
|
|
189
|
+
"*":
|
|
190
|
+
core:
|
|
191
|
+
customFileTypes:
|
|
192
|
+
"source.js": [
|
|
193
|
+
"jcss"
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
Other Editors
|
|
197
|
+
|
|
198
|
+
Most modern editors allow you to associate file extensions with language modes. Simply configure your editor to treat .jcss files as JavaScript.
|
|
199
|
+
✨ Features
|
|
200
|
+
Status Feature Description
|
|
201
|
+
✅ Basic JS → CSS Convert plain JS objects to CSS
|
|
202
|
+
🚧 Keyframe animations @keyframes support
|
|
203
|
+
🚧 Vendor prefixing Auto-add -webkit-, -moz-, etc.
|
|
204
|
+
🚧 Source maps Debug generated CSS
|
|
205
|
+
🚧 Watch mode Auto-recompile on file changes
|
|
189
206
|
|
|
207
|
+
✅ = Working, 🚧 = Coming soon
|
|
208
|
+
👨💻 Contributing
|
|
190
209
|
|
|
191
|
-
|
|
210
|
+
Contributions are welcome! Feel free to open issues or submit pull requests.
|
|
211
|
+
📄 License
|
|
192
212
|
|
|
193
|
-
|
|
213
|
+
MIT © Rommel Caneos
|
package/chaincss.js
CHANGED
|
@@ -15,13 +15,12 @@ console.log(__dirname);
|
|
|
15
15
|
const processScript = (scriptBlock) => {
|
|
16
16
|
//const output = 'cssOutput = undefined;';
|
|
17
17
|
const context = vm.createContext({
|
|
18
|
-
...transpilerModule
|
|
18
|
+
...transpilerModule
|
|
19
19
|
});
|
|
20
|
-
|
|
21
|
-
const jsCode = scriptBlock.trim(); //`(function() { ${scriptBlock.trim()} })();`; Wrap script in IIFE
|
|
20
|
+
const jsCode = scriptBlock.trim();
|
|
22
21
|
const chainScript = new vm.Script(jsCode);
|
|
23
|
-
chainScript.runInContext(context);
|
|
24
|
-
return context.chain.cssOutput;
|
|
22
|
+
chainScript.runInContext(context);
|
|
23
|
+
return context.chain.cssOutput;
|
|
25
24
|
};
|
|
26
25
|
|
|
27
26
|
// CSS Minification Function
|
|
@@ -60,7 +59,7 @@ const processor = (inputFile, outputFile) => {
|
|
|
60
59
|
const outputDir = path.resolve(outputFile);
|
|
61
60
|
const trimmedCSS = outputCSS.trim();
|
|
62
61
|
const minCSS = minifyCss(trimmedCSS);
|
|
63
|
-
fs.writeFileSync(outputDir, minCSS, 'utf8');
|
|
62
|
+
fs.writeFileSync(outputDir, minCSS, 'utf8');
|
|
64
63
|
};
|
|
65
64
|
|
|
66
65
|
// Watch function
|
package/package.json
CHANGED
package/transpiler.js
CHANGED
|
@@ -193,7 +193,7 @@ const compile = (obj) => {
|
|
|
193
193
|
for (const key in obj) {
|
|
194
194
|
if (obj.hasOwnProperty(key)) {
|
|
195
195
|
const element = obj[key];
|
|
196
|
-
let selectors = element.selectors || [];
|
|
196
|
+
let selectors = element.selectors || [];
|
|
197
197
|
let elementCSS = '';
|
|
198
198
|
|
|
199
199
|
for (let prop in element) {
|