juxscript 1.1.398 → 1.1.399

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/README.md CHANGED
@@ -1,271 +1,499 @@
1
- # The web needs a higher level of abstraction: Meet **JUX**
1
+ # JUX Build UIs in Pure JavaScript. No Markup Required.
2
2
 
3
+ > **JUX** is a headless UI authoring framework. Build reactive web applications with 100% JavaScript — no HTML templates, no JSX, no markup of any kind.
3
4
 
4
- ```diff
5
- - IF YOU ARE CURRENTLY USING THIS PACKAGE COOL! But it is still a little fragile.
6
- - We are working on opening our repo to public and working on our documentation pages.
7
- + Stay tuned! For now, you will see our roadmap here!
5
+ Think of it like a more reactive [Streamlit](https://streamlit.io), but for the web, written entirely in JavaScript. Author your UI top-down, procedurally — components appear in the order you call them.
8
6
 
7
+ ```bash
8
+ npx juxscript create my-app
9
+ cd my-app
10
+ npm run dev
9
11
  ```
10
- - [X] Router
11
- - [ ] Cross Page Store.
12
- - [ ] Distributable Bundle (Static Sites)
13
- - [ ] Tree Shake/Efficiencies.
14
-
15
- - [ ] Data
16
- - [ ] Drivers: File, S3, Database.
17
- - [ ] const d = jux.data('id',{});
18
- - [ ] d.driver(file|s3|database)
19
- - [ ] d.items([] | juxitem)
20
- - [ ] d.store(callback)
21
-
22
- - [X] Layouts (100% done.)
23
- - [ ] *Authoring Layout Pages* - `docs`
24
- - [ ] *Authoring Application Pages* - `docs`
25
- - [ ] *Authoring Custom Components* - `docs`
26
-
27
- - [ ] Render Dependency Tree
28
- > Idea here is, one element may be a predicate for another. Will need promises. **predicting problems with slow-loading components that depend on containers from other components. May to to separate concerns with container "building" vs. content addition OR use async processes (promises).
29
- - [X] Reactivity (90% done.)
30
- - [ ] Client Components (99% of what would be needed.)
31
- - [X] Charts
32
- - [X] Poor Intellisense support? Could be this issue. - fixed.
33
- - [ ] Api Wrapper
34
- - [X] Params/Active State for Menu/Nav matching - built in.
35
- - [ ] CDN Bundle (import CDN/'state', 'jux' from cdn.)
36
- - [ ] Icon
37
-
38
- - [ ] Quickstart Boilerplates (20% done,notion.jux)
39
- - [ ] Mobile Nav
40
- - [ ] `npx jux present notion|default` etc..
41
- - [ ] Server side components (api and database)
42
- - [ ] Quick deploy option
43
-
44
-
45
- ## *JUX* Authoring UI's in pure javascript.
46
-
47
- > Build beautiful, reactive UI's using only javascript. **No markup required.**
48
- > A clean authorship layer capable of being taught to non-developers, strong enough to be used by real developers.
49
-
50
- >> **jux** challenges the idea that markup based systems are the most efficient way to author web applications.
51
- ## AI friendly - **use less tokens!**
52
-
53
-
54
- ```diff
55
- - Markup is expensive!
56
- Have you ever considered the energy requirements to ship chunks of HTML markup like Vue or React components?
12
+
13
+ ---
14
+
15
+ ## Hello World
16
+
17
+ ```js
18
+ // jux/index.jux
19
+ import { jux } from 'juxscript';
20
+
21
+ jux.h1('greeting', { content: 'Hello, World!' });
22
+ jux.p('intro', { content: 'Welcome to JUX — no HTML required.' });
23
+ jux.btn('click-me', { content: 'Click me' });
57
24
  ```
58
25
 
59
- - [ ] Build a code calculator (token calculator)
60
- > As a user, I want to be efficient with the LLM's. I want my code to be clean. I want to avoid repeating myself. I ultimately, want to write less code. Less code is better code.
26
+ That's it. Three lines render a heading, a paragraph, and a button. The order you write them is the order they appear on the page.
61
27
 
62
- ## Ecosystem friendly (NPM)
28
+ ---
63
29
 
