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.
Files changed (176) hide show
  1. jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
  2. jac_client/tests/conftest.py +281 -0
  3. jac_client/tests/test_cli.py +755 -0
  4. jac_client/tests/test_it.py +347 -67
  5. {jac_client-0.2.2.dist-info → jac_client-0.2.4.dist-info}/METADATA +30 -24
  6. jac_client-0.2.4.dist-info/RECORD +10 -0
  7. {jac_client-0.2.2.dist-info → jac_client-0.2.4.dist-info}/WHEEL +2 -1
  8. jac_client-0.2.4.dist-info/entry_points.txt +4 -0
  9. jac_client-0.2.4.dist-info/top_level.txt +1 -0
  10. jac_client/docs/README.md +0 -689
  11. jac_client/docs/advanced-state.md +0 -1265
  12. jac_client/docs/asset-serving/intro.md +0 -209
  13. jac_client/docs/assets/pipe_line-v2.svg +0 -32
  14. jac_client/docs/assets/pipe_line.png +0 -0
  15. jac_client/docs/file-system/app.jac.md +0 -121
  16. jac_client/docs/file-system/backend-frontend.md +0 -217
  17. jac_client/docs/file-system/intro.md +0 -72
  18. jac_client/docs/file-system/nested-imports.md +0 -348
  19. jac_client/docs/guide-example/intro.md +0 -115
  20. jac_client/docs/guide-example/step-01-setup.md +0 -270
  21. jac_client/docs/guide-example/step-02-components.md +0 -416
  22. jac_client/docs/guide-example/step-03-styling.md +0 -478
  23. jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
  24. jac_client/docs/guide-example/step-05-local-state.md +0 -530
  25. jac_client/docs/guide-example/step-06-events.md +0 -749
  26. jac_client/docs/guide-example/step-07-effects.md +0 -468
  27. jac_client/docs/guide-example/step-08-walkers.md +0 -534
  28. jac_client/docs/guide-example/step-09-authentication.md +0 -586
  29. jac_client/docs/guide-example/step-10-routing.md +0 -539
  30. jac_client/docs/guide-example/step-11-final.md +0 -963
  31. jac_client/docs/imports.md +0 -1141
  32. jac_client/docs/lifecycle-hooks.md +0 -773
  33. jac_client/docs/routing.md +0 -659
  34. jac_client/docs/styling/intro.md +0 -249
  35. jac_client/docs/styling/js-styling.md +0 -367
  36. jac_client/docs/styling/material-ui.md +0 -341
  37. jac_client/docs/styling/pure-css.md +0 -299
  38. jac_client/docs/styling/sass.md +0 -403
  39. jac_client/docs/styling/styled-components.md +0 -395
  40. jac_client/docs/styling/tailwind.md +0 -298
  41. jac_client/examples/all-in-one/.babelrc +0 -9
  42. jac_client/examples/all-in-one/README.md +0 -16
  43. jac_client/examples/all-in-one/app.jac +0 -426
  44. jac_client/examples/all-in-one/assets/burger.png +0 -0
  45. jac_client/examples/all-in-one/button.jac +0 -7
  46. jac_client/examples/all-in-one/components/button.jac +0 -7
  47. jac_client/examples/all-in-one/package.json +0 -29
  48. jac_client/examples/all-in-one/styles.css +0 -26
  49. jac_client/examples/all-in-one/vite.config.js +0 -28
  50. jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
  51. jac_client/examples/asset-serving/css-with-image/README.md +0 -91
  52. jac_client/examples/asset-serving/css-with-image/app.jac +0 -88
  53. jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
  54. jac_client/examples/asset-serving/css-with-image/package.json +0 -28
  55. jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
  56. jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
  57. jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
  58. jac_client/examples/asset-serving/image-asset/README.md +0 -119
  59. jac_client/examples/asset-serving/image-asset/app.jac +0 -55
  60. jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
  61. jac_client/examples/asset-serving/image-asset/package.json +0 -28
  62. jac_client/examples/asset-serving/image-asset/styles.css +0 -26
  63. jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
  64. jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
  65. jac_client/examples/asset-serving/import-alias/README.md +0 -83
  66. jac_client/examples/asset-serving/import-alias/app.jac +0 -111
  67. jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
  68. jac_client/examples/asset-serving/import-alias/package.json +0 -28
  69. jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
  70. jac_client/examples/basic/.babelrc +0 -9
  71. jac_client/examples/basic/README.md +0 -16
  72. jac_client/examples/basic/app.jac +0 -21
  73. jac_client/examples/basic/package.json +0 -27
  74. jac_client/examples/basic/vite.config.js +0 -27
  75. jac_client/examples/basic-auth/.babelrc +0 -9
  76. jac_client/examples/basic-auth/README.md +0 -16
  77. jac_client/examples/basic-auth/app.jac +0 -308
  78. jac_client/examples/basic-auth/package.json +0 -27
  79. jac_client/examples/basic-auth/vite.config.js +0 -27
  80. jac_client/examples/basic-auth-with-router/.babelrc +0 -9
  81. jac_client/examples/basic-auth-with-router/README.md +0 -60
  82. jac_client/examples/basic-auth-with-router/app.jac +0 -464
  83. jac_client/examples/basic-auth-with-router/package.json +0 -28
  84. jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
  85. jac_client/examples/basic-full-stack/.babelrc +0 -9
  86. jac_client/examples/basic-full-stack/README.md +0 -18
  87. jac_client/examples/basic-full-stack/app.jac +0 -320
  88. jac_client/examples/basic-full-stack/package.json +0 -28
  89. jac_client/examples/basic-full-stack/vite.config.js +0 -27
  90. jac_client/examples/css-styling/js-styling/.babelrc +0 -9
  91. jac_client/examples/css-styling/js-styling/README.md +0 -183
  92. jac_client/examples/css-styling/js-styling/app.jac +0 -84
  93. jac_client/examples/css-styling/js-styling/package.json +0 -28
  94. jac_client/examples/css-styling/js-styling/styles.js +0 -100
  95. jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
  96. jac_client/examples/css-styling/material-ui/.babelrc +0 -9
  97. jac_client/examples/css-styling/material-ui/README.md +0 -16
  98. jac_client/examples/css-styling/material-ui/app.jac +0 -122
  99. jac_client/examples/css-styling/material-ui/package.json +0 -32
  100. jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
  101. jac_client/examples/css-styling/pure-css/.babelrc +0 -9
  102. jac_client/examples/css-styling/pure-css/README.md +0 -16
  103. jac_client/examples/css-styling/pure-css/app.jac +0 -64
  104. jac_client/examples/css-styling/pure-css/package.json +0 -28
  105. jac_client/examples/css-styling/pure-css/styles.css +0 -111
  106. jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
  107. jac_client/examples/css-styling/sass-example/.babelrc +0 -9
  108. jac_client/examples/css-styling/sass-example/README.md +0 -16
  109. jac_client/examples/css-styling/sass-example/app.jac +0 -64
  110. jac_client/examples/css-styling/sass-example/package.json +0 -29
  111. jac_client/examples/css-styling/sass-example/styles.scss +0 -153
  112. jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
  113. jac_client/examples/css-styling/styled-components/.babelrc +0 -9
  114. jac_client/examples/css-styling/styled-components/README.md +0 -16
  115. jac_client/examples/css-styling/styled-components/app.jac +0 -71
  116. jac_client/examples/css-styling/styled-components/package.json +0 -29
  117. jac_client/examples/css-styling/styled-components/styled.js +0 -90
  118. jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
  119. jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
  120. jac_client/examples/css-styling/tailwind-example/README.md +0 -16
  121. jac_client/examples/css-styling/tailwind-example/app.jac +0 -63
  122. jac_client/examples/css-styling/tailwind-example/global.css +0 -1
  123. jac_client/examples/css-styling/tailwind-example/package.json +0 -30
  124. jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
  125. jac_client/examples/full-stack-with-auth/.babelrc +0 -9
  126. jac_client/examples/full-stack-with-auth/README.md +0 -16
  127. jac_client/examples/full-stack-with-auth/app.jac +0 -722
  128. jac_client/examples/full-stack-with-auth/package.json +0 -28
  129. jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
  130. jac_client/examples/little-x/app.jac +0 -724
  131. jac_client/examples/little-x/package.json +0 -23
  132. jac_client/examples/little-x/submit-button.jac +0 -8
  133. jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
  134. jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +0 -11
  135. jac_client/examples/nested-folders/nested-advance/README.md +0 -77
  136. jac_client/examples/nested-folders/nested-advance/app.jac +0 -35
  137. jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +0 -19
  138. jac_client/examples/nested-folders/nested-advance/level1/Card.jac +0 -43
  139. jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +0 -25
  140. jac_client/examples/nested-folders/nested-advance/package.json +0 -29
  141. jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
  142. jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
  143. jac_client/examples/nested-folders/nested-basic/README.md +0 -183
  144. jac_client/examples/nested-folders/nested-basic/app.jac +0 -13
  145. jac_client/examples/nested-folders/nested-basic/app.js +0 -7
  146. jac_client/examples/nested-folders/nested-basic/button.jac +0 -7
  147. jac_client/examples/nested-folders/nested-basic/components/button.jac +0 -7
  148. jac_client/examples/nested-folders/nested-basic/package.json +0 -28
  149. jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
  150. jac_client/examples/with-router/.babelrc +0 -9
  151. jac_client/examples/with-router/README.md +0 -17
  152. jac_client/examples/with-router/app.jac +0 -323
  153. jac_client/examples/with-router/package.json +0 -28
  154. jac_client/examples/with-router/vite.config.js +0 -27
  155. jac_client/plugin/cli.py +0 -244
  156. jac_client/plugin/client.py +0 -152
  157. jac_client/plugin/client_runtime.jac +0 -234
  158. jac_client/plugin/vite_client_bundle.py +0 -503
  159. jac_client/tests/fixtures/basic-app/app.jac +0 -23
  160. jac_client/tests/fixtures/cl_file/app.cl.jac +0 -48
  161. jac_client/tests/fixtures/cl_file/app.jac +0 -15
  162. jac_client/tests/fixtures/client_app_with_antd/app.jac +0 -34
  163. jac_client/tests/fixtures/js_import/app.jac +0 -34
  164. jac_client/tests/fixtures/js_import/utils.js +0 -21
  165. jac_client/tests/fixtures/package-lock.json +0 -329
  166. jac_client/tests/fixtures/package.json +0 -11
  167. jac_client/tests/fixtures/relative_import/app.jac +0 -11
  168. jac_client/tests/fixtures/relative_import/button.jac +0 -7
  169. jac_client/tests/fixtures/spawn_test/app.jac +0 -129
  170. jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -67
  171. jac_client/tests/test_asset_examples.py +0 -322
  172. jac_client/tests/test_cl.py +0 -530
  173. jac_client/tests/test_create_jac_app.py +0 -131
  174. jac_client/tests/test_nested_file.py +0 -374
  175. jac_client-0.2.2.dist-info/RECORD +0 -171
  176. 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)**