jac-client 0.2.2__py3-none-any.whl → 0.2.4__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/examples/all-in-one/assets/workers/worker.py +5 -0
- jac_client/tests/conftest.py +281 -0
- jac_client/tests/test_cli.py +755 -0
- jac_client/tests/test_it.py +347 -67
- {jac_client-0.2.2.dist-info → jac_client-0.2.4.dist-info}/METADATA +30 -24
- jac_client-0.2.4.dist-info/RECORD +10 -0
- {jac_client-0.2.2.dist-info → jac_client-0.2.4.dist-info}/WHEEL +2 -1
- jac_client-0.2.4.dist-info/entry_points.txt +4 -0
- jac_client-0.2.4.dist-info/top_level.txt +1 -0
- jac_client/docs/README.md +0 -689
- jac_client/docs/advanced-state.md +0 -1265
- jac_client/docs/asset-serving/intro.md +0 -209
- jac_client/docs/assets/pipe_line-v2.svg +0 -32
- jac_client/docs/assets/pipe_line.png +0 -0
- jac_client/docs/file-system/app.jac.md +0 -121
- jac_client/docs/file-system/backend-frontend.md +0 -217
- jac_client/docs/file-system/intro.md +0 -72
- jac_client/docs/file-system/nested-imports.md +0 -348
- jac_client/docs/guide-example/intro.md +0 -115
- jac_client/docs/guide-example/step-01-setup.md +0 -270
- jac_client/docs/guide-example/step-02-components.md +0 -416
- jac_client/docs/guide-example/step-03-styling.md +0 -478
- jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
- jac_client/docs/guide-example/step-05-local-state.md +0 -530
- jac_client/docs/guide-example/step-06-events.md +0 -749
- jac_client/docs/guide-example/step-07-effects.md +0 -468
- jac_client/docs/guide-example/step-08-walkers.md +0 -534
- jac_client/docs/guide-example/step-09-authentication.md +0 -586
- jac_client/docs/guide-example/step-10-routing.md +0 -539
- jac_client/docs/guide-example/step-11-final.md +0 -963
- jac_client/docs/imports.md +0 -1141
- jac_client/docs/lifecycle-hooks.md +0 -773
- jac_client/docs/routing.md +0 -659
- jac_client/docs/styling/intro.md +0 -249
- jac_client/docs/styling/js-styling.md +0 -367
- jac_client/docs/styling/material-ui.md +0 -341
- jac_client/docs/styling/pure-css.md +0 -299
- jac_client/docs/styling/sass.md +0 -403
- jac_client/docs/styling/styled-components.md +0 -395
- jac_client/docs/styling/tailwind.md +0 -298
- jac_client/examples/all-in-one/.babelrc +0 -9
- jac_client/examples/all-in-one/README.md +0 -16
- jac_client/examples/all-in-one/app.jac +0 -426
- jac_client/examples/all-in-one/assets/burger.png +0 -0
- jac_client/examples/all-in-one/button.jac +0 -7
- jac_client/examples/all-in-one/components/button.jac +0 -7
- jac_client/examples/all-in-one/package.json +0 -29
- jac_client/examples/all-in-one/styles.css +0 -26
- jac_client/examples/all-in-one/vite.config.js +0 -28
- jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
- jac_client/examples/asset-serving/css-with-image/README.md +0 -91
- jac_client/examples/asset-serving/css-with-image/app.jac +0 -88
- jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
- jac_client/examples/asset-serving/css-with-image/package.json +0 -28
- jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
- jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
- jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
- jac_client/examples/asset-serving/image-asset/README.md +0 -119
- jac_client/examples/asset-serving/image-asset/app.jac +0 -55
- jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
- jac_client/examples/asset-serving/image-asset/package.json +0 -28
- jac_client/examples/asset-serving/image-asset/styles.css +0 -26
- jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
- jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
- jac_client/examples/asset-serving/import-alias/README.md +0 -83
- jac_client/examples/asset-serving/import-alias/app.jac +0 -111
- jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
- jac_client/examples/asset-serving/import-alias/package.json +0 -28
- jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
- jac_client/examples/basic/.babelrc +0 -9
- jac_client/examples/basic/README.md +0 -16
- jac_client/examples/basic/app.jac +0 -21
- jac_client/examples/basic/package.json +0 -27
- jac_client/examples/basic/vite.config.js +0 -27
- jac_client/examples/basic-auth/.babelrc +0 -9
- jac_client/examples/basic-auth/README.md +0 -16
- jac_client/examples/basic-auth/app.jac +0 -308
- jac_client/examples/basic-auth/package.json +0 -27
- jac_client/examples/basic-auth/vite.config.js +0 -27
- jac_client/examples/basic-auth-with-router/.babelrc +0 -9
- jac_client/examples/basic-auth-with-router/README.md +0 -60
- jac_client/examples/basic-auth-with-router/app.jac +0 -464
- jac_client/examples/basic-auth-with-router/package.json +0 -28
- jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
- jac_client/examples/basic-full-stack/.babelrc +0 -9
- jac_client/examples/basic-full-stack/README.md +0 -18
- jac_client/examples/basic-full-stack/app.jac +0 -320
- jac_client/examples/basic-full-stack/package.json +0 -28
- jac_client/examples/basic-full-stack/vite.config.js +0 -27
- jac_client/examples/css-styling/js-styling/.babelrc +0 -9
- jac_client/examples/css-styling/js-styling/README.md +0 -183
- jac_client/examples/css-styling/js-styling/app.jac +0 -84
- jac_client/examples/css-styling/js-styling/package.json +0 -28
- jac_client/examples/css-styling/js-styling/styles.js +0 -100
- jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
- jac_client/examples/css-styling/material-ui/.babelrc +0 -9
- jac_client/examples/css-styling/material-ui/README.md +0 -16
- jac_client/examples/css-styling/material-ui/app.jac +0 -122
- jac_client/examples/css-styling/material-ui/package.json +0 -32
- jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
- jac_client/examples/css-styling/pure-css/.babelrc +0 -9
- jac_client/examples/css-styling/pure-css/README.md +0 -16
- jac_client/examples/css-styling/pure-css/app.jac +0 -64
- jac_client/examples/css-styling/pure-css/package.json +0 -28
- jac_client/examples/css-styling/pure-css/styles.css +0 -111
- jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
- jac_client/examples/css-styling/sass-example/.babelrc +0 -9
- jac_client/examples/css-styling/sass-example/README.md +0 -16
- jac_client/examples/css-styling/sass-example/app.jac +0 -64
- jac_client/examples/css-styling/sass-example/package.json +0 -29
- jac_client/examples/css-styling/sass-example/styles.scss +0 -153
- jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
- jac_client/examples/css-styling/styled-components/.babelrc +0 -9
- jac_client/examples/css-styling/styled-components/README.md +0 -16
- jac_client/examples/css-styling/styled-components/app.jac +0 -71
- jac_client/examples/css-styling/styled-components/package.json +0 -29
- jac_client/examples/css-styling/styled-components/styled.js +0 -90
- jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
- jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
- jac_client/examples/css-styling/tailwind-example/README.md +0 -16
- jac_client/examples/css-styling/tailwind-example/app.jac +0 -63
- jac_client/examples/css-styling/tailwind-example/global.css +0 -1
- jac_client/examples/css-styling/tailwind-example/package.json +0 -30
- jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
- jac_client/examples/full-stack-with-auth/.babelrc +0 -9
- jac_client/examples/full-stack-with-auth/README.md +0 -16
- jac_client/examples/full-stack-with-auth/app.jac +0 -722
- jac_client/examples/full-stack-with-auth/package.json +0 -28
- jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
- jac_client/examples/little-x/app.jac +0 -724
- jac_client/examples/little-x/package.json +0 -23
- jac_client/examples/little-x/submit-button.jac +0 -8
- jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
- jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +0 -11
- jac_client/examples/nested-folders/nested-advance/README.md +0 -77
- jac_client/examples/nested-folders/nested-advance/app.jac +0 -35
- jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +0 -19
- jac_client/examples/nested-folders/nested-advance/level1/Card.jac +0 -43
- jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +0 -25
- jac_client/examples/nested-folders/nested-advance/package.json +0 -29
- jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
- jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
- jac_client/examples/nested-folders/nested-basic/README.md +0 -183
- jac_client/examples/nested-folders/nested-basic/app.jac +0 -13
- jac_client/examples/nested-folders/nested-basic/app.js +0 -7
- jac_client/examples/nested-folders/nested-basic/button.jac +0 -7
- jac_client/examples/nested-folders/nested-basic/components/button.jac +0 -7
- jac_client/examples/nested-folders/nested-basic/package.json +0 -28
- jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
- jac_client/examples/with-router/.babelrc +0 -9
- jac_client/examples/with-router/README.md +0 -17
- jac_client/examples/with-router/app.jac +0 -323
- jac_client/examples/with-router/package.json +0 -28
- jac_client/examples/with-router/vite.config.js +0 -27
- jac_client/plugin/cli.py +0 -244
- jac_client/plugin/client.py +0 -152
- jac_client/plugin/client_runtime.jac +0 -234
- jac_client/plugin/vite_client_bundle.py +0 -503
- jac_client/tests/fixtures/basic-app/app.jac +0 -23
- jac_client/tests/fixtures/cl_file/app.cl.jac +0 -48
- jac_client/tests/fixtures/cl_file/app.jac +0 -15
- jac_client/tests/fixtures/client_app_with_antd/app.jac +0 -34
- jac_client/tests/fixtures/js_import/app.jac +0 -34
- jac_client/tests/fixtures/js_import/utils.js +0 -21
- jac_client/tests/fixtures/package-lock.json +0 -329
- jac_client/tests/fixtures/package.json +0 -11
- jac_client/tests/fixtures/relative_import/app.jac +0 -11
- jac_client/tests/fixtures/relative_import/button.jac +0 -7
- jac_client/tests/fixtures/spawn_test/app.jac +0 -129
- jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -67
- jac_client/tests/test_asset_examples.py +0 -322
- jac_client/tests/test_cl.py +0 -530
- jac_client/tests/test_create_jac_app.py +0 -131
- jac_client/tests/test_nested_file.py +0 -374
- jac_client-0.2.2.dist-info/RECORD +0 -171
- jac_client-0.2.2.dist-info/entry_points.txt +0 -4
|
@@ -1,478 +0,0 @@
|
|
|
1
|
-
# Step 3: Styling Components
|
|
2
|
-
|
|
3
|
-
> ** Quick Tip:** Each step has two parts. **Part 1** shows you what to build. **Part 2** explains why it works. Want to just build? Skip all Part 2 sections!
|
|
4
|
-
|
|
5
|
-
In this step, you'll learn how to style your components using inline CSS to make them look great!
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Part 1: Building the App
|
|
10
|
-
|
|
11
|
-
### Step 3.1: Style the TodoItem Component
|
|
12
|
-
|
|
13
|
-
Let's make our TodoItem look better:
|
|
14
|
-
|
|
15
|
-
```jac
|
|
16
|
-
cl {
|
|
17
|
-
def TodoItem(props: any) -> any {
|
|
18
|
-
return <div style={{
|
|
19
|
-
"display": "flex",
|
|
20
|
-
"alignItems": "center",
|
|
21
|
-
"gap": "10px",
|
|
22
|
-
"padding": "10px",
|
|
23
|
-
"borderBottom": "1px solid #e5e7eb"
|
|
24
|
-
}}>
|
|
25
|
-
<input
|
|
26
|
-
type="checkbox"
|
|
27
|
-
checked={props.done}
|
|
28
|
-
style={{"cursor": "pointer"}}
|
|
29
|
-
/>
|
|
30
|
-
<span style={{
|
|
31
|
-
"flex": "1",
|
|
32
|
-
"textDecoration": ("line-through" if props.done else "none"),
|
|
33
|
-
"color": ("#999" if props.done else "#000")
|
|
34
|
-
}}>
|
|
35
|
-
{props.text}
|
|
36
|
-
</span>
|
|
37
|
-
<button style={{
|
|
38
|
-
"padding": "4px 8px",
|
|
39
|
-
"background": "#ef4444",
|
|
40
|
-
"color": "#ffffff",
|
|
41
|
-
"border": "none",
|
|
42
|
-
"borderRadius": "4px",
|
|
43
|
-
"cursor": "pointer",
|
|
44
|
-
"fontSize": "12px"
|
|
45
|
-
}}>
|
|
46
|
-
Delete
|
|
47
|
-
</button>
|
|
48
|
-
</div>;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
def app() -> any {
|
|
52
|
-
return <div style= {{"padding": "20px"}}>
|
|
53
|
-
<h1>My Todos</h1>
|
|
54
|
-
<TodoItem text="Learn Jac basics" done={true} />
|
|
55
|
-
<TodoItem text="Build a todo app" done={false} />
|
|
56
|
-
</div>;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
**Try it!** Your todos now have spacing, colors, and the completed ones show strikethrough text!
|
|
62
|
-
|
|
63
|
-
### Step 3.2: Style the TodoInput Component
|
|
64
|
-
|
|
65
|
-
```jac
|
|
66
|
-
cl {
|
|
67
|
-
def TodoInput(props: any) -> any {
|
|
68
|
-
return <div style={{
|
|
69
|
-
"display": "flex",
|
|
70
|
-
"gap": "8px",
|
|
71
|
-
"marginBottom": "16px"
|
|
72
|
-
}}>
|
|
73
|
-
<input
|
|
74
|
-
type="text"
|
|
75
|
-
placeholder="What needs to be done?"
|
|
76
|
-
style={{
|
|
77
|
-
"flex": "1",
|
|
78
|
-
"padding": "8px",
|
|
79
|
-
"border": "1px solid #ddd",
|
|
80
|
-
"borderRadius": "4px"
|
|
81
|
-
}}
|
|
82
|
-
/>
|
|
83
|
-
<button style={{
|
|
84
|
-
"padding": "8px 16px",
|
|
85
|
-
"background": "#3b82f6",
|
|
86
|
-
"color": "#ffffff",
|
|
87
|
-
"border": "none",
|
|
88
|
-
"borderRadius": "4px",
|
|
89
|
-
"cursor": "pointer",
|
|
90
|
-
"fontWeight": "600"
|
|
91
|
-
}}>
|
|
92
|
-
Add
|
|
93
|
-
</button>
|
|
94
|
-
</div>;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
def app() -> any {
|
|
98
|
-
return <div style={{"padding": "20px"}}>
|
|
99
|
-
<h1>My Todos</h1>
|
|
100
|
-
<TodoInput />
|
|
101
|
-
</div>;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Step 3.3: Style the TodoFilters Component
|
|
107
|
-
|
|
108
|
-
```jac
|
|
109
|
-
cl {
|
|
110
|
-
def TodoFilters(props: any) -> any {
|
|
111
|
-
return <div style={{
|
|
112
|
-
"display": "flex",
|
|
113
|
-
"gap": "8px",
|
|
114
|
-
"marginBottom": "16px"
|
|
115
|
-
}}>
|
|
116
|
-
<button style={{
|
|
117
|
-
"padding": "6px 12px",
|
|
118
|
-
"background": "#3b82f6",
|
|
119
|
-
"color": "#ffffff",
|
|
120
|
-
"border": "none",
|
|
121
|
-
"borderRadius": "4px",
|
|
122
|
-
"cursor": "pointer",
|
|
123
|
-
"fontSize": "14px"
|
|
124
|
-
}}>
|
|
125
|
-
All
|
|
126
|
-
</button>
|
|
127
|
-
<button style={{
|
|
128
|
-
"padding": "6px 12px",
|
|
129
|
-
"background": "#e5e7eb",
|
|
130
|
-
"color": "#000000",
|
|
131
|
-
"border": "none",
|
|
132
|
-
"borderRadius": "4px",
|
|
133
|
-
"cursor": "pointer",
|
|
134
|
-
"fontSize": "14px"
|
|
135
|
-
}}>
|
|
136
|
-
Active
|
|
137
|
-
</button>
|
|
138
|
-
<button style={{
|
|
139
|
-
"padding": "6px 12px",
|
|
140
|
-
"background": "#e5e7eb",
|
|
141
|
-
"color": "#000000",
|
|
142
|
-
"border": "none",
|
|
143
|
-
"borderRadius": "4px",
|
|
144
|
-
"cursor": "pointer",
|
|
145
|
-
"fontSize": "14px"
|
|
146
|
-
}}>
|
|
147
|
-
Completed
|
|
148
|
-
</button>
|
|
149
|
-
</div>;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
def app() -> any {
|
|
153
|
-
return <div style={{"padding": "20px"}}>
|
|
154
|
-
<h1>My Todos</h1>
|
|
155
|
-
<TodoFilters />
|
|
156
|
-
</div>;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Try it!** The "All" button is now blue (active), while the others are gray.
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
**⏭ Want to skip the theory?** Jump to [Step 4: Todo UI](./step-04-todo-ui.md)
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Part 2: Understanding the Concepts
|
|
170
|
-
|
|
171
|
-
### What are Inline Styles?
|
|
172
|
-
|
|
173
|
-
In traditional HTML/CSS, you might write:
|
|
174
|
-
|
|
175
|
-
```html
|
|
176
|
-
<!-- HTML -->
|
|
177
|
-
<div style="color: blue; font-size: 20px;">Hello</div>
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
In Jac (using JSX), styles are **dictionaries** (JavaScript objects):
|
|
181
|
-
|
|
182
|
-
```jac
|
|
183
|
-
<div style={{"color": "blue", "fontSize": "20px"}}>Hello</div>
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Why Double Curly Braces `{{ }}`?
|
|
187
|
-
|
|
188
|
-
```jac
|
|
189
|
-
<div style={{ "color": "blue" }}>
|
|
190
|
-
^ ^
|
|
191
|
-
| |
|
|
192
|
-
| └─ Dictionary: {"color": "blue"}
|
|
193
|
-
└──── JSX expression: insert Jac code here
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
- **Outer `{ }`** = "I'm inserting Jac code into JSX"
|
|
197
|
-
- **Inner `{ }`** = "This is a dictionary/object"
|
|
198
|
-
|
|
199
|
-
**Think of it like:**
|
|
200
|
-
|
|
201
|
-
```python
|
|
202
|
-
# Python
|
|
203
|
-
styles = {"color": "blue", "fontSize": "20px"}
|
|
204
|
-
element.set_style(styles)
|
|
205
|
-
|
|
206
|
-
# Jac/JSX
|
|
207
|
-
<div style={{"color": "blue", "fontSize": "20px"}}>
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### CSS Property Names: camelCase
|
|
211
|
-
|
|
212
|
-
CSS uses kebab-case (`background-color`), but JSX uses camelCase (`backgroundColor`):
|
|
213
|
-
|
|
214
|
-
```jac
|
|
215
|
-
# CSS property → JSX property
|
|
216
|
-
background-color → "backgroundColor"
|
|
217
|
-
font-size → "fontSize"
|
|
218
|
-
border-radius → "borderRadius"
|
|
219
|
-
margin-top → "marginTop"
|
|
220
|
-
text-align → "textAlign"
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
**Examples:**
|
|
224
|
-
|
|
225
|
-
```jac
|
|
226
|
-
# Correct (camelCase)
|
|
227
|
-
{
|
|
228
|
-
"backgroundColor": "#ffffff",
|
|
229
|
-
"fontSize": "16px",
|
|
230
|
-
"borderRadius": "8px"
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
# Wrong (kebab-case won't work)
|
|
234
|
-
{
|
|
235
|
-
"background-color": "#ffffff", # Error!
|
|
236
|
-
"font-size": "16px" # Error!
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### Common Style Properties
|
|
241
|
-
|
|
242
|
-
**Layout & Spacing:**
|
|
243
|
-
|
|
244
|
-
```jac
|
|
245
|
-
{
|
|
246
|
-
"display": "flex", # Flexbox layout
|
|
247
|
-
"flexDirection": "column", # Stack vertically
|
|
248
|
-
"gap": "16px", # Space between children
|
|
249
|
-
"padding": "20px", # Inner spacing
|
|
250
|
-
"margin": "10px" # Outer spacing
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Colors & Backgrounds:**
|
|
255
|
-
|
|
256
|
-
```jac
|
|
257
|
-
{
|
|
258
|
-
"color": "#1f2937", # Text color
|
|
259
|
-
"backgroundColor": "#ffffff", # Background color
|
|
260
|
-
"border": "1px solid #e5e7eb", # Border
|
|
261
|
-
"boxShadow": "0 1px 3px rgba(0,0,0,0.1)" # Shadow
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
**Typography:**
|
|
266
|
-
|
|
267
|
-
```jac
|
|
268
|
-
{
|
|
269
|
-
"fontSize": "16px",
|
|
270
|
-
"fontWeight": "600", # Bold (100-900)
|
|
271
|
-
"fontFamily": "sans-serif",
|
|
272
|
-
"textAlign": "center",
|
|
273
|
-
"lineHeight": "1.5"
|
|
274
|
-
}
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
**Borders & Corners:**
|
|
278
|
-
|
|
279
|
-
```jac
|
|
280
|
-
{
|
|
281
|
-
"borderRadius": "8px", # Rounded corners
|
|
282
|
-
"border": "1px solid #ccc",
|
|
283
|
-
"borderBottom": "2px solid blue"
|
|
284
|
-
}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
### String Values
|
|
288
|
-
|
|
289
|
-
All CSS values must be **strings** (in quotes):
|
|
290
|
-
|
|
291
|
-
```jac
|
|
292
|
-
# Correct
|
|
293
|
-
{
|
|
294
|
-
"padding": "20px",
|
|
295
|
-
"color": "#3b82f6",
|
|
296
|
-
"fontSize": "16px"
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
# Wrong (missing quotes)
|
|
300
|
-
{
|
|
301
|
-
"padding": 20px, # Error!
|
|
302
|
-
"color": #3b82f6, # Error!
|
|
303
|
-
"fontSize": 16px # Error!
|
|
304
|
-
}
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Conditional Styling
|
|
308
|
-
|
|
309
|
-
You can change styles based on conditions:
|
|
310
|
-
|
|
311
|
-
```jac
|
|
312
|
-
# Using ternary operator
|
|
313
|
-
<span style={{
|
|
314
|
-
"color": ("#999" if props.done else "#000"),
|
|
315
|
-
"textDecoration": ("line-through" if props.done else "none")
|
|
316
|
-
}}>
|
|
317
|
-
{props.text}
|
|
318
|
-
</span>
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
**This is like:**
|
|
322
|
-
|
|
323
|
-
```python
|
|
324
|
-
# Python
|
|
325
|
-
color = "#999" if done else "#000"
|
|
326
|
-
text_decoration = "line-through" if done else "none"
|
|
327
|
-
|
|
328
|
-
# Jac
|
|
329
|
-
"color": ("#999" if props.done else "#000")
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Flexbox Basics
|
|
333
|
-
|
|
334
|
-
Flexbox is a powerful layout system. Here are the basics:
|
|
335
|
-
|
|
336
|
-
```jac
|
|
337
|
-
# Parent container
|
|
338
|
-
<div style={{
|
|
339
|
-
"display": "flex", # Enable flexbox
|
|
340
|
-
"gap": "10px" # Space between children
|
|
341
|
-
}}>
|
|
342
|
-
<div>Item 1</div>
|
|
343
|
-
<div>Item 2</div>
|
|
344
|
-
<div>Item 3</div>
|
|
345
|
-
</div>
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
**Common flexbox properties:**
|
|
349
|
-
|
|
350
|
-
```jac
|
|
351
|
-
{
|
|
352
|
-
"display": "flex", # Enable flexbox
|
|
353
|
-
"flexDirection": "row", # Horizontal (default)
|
|
354
|
-
"flexDirection": "column", # Vertical
|
|
355
|
-
"justifyContent": "center", # Center horizontally
|
|
356
|
-
"alignItems": "center", # Center vertically
|
|
357
|
-
"gap": "16px" # Space between items
|
|
358
|
-
}
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
**Example: Centering content**
|
|
362
|
-
|
|
363
|
-
```jac
|
|
364
|
-
<div style={{
|
|
365
|
-
"display": "flex",
|
|
366
|
-
"justifyContent": "center", # Horizontal center
|
|
367
|
-
"alignItems": "center", # Vertical center
|
|
368
|
-
"height": "100vh" # Full screen height
|
|
369
|
-
}}>
|
|
370
|
-
<h1>Centered!</h1>
|
|
371
|
-
</div>
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
### Reusing Styles
|
|
375
|
-
|
|
376
|
-
You can store styles in variables to avoid repetition:
|
|
377
|
-
|
|
378
|
-
```jac
|
|
379
|
-
def app() -> any {
|
|
380
|
-
# Define common button style
|
|
381
|
-
let buttonStyle = {
|
|
382
|
-
"padding": "8px 16px",
|
|
383
|
-
"border": "none",
|
|
384
|
-
"borderRadius": "4px",
|
|
385
|
-
"cursor": "pointer",
|
|
386
|
-
"fontWeight": "600"
|
|
387
|
-
};
|
|
388
|
-
|
|
389
|
-
return <div>
|
|
390
|
-
<button style={buttonStyle}>Click me</button>
|
|
391
|
-
<button style={buttonStyle}>Or me</button>
|
|
392
|
-
</div>;
|
|
393
|
-
}
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
## What You've Learned
|
|
399
|
-
|
|
400
|
-
- How to write inline styles in Jac
|
|
401
|
-
- Double curly braces `{{ }}` syntax
|
|
402
|
-
- camelCase property names
|
|
403
|
-
- Common CSS properties
|
|
404
|
-
- Conditional styling with ternary operator
|
|
405
|
-
- Flexbox basics for layout
|
|
406
|
-
- Reusing styles with variables
|
|
407
|
-
|
|
408
|
-
---
|
|
409
|
-
|
|
410
|
-
## Common Issues
|
|
411
|
-
|
|
412
|
-
### Issue: Styles not applying
|
|
413
|
-
|
|
414
|
-
**Check:**
|
|
415
|
-
- Did you use double curly braces `{{ }}`?
|
|
416
|
-
- Are property names in quotes? `"padding"` not `padding`
|
|
417
|
-
- Are values in quotes? `"20px"` not `20px`
|
|
418
|
-
- Are you using camelCase? `"fontSize"` not `"font-size"`
|
|
419
|
-
|
|
420
|
-
### Issue: "Unexpected token"
|
|
421
|
-
|
|
422
|
-
**Cause**: Missing quotes around property names or values
|
|
423
|
-
|
|
424
|
-
```jac
|
|
425
|
-
# Wrong
|
|
426
|
-
{padding: 20px}
|
|
427
|
-
|
|
428
|
-
# Correct
|
|
429
|
-
{"padding": "20px"}
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
### Issue: CSS property not working
|
|
433
|
-
|
|
434
|
-
**Solution**: Convert kebab-case to camelCase
|
|
435
|
-
|
|
436
|
-
```jac
|
|
437
|
-
# Wrong
|
|
438
|
-
{"background-color": "#fff"}
|
|
439
|
-
|
|
440
|
-
# Correct
|
|
441
|
-
{"backgroundColor": "#fff"}
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
---
|
|
445
|
-
|
|
446
|
-
## Quick Exercise
|
|
447
|
-
|
|
448
|
-
Try adding a container with centered content:
|
|
449
|
-
|
|
450
|
-
```jac
|
|
451
|
-
def app() -> any {
|
|
452
|
-
return <div style={{
|
|
453
|
-
"maxWidth": "600px",
|
|
454
|
-
"margin": "0 auto",
|
|
455
|
-
"padding": "20px",
|
|
456
|
-
"backgroundColor": "#f9fafb",
|
|
457
|
-
"minHeight": "100vh"
|
|
458
|
-
}}>
|
|
459
|
-
<h1 style={{"textAlign": "center"}}>My Todos</h1>
|
|
460
|
-
<TodoInput />
|
|
461
|
-
<TodoFilters />
|
|
462
|
-
</div>;
|
|
463
|
-
}
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
This creates:
|
|
467
|
-
- Centered container (max width 600px)
|
|
468
|
-
- Light gray background
|
|
469
|
-
- Full height
|
|
470
|
-
- Centered title
|
|
471
|
-
|
|
472
|
-
---
|
|
473
|
-
|
|
474
|
-
## Next Step
|
|
475
|
-
|
|
476
|
-
Great! Your components now look professional. Next, let's build the **complete Todo UI** with all the components working together!
|
|
477
|
-
|
|
478
|
-
**[Continue to Step 4: Todo UI](./step-04-todo-ui.md)**
|