64
- > Because it is just javascript, .jux files work with any npm package you want to throw at it with standard ESM syntax.
30
+ ## Why JUX?
65
31
 
66
- ## GETTING STARTED
32
+ - **Zero markup** — no HTML, no JSX, no templates
33
+ - **Procedural authoring** — top-down code flow, just like writing a script
34
+ - **Built-in reactivity** — `pageState` connects components automatically
35
+ - **Headless components** — styled by default, fully customisable
36
+ - **Any npm package** — standard ESM imports work out of the box
37
+ - **AI friendly** — less code, fewer tokens, cleaner prompts
38
+
39
+ ---
40
+
41
+ ## Getting Started
42
+
43
+ ### Create a new project
67
44
 
68
45
  ```bash
69
- # New project
70
- mkdir my-project
71
- cd my-project
72
- npm init -y
73
- npm install juxscript
46
+ npx juxscript create my-app
47
+ cd my-app
48
+ npm run dev
49
+ ```
74
50
 
75
- # Initialize (creates jux/ directory)
76
- npx jux init
51
+ This scaffolds a new project, installs dependencies, and starts a hot-reload dev server.
77
52
 
78
- # Builds jux-dist and serves index.jux
79
- npx jux serve
53
+ ### Add to an existing project
54
+
55
+ ```bash
56
+ npm install juxscript
57
+ npx juxscript init # creates jux/ directory and juxconfig.js
58
+ npm run dev
80
59
  ```
81
- > install
82
- `npm i juxscript`
83
60
 
84
- >> Your IDE must be setup to read .jux files as .js files. In VS Code, this is do in the `.vscode/settings.json`. Here is an example.
61
+ ### VS Code setup
62
+
63
+ JUX files use the `.jux` extension but are plain JavaScript. Tell VS Code:
85
64
 
86
65
  ```json
87
- //.vscode/settings.json
66
+ // .vscode/settings.json
88
67
  {
89
68
  "files.associations": {
90
- "*.jux": "javascript",
91
- "*.juxt": "javascript"
69
+ "*.jux": "javascript"
92
70
  },
93
- "javascript.validate.enable": false,
94
- "[javascript]": {
95
- "editor.defaultFormatter": "vscode.typescript-language-features"
96
- }
71
+ "javascript.validate.enable": false
97
72
  }
98
73
  ```
99
74
 
100
- > building and serving the `examples` project directory.
101
- `npm run dev`
75
+ ---
102
76
 
103
- > building only (the `examples` project directory)
104
- `npm run build:examples`
77
+ ## The `jux` Namespace
105
78
 
79
+ Every component is accessed through the `jux` object. Import it once and everything you need is there.
106
80
 
107
- # Authoring in Jux
81
+ ```js
82
+ import { jux } from 'juxscript';
83
+ ```
108
84
 
109
- 1. Build a Layout Page you can reuse.
110
- Check out the presets, they speed this process up. Just modify them with your goals, such as logo, menu options, nav etc.
111
- 2. Build your Pages
112
- Just get to work, using the **jux** component library to build most of what you need, filling in any details with *javascript* logically arranged the way you want. Think, authoring SFC but with only the composition layer.
113
- 3. Test it out!
114
- Jux comes with a watcher system built in, so you can see your edits to *.jux* files live.
85
+ ### Text & headings
115
86
 
116
- # GOAL: Eliminating the Markup System of building UI's.
117
- > HTML markup is the equivalent of still writing in `C` ro `C++` despite the availability of more functional levels of abstraction like `python`.
118
- > To remove the requirement for markup, **jux** must address the utility of markup.
87
+ ```js
88
+ jux.h1('page-title', { content: 'Dashboard' });
89
+ jux.h2('section', { content: 'Overview' });
90
+ jux.p('description', { content: 'Here is your summary.' });
91
+ jux.span('note', { content: 'Updated just now' });
92
+ jux.pre('code-block', { content: 'const x = 42;' });
93
+ ```
119
94
 
