jac-client 0.2.0__py3-none-any.whl → 0.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. jac_client/docs/README.md +50 -20
  2. jac_client/docs/advanced-state.md +13 -14
  3. jac_client/docs/asset-serving/intro.md +209 -0
  4. jac_client/docs/assets/pipe_line-v2.svg +32 -0
  5. jac_client/docs/file-system/app.jac.md +121 -0
  6. jac_client/docs/file-system/backend-frontend.md +217 -0
  7. jac_client/docs/file-system/intro.md +72 -0
  8. jac_client/docs/file-system/nested-imports.md +348 -0
  9. jac_client/docs/guide-example/intro.md +11 -13
  10. jac_client/docs/guide-example/step-01-setup.md +30 -20
  11. jac_client/docs/guide-example/step-02-components.md +24 -24
  12. jac_client/docs/guide-example/step-03-styling.md +24 -24
  13. jac_client/docs/guide-example/step-04-todo-ui.md +17 -17
  14. jac_client/docs/guide-example/step-05-local-state.md +23 -23
  15. jac_client/docs/guide-example/step-06-events.md +23 -24
  16. jac_client/docs/guide-example/step-07-effects.md +27 -28
  17. jac_client/docs/guide-example/step-08-walkers.md +23 -23
  18. jac_client/docs/guide-example/step-09-authentication.md +18 -18
  19. jac_client/docs/guide-example/step-10-routing.md +20 -21
  20. jac_client/docs/guide-example/step-11-final.md +34 -35
  21. jac_client/docs/imports.md +4 -5
  22. jac_client/docs/lifecycle-hooks.md +12 -13
  23. jac_client/docs/routing.md +21 -22
  24. jac_client/docs/styling/intro.md +249 -0
  25. jac_client/docs/styling/js-styling.md +367 -0
  26. jac_client/docs/styling/material-ui.md +341 -0
  27. jac_client/docs/styling/pure-css.md +299 -0
  28. jac_client/docs/styling/sass.md +403 -0
  29. jac_client/docs/styling/styled-components.md +395 -0
  30. jac_client/docs/styling/tailwind.md +298 -0
  31. jac_client/examples/all-in-one/.babelrc +9 -0
  32. jac_client/examples/all-in-one/README.md +16 -0
  33. jac_client/examples/all-in-one/app.jac +426 -0
  34. jac_client/examples/all-in-one/assets/burger.png +0 -0
  35. jac_client/examples/all-in-one/button.jac +7 -0
  36. jac_client/examples/all-in-one/components/button.jac +7 -0
  37. jac_client/examples/all-in-one/package.json +29 -0
  38. jac_client/examples/all-in-one/styles.css +26 -0
  39. jac_client/examples/all-in-one/vite.config.js +28 -0
  40. jac_client/examples/asset-serving/css-with-image/.babelrc +9 -0
  41. jac_client/examples/asset-serving/css-with-image/README.md +91 -0
  42. jac_client/examples/asset-serving/css-with-image/app.jac +88 -0
  43. jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
  44. jac_client/examples/asset-serving/css-with-image/package.json +28 -0
  45. jac_client/examples/asset-serving/css-with-image/styles.css +26 -0
  46. jac_client/examples/asset-serving/css-with-image/vite.config.js +28 -0
  47. jac_client/examples/asset-serving/image-asset/.babelrc +9 -0
  48. jac_client/examples/asset-serving/image-asset/README.md +119 -0
  49. jac_client/examples/asset-serving/image-asset/app.jac +55 -0
  50. jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
  51. jac_client/examples/asset-serving/image-asset/package.json +28 -0
  52. jac_client/examples/asset-serving/image-asset/styles.css +26 -0
  53. jac_client/examples/asset-serving/image-asset/vite.config.js +28 -0
  54. jac_client/examples/asset-serving/import-alias/.babelrc +9 -0
  55. jac_client/examples/asset-serving/import-alias/README.md +83 -0
  56. jac_client/examples/asset-serving/import-alias/app.jac +111 -0
  57. jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
  58. jac_client/examples/asset-serving/import-alias/package.json +28 -0
  59. jac_client/examples/asset-serving/import-alias/vite.config.js +28 -0
  60. jac_client/examples/basic/app.jac +14 -9
  61. jac_client/examples/basic/package.json +1 -1
  62. jac_client/examples/basic/vite.config.js +0 -1
  63. jac_client/examples/basic-auth/package.json +1 -1
  64. jac_client/examples/basic-auth/vite.config.js +0 -1
  65. jac_client/examples/basic-auth-with-router/package.json +1 -1
  66. jac_client/examples/basic-auth-with-router/vite.config.js +0 -1
  67. jac_client/examples/basic-full-stack/package.json +1 -1
  68. jac_client/examples/basic-full-stack/vite.config.js +0 -1
  69. jac_client/examples/css-styling/js-styling/.babelrc +9 -0
  70. jac_client/examples/css-styling/js-styling/README.md +183 -0
  71. jac_client/examples/css-styling/js-styling/app.jac +84 -0
  72. jac_client/examples/css-styling/js-styling/package.json +28 -0
  73. jac_client/examples/css-styling/js-styling/styles.js +100 -0
  74. jac_client/examples/css-styling/js-styling/vite.config.js +27 -0
  75. jac_client/examples/css-styling/material-ui/.babelrc +9 -0
  76. jac_client/examples/css-styling/material-ui/README.md +16 -0
  77. jac_client/examples/css-styling/material-ui/app.jac +122 -0
  78. jac_client/examples/css-styling/material-ui/package.json +32 -0
  79. jac_client/examples/css-styling/material-ui/vite.config.js +27 -0
  80. jac_client/examples/css-styling/pure-css/.babelrc +9 -0
  81. jac_client/examples/css-styling/pure-css/README.md +16 -0
  82. jac_client/examples/css-styling/pure-css/app.jac +64 -0
  83. jac_client/examples/css-styling/pure-css/package.json +28 -0
  84. jac_client/examples/css-styling/pure-css/styles.css +111 -0
  85. jac_client/examples/css-styling/pure-css/vite.config.js +27 -0
  86. jac_client/examples/css-styling/sass-example/.babelrc +9 -0
  87. jac_client/examples/css-styling/sass-example/README.md +16 -0
  88. jac_client/examples/css-styling/sass-example/app.jac +64 -0
  89. jac_client/examples/css-styling/sass-example/package.json +29 -0
  90. jac_client/examples/css-styling/sass-example/styles.scss +153 -0
  91. jac_client/examples/css-styling/sass-example/vite.config.js +27 -0
  92. jac_client/examples/css-styling/styled-components/.babelrc +9 -0
  93. jac_client/examples/css-styling/styled-components/README.md +16 -0
  94. jac_client/examples/css-styling/styled-components/app.jac +71 -0
  95. jac_client/examples/css-styling/styled-components/package.json +29 -0
  96. jac_client/examples/css-styling/styled-components/styled.js +90 -0
  97. jac_client/examples/css-styling/styled-components/vite.config.js +27 -0
  98. jac_client/examples/css-styling/tailwind-example/.babelrc +9 -0
  99. jac_client/examples/css-styling/tailwind-example/README.md +16 -0
  100. jac_client/examples/css-styling/tailwind-example/app.jac +63 -0
  101. jac_client/examples/css-styling/tailwind-example/global.css +1 -0
  102. jac_client/examples/css-styling/tailwind-example/package.json +30 -0
  103. jac_client/examples/css-styling/tailwind-example/vite.config.js +29 -0
  104. jac_client/examples/full-stack-with-auth/app.jac +20 -33
  105. jac_client/examples/full-stack-with-auth/package.json +1 -1
  106. jac_client/examples/full-stack-with-auth/vite.config.js +0 -1
  107. jac_client/examples/little-x/app.jac +327 -218
  108. jac_client/examples/little-x/submit-button.jac +1 -1
  109. jac_client/examples/nested-folders/nested-advance/.babelrc +9 -0
  110. jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +11 -0
  111. jac_client/examples/nested-folders/nested-advance/README.md +77 -0
  112. jac_client/examples/nested-folders/nested-advance/app.jac +35 -0
  113. jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +19 -0
  114. jac_client/examples/nested-folders/nested-advance/level1/Card.jac +43 -0
  115. jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +25 -0
  116. jac_client/examples/nested-folders/nested-advance/package.json +29 -0
  117. jac_client/examples/nested-folders/nested-advance/vite.config.js +28 -0
  118. jac_client/examples/nested-folders/nested-basic/.babelrc +9 -0
  119. jac_client/examples/nested-folders/nested-basic/README.md +183 -0
  120. jac_client/examples/nested-folders/nested-basic/app.jac +13 -0
  121. jac_client/examples/nested-folders/nested-basic/app.js +7 -0
  122. jac_client/examples/nested-folders/nested-basic/button.jac +7 -0
  123. jac_client/examples/nested-folders/nested-basic/components/button.jac +7 -0
  124. jac_client/examples/nested-folders/nested-basic/package.json +28 -0
  125. jac_client/examples/nested-folders/nested-basic/vite.config.js +27 -0
  126. jac_client/examples/with-router/app.jac +1 -1
  127. jac_client/examples/with-router/package.json +1 -1
  128. jac_client/examples/with-router/vite.config.js +0 -1
  129. jac_client/plugin/cli.py +7 -2
  130. jac_client/plugin/client.py +68 -5
  131. jac_client/plugin/client_runtime.jac +1 -1
  132. jac_client/plugin/vite_client_bundle.py +162 -14
  133. jac_client/tests/__init__.py +0 -1
  134. jac_client/tests/fixtures/basic-app/app.jac +7 -2
  135. jac_client/tests/fixtures/cl_file/app.cl.jac +48 -0
  136. jac_client/tests/fixtures/cl_file/app.jac +15 -0
  137. jac_client/tests/fixtures/client_app_with_antd/app.jac +14 -8
  138. jac_client/tests/fixtures/js_import/app.jac +19 -15
  139. jac_client/tests/fixtures/js_import/utils.js +0 -1
  140. jac_client/tests/fixtures/package.json +1 -1
  141. jac_client/tests/fixtures/relative_import/app.jac +4 -6
  142. jac_client/tests/fixtures/relative_import/button.jac +7 -6
  143. jac_client/tests/fixtures/spawn_test/app.jac +1 -5
  144. jac_client/tests/fixtures/test_fragments_spread/app.jac +24 -10
  145. jac_client/tests/test_asset_examples.py +322 -0
  146. jac_client/tests/test_cl.py +480 -426
  147. jac_client/tests/test_create_jac_app.py +125 -133
  148. jac_client/tests/test_it.py +329 -0
  149. jac_client/tests/test_nested_file.py +374 -0
  150. {jac_client-0.2.0.dist-info → jac_client-0.2.3.dist-info}/METADATA +11 -3
  151. jac_client-0.2.3.dist-info/RECORD +171 -0
  152. jac_client-0.2.0.dist-info/RECORD +0 -72
  153. {jac_client-0.2.0.dist-info → jac_client-0.2.3.dist-info}/WHEEL +0 -0
  154. {jac_client-0.2.0.dist-info → jac_client-0.2.3.dist-info}/entry_points.txt +0 -0
