juxscript 1.0.64 → 1.0.66
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/bin/cli.js +18 -2
- package/create/all.jux +343 -0
- package/create/index.jux +90 -0
- package/create/layout.jux +57 -0
- package/create/style.css +1952 -0
- package/create/themes/assets/jux.svg +34 -0
- package/create/themes/base.css +60 -0
- package/create/themes/base2.css +54 -0
- package/create/themes/layouts/base.jux +16 -0
- package/create/themes/layouts/base_blog.jux +0 -0
- package/create/themes/layouts/base_docs.jux +0 -0
- package/create/themes/layouts/base_login.jux +0 -0
- package/create/themes/layouts/base_marketing.jux +0 -0
- package/create/themes/layouts/base_saas.jux +0 -0
- package/package.json +4 -11
- package/tests/dropdown-test.js +25 -0
- package/tests/juxerrors/bad_syntax.jux +8 -0
- package/tests/juxerrors/ghost_dep.jux +10 -0
- package/tests/server_plugin_test.ts +191 -0
- package/docs/DEPRECATIONS.md +0 -244
- package/docs/deprecation-code.png +0 -0
- package/docs/deprecation-console.png +0 -0
- package/docs/grid.png +0 -0
- package/docs/v2comps/HEADLESS.md +0 -83
- package/docs/v2comps/ISOMORPHISM.md +0 -10
package/bin/cli.js
CHANGED
|
@@ -14,8 +14,8 @@ const command = process.argv[2];
|
|
|
14
14
|
// ═══════════════════════════════════════════════════════════════════
|
|
15
15
|
|
|
16
16
|
if (command === 'create') {
|
|
17
|
-
|
|
18
|
-
const projectName = process.argv[3] ||
|
|
17
|
+
// ✅ FIX: Removed timestamp fallback from default name
|
|
18
|
+
const projectName = process.argv[3] || 'my-jux-app';
|
|
19
19
|
|
|
20
20
|
const projectPath = path.join(process.cwd(), projectName);
|
|
21
21
|
|
|
@@ -302,6 +302,7 @@ function findJuxFiles(dir, fileList = []) {
|
|
|
302
302
|
|
|
303
303
|
fs.mkdirSync(juxDir, { recursive: true }); // create it.
|
|
304
304
|
|
|
305
|
+
let filesCopied = 0;
|
|
305
306
|
// Copy default presets
|
|
306
307
|
const defaultPresetSrc = path.join(PATHS.packageRoot, 'create');
|
|
307
308
|
if (fs.existsSync(defaultPresetSrc)) {
|
|
@@ -309,11 +310,26 @@ function findJuxFiles(dir, fileList = []) {
|
|
|
309
310
|
for (const entry of entries) {
|
|
310
311
|
if (entry.isFile()) {
|
|
311
312
|
fs.copyFileSync(path.join(defaultPresetSrc, entry.name), path.join(juxDir, entry.name));
|
|
313
|
+
filesCopied++;
|
|
312
314
|
// console.log(`+ Created ${entry.name}`);
|
|
313
315
|
}
|
|
314
316
|
}
|
|
315
317
|
}
|
|
316
318
|
|
|
319
|
+
// ✅ ADD: Safe fallback if presets are missing so build doesn't fail
|
|
320
|
+
if (filesCopied === 0) {
|
|
321
|
+
console.warn('⚠️ Install pages not available. Creating default index.jux...');
|
|
322
|
+
const indexContent = `import { jux } from 'juxscript';
|
|
323
|
+
|
|
324
|
+
jux.hero('welcome', {
|
|
325
|
+
title: 'Welcome to JUX',
|
|
326
|
+
subtitle: 'Start building in jux/index.jux'
|
|
327
|
+
}).render('#app');
|
|
328
|
+
`;
|
|
329
|
+
fs.writeFileSync(path.join(juxDir, 'index.jux'), indexContent);
|
|
330
|
+
console.log('+ Created index.jux');
|
|
331
|
+
}
|
|
332
|
+
|
|
317
333
|
// Create juxconfig.js
|
|
318
334
|
const configExampleSrc = path.join(PATHS.packageRoot, 'juxconfig.example.js');
|
|
319
335
|
const configDest = path.join(PATHS.projectRoot, 'juxconfig.js');
|
package/create/all.jux
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { jux, state } from 'juxscript';
|
|
2
|
+
import { initializeGrid } from 'layout.jux';
|
|
3
|
+
|
|
4
|
+
// Initialize the grid layout - this executes the rendering
|
|
5
|
+
const grid = initializeGrid();
|
|
6
|
+
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
8
|
+
// ALL COMPONENTS SHOWCASE - Maximum DOM nodes per component
|
|
9
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
10
|
+
|
|
11
|
+
// Hero - All DOM-generating options
|
|
12
|
+
jux.heading('hero-heading').level(3).text('jux.hero').render("#appmain-content");
|
|
13
|
+
jux.hero('all-hero', {
|
|
14
|
+
title: 'Hero Title',
|
|
15
|
+
subtitle: 'Hero Subtitle',
|
|
16
|
+
content: 'Hero body content goes here',
|
|
17
|
+
cta: 'Call to Action',
|
|
18
|
+
ctaLink: '#',
|
|
19
|
+
backgroundOverlay: true,
|
|
20
|
+
centered: true
|
|
21
|
+
}).render("#appmain-content");
|
|
22
|
+
jux.divider().render("#appmain-content");
|
|
23
|
+
|
|
24
|
+
jux.heading('chart-heading').level(3).text('jux.chart, jux.calendar, jux.chatbox, jux.aiwidget, jux.media, jux.icons, jux.data!').render("#appmain-content");
|
|
25
|
+
jux.element('all-element')
|
|
26
|
+
.text('Need Elements! shadcn and tailwind analysis. Mobiles. ios/android - .text')
|
|
27
|
+
.render("#appmain-content");
|
|
28
|
+
jux.divider().render("#appmain-content");
|
|
29
|
+
|
|
30
|
+
jux.heading('alert-heading').level(3).text('jux.alert').render("#appmain-content");
|
|
31
|
+
jux.alert('all-alert')
|
|
32
|
+
.message('this is it - .message').render("#appmain-content");
|
|
33
|
+
jux.divider().render("#appmain-content");
|
|
34
|
+
|
|
35
|
+
jux.heading('badge-heading').level(3).text('jux.badge').render("#appmain-content");
|
|
36
|
+
jux.badge('all-badge')
|
|
37
|
+
.text('Badge Text - .text').render("#appmain-content");
|
|
38
|
+
jux.divider().render("#appmain-content");
|
|
39
|
+
|
|
40
|
+
jux.heading('button-heading').level(3).text('jux.button').render("#appmain-content");
|
|
41
|
+
jux.button('all-button')
|
|
42
|
+
.label('Button Label - .label').render("#appmain-content");
|
|
43
|
+
jux.divider().render("#appmain-content");
|
|
44
|
+
|
|
45
|
+
jux.heading('card-heading').level(3).text('jux.card').render("#appmain-content");
|
|
46
|
+
jux.card('all-card')
|
|
47
|
+
.title('Card Title - .title')
|
|
48
|
+
.content('Card content goes here - .content')
|
|
49
|
+
.footer('Card Footer - .footer')
|
|
50
|
+
.render("#appmain-content");
|
|
51
|
+
jux.divider().render("#appmain-content");
|
|
52
|
+
|
|
53
|
+
jux.heading('checkbox-heading').level(3).text('jux.checkbox').render("#appmain-content");
|
|
54
|
+
jux.checkbox('all-checkbox')
|
|
55
|
+
.label('Checkbox Label - .label')
|
|
56
|
+
.render("#appmain-content");
|
|
57
|
+
jux.divider().render("#appmain-content");
|
|
58
|
+
|
|
59
|
+
jux.heading('code-heading').level(3).text('jux.code').render("#appmain-content");
|
|
60
|
+
jux.code('all-code')
|
|
61
|
+
.code(`// Sample code - .code`)
|
|
62
|
+
.language('javascript')
|
|
63
|
+
.render("#appmain-content");
|
|
64
|
+
jux.divider().render("#appmain-content");
|
|
65
|
+
|
|
66
|
+
jux.heading('container-heading').level(3).text('jux.container').render("#appmain-content");
|
|
67
|
+
jux.container('all-container')
|
|
68
|
+
.render("#appmain-content");
|
|
69
|
+
jux.divider().render("#appmain-content");
|
|
70
|
+
|
|
71
|
+
jux.heading('datepicker-heading').level(3).text('jux.datepicker').render("#appmain-content");
|
|
72
|
+
jux.datepicker('all-datepicker')
|
|
73
|
+
.label('Select Date - .label')
|
|
74
|
+
.render("#appmain-content");
|
|
75
|
+
jux.divider().render("#appmain-content");
|
|
76
|
+
|
|
77
|
+
jux.heading('dropdown-heading').level(3).text('jux.dropdown').render("#appmain-content");
|
|
78
|
+
jux.dropdown('all-dropdown', {
|
|
79
|
+
items: [{ label: 'Item 1', value: '1' }, { label: 'Item 2', value: '2' }]
|
|
80
|
+
})
|
|
81
|
+
.render("#appmain-content");
|
|
82
|
+
jux.divider().render("#appmain-content");
|
|
83
|
+
|
|
84
|
+
jux.heading('fileupload-heading').level(3).text('jux.fileupload').render("#appmain-content");
|
|
85
|
+
jux.fileupload('all-fileupload')
|
|
86
|
+
.label('File Upload - .label')
|
|
87
|
+
.render("#appmain-content");
|
|
88
|
+
jux.divider().render("#appmain-content");
|
|
89
|
+
|
|
90
|
+
jux.heading('heading-heading').level(3).text('jux.heading').render("#appmain-content");
|
|
91
|
+
jux.heading('all-h1')
|
|
92
|
+
.text('Heading Level 1 - .text')
|
|
93
|
+
.level(1)
|
|
94
|
+
.render("#appmain-content");
|
|
95
|
+
jux.divider().render("#appmain-content");
|
|
96
|
+
|
|
97
|
+
// jux.heading('icon-heading').level(3).text('jux.icon').render("#appmain-content");
|
|
98
|
+
// jux.icon('all-icon').render("#appmain-content");
|
|
99
|
+
// jux.divider().render("#appmain-content");
|
|
100
|
+
|
|
101
|
+
jux.heading('input-heading').level(3).text('jux.input').render("#appmain-content");
|
|
102
|
+
jux.input('all-input')
|
|
103
|
+
.label('Input Label - .label')
|
|
104
|
+
.render("#appmain-content");
|
|
105
|
+
jux.divider().render("#appmain-content");
|
|
106
|
+
|
|
107
|
+
jux.heading('kpicard-heading').level(3).text('jux.kpicard').render("#appmain-content");
|
|
108
|
+
jux.kpicard('all-kpicard')
|
|
109
|
+
.delta('+5% - .delta')
|
|
110
|
+
.prefix('$ - .prefix')
|
|
111
|
+
.value('1,000 - .value')
|
|
112
|
+
.title('KPI Card Title - .title')
|
|
113
|
+
.render("#appmain-content");
|
|
114
|
+
jux.divider().render("#appmain-content");
|
|
115
|
+
|
|
116
|
+
jux.heading('list-heading').level(3).text('jux.list').render("#appmain-content");
|
|
117
|
+
jux.list('all-list', {
|
|
118
|
+
items: ['Item 1', 'Item 2', 'Item 3']
|
|
119
|
+
})
|
|
120
|
+
.render("#appmain-content");
|
|
121
|
+
jux.divider().render("#appmain-content");
|
|
122
|
+
|
|
123
|
+
jux.heading('loading-heading').level(3).text('jux.loading').render("#appmain-content");
|
|
124
|
+
jux.loading('all-loading')
|
|
125
|
+
.variant('spinner')
|
|
126
|
+
.size('lg')
|
|
127
|
+
.render("#appmain-content");
|
|
128
|
+
jux.divider().render("#appmain-content");
|
|
129
|
+
|
|
130
|
+
jux.heading('sidebar-heading').level(3).text('jux.sidebar').render("#appaside");
|
|
131
|
+
jux.sidebar('all-sidebar')
|
|
132
|
+
.collapsible(true)
|
|
133
|
+
.render("#appaside");
|
|
134
|
+
jux.divider().render("#appaside");
|
|
135
|
+
|
|
136
|
+
jux.heading('menu-heading').level(3).text('jux.menu').render("#appaside");
|
|
137
|
+
jux.menu('all-menu', {
|
|
138
|
+
items: [{ label: 'Home', path: '/' }, { label: 'About', path: '/about' }]
|
|
139
|
+
})
|
|
140
|
+
.render("#appaside");
|
|
141
|
+
jux.divider().render("#appaside");
|
|
142
|
+
|
|
143
|
+
jux.heading('nav-heading').level(3).text('jux.nav').render("#appmain-content");
|
|
144
|
+
jux.nav('all-nav', {
|
|
145
|
+
items: [{ label: 'Home', path: '/' }, { label: 'About', path: '/about' }]
|
|
146
|
+
}).render("#appmain-content");
|
|
147
|
+
jux.divider().render("#appmain-content");
|
|
148
|
+
|
|
149
|
+
jux.heading('paragraph-heading').level(3).text('jux.paragraph').render("#appmain-content");
|
|
150
|
+
jux.paragraph('all-paragraph')
|
|
151
|
+
.text('This is a sample paragraph created with jux.paragraph - .text')
|
|
152
|
+
.render("#appmain-content");
|
|
153
|
+
jux.divider().render("#appmain-content");
|
|
154
|
+
|
|
155
|
+
jux.heading('progress-heading').level(3).text('jux.progress').render("#appmain-content");
|
|
156
|
+
jux.progress('all-progress')
|
|
157
|
+
.value(70)
|
|
158
|
+
.max(100)
|
|
159
|
+
.variant('success')
|
|
160
|
+
.render("#appmain-content");
|
|
161
|
+
jux.divider().render("#appmain-content");
|
|
162
|
+
|
|
163
|
+
jux.heading('radio-heading').level(3).text('jux.radio').render("#appmain-content");
|
|
164
|
+
jux.radio('all-radio', {
|
|
165
|
+
options: [{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }]
|
|
166
|
+
})
|
|
167
|
+
.label('Radio Label - .label')
|
|
168
|
+
.render("#appmain-content");
|
|
169
|
+
jux.divider().render("#appmain-content");
|
|
170
|
+
|
|
171
|
+
jux.heading('select-heading').level(3).text('jux.select').render("#appmain-content");
|
|
172
|
+
jux.select('all-select', {
|
|
173
|
+
options: [{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }]
|
|
174
|
+
})
|
|
175
|
+
.label('Select Label - .label')
|
|
176
|
+
.render("#appmain-content");
|
|
177
|
+
jux.divider().render("#appmain-content");
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
jux.heading('switch-heading').level(3).text('jux.switch').render("#appmain-content");
|
|
182
|
+
jux.switch('all-switch')
|
|
183
|
+
.label('Switch Label - .label')
|
|
184
|
+
.render("#appmain-content");
|
|
185
|
+
jux.divider().render("#appmain-content");
|
|
186
|
+
|
|
187
|
+
jux.heading('table-heading').level(3).text('jux.table').render("#appmain-content");
|
|
188
|
+
jux.table('all-table', {
|
|
189
|
+
columns: ['Name', 'Age'],
|
|
190
|
+
rows: [
|
|
191
|
+
{ Name: 'John', Age: '25' },
|
|
192
|
+
{ Name: 'Jane', Age: '30' },
|
|
193
|
+
{ Name: 'Jane', Age: '30' },
|
|
194
|
+
{ Name: 'Jane', Age: '30' },
|
|
195
|
+
{ Name: 'Jane', Age: '30' }
|
|
196
|
+
]
|
|
197
|
+
})
|
|
198
|
+
.bordered(true)
|
|
199
|
+
.selectable(true)
|
|
200
|
+
.filterable(true)
|
|
201
|
+
.paginated(true)
|
|
202
|
+
.rowsPerPage(2)
|
|
203
|
+
.render("#appmain-content");
|
|
204
|
+
jux.divider().render("#appmain-content");
|
|
205
|
+
|
|
206
|
+
jux.heading('tabs-heading').level(3).text('jux.tabs').render("#appmain-content");
|
|
207
|
+
jux.tabs('all-tabs', {
|
|
208
|
+
tabs: [{ id: 1, label: 'Tab 1', content: 'Content 1' }, { id: 2, label: 'Tab 2', content: 'Content 2' }]
|
|
209
|
+
})
|
|
210
|
+
.activeTab('1')
|
|
211
|
+
.render("#appmain-content");
|
|
212
|
+
jux.divider().render("#appmain-content");
|
|
213
|
+
|
|
214
|
+
jux.heading('tooltip-heading').level(3).text('jux.tooltip').render("#appmain-content");
|
|
215
|
+
jux.button('tooltip-trigger').label('Hover for tooltip').render("#appmain-content");
|
|
216
|
+
jux.tooltip('all-tooltip', {
|
|
217
|
+
text: 'Tooltip content',
|
|
218
|
+
position: 'top'
|
|
219
|
+
}).render('#tooltip-trigger');
|
|
220
|
+
jux.divider().render("#appmain-content");
|
|
221
|
+
|
|
222
|
+
jux.heading('view-heading').level(3).text('jux.view').render("#appmain-content");
|
|
223
|
+
jux.view('all-view')
|
|
224
|
+
.title('View Title - Need to Rethink - this is for nesting! - .title')
|
|
225
|
+
.render("#appmain-content");
|
|
226
|
+
jux.divider().render("#appmain-content");
|
|
227
|
+
|
|
228
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
229
|
+
// SELF-ANALYSIS: Build component tree from #app
|
|
230
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
231
|
+
|
|
232
|
+
function buildComponentTree(element, depth = 0) {
|
|
233
|
+
const indent = ' '.repeat(depth);
|
|
234
|
+
const tagName = element.tagName.toLowerCase();
|
|
235
|
+
// ✅ Fix: Check if className exists and is a string
|
|
236
|
+
const classes = (element.className && typeof element.className === 'string')
|
|
237
|
+
? `.${element.className.split(' ').join('.')}`
|
|
238
|
+
: '';
|
|
239
|
+
|
|
240
|
+
let tree = `${indent}${tagName}${classes}\n`;
|
|
241
|
+
|
|
242
|
+
// Recurse through children
|
|
243
|
+
Array.from(element.children).forEach(child => {
|
|
244
|
+
tree += buildComponentTree(child, depth + 1);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
return tree;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function analyzeComponents() {
|
|
251
|
+
const app = document.getElementById('app');
|
|
252
|
+
if (!app) return 'No #app container found';
|
|
253
|
+
|
|
254
|
+
const components = Array.from(app.children);
|
|
255
|
+
const componentTypes = new Map();
|
|
256
|
+
|
|
257
|
+
let analysis = `═══════════════════════════════════════════════════════════════
|
|
258
|
+
COMPONENT TREE ANALYSIS
|
|
259
|
+
═══════════════════════════════════════════════════════════════
|
|
260
|
+
|
|
261
|
+
Found ${components.length} components in #app
|
|
262
|
+
|
|
263
|
+
`;
|
|
264
|
+
|
|
265
|
+
components.forEach((component, index) => {
|
|
266
|
+
const componentId = component.id || `component-${index}`;
|
|
267
|
+
// ✅ Fix: Safely handle className
|
|
268
|
+
const className = (component.className && typeof component.className === 'string')
|
|
269
|
+
? component.className
|
|
270
|
+
: '';
|
|
271
|
+
const rootClasses = className.split(' ').filter(c => c);
|
|
272
|
+
const primaryClass = rootClasses.find(c => c.startsWith('jux-')) || rootClasses[0] || 'unknown';
|
|
273
|
+
|
|
274
|
+
const componentName = primaryClass
|
|
275
|
+
.replace(/^jux-/, '')
|
|
276
|
+
.split('-')
|
|
277
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
278
|
+
.join('');
|
|
279
|
+
|
|
280
|
+
// Track component types
|
|
281
|
+
const typeName = primaryClass.replace(/^jux-/, '');
|
|
282
|
+
componentTypes.set(typeName, (componentTypes.get(typeName) || 0) + 1);
|
|
283
|
+
|
|
284
|
+
analysis += `┌─ ${componentName} (${componentId})\n`;
|
|
285
|
+
analysis += '│\n';
|
|
286
|
+
|
|
287
|
+
const tree = buildComponentTree(component);
|
|
288
|
+
tree.split('\n').forEach(line => {
|
|
289
|
+
if (line.trim()) {
|
|
290
|
+
analysis += `│ ${line}\n`;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
analysis += `└${'─'.repeat(66)}\n\n`;
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Add summary
|
|
298
|
+
analysis += `═══════════════════════════════════════════════════════════════
|
|
299
|
+
SUMMARY
|
|
300
|
+
═══════════════════════════════════════════════════════════════
|
|
301
|
+
|
|
302
|
+
Component Types:
|
|
303
|
+
`;
|
|
304
|
+
|
|
305
|
+
Array.from(componentTypes.entries())
|
|
306
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
307
|
+
.forEach(([type, count]) => {
|
|
308
|
+
analysis += ` - ${type}: ${count}\n`;
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
analysis += `\nTotal: ${components.length} components rendered\n`;
|
|
312
|
+
|
|
313
|
+
return analysis;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Wait for DOM to be fully rendered
|
|
317
|
+
setTimeout(() => {
|
|
318
|
+
const analysis = analyzeComponents();
|
|
319
|
+
|
|
320
|
+
// Create analysis display
|
|
321
|
+
jux.container('analysis-container')
|
|
322
|
+
.style('margin-top: 3rem; padding: 2rem; background: #1e1e1e; border-radius: 8px;')
|
|
323
|
+
.render("#appmain-content");
|
|
324
|
+
|
|
325
|
+
jux.heading('analysis-title')
|
|
326
|
+
.level(2)
|
|
327
|
+
.text('🔍 Self-Analysis')
|
|
328
|
+
.style('color: #10b981; margin-bottom: 1rem;')
|
|
329
|
+
.render('#analysis-container');
|
|
330
|
+
|
|
331
|
+
jux.code('component-tree')
|
|
332
|
+
.language('text')
|
|
333
|
+
.code(analysis)
|
|
334
|
+
.style('background: #0d1117; color: #c9d1d9; font-size: 0.875rem; max-height: 600px; overflow-y: auto;')
|
|
335
|
+
.render('#analysis-container');
|
|
336
|
+
|
|
337
|
+
jux.paragraph('analysis-note')
|
|
338
|
+
.text('This tree was generated by JavaScript analyzing the DOM structure of this page.')
|
|
339
|
+
.style('margin-top: 1rem; color: #8b949e; font-size: 0.875rem;')
|
|
340
|
+
.render('#analysis-container');
|
|
341
|
+
}, 100);
|
|
342
|
+
|
|
343
|
+
|
package/create/index.jux
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jux, state } from 'juxscript';
|
|
2
|
+
import { initializeGrid } from 'layout.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.set(count.value + 1))
|
|
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.set(count.value + 1))
|
|
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 Authoring Framework')
|
|
89
|
+
.style('color: var(--color-text-tertiary);')
|
|
90
|
+
.render('#appfooter-content');
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jux } from 'juxscript';
|
|
2
|
+
|
|
3
|
+
// Import the layout styles - testing link.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
7
|
+
// GRID LAYOUT - INITIALIZATION FUNCTION
|
|
8
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
9
|
+
// Note: #app is automatically created by the Jux compiler
|
|
10
|
+
|
|
11
|
+
export function initializeGrid() {
|
|
12
|
+
// add the base jux styles
|
|
13
|
+
jux.include('style.css');
|
|
14
|
+
// Header area
|
|
15
|
+
const appHeader = jux.container('appheader').render('#app');
|
|
16
|
+
const appHeaderContent = jux.container('appheader-content').render('#appheader');
|
|
17
|
+
const appHeaderLogo = jux.container('appheader-logo').render('#appheader-content');
|
|
18
|
+
const appHeaderNav = jux.container('appheader-nav').render('#appheader-content');
|
|
19
|
+
const appHeaderActions = jux.container('appheader-actions').render('#appheader-content');
|
|
20
|
+
|
|
21
|
+
// Left sidebar
|
|
22
|
+
const appAside = jux.container('appaside').render('#app');
|
|
23
|
+
|
|
24
|
+
// Main content area
|
|
25
|
+
const appMain = jux.container('appmain').render('#app');
|
|
26
|
+
const appMainContent = jux.container('appmain-content').render('#appmain');
|
|
27
|
+
|
|
28
|
+
// Right sidebar (optional - starts hidden)
|
|
29
|
+
const appSidebar = jux.container('appsidebar').render('#app');
|
|
30
|
+
const appSidebarHeader = jux.container('appsidebar-header').render('#appsidebar');
|
|
31
|
+
const appSidebarContent = jux.container('appsidebar-content').render('#appsidebar');
|
|
32
|
+
const appSidebarFooter = jux.container('appsidebar-footer').render('#appsidebar');
|
|
33
|
+
|
|
34
|
+
// Footer area
|
|
35
|
+
const appFooter = jux.container('appfooter').render('#app');
|
|
36
|
+
const appFooterContent = jux.container('appfooter-content').render('#appfooter');
|
|
37
|
+
const appFooterLegal = jux.container('appfooter-legal').render('#appfooter-content');
|
|
38
|
+
|
|
39
|
+
// Return references to all containers
|
|
40
|
+
return {
|
|
41
|
+
appHeader,
|
|
42
|
+
appHeaderContent,
|
|
43
|
+
appHeaderLogo,
|
|
44
|
+
appHeaderNav,
|
|
45
|
+
appHeaderActions,
|
|
46
|
+
appAside,
|
|
47
|
+
appMain,
|
|
48
|
+
appMainContent,
|
|
49
|
+
appSidebar,
|
|
50
|
+
appSidebarHeader,
|
|
51
|
+
appSidebarContent,
|
|
52
|
+
appSidebarFooter,
|
|
53
|
+
appFooter,
|
|
54
|
+
appFooterContent,
|
|
55
|
+
appFooterLegal
|
|
56
|
+
};
|
|
57
|
+
}
|