120
- ## Layouts
95
+ ### Form inputs
96
+
97
+ ```js
98
+ jux.input('username', { label: 'Username', placeholder: 'Enter name...' });
99
+ jux.email('email', { label: 'Email' });
100
+ jux.password('pass', { label: 'Password' });
101
+ jux.number('quantity', { label: 'Quantity', value: '1' });
102
+ jux.select('color', {
103
+ label: 'Favourite colour',
104
+ options: [
105
+ { label: 'Red', value: 'red' },
106
+ { label: 'Green', value: 'green' },
107
+ { label: 'Blue', value: 'blue' }
108
+ ]
109
+ });
110
+ jux.checkbox('agree', { label: 'I agree to the terms' });
111
+ jux.radio('size', {
112
+ label: 'Size',
113
+ options: [
114
+ { label: 'Small', value: 'sm' },
115
+ { label: 'Medium', value: 'md' },
116
+ { label: 'Large', value: 'lg' }
117
+ ]
118
+ });
119
+ ```
121
120
 
122
- ### Grid System
123
- - [ ] Laying out JUX files in a rational way.
124
- > Develop a higher-level layout javascript grammar for building layouts and palettes of style using *ZERO markup*.
121
+ ### Buttons & links
125
122
 
126
- - [ ] A Partial View Strategy
127
- >>> As a dev I may need to load partial pages/components into other pages. This should avoid noisy wrappers and ideally be just javascript imports of jux objects.
123
+ ```js
124
+ jux.btn('save', { content: 'Save', variant: 'default' });
125
+ jux.btn('delete', { content: 'Delete', variant: 'destructive' });
126
+ jux.btn('cancel', { content: 'Cancel', variant: 'outline' });
127
+ jux.a('home-link', { content: 'Home', href: '/' });
128
+ ```
128
129
 
129
- ### Components
130
+ ### Layout & containers
130
131
 
131
- We have constructed the most helpful components for building 99% of core business/saas web applications, that present beautifully on the page and are created purely with javascript.
132
- > https://www.shadcn-vue.com/docs/components
133
- > Run time slots.. Example, `table.slot(columnName -> object);`
132
+ ```js
133
+ // c(width, height, padding, borderRadius)
134
+ const card = jux.c('100%', 'auto', '1rem', '8px');
134
135
 
135
- # Backend
136
+ // Render something inside the card
137
+ jux.p('card-text', { content: 'I live inside the card', target: card.id });
138
+ ```
136
139
 
137
- ### Routing & Views
138
- - [X] Subviews architecture
139
- - [X] Nested routing support
140
- - [X] View composition
141
- - [X] Layout system
142
- - [X] User views
143
- - [X] `profile.jux` - User
140
+ ### Lists & tables
141
+
142
+ ```js
143
+ jux.list('todo-list', {
144
+ items: [
145
+ { id: 'a', content: 'Buy milk', icon: '🛒' },
146
+ { id: 'b', content: 'Write code', icon: '💻' }
147
+ ],
148
+ selectable: true
149
+ });
150
+
151
+ jux.table('users-table', {
152
+ columns: [
153
+ { key: 'name', label: 'Name' },
154
+ { key: 'email', label: 'Email' },
155
+ { key: 'role', label: 'Role' }
156
+ ],
157
+ items: [
158
+ { name: 'Alice', email: 'alice@example.com', role: 'Admin' },
159
+ { name: 'Bob', email: 'bob@example.com', role: 'User' }
160
+ ]
161
+ });
162
+ ```
144
163
 
145
- ### Server Docs/Documentation.
164
+ ### Navigation
146
165
 
147
- - [ ] Should *jux* ship with a server at all? Or merely for demos.
166
+ ```js
167
+ jux.nav('main-nav', {
168
+ items: [
169
+ { id: 'nav-home', icon: '🏠', label: 'Home', path: '/' },
170
+ { id: 'nav-settings', icon: '⚙️', label: 'Settings', path: '/settings' }
171
+ ]
172
+ });
173
+ ```
148
174
 
