juxscript 1.0.25 → 1.0.27
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.
- package/machinery/compiler.js +19 -14
- package/package.json +1 -1
- package/presets/grid.jux +55 -0
- package/presets/index.jux +90 -0
- package/presets/styles/layout.css +280 -0
- package/presets/hey.jux +0 -60
package/machinery/compiler.js
CHANGED
|
@@ -173,7 +173,7 @@ export async function transpileProjectTypeScript(srcDir, destDir) {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
/**
|
|
176
|
-
* Copy presets folder from lib to dist
|
|
176
|
+
* Copy presets folder from lib to dist (maintaining directory structure)
|
|
177
177
|
*
|
|
178
178
|
* @param {string} packageRoot - Source package root directory
|
|
179
179
|
* @param {string} distDir - Destination directory
|
|
@@ -195,21 +195,30 @@ export async function copyPresetsToOutput(packageRoot, distDir) {
|
|
|
195
195
|
|
|
196
196
|
fs.mkdirSync(presetsDest, { recursive: true });
|
|
197
197
|
|
|
198
|
-
//
|
|
199
|
-
const files = fs.readdirSync(presetsSrc);
|
|
198
|
+
// Recursively copy entire presets directory structure
|
|
200
199
|
let copiedCount = 0;
|
|
201
200
|
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
const destPath = path.join(presetsDest, file);
|
|
201
|
+
function copyRecursive(src, dest) {
|
|
202
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
205
203
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
204
|
+
for (const entry of entries) {
|
|
205
|
+
const srcPath = path.join(src, entry.name);
|
|
206
|
+
const destPath = path.join(dest, entry.name);
|
|
207
|
+
|
|
208
|
+
if (entry.isDirectory()) {
|
|
209
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
210
|
+
copyRecursive(srcPath, destPath);
|
|
211
|
+
} else if (entry.isFile()) {
|
|
212
|
+
fs.copyFileSync(srcPath, destPath);
|
|
213
|
+
const relativePath = path.relative(presetsSrc, srcPath);
|
|
214
|
+
console.log(` ✓ ${relativePath}`);
|
|
215
|
+
copiedCount++;
|
|
216
|
+
}
|
|
210
217
|
}
|
|
211
218
|
}
|
|
212
219
|
|
|
220
|
+
copyRecursive(presetsSrc, presetsDest);
|
|
221
|
+
|
|
213
222
|
console.log(`✅ Copied ${copiedCount} preset file(s)\n`);
|
|
214
223
|
}
|
|
215
224
|
|
|
@@ -653,10 +662,6 @@ export function generateIndexHtml(distDir, routes, mainJsFilename = 'main.js') {
|
|
|
653
662
|
<title>Jux Application</title>
|
|
654
663
|
</head>
|
|
655
664
|
<body data-theme="">
|
|
656
|
-
<!-- Navigation -->
|
|
657
|
-
<nav style="padding: 20px; background: #f5f5f5; border-bottom: 2px solid #ddd;">
|
|
658
|
-
${navLinks}
|
|
659
|
-
</nav>
|
|
660
665
|
<!-- App container - router renders here -->
|
|
661
666
|
<div id="app"></div>
|
|
662
667
|
${importMapScript}
|
package/package.json
CHANGED
package/presets/grid.jux
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jux } from 'juxscript';
|
|
2
|
+
|
|
3
|
+
// Import the layout styles
|
|
4
|
+
jux.include('styles/layout.css');
|
|
5
|
+
|
|
6
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
7
|
+
// GRID LAYOUT - INITIALIZATION FUNCTION
|
|
8
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
9
|
+
// Note: #app is automatically created by the Jux compiler
|
|
10
|
+
|
|
11
|
+
export function initializeGrid() {
|
|
12
|
+
// Header area
|
|
13
|
+
const appHeader = jux.container('appheader').render('#app');
|
|
14
|
+
const appHeaderContent = jux.container('appheader-content').render('#appheader');
|
|
15
|
+
const appHeaderLogo = jux.container('appheader-logo').render('#appheader-content');
|
|
16
|
+
const appHeaderNav = jux.container('appheader-nav').render('#appheader-content');
|
|
17
|
+
const appHeaderActions = jux.container('appheader-actions').render('#appheader-content');
|
|
18
|
+
|
|
19
|
+
// Left sidebar
|
|
20
|
+
const appAside = jux.container('appaside').render('#app');
|
|
21
|
+
|
|
22
|
+
// Main content area
|
|
23
|
+
const appMain = jux.container('appmain').render('#app');
|
|
24
|
+
const appMainContent = jux.container('appmain-content').render('#appmain');
|
|
25
|
+
|
|
26
|
+
// Right sidebar (optional - starts hidden)
|
|
27
|
+
const appSidebar = jux.container('appsidebar').render('#app');
|
|
28
|
+
const appSidebarHeader = jux.container('appsidebar-header').render('#appsidebar');
|
|
29
|
+
const appSidebarContent = jux.container('appsidebar-content').render('#appsidebar');
|
|
30
|
+
const appSidebarFooter = jux.container('appsidebar-footer').render('#appsidebar');
|
|
31
|
+
|
|
32
|
+
// Footer area
|
|
33
|
+
const appFooter = jux.container('appfooter').render('#app');
|
|
34
|
+
const appFooterContent = jux.container('appfooter-content').render('#appfooter');
|
|
35
|
+
const appFooterLegal = jux.container('appfooter-legal').render('#appfooter-content');
|
|
36
|
+
|
|
37
|
+
// Return references to all containers
|
|
38
|
+
return {
|
|
39
|
+
appHeader,
|
|
40
|
+
appHeaderContent,
|
|
41
|
+
appHeaderLogo,
|
|
42
|
+
appHeaderNav,
|
|
43
|
+
appHeaderActions,
|
|
44
|
+
appAside,
|
|
45
|
+
appMain,
|
|
46
|
+
appMainContent,
|
|
47
|
+
appSidebar,
|
|
48
|
+
appSidebarHeader,
|
|
49
|
+
appSidebarContent,
|
|
50
|
+
appSidebarFooter,
|
|
51
|
+
appFooter,
|
|
52
|
+
appFooterContent,
|
|
53
|
+
appFooterLegal
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jux, state } from 'juxscript';
|
|
2
|
+
import { initializeGrid } from './grid.jux';
|
|
3
|
+
|
|
4
|
+
// Initialize the grid layout - this executes the rendering
|
|
5
|
+
const grid = initializeGrid();
|
|
6
|
+
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
8
|
+
// HEADER CONTENT
|
|
9
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
10
|
+
|
|
11
|
+
jux.heading('logo-text')
|
|
12
|
+
.level(1)
|
|
13
|
+
.text('JUX')
|
|
14
|
+
.render('#appheader-logo');
|
|
15
|
+
|
|
16
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
17
|
+
// MAIN CONTENT
|
|
18
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
19
|
+
|
|
20
|
+
jux.hero('welcome', {
|
|
21
|
+
title: 'Welcome to JUX',
|
|
22
|
+
subtitle: 'A JavaScript UX authorship platform'
|
|
23
|
+
}).render('#appmain-content');
|
|
24
|
+
|
|
25
|
+
jux.divider().render('#appmain-content');
|
|
26
|
+
|
|
27
|
+
jux.heading('start-heading')
|
|
28
|
+
.level(2)
|
|
29
|
+
.text('Getting Started')
|
|
30
|
+
.render('#appmain-content');
|
|
31
|
+
|
|
32
|
+
jux.paragraph('start-intro')
|
|
33
|
+
.text('Edit this file to build your app. Here are some quick tips:')
|
|
34
|
+
.style('margin: 1rem 0;')
|
|
35
|
+
.render('#appmain-content');
|
|
36
|
+
|
|
37
|
+
jux.list('quick-tips', {
|
|
38
|
+
items: [
|
|
39
|
+
'Run npx jux serve for dev mode with hot reload',
|
|
40
|
+
'Run npx jux build to compile for production',
|
|
41
|
+
'Serve jux-dist/ from your backend',
|
|
42
|
+
'Check out the docs at juxscript.com/docs'
|
|
43
|
+
]
|
|
44
|
+
}).render('#appmain-content');
|
|
45
|
+
|
|
46
|
+
jux.divider().render('#appmain-content');
|
|
47
|
+
|
|
48
|
+
jux.heading('example-heading')
|
|
49
|
+
.level(3)
|
|
50
|
+
.text('Quick Example')
|
|
51
|
+
.render('#appmain-content');
|
|
52
|
+
|
|
53
|
+
jux.code('example-code')
|
|
54
|
+
.language('javascript')
|
|
55
|
+
.code(`import { jux, state } from 'juxscript';
|
|
56
|
+
|
|
57
|
+
const count = state(0);
|
|
58
|
+
|
|
59
|
+
jux.button('increment')
|
|
60
|
+
.label('Click me!')
|
|
61
|
+
.bind('click', () => count.value++)
|
|
62
|
+
.render('#app');
|
|
63
|
+
|
|
64
|
+
jux.paragraph('counter')
|
|
65
|
+
.sync('text', count, val => \`Count: \${val}\`)
|
|
66
|
+
.render('#app');`)
|
|
67
|
+
.render('#appmain-content');
|
|
68
|
+
|
|
69
|
+
// Create a reactive counter demo
|
|
70
|
+
const count = state(0);
|
|
71
|
+
|
|
72
|
+
jux.button('increment')
|
|
73
|
+
.label('Click me!')
|
|
74
|
+
.bind('click', () => count.value++)
|
|
75
|
+
.style('margin: 1rem 0;')
|
|
76
|
+
.render('#appmain-content');
|
|
77
|
+
|
|
78
|
+
jux.paragraph('counter')
|
|
79
|
+
.sync('text', count, val => `Count: ${val}`)
|
|
80
|
+
.style('font-size: 1.25rem; font-weight: 600; color: var(--color-brand);')
|
|
81
|
+
.render('#appmain-content');
|
|
82
|
+
|
|
83
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
84
|
+
// FOOTER CONTENT
|
|
85
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
86
|
+
|
|
87
|
+
jux.paragraph('footer-text')
|
|
88
|
+
.text('© 2026 JUX Platform')
|
|
89
|
+
.style('color: var(--color-text-tertiary);')
|
|
90
|
+
.render('#appfooter-content');
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
APP CONTAINER - Main Layout Grid
|
|
3
|
+
============================================ */
|
|
4
|
+
#app {
|
|
5
|
+
display: grid;
|
|
6
|
+
grid-template-columns: auto 1fr auto;
|
|
7
|
+
grid-template-rows: auto 1fr auto;
|
|
8
|
+
grid-template-areas:
|
|
9
|
+
"header header header"
|
|
10
|
+
"sidebar main aside"
|
|
11
|
+
"footer footer footer";
|
|
12
|
+
width: 100vw;
|
|
13
|
+
height: 100vh;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* ============================================
|
|
18
|
+
HEADER - Top Navigation Bar
|
|
19
|
+
============================================ */
|
|
20
|
+
#appheader {
|
|
21
|
+
grid-area: header;
|
|
22
|
+
background: var(--color-surface-elevated);
|
|
23
|
+
border-bottom: var(--border-width) solid var(--color-border);
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
padding: 0 var(--space-lg);
|
|
27
|
+
height: 48px;
|
|
28
|
+
z-index: 100;
|
|
29
|
+
transition: background-color var(--transition-base), border-color var(--transition-base);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#appheader-content {
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: space-between;
|
|
36
|
+
width: 100%;
|
|
37
|
+
gap: var(--space-xl);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#appheader-logo {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
gap: var(--space-md);
|
|
44
|
+
font-size: var(--font-size-lg);
|
|
45
|
+
font-weight: var(--font-weight-semibold);
|
|
46
|
+
color: var(--color-text-primary);
|
|
47
|
+
text-decoration: none;
|
|
48
|
+
padding: var(--space-sm) var(--space-md);
|
|
49
|
+
border-radius: var(--radius-md);
|
|
50
|
+
transition: background-color var(--transition-fast);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#appheader-logo:hover {
|
|
54
|
+
background: var(--color-surface-hover);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#appheader-nav {
|
|
58
|
+
flex: 1;
|
|
59
|
+
display: flex;
|
|
60
|
+
align-items: center;
|
|
61
|
+
gap: var(--space-sm);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#appheader-actions {
|
|
65
|
+
display: flex;
|
|
66
|
+
align-items: center;
|
|
67
|
+
gap: var(--space-md);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ============================================
|
|
71
|
+
LEFT SIDEBAR - Navigation
|
|
72
|
+
============================================ */
|
|
73
|
+
.jux-sidebar,
|
|
74
|
+
#appaside {
|
|
75
|
+
grid-area: sidebar;
|
|
76
|
+
width: 260px;
|
|
77
|
+
background: var(--color-surface-base);
|
|
78
|
+
border-right: var(--border-width) solid var(--color-border);
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
transition: width var(--transition-base);
|
|
83
|
+
position: relative;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* ============================================
|
|
87
|
+
MAIN CONTENT - Center Area
|
|
88
|
+
============================================ */
|
|
89
|
+
#appmain {
|
|
90
|
+
grid-area: main;
|
|
91
|
+
background: var(--color-background);
|
|
92
|
+
overflow-y: auto;
|
|
93
|
+
overflow-x: hidden;
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
position: relative;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#appmain-content {
|
|
100
|
+
flex: 1;
|
|
101
|
+
padding: var(--space-3xl) var(--space-2xl);
|
|
102
|
+
max-width: 1600px;
|
|
103
|
+
width: 100%;
|
|
104
|
+
margin: 0 auto;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Custom scrollbar for main content */
|
|
108
|
+
#appmain::-webkit-scrollbar {
|
|
109
|
+
width: 8px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#appmain::-webkit-scrollbar-track {
|
|
113
|
+
background: var(--color-surface-base);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#appmain::-webkit-scrollbar-thumb {
|
|
117
|
+
background: var(--color-border);
|
|
118
|
+
border-radius: var(--radius-full);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
#appmain::-webkit-scrollbar-thumb:hover {
|
|
122
|
+
background: var(--color-border-hover);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ============================================
|
|
126
|
+
RIGHT SIDEBAR - Optional Panel
|
|
127
|
+
============================================ */
|
|
128
|
+
#appsidebar {
|
|
129
|
+
grid-area: aside;
|
|
130
|
+
width: 280px;
|
|
131
|
+
background: var(--color-surface-base);
|
|
132
|
+
border-left: var(--border-width) solid var(--color-border);
|
|
133
|
+
display: none;
|
|
134
|
+
flex-direction: column;
|
|
135
|
+
overflow: hidden;
|
|
136
|
+
transition: width var(--transition-base), background-color var(--transition-base);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#appsidebar.show {
|
|
140
|
+
display: flex;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#appsidebar.collapsed {
|
|
144
|
+
width: 0;
|
|
145
|
+
border: none;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#appsidebar-header {
|
|
149
|
+
padding: var(--space-lg);
|
|
150
|
+
border-bottom: var(--border-width) solid var(--color-border);
|
|
151
|
+
font-weight: var(--font-weight-semibold);
|
|
152
|
+
font-size: var(--font-size-sm);
|
|
153
|
+
color: var(--color-text-secondary);
|
|
154
|
+
text-transform: uppercase;
|
|
155
|
+
letter-spacing: 0.05em;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
#appsidebar-content {
|
|
159
|
+
flex: 1;
|
|
160
|
+
overflow-y: auto;
|
|
161
|
+
overflow-x: hidden;
|
|
162
|
+
padding: var(--space-lg);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#appsidebar-content::-webkit-scrollbar {
|
|
166
|
+
width: 6px;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
#appsidebar-content::-webkit-scrollbar-track {
|
|
170
|
+
background: transparent;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
#appsidebar-content::-webkit-scrollbar-thumb {
|
|
174
|
+
background: var(--color-border);
|
|
175
|
+
border-radius: var(--radius-full);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#appsidebar-content::-webkit-scrollbar-thumb:hover {
|
|
179
|
+
background: var(--color-border-hover);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
#appsidebar-footer {
|
|
183
|
+
padding: var(--space-lg);
|
|
184
|
+
border-top: var(--border-width) solid var(--color-border);
|
|
185
|
+
font-size: var(--font-size-xs);
|
|
186
|
+
color: var(--color-text-tertiary);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* ============================================
|
|
190
|
+
FOOTER - Bottom Bar
|
|
191
|
+
============================================ */
|
|
192
|
+
#appfooter {
|
|
193
|
+
grid-area: footer;
|
|
194
|
+
background: var(--color-surface-elevated);
|
|
195
|
+
border-top: var(--border-width) solid var(--color-border);
|
|
196
|
+
padding: var(--space-lg) var(--space-2xl);
|
|
197
|
+
display: flex;
|
|
198
|
+
align-items: center;
|
|
199
|
+
justify-content: space-between;
|
|
200
|
+
font-size: var(--font-size-sm);
|
|
201
|
+
color: var(--color-text-tertiary);
|
|
202
|
+
transition: background-color var(--transition-base), border-color var(--transition-base);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
#appfooter-content {
|
|
206
|
+
display: flex;
|
|
207
|
+
align-items: center;
|
|
208
|
+
gap: var(--space-xl);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#appfooter-legal {
|
|
212
|
+
display: flex;
|
|
213
|
+
align-items: center;
|
|
214
|
+
gap: var(--space-lg);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
#appfooter a {
|
|
218
|
+
color: var(--color-text-secondary);
|
|
219
|
+
text-decoration: none;
|
|
220
|
+
transition: color var(--transition-fast);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
#appfooter a:hover {
|
|
224
|
+
color: var(--color-text-primary);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* ============================================
|
|
228
|
+
RESPONSIVE GRID LAYOUTS
|
|
229
|
+
============================================ */
|
|
230
|
+
@media (max-width: 1024px) {
|
|
231
|
+
#appsidebar {
|
|
232
|
+
display: none;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
#app {
|
|
236
|
+
grid-template-columns: auto 1fr;
|
|
237
|
+
grid-template-areas:
|
|
238
|
+
"header header"
|
|
239
|
+
"sidebar main"
|
|
240
|
+
"footer footer";
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@media (max-width: 768px) {
|
|
245
|
+
#app {
|
|
246
|
+
grid-template-columns: 1fr;
|
|
247
|
+
grid-template-areas:
|
|
248
|
+
"header"
|
|
249
|
+
"main"
|
|
250
|
+
"footer";
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.jux-sidebar,
|
|
254
|
+
#appaside {
|
|
255
|
+
display: none;
|
|
256
|
+
position: fixed;
|
|
257
|
+
left: 0;
|
|
258
|
+
top: 0;
|
|
259
|
+
bottom: 0;
|
|
260
|
+
z-index: 1000;
|
|
261
|
+
width: 260px;
|
|
262
|
+
box-shadow: var(--shadow-xl);
|
|
263
|
+
transform: translateX(-100%);
|
|
264
|
+
transition: transform var(--transition-base);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.jux-sidebar.open,
|
|
268
|
+
#appaside.open {
|
|
269
|
+
display: flex;
|
|
270
|
+
transform: translateX(0);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
#appmain-content {
|
|
274
|
+
padding: var(--space-2xl) var(--space-lg);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
#appheader {
|
|
278
|
+
padding: 0 var(--space-md) 0 calc(var(--space-md) + 48px);
|
|
279
|
+
}
|
|
280
|
+
}
|
package/presets/hey.jux
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { jux } from 'juxscript';
|
|
2
|
-
|
|
3
|
-
// Welcome page with examples
|
|
4
|
-
jux.hero('welcome', {
|
|
5
|
-
title: 'Welcome to JUX',
|
|
6
|
-
subtitle: 'A JavaScript UX authorship platform'
|
|
7
|
-
}).render('#app');
|
|
8
|
-
|
|
9
|
-
jux.divider().render('#app');
|
|
10
|
-
|
|
11
|
-
jux.container('getting-started')
|
|
12
|
-
.style('max-width: 800px; margin: 2rem auto; padding: 2rem;')
|
|
13
|
-
.render('#app');
|
|
14
|
-
|
|
15
|
-
jux.heading('start-heading')
|
|
16
|
-
.level(2)
|
|
17
|
-
.text('Getting Started')
|
|
18
|
-
.render('#getting-started');
|
|
19
|
-
|
|
20
|
-
jux.paragraph('start-intro')
|
|
21
|
-
.text('Edit this file to build your app. Here are some quick tips:')
|
|
22
|
-
.style('margin: 1rem 0;')
|
|
23
|
-
.render('#getting-started');
|
|
24
|
-
|
|
25
|
-
jux.list('quick-tips', {
|
|
26
|
-
items: [
|
|
27
|
-
'Run npx jux serve for dev mode with hot reload',
|
|
28
|
-
'Run npx jux build to compile for production',
|
|
29
|
-
'Serve jux-dist/ from your backend',
|
|
30
|
-
'Check out the docs at juxscript.com/docs'
|
|
31
|
-
]
|
|
32
|
-
}).render('#getting-started');
|
|
33
|
-
|
|
34
|
-
jux.divider().render('#app');
|
|
35
|
-
|
|
36
|
-
jux.container('example-container')
|
|
37
|
-
.style('max-width: 800px; margin: 2rem auto; padding: 2rem; background: #f9fafb; border-radius: 8px;')
|
|
38
|
-
.render('#app');
|
|
39
|
-
|
|
40
|
-
jux.heading('example-heading')
|
|
41
|
-
.level(3)
|
|
42
|
-
.text('Quick Example')
|
|
43
|
-
.render('#example-container');
|
|
44
|
-
|
|
45
|
-
jux.code('example-code')
|
|
46
|
-
.language('javascript')
|
|
47
|
-
.code(`import { jux, state } from 'juxscript';
|
|
48
|
-
|
|
49
|
-
// Create a reactive counter
|
|
50
|
-
const count = state(0);
|
|
51
|
-
|
|
52
|
-
jux.button('increment')
|
|
53
|
-
.label('Click me!')
|
|
54
|
-
.bind('click', () => count.value++)
|
|
55
|
-
.render('#app');
|
|
56
|
-
|
|
57
|
-
jux.paragraph('counter')
|
|
58
|
-
.sync('text', count, val => \`Count: \${val}\`)
|
|
59
|
-
.render('#app');`)
|
|
60
|
-
.render('#example-container');
|