jac-client 0.2.0__py3-none-any.whl → 0.2.3__py3-none-any.whl
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.
- jac_client/docs/README.md +50 -20
- jac_client/docs/advanced-state.md +13 -14
- jac_client/docs/asset-serving/intro.md +209 -0
- jac_client/docs/assets/pipe_line-v2.svg +32 -0
- jac_client/docs/file-system/app.jac.md +121 -0
- jac_client/docs/file-system/backend-frontend.md +217 -0
- jac_client/docs/file-system/intro.md +72 -0
- jac_client/docs/file-system/nested-imports.md +348 -0
- jac_client/docs/guide-example/intro.md +11 -13
- jac_client/docs/guide-example/step-01-setup.md +30 -20
- jac_client/docs/guide-example/step-02-components.md +24 -24
- jac_client/docs/guide-example/step-03-styling.md +24 -24
- jac_client/docs/guide-example/step-04-todo-ui.md +17 -17
- jac_client/docs/guide-example/step-05-local-state.md +23 -23
- jac_client/docs/guide-example/step-06-events.md +23 -24
- jac_client/docs/guide-example/step-07-effects.md +27 -28
- jac_client/docs/guide-example/step-08-walkers.md +23 -23
- jac_client/docs/guide-example/step-09-authentication.md +18 -18
- jac_client/docs/guide-example/step-10-routing.md +20 -21
- jac_client/docs/guide-example/step-11-final.md +34 -35
- jac_client/docs/imports.md +4 -5
- jac_client/docs/lifecycle-hooks.md +12 -13
- jac_client/docs/routing.md +21 -22
- jac_client/docs/styling/intro.md +249 -0
- jac_client/docs/styling/js-styling.md +367 -0
- jac_client/docs/styling/material-ui.md +341 -0
- jac_client/docs/styling/pure-css.md +299 -0
- jac_client/docs/styling/sass.md +403 -0
- jac_client/docs/styling/styled-components.md +395 -0
- jac_client/docs/styling/tailwind.md +298 -0
- jac_client/examples/all-in-one/.babelrc +9 -0
- jac_client/examples/all-in-one/README.md +16 -0
- jac_client/examples/all-in-one/app.jac +426 -0
- jac_client/examples/all-in-one/assets/burger.png +0 -0
- jac_client/examples/all-in-one/button.jac +7 -0
- jac_client/examples/all-in-one/components/button.jac +7 -0
- jac_client/examples/all-in-one/package.json +29 -0
- jac_client/examples/all-in-one/styles.css +26 -0
- jac_client/examples/all-in-one/vite.config.js +28 -0
- jac_client/examples/asset-serving/css-with-image/.babelrc +9 -0
- jac_client/examples/asset-serving/css-with-image/README.md +91 -0
- jac_client/examples/asset-serving/css-with-image/app.jac +88 -0
- jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
- jac_client/examples/asset-serving/css-with-image/package.json +28 -0
- jac_client/examples/asset-serving/css-with-image/styles.css +26 -0
- jac_client/examples/asset-serving/css-with-image/vite.config.js +28 -0
- jac_client/examples/asset-serving/image-asset/.babelrc +9 -0
- jac_client/examples/asset-serving/image-asset/README.md +119 -0
- jac_client/examples/asset-serving/image-asset/app.jac +55 -0
- jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
- jac_client/examples/asset-serving/image-asset/package.json +28 -0
- jac_client/examples/asset-serving/image-asset/styles.css +26 -0
- jac_client/examples/asset-serving/image-asset/vite.config.js +28 -0
- jac_client/examples/asset-serving/import-alias/.babelrc +9 -0
- jac_client/examples/asset-serving/import-alias/README.md +83 -0
- jac_client/examples/asset-serving/import-alias/app.jac +111 -0
- jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
- jac_client/examples/asset-serving/import-alias/package.json +28 -0
- jac_client/examples/asset-serving/import-alias/vite.config.js +28 -0
- jac_client/examples/basic/app.jac +14 -9
- jac_client/examples/basic/package.json +1 -1
- jac_client/examples/basic/vite.config.js +0 -1
- jac_client/examples/basic-auth/package.json +1 -1
- jac_client/examples/basic-auth/vite.config.js +0 -1
- jac_client/examples/basic-auth-with-router/package.json +1 -1
- jac_client/examples/basic-auth-with-router/vite.config.js +0 -1
- jac_client/examples/basic-full-stack/package.json +1 -1
- jac_client/examples/basic-full-stack/vite.config.js +0 -1
- jac_client/examples/css-styling/js-styling/.babelrc +9 -0
- jac_client/examples/css-styling/js-styling/README.md +183 -0
- jac_client/examples/css-styling/js-styling/app.jac +84 -0
- jac_client/examples/css-styling/js-styling/package.json +28 -0
- jac_client/examples/css-styling/js-styling/styles.js +100 -0
- jac_client/examples/css-styling/js-styling/vite.config.js +27 -0
- jac_client/examples/css-styling/material-ui/.babelrc +9 -0
- jac_client/examples/css-styling/material-ui/README.md +16 -0
- jac_client/examples/css-styling/material-ui/app.jac +122 -0
- jac_client/examples/css-styling/material-ui/package.json +32 -0
- jac_client/examples/css-styling/material-ui/vite.config.js +27 -0
- jac_client/examples/css-styling/pure-css/.babelrc +9 -0
- jac_client/examples/css-styling/pure-css/README.md +16 -0
- jac_client/examples/css-styling/pure-css/app.jac +64 -0
- jac_client/examples/css-styling/pure-css/package.json +28 -0
- jac_client/examples/css-styling/pure-css/styles.css +111 -0
- jac_client/examples/css-styling/pure-css/vite.config.js +27 -0
- jac_client/examples/css-styling/sass-example/.babelrc +9 -0
- jac_client/examples/css-styling/sass-example/README.md +16 -0
- jac_client/examples/css-styling/sass-example/app.jac +64 -0
- jac_client/examples/css-styling/sass-example/package.json +29 -0
- jac_client/examples/css-styling/sass-example/styles.scss +153 -0
- jac_client/examples/css-styling/sass-example/vite.config.js +27 -0
- jac_client/examples/css-styling/styled-components/.babelrc +9 -0
- jac_client/examples/css-styling/styled-components/README.md +16 -0
- jac_client/examples/css-styling/styled-components/app.jac +71 -0
- jac_client/examples/css-styling/styled-components/package.json +29 -0
- jac_client/examples/css-styling/styled-components/styled.js +90 -0
- jac_client/examples/css-styling/styled-components/vite.config.js +27 -0
- jac_client/examples/css-styling/tailwind-example/.babelrc +9 -0
- jac_client/examples/css-styling/tailwind-example/README.md +16 -0
- jac_client/examples/css-styling/tailwind-example/app.jac +63 -0
- jac_client/examples/css-styling/tailwind-example/global.css +1 -0
- jac_client/examples/css-styling/tailwind-example/package.json +30 -0
- jac_client/examples/css-styling/tailwind-example/vite.config.js +29 -0
- jac_client/examples/full-stack-with-auth/app.jac +20 -33
- jac_client/examples/full-stack-with-auth/package.json +1 -1
- jac_client/examples/full-stack-with-auth/vite.config.js +0 -1
- jac_client/examples/little-x/app.jac +327 -218
- jac_client/examples/little-x/submit-button.jac +1 -1
- jac_client/examples/nested-folders/nested-advance/.babelrc +9 -0
- jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +11 -0
- jac_client/examples/nested-folders/nested-advance/README.md +77 -0
- jac_client/examples/nested-folders/nested-advance/app.jac +35 -0
- jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +19 -0
- jac_client/examples/nested-folders/nested-advance/level1/Card.jac +43 -0
- jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +25 -0
- jac_client/examples/nested-folders/nested-advance/package.json +29 -0
- jac_client/examples/nested-folders/nested-advance/vite.config.js +28 -0
- jac_client/examples/nested-folders/nested-basic/.babelrc +9 -0
- jac_client/examples/nested-folders/nested-basic/README.md +183 -0
- jac_client/examples/nested-folders/nested-basic/app.jac +13 -0
- jac_client/examples/nested-folders/nested-basic/app.js +7 -0
- jac_client/examples/nested-folders/nested-basic/button.jac +7 -0
- jac_client/examples/nested-folders/nested-basic/components/button.jac +7 -0
- jac_client/examples/nested-folders/nested-basic/package.json +28 -0
- jac_client/examples/nested-folders/nested-basic/vite.config.js +27 -0
- jac_client/examples/with-router/app.jac +1 -1
- jac_client/examples/with-router/package.json +1 -1
- jac_client/examples/with-router/vite.config.js +0 -1
- jac_client/plugin/cli.py +7 -2
- jac_client/plugin/client.py +68 -5
- jac_client/plugin/client_runtime.jac +1 -1
- jac_client/plugin/vite_client_bundle.py +162 -14
- jac_client/tests/__init__.py +0 -1
- jac_client/tests/fixtures/basic-app/app.jac +7 -2
- jac_client/tests/fixtures/cl_file/app.cl.jac +48 -0
- jac_client/tests/fixtures/cl_file/app.jac +15 -0
- jac_client/tests/fixtures/client_app_with_antd/app.jac +14 -8
- jac_client/tests/fixtures/js_import/app.jac +19 -15
- jac_client/tests/fixtures/js_import/utils.js +0 -1
- jac_client/tests/fixtures/package.json +1 -1
- jac_client/tests/fixtures/relative_import/app.jac +4 -6
- jac_client/tests/fixtures/relative_import/button.jac +7 -6
- jac_client/tests/fixtures/spawn_test/app.jac +1 -5
- jac_client/tests/fixtures/test_fragments_spread/app.jac +24 -10
- jac_client/tests/test_asset_examples.py +322 -0
- jac_client/tests/test_cl.py +480 -426
- jac_client/tests/test_create_jac_app.py +125 -133
- jac_client/tests/test_it.py +329 -0
- jac_client/tests/test_nested_file.py +374 -0
- {jac_client-0.2.0.dist-info → jac_client-0.2.3.dist-info}/METADATA +11 -3
- jac_client-0.2.3.dist-info/RECORD +171 -0
- jac_client-0.2.0.dist-info/RECORD +0 -72
- {jac_client-0.2.0.dist-info → jac_client-0.2.3.dist-info}/WHEEL +0 -0
- {jac_client-0.2.0.dist-info → jac_client-0.2.3.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Pure CSS
|
|
2
|
+
|
|
3
|
+
Traditional CSS with external stylesheets. The most straightforward styling approach for Jac applications.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Pure CSS is the foundation of web styling. You write CSS in a separate file and import it into your Jac code. This approach is perfect for:
|
|
8
|
+
- Simple projects
|
|
9
|
+
- Learning CSS fundamentals
|
|
10
|
+
- Maximum control over styling
|
|
11
|
+
- Minimal dependencies
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
See the complete working example: [`examples/css-styling/pure-css/`](../../examples/css-styling/pure-css/)
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### 1. Create CSS File
|
|
20
|
+
|
|
21
|
+
Create a `styles.css` file in your project:
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
.container {
|
|
25
|
+
display: flex;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
align-items: center;
|
|
28
|
+
min-height: 100vh;
|
|
29
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.card {
|
|
33
|
+
background: white;
|
|
34
|
+
border-radius: 20px;
|
|
35
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
36
|
+
padding: 40px;
|
|
37
|
+
min-width: 400px;
|
|
38
|
+
text-align: center;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.title {
|
|
42
|
+
font-size: 2rem;
|
|
43
|
+
color: #667eea;
|
|
44
|
+
margin: 0 0 10px 0;
|
|
45
|
+
font-weight: 600;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 2. Import CSS in Jac
|
|
50
|
+
|
|
51
|
+
In your Jac file, import the CSS file:
|
|
52
|
+
|
|
53
|
+
```jac
|
|
54
|
+
# Pages
|
|
55
|
+
cl import from react {useState, useEffect}
|
|
56
|
+
cl import ".styles.css";
|
|
57
|
+
|
|
58
|
+
cl {
|
|
59
|
+
def app() -> any {
|
|
60
|
+
let [count, setCount] = useState(0);
|
|
61
|
+
|
|
62
|
+
return <div className="container">
|
|
63
|
+
<div className="card">
|
|
64
|
+
<h1 className="title">Counter Application</h1>
|
|
65
|
+
<p>Count: {count}</p>
|
|
66
|
+
</div>
|
|
67
|
+
</div>;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 3. Use Class Names
|
|
73
|
+
|
|
74
|
+
Apply CSS classes using the `className` prop:
|
|
75
|
+
|
|
76
|
+
```jac
|
|
77
|
+
return <div className="container">
|
|
78
|
+
<div className="card">
|
|
79
|
+
<h1 className="title">Counter Application</h1>
|
|
80
|
+
</div>
|
|
81
|
+
</div>;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 4. Dynamic Classes
|
|
85
|
+
|
|
86
|
+
Dynamically construct class names based on state:
|
|
87
|
+
|
|
88
|
+
```jac
|
|
89
|
+
let countClass = "countDisplay " + ("positive" if count > 0 else "negative" if count < 0 else "zero");
|
|
90
|
+
|
|
91
|
+
return <div className={countClass}>{count}</div>;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Import Syntax
|
|
95
|
+
|
|
96
|
+
CSS files are imported using the `cl import` syntax:
|
|
97
|
+
|
|
98
|
+
```jac
|
|
99
|
+
cl import ".styles.css";
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This compiles to:
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
import "./styles.css";
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Vite automatically processes CSS imports and extracts them to a separate CSS file during the build process.
|
|
109
|
+
|
|
110
|
+
## Best Practices
|
|
111
|
+
|
|
112
|
+
### 1. Organize Your CSS
|
|
113
|
+
|
|
114
|
+
Use comments to separate sections:
|
|
115
|
+
|
|
116
|
+
```css
|
|
117
|
+
/* ============================================
|
|
118
|
+
Container Styles
|
|
119
|
+
============================================ */
|
|
120
|
+
.container {
|
|
121
|
+
/* styles */
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* ============================================
|
|
125
|
+
Card Styles
|
|
126
|
+
============================================ */
|
|
127
|
+
.card {
|
|
128
|
+
/* styles */
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 2. Use Semantic Class Names
|
|
133
|
+
|
|
134
|
+
Make class names descriptive and meaningful:
|
|
135
|
+
|
|
136
|
+
```css
|
|
137
|
+
/* Good */
|
|
138
|
+
.button-primary { }
|
|
139
|
+
.card-header { }
|
|
140
|
+
.navigation-menu { }
|
|
141
|
+
|
|
142
|
+
/* Avoid */
|
|
143
|
+
.btn1 { }
|
|
144
|
+
.div1 { }
|
|
145
|
+
.red { }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 3. Use CSS Variables for Theming
|
|
149
|
+
|
|
150
|
+
Leverage CSS custom properties for theming:
|
|
151
|
+
|
|
152
|
+
```css
|
|
153
|
+
:root {
|
|
154
|
+
--primary-color: #007bff;
|
|
155
|
+
--secondary-color: #6c757d;
|
|
156
|
+
--spacing-unit: 1rem;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.button {
|
|
160
|
+
background-color: var(--primary-color);
|
|
161
|
+
padding: var(--spacing-unit);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 4. Mobile-First Design
|
|
166
|
+
|
|
167
|
+
Design for mobile, then enhance for desktop:
|
|
168
|
+
|
|
169
|
+
```css
|
|
170
|
+
/* Mobile first */
|
|
171
|
+
.container {
|
|
172
|
+
padding: 1rem;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Desktop */
|
|
176
|
+
@media (min-width: 768px) {
|
|
177
|
+
.container {
|
|
178
|
+
padding: 2rem;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 5. Avoid Inline Styles
|
|
184
|
+
|
|
185
|
+
Keep styles in the CSS file for maintainability:
|
|
186
|
+
|
|
187
|
+
```jac
|
|
188
|
+
// Avoid
|
|
189
|
+
<div style={{"padding": "1rem", "color": "blue"}}>
|
|
190
|
+
|
|
191
|
+
// Prefer
|
|
192
|
+
<div className="container">
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Advantages
|
|
196
|
+
|
|
197
|
+
- **No build step required** for CSS
|
|
198
|
+
- **Easy to understand** and maintain
|
|
199
|
+
- **Works with any CSS framework**
|
|
200
|
+
- **Minimal dependencies**
|
|
201
|
+
- **Great browser support**
|
|
202
|
+
- **Familiar syntax** for developers
|
|
203
|
+
|
|
204
|
+
## Limitations
|
|
205
|
+
|
|
206
|
+
- **No variables or nesting** (use CSS variables for theming)
|
|
207
|
+
- **No preprocessing features**
|
|
208
|
+
- **Global scope** (use BEM or similar for scoping)
|
|
209
|
+
- **No dynamic styling** based on props
|
|
210
|
+
- **Manual organization** required
|
|
211
|
+
|
|
212
|
+
## When to Use
|
|
213
|
+
|
|
214
|
+
Choose Pure CSS when:
|
|
215
|
+
|
|
216
|
+
- You're building a simple application
|
|
217
|
+
- You want minimal dependencies
|
|
218
|
+
- You prefer traditional CSS workflow
|
|
219
|
+
- You're learning CSS fundamentals
|
|
220
|
+
- You need maximum control
|
|
221
|
+
- You want to avoid build complexity
|
|
222
|
+
|
|
223
|
+
## CSS Variables (Custom Properties)
|
|
224
|
+
|
|
225
|
+
Use CSS custom properties for theming and dynamic values:
|
|
226
|
+
|
|
227
|
+
```css
|
|
228
|
+
:root {
|
|
229
|
+
--primary: #007bff;
|
|
230
|
+
--secondary: #6c757d;
|
|
231
|
+
--success: #28a745;
|
|
232
|
+
--danger: #dc3545;
|
|
233
|
+
--spacing-sm: 0.5rem;
|
|
234
|
+
--spacing-md: 1rem;
|
|
235
|
+
--spacing-lg: 2rem;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.button {
|
|
239
|
+
background-color: var(--primary);
|
|
240
|
+
padding: var(--spacing-md);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.button-success {
|
|
244
|
+
background-color: var(--success);
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Responsive Design
|
|
249
|
+
|
|
250
|
+
Use media queries for responsive layouts:
|
|
251
|
+
|
|
252
|
+
```css
|
|
253
|
+
.container {
|
|
254
|
+
padding: 1rem;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@media (min-width: 768px) {
|
|
258
|
+
.container {
|
|
259
|
+
padding: 2rem;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
@media (min-width: 1024px) {
|
|
264
|
+
.container {
|
|
265
|
+
padding: 3rem;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Naming Conventions
|
|
271
|
+
|
|
272
|
+
### BEM (Block Element Modifier)
|
|
273
|
+
|
|
274
|
+
```css
|
|
275
|
+
.card { } /* Block */
|
|
276
|
+
.card__header { } /* Element */
|
|
277
|
+
.card__header--highlighted { } /* Modifier */
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Utility Classes
|
|
281
|
+
|
|
282
|
+
```css
|
|
283
|
+
.text-center { text-align: center; }
|
|
284
|
+
.mt-1 { margin-top: 0.25rem; }
|
|
285
|
+
.p-2 { padding: 0.5rem; }
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Next Steps
|
|
289
|
+
|
|
290
|
+
- Learn about [CSS Variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) for advanced theming
|
|
291
|
+
- Explore [Sass/SCSS](./sass.md) for preprocessing features
|
|
292
|
+
- Check out [Tailwind CSS](./tailwind.md) for utility-first approach
|
|
293
|
+
- See [CSS Modules](./css-modules.md) for scoped styles (coming soon)
|
|
294
|
+
|
|
295
|
+
## Resources
|
|
296
|
+
|
|
297
|
+
- [MDN CSS Documentation](https://developer.mozilla.org/en-US/docs/Web/CSS)
|
|
298
|
+
- [CSS Tricks](https://css-tricks.com/)
|
|
299
|
+
- [Can I Use](https://caniuse.com/) - Browser compatibility
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# Sass/SCSS
|
|
2
|
+
|
|
3
|
+
CSS preprocessor with variables, nesting, mixins, and functions for Jac applications.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Sass (Syntactically Awesome Style Sheets) extends CSS with powerful features like variables, nesting, mixins, and functions. This approach is perfect for:
|
|
8
|
+
- Large projects with shared styles
|
|
9
|
+
- DRY (Don't Repeat Yourself) principles
|
|
10
|
+
- Complex styling logic
|
|
11
|
+
- Maintainable CSS architecture
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
See the complete working example: [`examples/css-styling/sass-example/`](../../examples/css-styling/sass-example/)
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### 1. Install Sass
|
|
20
|
+
|
|
21
|
+
Add to `package.json`:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"sass": "^1.77.8"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Create SCSS File
|
|
32
|
+
|
|
33
|
+
Create `styles.scss`:
|
|
34
|
+
|
|
35
|
+
```scss
|
|
36
|
+
$primary-color: #007bff;
|
|
37
|
+
$secondary-color: #6c757d;
|
|
38
|
+
|
|
39
|
+
.button {
|
|
40
|
+
background-color: $primary-color;
|
|
41
|
+
color: white;
|
|
42
|
+
padding: 0.75rem 1.5rem;
|
|
43
|
+
border-radius: 0.5rem;
|
|
44
|
+
|
|
45
|
+
&:hover {
|
|
46
|
+
background-color: darken($primary-color, 10%);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. Import in Jac
|
|
52
|
+
|
|
53
|
+
```jac
|
|
54
|
+
# Pages
|
|
55
|
+
cl import from react {useState, useEffect}
|
|
56
|
+
cl import ".styles.scss";
|
|
57
|
+
|
|
58
|
+
cl {
|
|
59
|
+
def app() -> any {
|
|
60
|
+
return <div className="container">
|
|
61
|
+
<button className="button">Click Me</button>
|
|
62
|
+
</div>;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Vite automatically compiles SCSS to CSS during the build process.
|
|
68
|
+
|
|
69
|
+
## Sass Features
|
|
70
|
+
|
|
71
|
+
### Variables
|
|
72
|
+
|
|
73
|
+
Define reusable values:
|
|
74
|
+
|
|
75
|
+
```scss
|
|
76
|
+
$primary-gradient-start: #dbeafe;
|
|
77
|
+
$primary-gradient-end: #e0e7ff;
|
|
78
|
+
$white: #ffffff;
|
|
79
|
+
$gray-800: #1f2937;
|
|
80
|
+
$spacing-unit: 1rem;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Nesting
|
|
84
|
+
|
|
85
|
+
Nest selectors for better organization:
|
|
86
|
+
|
|
87
|
+
```scss
|
|
88
|
+
.button {
|
|
89
|
+
padding: 0.75rem 1.5rem;
|
|
90
|
+
border-radius: 0.5rem;
|
|
91
|
+
|
|
92
|
+
&:hover {
|
|
93
|
+
transform: scale(1.05);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&:active {
|
|
97
|
+
transform: scale(0.95);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&Decrement {
|
|
101
|
+
background-color: $red-500;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
&Reset {
|
|
105
|
+
background-color: $gray-500;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Mixins
|
|
111
|
+
|
|
112
|
+
Create reusable style blocks:
|
|
113
|
+
|
|
114
|
+
```scss
|
|
115
|
+
@mixin flex-center {
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: center;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@mixin button-base {
|
|
122
|
+
color: $white;
|
|
123
|
+
font-weight: bold;
|
|
124
|
+
padding: 0.75rem 1.5rem;
|
|
125
|
+
border-radius: 0.5rem;
|
|
126
|
+
border: none;
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
|
|
129
|
+
&:hover {
|
|
130
|
+
transform: scale(1.05);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.container {
|
|
135
|
+
@include flex-center;
|
|
136
|
+
min-height: 100vh;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.button {
|
|
140
|
+
@include button-base;
|
|
141
|
+
background-color: $primary-color;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Functions
|
|
146
|
+
|
|
147
|
+
Use built-in and custom functions:
|
|
148
|
+
|
|
149
|
+
```scss
|
|
150
|
+
.button {
|
|
151
|
+
background-color: $red-500;
|
|
152
|
+
|
|
153
|
+
&:hover {
|
|
154
|
+
background-color: darken($red-500, 10%);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.card {
|
|
159
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
160
|
+
|
|
161
|
+
&:hover {
|
|
162
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Partials and Imports
|
|
168
|
+
|
|
169
|
+
Organize styles across multiple files:
|
|
170
|
+
|
|
171
|
+
```scss
|
|
172
|
+
// _variables.scss
|
|
173
|
+
$primary: #007bff;
|
|
174
|
+
$secondary: #6c757d;
|
|
175
|
+
|
|
176
|
+
// _mixins.scss
|
|
177
|
+
@mixin flex-center {
|
|
178
|
+
display: flex;
|
|
179
|
+
align-items: center;
|
|
180
|
+
justify-content: center;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// styles.scss
|
|
184
|
+
@import 'variables';
|
|
185
|
+
@import 'mixins';
|
|
186
|
+
|
|
187
|
+
.container {
|
|
188
|
+
@include flex-center;
|
|
189
|
+
background-color: $primary;
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Best Practices
|
|
194
|
+
|
|
195
|
+
### 1. Use Variables
|
|
196
|
+
|
|
197
|
+
Define colors, spacing, and other values as variables:
|
|
198
|
+
|
|
199
|
+
```scss
|
|
200
|
+
$colors: (
|
|
201
|
+
primary: #007bff,
|
|
202
|
+
secondary: #6c757d,
|
|
203
|
+
success: #28a745,
|
|
204
|
+
danger: #dc3545,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
.button {
|
|
208
|
+
background-color: map-get($colors, primary);
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 2. Create Mixins
|
|
213
|
+
|
|
214
|
+
Extract common patterns into mixins:
|
|
215
|
+
|
|
216
|
+
```scss
|
|
217
|
+
@mixin respond-to($breakpoint) {
|
|
218
|
+
@media (min-width: $breakpoint) {
|
|
219
|
+
@content;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.container {
|
|
224
|
+
padding: 1rem;
|
|
225
|
+
|
|
226
|
+
@include respond-to(768px) {
|
|
227
|
+
padding: 2rem;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 3. Organize with Partials
|
|
233
|
+
|
|
234
|
+
Split large files into smaller modules:
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
styles/
|
|
238
|
+
├── _variables.scss
|
|
239
|
+
├── _mixins.scss
|
|
240
|
+
├── _components.scss
|
|
241
|
+
└── main.scss
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### 4. Use Nesting Wisely
|
|
245
|
+
|
|
246
|
+
Don't nest too deeply (max 3-4 levels):
|
|
247
|
+
|
|
248
|
+
```scss
|
|
249
|
+
// Good
|
|
250
|
+
.card {
|
|
251
|
+
padding: 1rem;
|
|
252
|
+
|
|
253
|
+
&__header {
|
|
254
|
+
font-weight: bold;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Avoid
|
|
259
|
+
.card {
|
|
260
|
+
.header {
|
|
261
|
+
.title {
|
|
262
|
+
.text {
|
|
263
|
+
// Too deep!
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 5. Leverage Functions
|
|
271
|
+
|
|
272
|
+
Use Sass functions for calculations:
|
|
273
|
+
|
|
274
|
+
```scss
|
|
275
|
+
.container {
|
|
276
|
+
width: percentage(2/3);
|
|
277
|
+
margin: rem(16px);
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Common Patterns
|
|
282
|
+
|
|
283
|
+
### BEM with Nesting
|
|
284
|
+
|
|
285
|
+
```scss
|
|
286
|
+
.card {
|
|
287
|
+
padding: 1rem;
|
|
288
|
+
|
|
289
|
+
&__header {
|
|
290
|
+
padding: 1rem;
|
|
291
|
+
border-bottom: 1px solid #ddd;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
&__body {
|
|
295
|
+
padding: 1.5rem;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
&--highlighted {
|
|
299
|
+
border: 2px solid $primary;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Color Management
|
|
305
|
+
|
|
306
|
+
```scss
|
|
307
|
+
$colors: (
|
|
308
|
+
primary: #007bff,
|
|
309
|
+
secondary: #6c757d,
|
|
310
|
+
success: #28a745,
|
|
311
|
+
danger: #dc3545,
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
@function color($name) {
|
|
315
|
+
@return map-get($colors, $name);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.button {
|
|
319
|
+
background-color: color(primary);
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Responsive Mixins
|
|
324
|
+
|
|
325
|
+
```scss
|
|
326
|
+
@mixin respond-to($breakpoint) {
|
|
327
|
+
@if $breakpoint == mobile {
|
|
328
|
+
@media (max-width: 767px) { @content; }
|
|
329
|
+
}
|
|
330
|
+
@else if $breakpoint == tablet {
|
|
331
|
+
@media (min-width: 768px) { @content; }
|
|
332
|
+
}
|
|
333
|
+
@else if $breakpoint == desktop {
|
|
334
|
+
@media (min-width: 1024px) { @content; }
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.container {
|
|
339
|
+
padding: 1rem;
|
|
340
|
+
|
|
341
|
+
@include respond-to(tablet) {
|
|
342
|
+
padding: 2rem;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Advantages
|
|
348
|
+
|
|
349
|
+
- **Variables** for maintainable theming
|
|
350
|
+
- **Nesting** for better organization
|
|
351
|
+
- **Mixins** for reusable code
|
|
352
|
+
- **Functions** for dynamic values
|
|
353
|
+
- **Partials** for modular CSS
|
|
354
|
+
- **Compiles to standard CSS**
|
|
355
|
+
- **Large ecosystem** and community
|
|
356
|
+
|
|
357
|
+
## Limitations
|
|
358
|
+
|
|
359
|
+
- **Requires build step**
|
|
360
|
+
- **Learning curve** for Sass syntax
|
|
361
|
+
- **Can get complex** with deep nesting
|
|
362
|
+
- **Additional dependency**
|
|
363
|
+
- **Debugging** can be harder (source maps help)
|
|
364
|
+
|
|
365
|
+
## When to Use
|
|
366
|
+
|
|
367
|
+
Choose Sass/SCSS when:
|
|
368
|
+
|
|
369
|
+
- You're working on large projects
|
|
370
|
+
- You need variables and mixins
|
|
371
|
+
- You want better CSS organization
|
|
372
|
+
- You prefer preprocessing over runtime CSS
|
|
373
|
+
- You need complex styling logic
|
|
374
|
+
- You want to share styles across components
|
|
375
|
+
|
|
376
|
+
## Import Syntax
|
|
377
|
+
|
|
378
|
+
SCSS files are imported using the `cl import` syntax:
|
|
379
|
+
|
|
380
|
+
```jac
|
|
381
|
+
cl import ".styles.scss";
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
This compiles to:
|
|
385
|
+
|
|
386
|
+
```javascript
|
|
387
|
+
import "./styles.scss";
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Vite automatically processes SCSS imports and compiles them to CSS.
|
|
391
|
+
|
|
392
|
+
## Next Steps
|
|
393
|
+
|
|
394
|
+
- Explore [Sass Documentation](https://sass-lang.com/documentation)
|
|
395
|
+
- Check out [Less](./less.md) for similar preprocessing (coming soon)
|
|
396
|
+
- Learn about [PostCSS](./postcss.md) for CSS transformations (coming soon)
|
|
397
|
+
- See [Pure CSS](./pure-css.md) for traditional CSS approach
|
|
398
|
+
|
|
399
|
+
## Resources
|
|
400
|
+
|
|
401
|
+
- [Sass Documentation](https://sass-lang.com/documentation)
|
|
402
|
+
- [Sass Guidelines](https://sass-guidelin.es/)
|
|
403
|
+
- [Sass Playground](https://www.sassmeister.com/)
|