149
- > What is the server even doing? Is it merely a matter of understanding that JUX builder/compilation gives you a mirror of how you setup your project. It can be as flat or deep as you would like.
175
+ ### Tabs
176
+
177
+ ```js
178
+ const tabs = jux.tabs('page-tabs');
179
+ tabs.addTab({ id: 'overview', label: 'Overview', content: 'Overview content here.' });
180
+ tabs.addTab({ id: 'details', label: 'Details', content: 'Details content here.' });
181
+ tabs.activeTab('overview');
182
+ tabs.render('#app');
183
+ ```
184
+
185
+ ### Data fetching
186
+
187
+ ```js
188
+ const api = await jux.data('my-api', { url: '/api/users' });
189
+ // api.value contains the response
190
+ console.log(api.getValue());
191
+ ```
192
+
193
+ ### Styles
194
+
195
+ ```js
196
+ jux.include('/css/shadcn.css'); // inject a stylesheet link
197
+ jux.style('custom', 'body { margin: 0; }'); // inject inline CSS
198
+ ```
150
199
 
151
- > *At this point*, we are speaking almost 100% towards UI interfaces.
152
- > Servers should be 'loosely coupled.'. This allows for a standard.
153
- >>> In the future, we could introduce an *auto api* feature, similar to *next.js* api heuristic for folders and files.
154
200
  ---
155
201
 
202
+ ## Reactivity with `pageState`
156
203
 
157
- [ **@jesseallenrxtrail -> Discuss.** ]
204
+ `pageState` is JUX's reactivity layer. Every component you create is automatically registered in `pageState`, keyed by its `id`. Read values, react to events, and update the DOM — all from plain JavaScript.
158
205
 
159
- ### Chore: Commit to building more in package directory.
206
+ ```js
207
+ import { jux, pageState } from 'juxscript';
208
+ ```
160
209
 
161
- > We can experiment with our example project, using a simple `express` server, running. What third-party integration do we need?
162
- - [ ] Chore: Cleanup our `machinery/server.js` to separate concerns and build our actual endpoints we need to build software here.
210
+ ### Reading & writing state
163
211
 
164
- #### Alternative Chore: package this for `npmjs.org`, combine with our existing project, re-author frontend in *jux*.
212
+ ```js
213
+ jux.input('search', { label: 'Search' });
214
+ jux.p('result', { content: '' });
165
215
 
166
- - [ ] Alternative Chore: package this for `npmjs.org` and ship it.
167
- - [ ] Start a brand new project.
168
- - [ ] Build the server aspect in `flask` (already done).
169
- - [ ] Author the frontend in **jux** instead of **vue**.
216
+ // Whenever 'search' changes, update 'result'
217
+ pageState.__watch(() => {
218
+ pageState['result'].content = 'You typed: ' + pageState['search'].value;
219
+ });
220
+ ```
170
221
 
171
- > This may require us to move our 'complilation error module', `lib/components/error-handler.ts` to the front-end for display without a 'server call' at all?
172
- - [ ] Chore for this? This takes more analysis, discussion.
222
+ ### Reacting to events
173
223
 
174
- > How and what will we wire for backend and what **jux** components will we support for working with backends.
175
- - [ X ] SQL Database (query component)
176
- - [ ] Chore: This is currently supported. Needs revisiting and testing
177
- > API's
178
- - [ ] Base payload creater and consumer as a **jux** component. *jux.api*??
224
+ ```js
225
+ jux.btn('submit-btn', { content: 'Submit' });
226
+ jux.p('status', { content: 'Waiting...' });
179
227
 
180
- ---
228
+ pageState.__watch(() => {
229
+ if (pageState['submit-btn'].click) {
230
+ pageState['status'].content = 'Submitted! ✅';
231
+ }
232
+ });
233
+ ```
181
234
 
182
- # Jux Configs
235
+ Available event flags: `click`, `change`, `input`, `blur`, `focus`, `keydown`, `keyup`, `hover`, `active`, `focused`.
183
236
 
184
- > Jux configs.. `jux.config.js` what should this entail?
185
- Currently it looks like this:
186
- - [ ] Chore: **WHAT IS ACTUALLY BEING USED AND WHERE?**
237
+ ### Chaining reactions
187
238
 
