jac-client 0.2.3__py3-none-any.whl → 0.2.8__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 (224) hide show
  1. jac_client/examples/all-in-one/app.jac +494 -347
  2. jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
  3. jac_client/examples/all-in-one/button.jac +1 -1
  4. jac_client/examples/all-in-one/components/CategoryFilter.jac +35 -0
  5. jac_client/examples/all-in-one/components/Header.jac +13 -0
  6. jac_client/examples/all-in-one/components/ProfitOverview.jac +50 -0
  7. jac_client/examples/all-in-one/components/Summary.jac +53 -0
  8. jac_client/examples/all-in-one/components/TransactionForm.jac +158 -0
  9. jac_client/examples/all-in-one/components/TransactionItem.jac +55 -0
  10. jac_client/examples/all-in-one/components/TransactionList.jac +37 -0
  11. jac_client/examples/all-in-one/components/button.jac +1 -1
  12. jac_client/examples/all-in-one/components/navigation.jac +132 -0
  13. jac_client/examples/all-in-one/constants/categories.jac +37 -0
  14. jac_client/examples/all-in-one/constants/clients.jac +13 -0
  15. jac_client/examples/all-in-one/context/BudgetContext.jac +28 -0
  16. jac_client/examples/all-in-one/hooks/useBudget.jac +116 -0
  17. jac_client/examples/all-in-one/hooks/useLocalStorage.jac +36 -0
  18. jac_client/examples/all-in-one/pages/BudgetPlanner.cl.jac +70 -0
  19. jac_client/examples/all-in-one/pages/BudgetPlanner.jac +126 -0
  20. jac_client/examples/all-in-one/pages/FeaturesTest.cl.jac +552 -0
  21. jac_client/examples/all-in-one/pages/FeaturesTest.jac +126 -0
  22. jac_client/examples/all-in-one/pages/LandingPage.jac +101 -0
  23. jac_client/examples/all-in-one/pages/loginPage.jac +132 -0
  24. jac_client/examples/all-in-one/pages/nestedDemo.jac +61 -0
  25. jac_client/examples/all-in-one/pages/notFound.jac +24 -0
  26. jac_client/examples/all-in-one/pages/signupPage.jac +133 -0
  27. jac_client/examples/all-in-one/utils/formatters.jac +52 -0
  28. jac_client/examples/asset-serving/css-with-image/{app.jac → src/app.jac} +4 -4
  29. jac_client/examples/asset-serving/image-asset/{app.jac → src/app.jac} +4 -4
  30. jac_client/examples/asset-serving/import-alias/{app.jac → src/app.jac} +5 -5
  31. jac_client/examples/basic/{app.jac → src/app.jac} +4 -4
  32. jac_client/examples/basic-auth/src/app.jac +371 -0
  33. jac_client/examples/basic-auth-with-router/{app.jac → src/app.jac} +28 -28
  34. jac_client/examples/basic-full-stack/{app.jac → src/app.jac} +166 -127
  35. jac_client/examples/css-styling/js-styling/{app.jac → src/app.jac} +7 -7
  36. jac_client/examples/css-styling/material-ui/{app.jac → src/app.jac} +6 -6
  37. jac_client/examples/css-styling/pure-css/{app.jac → src/app.jac} +7 -7
  38. jac_client/examples/css-styling/sass-example/{app.jac → src/app.jac} +7 -7
  39. jac_client/examples/css-styling/styled-components/{app.jac → src/app.jac} +6 -6
  40. jac_client/examples/css-styling/tailwind-example/{app.jac → src/app.jac} +7 -7
  41. jac_client/examples/full-stack-with-auth/{app.jac → src/app.jac} +47 -47
  42. jac_client/examples/little-x/{app.jac → src/app.jac} +27 -32
  43. jac_client/examples/little-x/src/submit-button.jac +16 -0
  44. jac_client/examples/nested-folders/nested-advance/{ButtonRoot.jac → src/ButtonRoot.jac} +1 -1
  45. jac_client/examples/nested-folders/nested-advance/{app.jac → src/app.jac} +1 -1
  46. jac_client/examples/nested-folders/nested-advance/{level1 → src/level1}/ButtonSecondL.jac +1 -1
  47. jac_client/examples/nested-folders/nested-advance/{level1 → src/level1}/Card.jac +1 -1
  48. jac_client/examples/nested-folders/nested-advance/{level1 → src/level1}/level2/ButtonThirdL.jac +1 -1
  49. jac_client/examples/nested-folders/nested-basic/{app.jac → src/app.jac} +2 -2
  50. jac_client/examples/nested-folders/nested-basic/{button.jac → src/button.jac} +1 -1
  51. jac_client/examples/nested-folders/nested-basic/{components → src/components}/button.jac +1 -1
  52. jac_client/examples/ts-support/src/app.jac +35 -0
  53. jac_client/examples/with-router/{app.jac → src/app.jac} +15 -15
  54. jac_client/plugin/cli.jac +504 -0
  55. jac_client/plugin/client.jac +45 -0
  56. jac_client/plugin/client_runtime.cl.jac +42 -0
  57. jac_client/plugin/impl/client.impl.jac +193 -0
  58. jac_client/plugin/impl/client_runtime.impl.jac +195 -0
  59. jac_client/plugin/impl/vite_client_bundle.impl.jac +72 -0
  60. jac_client/plugin/plugin_config.jac +195 -0
  61. jac_client/plugin/src/__init__.jac +20 -0
  62. jac_client/plugin/src/asset_processor.jac +33 -0
  63. jac_client/plugin/src/babel_processor.jac +18 -0
  64. jac_client/plugin/src/compiler.jac +67 -0
  65. jac_client/plugin/src/config_loader.jac +32 -0
  66. jac_client/plugin/src/impl/asset_processor.impl.jac +127 -0
  67. jac_client/plugin/src/impl/babel_processor.impl.jac +89 -0
  68. jac_client/plugin/src/impl/compiler.impl.jac +288 -0
  69. jac_client/plugin/src/impl/config_loader.impl.jac +119 -0
  70. jac_client/plugin/src/impl/import_processor.impl.jac +33 -0
  71. jac_client/plugin/src/impl/jac_to_js.impl.jac +41 -0
  72. jac_client/plugin/src/impl/package_installer.impl.jac +105 -0
  73. jac_client/plugin/src/impl/vite_bundler.impl.jac +626 -0
  74. jac_client/plugin/src/import_processor.jac +19 -0
  75. jac_client/plugin/src/jac_to_js.jac +35 -0
  76. jac_client/plugin/src/package_installer.jac +26 -0
  77. jac_client/plugin/src/vite_bundler.jac +44 -0
  78. jac_client/plugin/vite_client_bundle.jac +31 -0
  79. jac_client/tests/conftest.py +283 -0
  80. jac_client/tests/fixtures/basic-app/app.jac +2 -2
  81. jac_client/tests/fixtures/cl_file/app.cl.jac +2 -2
  82. jac_client/tests/fixtures/client_app_with_antd/app.jac +1 -1
  83. jac_client/tests/fixtures/js_import/app.jac +5 -5
  84. jac_client/tests/fixtures/spawn_test/app.jac +15 -18
  85. jac_client/tests/fixtures/with-ts/app.jac +35 -0
  86. jac_client/tests/test_cli.py +811 -0
  87. jac_client/tests/test_it.py +592 -97
  88. {jac_client-0.2.3.dist-info → jac_client-0.2.8.dist-info}/METADATA +41 -34
  89. jac_client-0.2.8.dist-info/RECORD +97 -0
  90. {jac_client-0.2.3.dist-info → jac_client-0.2.8.dist-info}/WHEEL +2 -1
  91. jac_client-0.2.8.dist-info/entry_points.txt +4 -0
  92. jac_client-0.2.8.dist-info/top_level.txt +1 -0
  93. jac_client/docs/README.md +0 -689
  94. jac_client/docs/advanced-state.md +0 -1265
  95. jac_client/docs/asset-serving/intro.md +0 -209
  96. jac_client/docs/assets/pipe_line-v2.svg +0 -32
  97. jac_client/docs/assets/pipe_line.png +0 -0
  98. jac_client/docs/file-system/app.jac.md +0 -121
  99. jac_client/docs/file-system/backend-frontend.md +0 -217
  100. jac_client/docs/file-system/intro.md +0 -72
  101. jac_client/docs/file-system/nested-imports.md +0 -348
  102. jac_client/docs/guide-example/intro.md +0 -115
  103. jac_client/docs/guide-example/step-01-setup.md +0 -270
  104. jac_client/docs/guide-example/step-02-components.md +0 -416
  105. jac_client/docs/guide-example/step-03-styling.md +0 -478
  106. jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
  107. jac_client/docs/guide-example/step-05-local-state.md +0 -530
  108. jac_client/docs/guide-example/step-06-events.md +0 -749
  109. jac_client/docs/guide-example/step-07-effects.md +0 -468
  110. jac_client/docs/guide-example/step-08-walkers.md +0 -534
  111. jac_client/docs/guide-example/step-09-authentication.md +0 -586
  112. jac_client/docs/guide-example/step-10-routing.md +0 -539
  113. jac_client/docs/guide-example/step-11-final.md +0 -963
  114. jac_client/docs/imports.md +0 -1141
  115. jac_client/docs/lifecycle-hooks.md +0 -773
  116. jac_client/docs/routing.md +0 -659
  117. jac_client/docs/styling/intro.md +0 -249
  118. jac_client/docs/styling/js-styling.md +0 -367
  119. jac_client/docs/styling/material-ui.md +0 -341
  120. jac_client/docs/styling/pure-css.md +0 -299
  121. jac_client/docs/styling/sass.md +0 -403
  122. jac_client/docs/styling/styled-components.md +0 -395
  123. jac_client/docs/styling/tailwind.md +0 -298
  124. jac_client/examples/all-in-one/.babelrc +0 -9
  125. jac_client/examples/all-in-one/README.md +0 -16
  126. jac_client/examples/all-in-one/assets/burger.png +0 -0
  127. jac_client/examples/all-in-one/package.json +0 -29
  128. jac_client/examples/all-in-one/styles.css +0 -26
  129. jac_client/examples/all-in-one/vite.config.js +0 -28
  130. jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
  131. jac_client/examples/asset-serving/css-with-image/README.md +0 -91
  132. jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
  133. jac_client/examples/asset-serving/css-with-image/package.json +0 -28
  134. jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
  135. jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
  136. jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
  137. jac_client/examples/asset-serving/image-asset/README.md +0 -119
  138. jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
  139. jac_client/examples/asset-serving/image-asset/package.json +0 -28
  140. jac_client/examples/asset-serving/image-asset/styles.css +0 -26
  141. jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
  142. jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
  143. jac_client/examples/asset-serving/import-alias/README.md +0 -83
  144. jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
  145. jac_client/examples/asset-serving/import-alias/package.json +0 -28
  146. jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
  147. jac_client/examples/basic/.babelrc +0 -9
  148. jac_client/examples/basic/README.md +0 -16
  149. jac_client/examples/basic/package.json +0 -27
  150. jac_client/examples/basic/vite.config.js +0 -27
  151. jac_client/examples/basic-auth/.babelrc +0 -9
  152. jac_client/examples/basic-auth/README.md +0 -16
  153. jac_client/examples/basic-auth/app.jac +0 -308
  154. jac_client/examples/basic-auth/package.json +0 -27
  155. jac_client/examples/basic-auth/vite.config.js +0 -27
  156. jac_client/examples/basic-auth-with-router/.babelrc +0 -9
  157. jac_client/examples/basic-auth-with-router/README.md +0 -60
  158. jac_client/examples/basic-auth-with-router/package.json +0 -28
  159. jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
  160. jac_client/examples/basic-full-stack/.babelrc +0 -9
  161. jac_client/examples/basic-full-stack/README.md +0 -18
  162. jac_client/examples/basic-full-stack/package.json +0 -28
  163. jac_client/examples/basic-full-stack/vite.config.js +0 -27
  164. jac_client/examples/css-styling/js-styling/.babelrc +0 -9
  165. jac_client/examples/css-styling/js-styling/README.md +0 -183
  166. jac_client/examples/css-styling/js-styling/package.json +0 -28
  167. jac_client/examples/css-styling/js-styling/styles.js +0 -100
  168. jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
  169. jac_client/examples/css-styling/material-ui/.babelrc +0 -9
  170. jac_client/examples/css-styling/material-ui/README.md +0 -16
  171. jac_client/examples/css-styling/material-ui/package.json +0 -32
  172. jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
  173. jac_client/examples/css-styling/pure-css/.babelrc +0 -9
  174. jac_client/examples/css-styling/pure-css/README.md +0 -16
  175. jac_client/examples/css-styling/pure-css/package.json +0 -28
  176. jac_client/examples/css-styling/pure-css/styles.css +0 -111
  177. jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
  178. jac_client/examples/css-styling/sass-example/.babelrc +0 -9
  179. jac_client/examples/css-styling/sass-example/README.md +0 -16
  180. jac_client/examples/css-styling/sass-example/package.json +0 -29
  181. jac_client/examples/css-styling/sass-example/styles.scss +0 -153
  182. jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
  183. jac_client/examples/css-styling/styled-components/.babelrc +0 -9
  184. jac_client/examples/css-styling/styled-components/README.md +0 -16
  185. jac_client/examples/css-styling/styled-components/package.json +0 -29
  186. jac_client/examples/css-styling/styled-components/styled.js +0 -90
  187. jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
  188. jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
  189. jac_client/examples/css-styling/tailwind-example/README.md +0 -16
  190. jac_client/examples/css-styling/tailwind-example/global.css +0 -1
  191. jac_client/examples/css-styling/tailwind-example/package.json +0 -30
  192. jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
  193. jac_client/examples/full-stack-with-auth/.babelrc +0 -9
  194. jac_client/examples/full-stack-with-auth/README.md +0 -16
  195. jac_client/examples/full-stack-with-auth/package.json +0 -28
  196. jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
  197. jac_client/examples/little-x/package.json +0 -23
  198. jac_client/examples/little-x/submit-button.jac +0 -8
  199. jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
  200. jac_client/examples/nested-folders/nested-advance/README.md +0 -77
  201. jac_client/examples/nested-folders/nested-advance/package.json +0 -29
  202. jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
  203. jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
  204. jac_client/examples/nested-folders/nested-basic/README.md +0 -183
  205. jac_client/examples/nested-folders/nested-basic/app.js +0 -7
  206. jac_client/examples/nested-folders/nested-basic/package.json +0 -28
  207. jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
  208. jac_client/examples/with-router/.babelrc +0 -9
  209. jac_client/examples/with-router/README.md +0 -17
  210. jac_client/examples/with-router/package.json +0 -28
  211. jac_client/examples/with-router/vite.config.js +0 -27
  212. jac_client/plugin/cli.py +0 -244
  213. jac_client/plugin/client.py +0 -152
  214. jac_client/plugin/client_runtime.jac +0 -234
  215. jac_client/plugin/vite_client_bundle.py +0 -503
  216. jac_client/tests/fixtures/js_import/utils.js +0 -21
  217. jac_client/tests/fixtures/package-lock.json +0 -329
  218. jac_client/tests/fixtures/package.json +0 -11
  219. jac_client/tests/test_asset_examples.py +0 -322
  220. jac_client/tests/test_cl.py +0 -530
  221. jac_client/tests/test_create_jac_app.py +0 -131
  222. jac_client/tests/test_nested_file.py +0 -374
  223. jac_client-0.2.3.dist-info/RECORD +0 -171
  224. jac_client-0.2.3.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)**