jac-client 0.2.3__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.3.dist-info → jac_client-0.2.4.dist-info}/METADATA +28 -30
  6. jac_client-0.2.4.dist-info/RECORD +10 -0
  7. {jac_client-0.2.3.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.3.dist-info/RECORD +0 -171
  176. jac_client-0.2.3.dist-info/entry_points.txt +0 -4
@@ -1,320 +0,0 @@
1
- # Todo App
2
- cl import from react {useState, useEffect}
3
-
4
- node Todo {
5
- has text: str;
6
- has done: bool = False;
7
- }
8
-
9
- walker create_todo {
10
- has text:str;
11
- can create with `root entry {
12
- new_todo = here ++> Todo(text= self.text);
13
- report new_todo;
14
- }
15
- }
16
- walker toggle_todo {
17
- can toggle with Todo entry {
18
- here.done = not here.done;
19
- report here;
20
- }
21
- }
22
- walker read_todos {
23
- can read with `root entry {
24
- visit [-->(`?Todo)];
25
- }
26
- can report_todos with exit {
27
- report here;
28
- }
29
- }
30
-
31
- cl {
32
- def app() -> any {
33
- let [todos, setTodos] = useState([]);
34
- let [inputValue, setInputValue] = useState("");
35
- let [filter, setFilter] = useState("all");
36
-
37
- useEffect(lambda -> None {
38
- async def loadTodos() -> None {
39
- todos = root spawn read_todos();
40
- setTodos(todos.reports);
41
- }
42
- loadTodos();
43
- }, []);
44
-
45
- # Add a new todo
46
- async def addTodo() -> None {
47
- if not inputValue.trim() { return; }
48
- newTodo = {
49
- "id": Date.now(),
50
- "text": inputValue.trim(),
51
- "done": False
52
- };
53
- response = root spawn create_todo(text=inputValue.trim());
54
- newTodos = todos.concat([response.reports[0][0]]);
55
- setTodos(newTodos);
56
- setInputValue("");
57
- }
58
-
59
- # Toggle todo completion status
60
- async def toggleTodo(id: any) -> None {
61
- console.log("toggleTodo", id);
62
- id spawn toggle_todo();
63
- setTodos(todos.map(lambda todo: any -> any {
64
- if todo._jac_id == id {
65
- updatedTodo = {
66
- "_jac_id": todo._jac_id,
67
- "text": todo.text,
68
- "done": not todo.done,
69
- "id": todo.id
70
- };
71
- return updatedTodo;
72
- }
73
- return todo;
74
- }));
75
- }
76
-
77
- # Delete a todo
78
- def deleteTodo(id: any) -> None {
79
- setTodos(todos.filter(lambda todo: any -> bool { return todo.id != id; }));
80
- }
81
-
82
- # Clear all completed todos
83
- def clearCompleted() -> None {
84
- setTodos(todos.filter(lambda todo: any -> bool { return not todo.done; }));
85
- }
86
-
87
- # Filter todos based on current filter
88
- def getFilteredTodos() -> list {
89
- if filter == "active" {
90
- return todos.filter(lambda todo: any -> bool { return not todo.done; });
91
- } elif filter == "completed" {
92
- return todos.filter(lambda todo: any -> bool { return todo.done; });
93
- }
94
- return todos;
95
- }
96
-
97
- # Count active todos
98
- activeCount = todos.filter(lambda todo: any -> bool { return not todo.done; }).length;
99
-
100
- filteredTodos = getFilteredTodos();
101
-
102
-
103
- return <div style={{
104
- "maxWidth": "600px",
105
- "margin": "40px auto",
106
- "padding": "24px",
107
- "fontFamily": "system-ui, -apple-system, sans-serif",
108
- "background": "#f9fafb",
109
- "minHeight": "100vh"
110
- }}>
111
- <h1 style={{
112
- "textAlign": "center",
113
- "color": "#1f2937",
114
- "marginBottom": "32px",
115
- "fontSize": "2.5rem",
116
- "fontWeight": "700"
117
- }}>📝 My Todo App</h1>
118
-
119
- # Add todo form
120
- <div style={{
121
- "display": "flex",
122
- "gap": "8px",
123
- "marginBottom": "24px",
124
- "background": "#ffffff",
125
- "padding": "16px",
126
- "borderRadius": "12px",
127
- "boxShadow": "0 1px 3px rgba(0,0,0,0.1)"
128
- }}>
129
- <input
130
- type="text"
131
- value={inputValue}
132
- onChange={lambda e: any -> None { setInputValue(e.target.value); }}
133
- onKeyPress={lambda e: any -> None {
134
- if e.key == "Enter" { addTodo(); }
135
- }}
136
- placeholder="What needs to be done?"
137
- style={{
138
- "flex": "1",
139
- "padding": "12px 16px",
140
- "border": "1px solid #e5e7eb",
141
- "borderRadius": "8px",
142
- "fontSize": "16px",
143
- "outline": "none"
144
- }}
145
- />
146
- <button
147
- onClick={addTodo}
148
- style={{
149
- "padding": "12px 24px",
150
- "background": "#3b82f6",
151
- "color": "#ffffff",
152
- "border": "none",
153
- "borderRadius": "8px",
154
- "fontSize": "16px",
155
- "fontWeight": "600",
156
- "cursor": "pointer",
157
- "transition": "background 0.2s"
158
- }}
159
- >
160
- Add
161
- </button>
162
- </div>
163
-
164
- # Filter buttons
165
- <div style={{
166
- "display": "flex",
167
- "gap": "8px",
168
- "marginBottom": "24px",
169
- "justifyContent": "center"
170
- }}>
171
- <button
172
- onClick={lambda -> None { setFilter("all"); }}
173
- style={{
174
- "padding": "8px 16px",
175
- "background": ("#3b82f6" if filter == "all" else "#ffffff"),
176
- "color": ("#ffffff" if filter == "all" else "#3b82f6"),
177
- "border": "1px solid #3b82f6",
178
- "borderRadius": "6px",
179
- "fontSize": "14px",
180
- "fontWeight": "600",
181
- "cursor": "pointer"
182
- }}
183
- >
184
- All
185
- </button>
186
- <button
187
- onClick={lambda -> None { setFilter("active"); }}
188
- style={{
189
- "padding": "8px 16px",
190
- "background": ("#3b82f6" if filter == "active" else "#ffffff"),
191
- "color": ("#ffffff" if filter == "active" else "#3b82f6"),
192
- "border": "1px solid #3b82f6",
193
- "borderRadius": "6px",
194
- "fontSize": "14px",
195
- "fontWeight": "600",
196
- "cursor": "pointer"
197
- }}
198
- >
199
- Active
200
- </button>
201
- <button
202
- onClick={lambda -> None { setFilter("completed"); }}
203
- style={{
204
- "padding": "8px 16px",
205
- "background": ("#3b82f6" if filter == "completed" else "#ffffff"),
206
- "color": ("#ffffff" if filter == "completed" else "#3b82f6"),
207
- "border": "1px solid #3b82f6",
208
- "borderRadius": "6px",
209
- "fontSize": "14px",
210
- "fontWeight": "600",
211
- "cursor": "pointer"
212
- }}
213
- >
214
- Completed
215
- </button>
216
- </div>
217
-
218
- # Todo list
219
- <div style={{
220
- "background": "#ffffff",
221
- "borderRadius": "12px",
222
- "boxShadow": "0 1px 3px rgba(0,0,0,0.1)",
223
- "overflow": "hidden"
224
- }}>
225
- {(<div style={{
226
- "padding": "40px",
227
- "textAlign": "center",
228
- "color": "#9ca3af"
229
- }}>
230
- {("No todos yet. Add one above!" if filter == "all" else
231
- ("No active todos!" if filter == "active" else
232
- "No completed todos!"))}
233
- </div>) if filteredTodos.length == 0 else (
234
- filteredTodos.map(lambda todo: any -> any {
235
- return <div
236
- key={todo._jac_id}
237
- style={{
238
- "display": "flex",
239
- "alignItems": "center",
240
- "gap": "12px",
241
- "padding": "16px",
242
- "borderBottom": "1px solid #e5e7eb",
243
- "transition": "background 0.2s"
244
- }}
245
- >
246
- <input
247
- type="checkbox"
248
- checked={todo.done}
249
- onChange={lambda -> None { toggleTodo(todo._jac_id); }}
250
- style={{
251
- "width": "20px",
252
- "height": "20px",
253
- "cursor": "pointer"
254
- }}
255
- />
256
- <span style={{
257
- "flex": "1",
258
- "textDecoration": ("line-through" if todo.done else "none"),
259
- "color": ("#9ca3af" if todo.done else "#1f2937"),
260
- "fontSize": "16px"
261
- }}>
262
- {todo.text}
263
- </span>
264
- <button
265
- onClick={lambda -> None { deleteTodo(todo.__jac_id); }}
266
- style={{
267
- "padding": "6px 12px",
268
- "background": "#ef4444",
269
- "color": "#ffffff",
270
- "border": "none",
271
- "borderRadius": "6px",
272
- "fontSize": "14px",
273
- "fontWeight": "500",
274
- "cursor": "pointer",
275
- "transition": "background 0.2s"
276
- }}
277
- >
278
- Delete
279
- </button>
280
- </div>;
281
- })
282
- )}
283
- </div>
284
-
285
- # Stats and clear completed button
286
- {(<div style={{
287
- "display": "flex",
288
- "justifyContent": "space-between",
289
- "alignItems": "center",
290
- "marginTop": "24px",
291
- "padding": "16px",
292
- "background": "#ffffff",
293
- "borderRadius": "12px",
294
- "boxShadow": "0 1px 3px rgba(0,0,0,0.1)"
295
- }}>
296
- <span style={{
297
- "color": "#6b7280",
298
- "fontSize": "14px"
299
- }}>
300
- {activeCount} {"item" if activeCount == 1 else "items"} left
301
- </span>
302
- {(<button
303
- onClick={clearCompleted}
304
- style={{
305
- "padding": "8px 16px",
306
- "background": "#ef4444",
307
- "color": "#ffffff",
308
- "border": "none",
309
- "borderRadius": "6px",
310
- "fontSize": "14px",
311
- "fontWeight": "600",
312
- "cursor": "pointer"
313
- }}
314
- >
315
- Clear Completed
316
- </button>) if todos.some(lambda todo: any -> bool { return todo.done; }) else None}
317
- </div>) if todos.length > 0 else None}
318
- </div>;
319
- }
320
- }
@@ -1,28 +0,0 @@
1
- {
2
- "name": "basic-full-stack",
3
- "version": "1.0.0",
4
- "main": "index.js",
5
- "scripts": {
6
- "build": "npm run compile && vite build",
7
- "dev": "vite dev",
8
- "preview": "vite preview",
9
- "compile": "babel src --out-dir build --extensions \".jsx,.js\" --out-file-extension .js"
10
- },
11
- "keywords": [],
12
- "author": "",
13
- "license": "ISC",
14
- "description": "Jac application: basic-full-stack",
15
- "type": "module",
16
- "devDependencies": {
17
- "vite": "^6.4.1",
18
- "@babel/cli": "^7.28.3",
19
- "@babel/core": "^7.28.5",
20
- "@babel/preset-env": "^7.28.5",
21
- "@babel/preset-react": "^7.28.5"
22
- },
23
- "dependencies": {
24
- "react": "^19.2.0",
25
- "react-dom": "^19.2.0",
26
- "react-router-dom": "^7.3.0"
27
- }
28
- }
@@ -1,27 +0,0 @@
1
-
2
- import { defineConfig } from "vite";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
-
8
- export default defineConfig({
9
- root: ".", // base folder
10
- build: {
11
- rollupOptions: {
12
- input: "build/main.js", // your compiled entry file
13
- output: {
14
- entryFileNames: "client.[hash].js", // name of the final js file
15
- assetFileNames: "[name].[ext]",
16
- },
17
- },
18
- outDir: "dist", // final bundled output
19
- emptyOutDir: true,
20
- },
21
- publicDir: false,
22
- resolve: {
23
- alias: {
24
- "@jac-client/utils": path.resolve(__dirname, "src/client_runtime.js"),
25
- },
26
- },
27
- });
@@ -1,9 +0,0 @@
1
-
2
- {
3
- "presets": [[
4
- "@babel/preset-env",
5
- {
6
- "modules": false
7
- }
8
- ], "@babel/preset-react"]
9
- }
@@ -1,183 +0,0 @@
1
- # JavaScript Styling Example
2
-
3
- This example demonstrates styling a Jac application using JavaScript objects for inline styles.
4
-
5
- ## Overview
6
-
7
- JavaScript styling uses JavaScript objects to define styles, which are then applied via the `style` prop. This approach is perfect for:
8
- - Dynamic styling based on state
9
- - Programmatic style generation
10
- - Component-scoped styles without CSS files
11
- - React-style inline styling
12
-
13
- ## Project Structure
14
-
15
- ```
16
- js-styling/
17
- ├── app.jac # Main application component
18
- ├── styles.js # Style objects exported as default
19
- ├── package.json # Dependencies
20
- └── vite.config.js # Vite configuration
21
- ```
22
-
23
- ## Setup
24
-
25
- 1. Install dependencies:
26
- ```bash
27
- npm install
28
- ```
29
-
30
- 2. Run the application:
31
- ```bash
32
- jac serve app.jac
33
- ```
34
-
35
- ## How It Works
36
-
37
- ### 1. Define Style Objects
38
-
39
- In `styles.js`, export a default object with all styles:
40
-
41
- ```javascript
42
- const countDisplay = {
43
- fontSize: "3.75rem",
44
- fontWeight: "bold",
45
- transition: "color 0.3s ease"
46
- };
47
-
48
- export default {
49
- container: {
50
- minHeight: "100vh",
51
- background: "linear-gradient(to bottom right, #dbeafe, #e0e7ff)",
52
- display: "flex",
53
- alignItems: "center",
54
- justifyContent: "center",
55
- padding: "1rem"
56
- },
57
- card: {
58
- backgroundColor: "#ffffff",
59
- borderRadius: "1rem",
60
- boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
61
- padding: "2rem",
62
- maxWidth: "28rem",
63
- width: "100%"
64
- },
65
- countDisplayZero: {
66
- ...countDisplay,
67
- color: "#1f2937"
68
- },
69
- countDisplayPositive: {
70
- ...countDisplay,
71
- color: "#16a34a"
72
- },
73
- // ... more styles
74
- };
75
- ```
76
-
77
- ### 2. Import Styles
78
-
79
- In your Jac file:
80
-
81
- ```jac
82
- cl import from .styles { default as styles }
83
- ```
84
-
85
- ### 3. Apply Styles
86
-
87
- Use the `style` prop with style objects:
88
-
89
- ```jac
90
- return <div style={styles.container}>
91
- <div style={styles.card}>
92
- <h1 style={styles.title}>Counter Application</h1>
93
- </div>
94
- </div>;
95
- ```
96
-
97
- ### 4. Dynamic Styles
98
-
99
- Select styles based on state:
100
-
101
- ```jac
102
- let countStyle = styles.countDisplayZero if count == 0 else (styles.countDisplayPositive if count > 0 else styles.countDisplayNegative);
103
-
104
- return <div style={countStyle}>{count}</div>;
105
- ```
106
-
107
- ## Style Object Format
108
-
109
- JavaScript style objects use camelCase property names (React convention):
110
-
111
- ```javascript
112
- {
113
- backgroundColor: "#ffffff", // not background-color
114
- fontSize: "1.5rem", // not font-size
115
- marginTop: "10px", // not margin-top
116
- zIndex: 1 // not z-index
117
- }
118
- ```
119
-
120
- ## Best Practices
121
-
122
- 1. **Use object spread**: Share common styles with spread operator
123
- 2. **Organize by component**: Group related styles together
124
- 3. **Use constants**: Define reusable values at the top
125
- 4. **CamelCase properties**: Follow React naming convention
126
- 5. **Extract complex logic**: Move style calculations to functions
127
-
128
- ## Advantages
129
-
130
- - ✅ Dynamic styling based on props/state
131
- - ✅ No CSS file needed
132
- - ✅ Type-safe (with TypeScript)
133
- - ✅ Component-scoped by default
134
- - ✅ Programmatic style generation
135
-
136
- ## Limitations
137
-
138
- - ❌ No pseudo-classes (hover, focus, etc.)
139
- - ❌ No media queries
140
- - ❌ No CSS animations (use JavaScript)
141
- - ❌ Verbose for complex styles
142
- - ❌ No CSS preprocessor features
143
-
144
- ## When to Use
145
-
146
- Choose JavaScript Styling when:
147
- - You need dynamic styles based on state
148
- - You want programmatic style generation
149
- - You prefer keeping styles in JavaScript
150
- - You're building component libraries
151
- - You need runtime style calculations
152
-
153
- ## Advanced Patterns
154
-
155
- ### Style Functions
156
-
157
- Create functions that return styles:
158
-
159
- ```javascript
160
- export const getButtonStyle = (variant) => ({
161
- ...buttonBase,
162
- backgroundColor: variant === 'primary' ? '#007bff' : '#6c757d'
163
- });
164
- ```
165
-
166
- ### Conditional Styles
167
-
168
- Use ternary operators for conditional styles:
169
-
170
- ```javascript
171
- export default {
172
- button: {
173
- backgroundColor: isActive ? '#007bff' : '#6c757d',
174
- opacity: isDisabled ? 0.5 : 1,
175
- }
176
- };
177
- ```
178
-
179
- ## Next Steps
180
-
181
- - Explore [Styled Components](../styled-components/) for CSS-in-JS with more features
182
- - Check out [Emotion](../emotion-example/) for similar CSS-in-JS approach (coming soon)
183
- - Learn about [CSS Modules](../css-modules/) for scoped CSS (coming soon)
@@ -1,84 +0,0 @@
1
- # Pages
2
- cl import from react { useState, useEffect }
3
- cl import from .styles { default as styles }
4
-
5
- cl {
6
- def app() -> any {
7
- let [count, setCount] = useState(0);
8
-
9
- useEffect(lambda -> None{ console.log("Count changed: ", count);} , [count]);
10
-
11
- let handleIncrement = lambda e: any -> None{ setCount(count + 1);} ;
12
-
13
- let handleDecrement = lambda e: any -> None{ setCount(count - 1);} ;
14
-
15
- let handleReset = lambda e: any -> None{ setCount(0);} ;
16
-
17
- let countStyle = styles.countDisplayZero
18
- if count == 0
19
- else (
20
- styles.countDisplayPositive if count > 0 else styles.countDisplayNegative
21
- );
22
-
23
- return <div
24
- style={styles.container}
25
- >
26
- <div
27
- style={styles.card}
28
- >
29
- <h1
30
- style={styles.title}
31
- >
32
- Counter Application
33
- </h1>
34
- <div
35
- style={styles.divider}
36
- ></div>
37
- <div
38
- style={styles.counterSection}
39
- >
40
- <div
41
- style={styles.label}
42
- >
43
- Current Count
44
- </div>
45
- <div
46
- style={countStyle}
47
- >
48
- {count}
49
- </div>
50
- </div>
51
- <div
52
- style={styles.divider}
53
- ></div>
54
- <div
55
- style={styles.buttonGroup}
56
- >
57
- <button
58
- style={styles.buttonDecrement}
59
- onClick={handleDecrement}
60
- >
61
- -
62
- </button>
63
- <button
64
- style={styles.buttonReset}
65
- onClick={handleReset}
66
- >
67
-
68
- </button>
69
- <button
70
- style={styles.buttonIncrement}
71
- onClick={handleIncrement}
72
- >
73
- +
74
- </button>
75
- </div>
76
- <div
77
- style={styles.hint}
78
- >
79
- Click the buttons to increment, decrement, or reset the counter
80
- </div>
81
- </div>
82
- </div>;
83
- }
84
- }
@@ -1,28 +0,0 @@
1
- {
2
- "name": "bootstrap-example",
3
- "version": "1.0.0",
4
- "main": "index.js",
5
- "scripts": {
6
- "build": "npm run compile && vite build",
7
- "dev": "vite dev",
8
- "preview": "vite preview",
9
- "compile": "babel src --out-dir build --extensions \".jsx,.js\" --out-file-extension .js"
10
- },
11
- "keywords": [],
12
- "author": "",
13
- "license": "ISC",
14
- "description": "Jac application: bootstrap-example",
15
- "type": "module",
16
- "devDependencies": {
17
- "@babel/cli": "^7.28.3",
18
- "@babel/core": "^7.28.5",
19
- "@babel/preset-env": "^7.28.5",
20
- "@babel/preset-react": "^7.28.5",
21
- "vite": "^6.4.1"
22
- },
23
- "dependencies": {
24
- "react": "^19.2.0",
25
- "react-dom": "^19.2.0",
26
- "react-router-dom": "^6.30.1"
27
- }
28
- }