188
- ```javascript
189
- export default {
190
- projectRoot: __dirname,
191
- distDir: path.join(__dirname, 'dist'),
192
- build: {
193
- minify: false
194
- },
195
-
196
- database: {
197
- // Default connection
198
- default: 'sqlite',
199
-
200
- // Named connections
201
- connections: {
202
- sqlite: {
203
- driver: 'sqlite',
204
- database: path.join(__dirname, 'db', 'jux.db')
205
- },
206
- ... // props to feed drivers for mysql/postgres
239
+ Reactions re-run whenever any `pageState` value they read changes — just like a spreadsheet. Chain them freely:
240
+
241
+ ```js
242
+ jux.input('first-name', { label: 'First name' });
243
+ jux.input('last-name', { label: 'Last name' });
244
+ jux.p('full-name', { content: '' });
245
+
246
+ // Reacts to either input changing
247
+ pageState.__watch(() => {
248
+ const first = pageState['first-name'].value;
249
+ const last = pageState['last-name'].value;
250
+ pageState['full-name'].content = `${first} ${last}`.trim();
251
+ });
252
+ ```
253
+
254
+ ### Conditional rendering
255
+
256
+ Because authoring is top-down procedural code, you can use plain `if` statements:
257
+
258
+ ```js
259
+ jux.input('promo-code', { label: 'Promo code' });
260
+
261
+ pageState.__watch(() => {
262
+ if (pageState['promo-code'].value === 'JUXROCKS') {
263
+ jux.p('promo-msg', { content: '🎉 10% discount applied!' });
207
264
  }
208
- },
209
-
210
- server: {
211
- port: process.env.PORT || 3000,
212
- host: process.env.HOST || 'localhost'
213
- },
214
-
215
- };
216
- ```
217
- **As a user, I will want to control where JUX sends queries.**
218
- **As a user, I may want to specify a default proxy for backend. I may also want to specify, explicitly, URL's to hit other service endpoints**
219
- - [ ] Escape hatch (backend API proxy vs default)
220
- - [ ] As a user, I may want to run my own server for backend requests/proxies.
221
- - [ ] As a user, I may want to hit multiple endpoints in the same JUX file.
265
+ });
266
+ ```
222
267
 
223
- ---
268
+ ### Visibility toggling
224
269
 
225
- # CORE
270
+ ```js
271
+ jux.p('hint', { content: 'Fill in all fields first.' });
226
272
 
227
- ### STATIC SERVING (your local file system, s3 bucket static sites, any host that allows serving etc...)
228
- **Should JUX function, as a 100% client side app (STATIC WEBSITES)**
229
- - [ ] Chore: Discovery... I think the answer is yes. I think what might be missing is bundling.
230
- ![alt text](local.png)
273
+ pageState.__watch(() => {
274
+ pageState['hint'].visible = pageState['username'].value === '';
275
+ });
276
+ ```
231
277
 
232
278
  ---
233
- ## REACTIVITY LAYER.
234
- ### Goal for Reactivity
235
- > We are shooting for better than nasty amounts of javascript, not as sophisticated as vue/react.
236
279
 