@@ -5,4 +5,4 @@ cl def SubmitButton() -> any {
5
5
  {"width" : "100%" , "padding" : "10px" , "backgroundColor" : "#1da1f2" , "color" : "white" , "border" : "none" , "borderRadius" : "4px" , "cursor" : "pointer" }}>
6
6
  Sign Up
7
7
  </button>
8
- }
8
+ }
@@ -0,0 +1,9 @@
1
+
2
+ {
3
+ "presets": [[
4
+ "@babel/preset-env",
5
+ {
6
+ "modules": false
7
+ }
8
+ ], "@babel/preset-react"]
9
+ }
@@ -0,0 +1,11 @@
1
+ # Root Level Button
2
+ cl import from antd { Button }
3
+
4
+ cl def ButtonRoot() -> any {
5
+ return <Button
6
+ type="primary"
7
+ size="large"
8
+ >
9
+ Root Level Button
10
+ </Button>;
11
+ }
@@ -0,0 +1,77 @@
1
+ # Nested Folder Levels Example
2
+
3
+ This example demonstrates multiple levels of folder nesting and how relative imports work across different directory levels.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ nested-advance/
9
+ ├── app.jac # Root entry point
10
+ ├── ButtonRoot.jac # Root level button
11
+ └── level1/
12
+ ├── ButtonSecondL.jac # Second level button
13
+ ├── Card.jac # Card component (imports from root and level2)
14
+ └── level2/
15
+ └── ButtonThirdL.jac # Third level button
16
+ ```
17
+
18
+ ## Import Patterns Demonstrated
19
+
20
+ ### 1. Root Level (`app.jac`)
21
+ ```jac
22
+ # Import from root
23
+ cl import from .ButtonRoot { ButtonRoot }
24
+
25
+ # Import from level1
26
+ cl import from .level1.ButtonSecondL { ButtonSecondL }
27
+
28
+ # Import from level1/level2
29
+ cl import from .level1.level2.ButtonThirdL { ButtonThirdL }
30
+ ```
31
+
32
+ ### 2. Second Level (`level1/ButtonSecondL.jac`)
33
+ ```jac
34
+ # Import from root (go up one level with ..)
35
+ cl import from ..ButtonRoot { ButtonRoot }
36
+ ```
37
+
38
+ ### 3. Card Component (`level1/Card.jac`)
39
+ This demonstrates importing from both above and below:
40
+ ```jac
41
+ # Import from root (go up two levels with ..)
42
+ cl import from ..ButtonRoot { ButtonRoot }
43
+
44
+ # Import from level2 (go down one level with .level2)
45
+ cl import from .level2.ButtonThirdL { ButtonThirdL }
46
+ ```
47
+
48
+ ### 4. Third Level (`level1/level2/ButtonThirdL.jac`)
49
+ ```jac
50
+ # Import from root (go up three levels with ...)
51
+ cl import from ...ButtonRoot { ButtonRoot }
52
+
53
+ # Import from second level (go up one level with ..)
54
+ cl import from ..ButtonSecondL { ButtonSecondL }
55
+ ```
56
+
57
+ ## Running the Example
58
+
59
+ Make sure node modules are installed:
60
+ ```bash
61
+ npm install
62
+ ```
63
+
64
+ To run your Jac code, use the Jac CLI:
65
+ ```bash
66
+ jac serve app.jac
67
+ ```
68
+
69
+ ## Key Concepts
70
+
71
+ - **Single dot (`.`)** - Current directory
72
+ - **Double dot (`..`)** - Parent directory (one level up)
73
+ - **Triple dot (`...`)** - Two levels up
74
+ - **Multiple dots** - Continue going up the directory tree
75
+ - **Dot notation after dots** - Go down into subdirectories (e.g., `.level2`)
76
+
77
+ This example shows how folder structure is preserved during compilation, ensuring all relative imports work correctly!
@@ -0,0 +1,35 @@
1
+ # Nested Folder Levels Example
2
+ cl import from .ButtonRoot { ButtonRoot }
3
+ cl import from .level1.ButtonSecondL { ButtonSecondL }
4
+ cl import from .level1.level2.ButtonThirdL { ButtonThirdL }
5
+ cl import from .level1.Card { Card }
6
+
7
+ cl def app() -> any {
8
+ return <div
9
+ style={{padding: "20px"}}
10
+ >
11
+ <h1>
12
+ Nested Folder Levels Demo
13
+ </h1>
14
+ <div
15
+ style={{margin: "10px 0"}}
16
+ >
17
+ <ButtonRoot />
18
+ </div>
19
+ <div
20
+ style={{margin: "10px 0"}}
21
+ >
22
+ <ButtonSecondL />
23
+ </div>
24
+ <div
25
+ style={{margin: "10px 0"}}
26
+ >
27
+ <ButtonThirdL />
28
+ </div>
29
+ <div
30
+ style={{margin: "10px 0"}}
31
+ >
32
+ <Card />
33
+ </div>
34
+ </div>;
35
+ }
@@ -0,0 +1,19 @@
1
+ # Second Level Button (level1/)
2
+ cl import from antd { Button }
3
+ cl import from ..ButtonRoot { ButtonRoot }
4
+
5
+ cl def ButtonSecondL() -> any {
6
+ return <div>
7
+ <Button
8
+ type="default"
9
+ size="large"
10
+ >
11
+ Second Level Button (imports from root)
12
+ </Button>
13
+ <div
14
+ style={{marginTop: "10px"}}
15
+ >
16
+ <ButtonRoot />
17
+ </div>
18
+ </div>;
19
+ }
@@ -0,0 +1,43 @@
1
+ # Card Component on Second Level
2
+ # Imports from both above (root) and below (level2)
3
+ cl import from ..ButtonRoot {
4
+ ButtonRoot
5
+ }
6
+ cl import from .level2.ButtonThirdL { ButtonThirdL }
7
+
8
+ cl def Card() -> any {
9
+ return <div
10
+ style={{
11
+ border: "2px solid #007bff",
12
+ borderRadius: "8px",
13
+ padding: "20px",
14
+ margin: "10px 0",
15
+ backgroundColor: "#f8f9fa"
16
+ }}
17
+ >
18
+ <h3>
19
+ Card Component (Second Level)
20
+ </h3>
21
+ <p>
22
+ This card imports from:
23
+ </p>
24
+ <ul>
25
+ <li>
26
+ Root level: ButtonRoot (using ..)
27
+ </li>
28
+ <li>
29
+ Third level: ButtonThirdL (using .level2)
30
+ </li>
31
+ </ul>
32
+ <div
33
+ style={{marginTop: "15px"}}
34
+ >
35
+ <ButtonRoot />
36
+ </div>
37
+ <div
38
+ style={{marginTop: "10px"}}
39
+ >
40
+ <ButtonThirdL />
41
+ </div>
42
+ </div>;
43
+ }
@@ -0,0 +1,25 @@
1
+ # Third Level Button (level1/level2/)
2
+ cl import from antd { Button }
3
+ cl import from ...ButtonRoot { ButtonRoot }
4
+ cl import from ..ButtonSecondL { ButtonSecondL }
5
+
6
+ cl def ButtonThirdL() -> any {
7
+ return <div>
8
+ <Button
9
+ type="dashed"
10
+ size="large"
11
+ >
12
+ Third Level Button (imports from root and second level)
13
+ </Button>
14
+ <div
15
+ style={{marginTop: "10px"}}
16
+ >
17
+ <ButtonRoot />
18
+ </div>
19
+ <div
20
+ style={{marginTop: "10px"}}
21
+ >
22
+ <ButtonSecondL />
23
+ </div>
24
+ </div>;
25
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "nested-advance",
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: nested-advance",
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
+ "antd": "^6.0.0",
25
+ "react": "^19.2.0",
26
+ "react-dom": "^19.2.0",
27
+ "react-router-dom": "^6.30.1"
28
+ }
29
+ }
@@ -0,0 +1,28 @@
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
+ "@jac-client/assets": path.resolve(__dirname, "src/assets"),
26
+ },
27
+ },
28
+ });
@@ -0,0 +1,9 @@
1
+
2
+ {
3
+ "presets": [[
4
+ "@babel/preset-env",
5
+ {
6
+ "modules": false
7
+ }
8
+ ], "@babel/preset-react"]
9
+ }
@@ -0,0 +1,183 @@
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)
@@ -0,0 +1,13 @@
1
+ cl import from .components.button { CustomButton }
2
+ cl import from .button { CustomButtonRoot }
3
+
4
+ cl def RelativeImport() -> any {
5
+ return <div>
6
+ <CustomButton />
7
+ <CustomButtonRoot />
8
+ </div>;
9
+ }
10
+
11
+ cl def app() -> any {
12
+ return <RelativeImport />;
13
+ }
@@ -0,0 +1,7 @@
1
+ import { CustomButton } from "./components/button.js";
2
+ function RelativeImport() {
3
+ return __jacJsx("div", {}, [__jacJsx(CustomButton, {}, [])]);
4
+ }
5
+ function app() {
6
+ return __jacJsx(RelativeImport, {}, []);
7
+ }
@@ -0,0 +1,7 @@
1
+ cl import from antd { Button }
2
+
3
+ cl def CustomButtonRoot() -> any {
4
+ return <Button>
5
+ Click Me
6
+ </Button>;
7
+ }
@@ -0,0 +1,7 @@
1
+ cl import from antd { Button }
2
+
3
+ cl def CustomButton() -> any {
4
+ return <Button>
5
+ Click Me
6
+ </Button>;
7
+ }
@@ -0,0 +1,28 @@
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
+ }
@@ -0,0 +1,27 @@
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
+ });
@@ -32,7 +32,7 @@ cl {
32
32
  <strong>
33
33
  HashRouter
34
34
  </strong>
35
- for client-side routing.
35
+ # for client-side routing.
36
36
  </p>
37
37
  <p>
38
38
  Current path:
@@ -25,4 +25,4 @@
25
25
  "react-dom": "^19.2.0",
26
26
  "react-router-dom": "^6.30.1"
27
27
  }
28
- }
28
+ }
@@ -25,4 +25,3 @@ export default defineConfig({
25
25
  },
26
26
  },
27
27
  });
28
-
jac_client/plugin/cli.py CHANGED
@@ -7,7 +7,7 @@ import subprocess
7
7
  import sys
8
8
 
9
9
  from jaclang.cli.cmdreg import cmd_registry
10
- from jaclang.runtimelib.machine import hookimpl
10
+ from jaclang.runtimelib.runtime import hookimpl
11
11
 
12
12
 
13
13
  class JacCmd:
@@ -73,7 +73,7 @@ class JacCmd:
73
73
 
74
74
  # Read the generated package.json
75
75
  package_json_path = os.path.join(project_path, "package.json")
76
- with open(package_json_path, "r") as f:
76
+ with open(package_json_path) as f:
77
77
  package_data = json.load(f)
78
78
 
79
79
  # create temp folder
@@ -84,6 +84,10 @@ class JacCmd:
84
84
  build_folder = os.path.join(project_path, "build")
85
85
  os.makedirs(build_folder, exist_ok=True)
86
86
 
87
+ # create assets folder for static assets (images, fonts, etc.)
88
+ assets_folder = os.path.join(project_path, "assets")
89
+ os.makedirs(assets_folder, exist_ok=True)
90
+
87
91
  # Update package.json with Jac-specific configuration
88
92
  package_data.update(
89
93
  {
@@ -186,6 +190,7 @@ export default defineConfig({
186
190
  resolve: {
187
191
  alias: {
188
192
  "@jac-client/utils": path.resolve(__dirname, "src/client_runtime.js"),
193
+ "@jac-client/assets": path.resolve(__dirname, "src/assets"),
189
194
  },
190
195
  },
191
196
  });