237
- > As a user, I want changes in state of my objects to be consumable by other objects on the page so they can paint changes and interface with each other seamlessly.
238
- - [ ] Build a basic `v-model` strategy in pure javascript. Different than jquery, javascript etc.
239
- - [ ] Build standard eventing systems, listeners and emitters on components where they make sense.
240
- `
241
- # ROADMAP
280
+ ## Layout with `c` (Container)
281
+
282
+ `c` is a lightweight container that handles sizing and layout without any CSS classes.
283
+
284
+ ```js
285
+ import { jux, c } from 'juxscript';
286
+
287
+ // c(width, height, padding, borderRadius)
288
+ const sidebar = c('260px', '100vh', '1rem', '0');
289
+ const main = c('calc(100% - 260px)', '100vh', '2rem', '0');
290
+
291
+ // Nest components inside a container using target
292
+ jux.h2('sidebar-title', { content: 'Menu', target: sidebar.id });
293
+ jux.h1('page-heading', { content: 'Welcome', target: main.id });
294
+ ```
295
+
296
+ ---
297
+
298
+ ## Component Presets
299
+
300
+ Copy ready-made components into your project with:
301
+
302
+ ```bash
303
+ npx juxscript comp sidebar
304
+ ```
305
+
306
+ Available presets:
307
+
308
+ | Preset | Description |
309
+ |-----------|------------------------------------------|
310
+ | `sidebar` | Collapsible sidebar with nav sections |
311
+
312
+ More presets coming soon. Contribute your own to `components/`.
313
+
314
+ ---
315
+
316
+ ## Advanced: Charts
317
+
318
+ JUX ships with a bar chart component you can drop into any page.
319
+
320
+ ### Horizontal bar chart
321
+
322
+ ```js
323
+ import { juxBarChart } from './bar.jux';
324
+
325
+ juxBarChart('revenue-chart', [
326
+ { x: 4200, label: 'Jan' },
327
+ { x: 5800, label: 'Feb' },
328
+ { x: 3900, label: 'Mar' },
329
+ { x: 7100, label: 'Apr' }
330
+ ], {
331
+ title: 'Monthly Revenue',
332
+ subtitle: 'USD, 2024',
333
+ orientation: 'horizontal',
334
+ colors: 'blue',
335
+ width: 600,
336
+ showValues: true
337
+ }).render('#app');
338
+ ```
339
+
340
+ ### Vertical bar chart
341
+
342
+ ```js
343
+ juxBarChart('visitors', [
344
+ { x: 1200, label: 'Mon' },
345
+ { x: 980, label: 'Tue' },
346
+ { x: 1540, label: 'Wed' }
347
+ ], {
348
+ orientation: 'vertical',
349
+ colors: 'green',
350
+ width: 500
351
+ }).render('#app');
352
+ ```
242
353
 
243
- ### KEY UI PAGES
244
- - [ ] JWT Authentication (`authJWT`) (demo `examples` only)
245
- - [ ] Token generation (demo `examples` only)
246
- - [ ] Token validation middleware (demo `examples` only)
247
- - [ ] Refresh token logic (demo `examples` only)
248
- - [ ] *Login system PAGES! Ships with `vendor` assets like lib files/layouts etc.*
249
- - [ ] Login
250
- - [ ] Logout
251
- - [ ] Profile
354
+ ### Chart options
252
355
 
356
+ | Option | Default | Description |
357
+ |---------------|----------------|---------------------------------------------|
358
+ | `orientation` | `'horizontal'` | `'horizontal'` or `'vertical'` |
359
+ | `colors` | `'green'` | Palette name or array of hex colours |
360
+ | `title` | `''` | Chart title |
361
+ | `subtitle` | `''` | Chart subtitle |
362
+ | `width` | `500` | Width in pixels |
363
+ | `aspectRatio` | `'16:9'` | `'16:9'`, `'4:3'`, `'1:1'`, `'21:9'`, etc. |
364
+ | `showValues` | `false` | Show value labels on bars |
365
+ | `ticks` | `4` | Number of axis tick marks |
366
+ | `animate` | `true` | Animate bars on load |
253
367
 
254
- ### Additional Features
255
- - [ ] API documentation
256
- - [ ] Testing setup
368
+ ### Colour palettes
257
369
 
370
+ ```js
371
+ import { jux } from 'juxscript';
258
372
 
373
+ // Named palettes
374
+ jux.palette('green'); // greens
375
+ jux.palette('blue'); // blues
376
+ jux.palette('multi'); // multi-colour
259
377
 
378
+ // Or pass a custom array
379
+ colors: ['#6366f1', '#8b5cf6', '#a78bfa']
380
+ ```
260
381
 
382
+ ---
261
383
 
262
- ### LAYOUT NOTES...
263
- ### Jux Standard Layout Regions
384
+ ## Authoring a Full Page — Realistic Example
385
+
386
+ ```js
387
+ // jux/dashboard.jux
388
+ import { jux, pageState } from 'juxscript';
389
+ import { juxBarChart } from './bar.jux';
390
+
391
+ // ── Layout ─────────────────────────────────────────────────────
392
+ jux.h1('dash-title', { content: 'Sales Dashboard' });
393
+ jux.p('dash-subtitle', { content: 'Real-time overview' });
394
+
395
+ // ── Filters ────────────────────────────────────────────────────
396
+ jux.select('period', {
397
+ label: 'Period',
398
+ options: [
399
+ { label: 'This week', value: 'week' },
400
+ { label: 'This month', value: 'month' },
401
+ { label: 'This year', value: 'year' }
402
+ ]
403
+ });
404
+
405
+ // ── Chart ──────────────────────────────────────────────────────
406
+ juxBarChart('sales-chart', [
407
+ { x: 3200, label: 'Mon' },
408
+ { x: 4100, label: 'Tue' },
409
+ { x: 2900, label: 'Wed' },
410
+ { x: 5300, label: 'Thu' },
411
+ { x: 4800, label: 'Fri' }
412
+ ], { title: 'Sales This Week', colors: 'blue', width: 600 }).render('#app');
413
+
414
+ // ── Table ──────────────────────────────────────────────────────
415
+ jux.table('top-products', {
416
+ columns: [
417
+ { key: 'name', label: 'Product' },
418
+ { key: 'sales', label: 'Sales' },
419
+ { key: 'rev', label: 'Revenue' }
420
+ ],
421
+ items: [
422
+ { name: 'Widget A', sales: 320, rev: '$6,400' },
423
+ { name: 'Widget B', sales: 210, rev: '$4,200' }
424
+ ]
425
+ });
426
+
427
+ // ── Reactivity ─────────────────────────────────────────────────
428
+ jux.p('selected-period', { content: 'Showing: This week' });
429
+
430
+ pageState.__watch(() => {
431
+ const p = pageState['period'].value;
432
+ if (p) pageState['selected-period'].content = 'Showing: ' + p;
433
+ });
434
+ ```
264
435
 
265
- - [ ] CHORE : REVISIT! I think maybe we ship with our figma, notion, default etc. But then document how to build and reuse a .jux page as a layout using the `jux.layout` class.
436
+ ---
266
437
 
267
- ### Start with a layout page
438
+ ## CLI Reference
268
439
 
269
- You can build a simple one, or copy and use one of the Jux presets.
440
+ ```bash
441
+ npx juxscript create <name> # Scaffold a new project
442
+ npx juxscript init # Init JUX in an existing directory
443
+ npx juxscript serve # Start production server
444
+ npx juxscript serve --hot # Start dev server with hot reload
445
+ npx juxscript build # Build for production
446
+ npx juxscript comp [name] # Add a component preset
447
+ npx juxscript comp [name] -f # Force overwrite (backs up existing)
448
+ ```
449
+
450
+ ---
451
+
452
+ ## Project Structure
453
+
454
+ ```
455
+ my-app/
456
+ ├── jux/
457
+ │ ├── index.jux ← entry page (rendered at /)
458
+ │ ├── about.jux ← rendered at /about
459
+ │ └── sidebar/ ← component presets live here
460
+ │ └── index.jux
461
+ ├── public/
462
+ │ └── styles.css
463
+ ├── juxconfig.js
464
+ └── package.json
465
+ ```
466
+
467
+ ---
468
+
469
+ ## Configuration (`juxconfig.js`)
470
+
471
+ ```js
472
+ export const config = {
473
+ directories: {
474
+ src: 'jux',
475
+ public: 'public',
476
+ dist: '.jux-dist'
477
+ },
478
+ server: {
479
+ port: 3000,
480
+ host: 'localhost'
481
+ }
482
+ };
483
+ ```
484
+
485
+ ---
270
486
 
271
- `npx jux preset notion|default|figma|slack|other`
487
+ ## Roadmap
488
+
489
+ - [x] Core component library (inputs, buttons, tables, lists, nav, tabs, charts)
490
+ - [x] `pageState` reactivity system
491
+ - [x] Router with nested routes and layouts
492
+ - [x] Hot-reload dev server
493
+ - [x] Component presets (`jux comp`)
494
+ - [ ] Cross-page state store
495
+ - [ ] Distributable static site bundles
496
+ - [ ] Data drivers (file, S3, database)
497
+ - [ ] CDN bundle
498
+ - [ ] Icon component
499
+ - [ ] More component presets (mobile nav, login page, profile page)