juxscript 1.0.2 → 1.0.4

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 (71) hide show
  1. package/README.md +37 -92
  2. package/bin/cli.js +57 -56
  3. package/lib/components/alert.ts +240 -0
  4. package/lib/components/app.ts +216 -82
  5. package/lib/components/badge.ts +164 -0
  6. package/lib/components/button.ts +188 -53
  7. package/lib/components/card.ts +75 -61
  8. package/lib/components/chart.ts +17 -15
  9. package/lib/components/checkbox.ts +228 -0
  10. package/lib/components/code.ts +66 -152
  11. package/lib/components/container.ts +104 -208
  12. package/lib/components/data.ts +1 -3
  13. package/lib/components/datepicker.ts +226 -0
  14. package/lib/components/dialog.ts +258 -0
  15. package/lib/components/docs-data.json +1697 -388
  16. package/lib/components/dropdown.ts +244 -0
  17. package/lib/components/element.ts +271 -0
  18. package/lib/components/fileupload.ts +319 -0
  19. package/lib/components/footer.ts +37 -18
  20. package/lib/components/header.ts +53 -33
  21. package/lib/components/heading.ts +119 -0
  22. package/lib/components/helpers.ts +34 -0
  23. package/lib/components/hero.ts +57 -31
  24. package/lib/components/include.ts +292 -0
  25. package/lib/components/input.ts +166 -78
  26. package/lib/components/layout.ts +144 -18
  27. package/lib/components/list.ts +83 -74
  28. package/lib/components/loading.ts +263 -0
  29. package/lib/components/main.ts +43 -17
  30. package/lib/components/menu.ts +108 -24
  31. package/lib/components/modal.ts +50 -21
  32. package/lib/components/nav.ts +60 -18
  33. package/lib/components/paragraph.ts +111 -0
  34. package/lib/components/progress.ts +276 -0
  35. package/lib/components/radio.ts +236 -0
  36. package/lib/components/req.ts +300 -0
  37. package/lib/components/script.ts +33 -74
  38. package/lib/components/select.ts +247 -0
  39. package/lib/components/sidebar.ts +86 -36
  40. package/lib/components/style.ts +47 -70
  41. package/lib/components/switch.ts +261 -0
  42. package/lib/components/table.ts +47 -24
  43. package/lib/components/tabs.ts +105 -63
  44. package/lib/components/theme-toggle.ts +361 -0
  45. package/lib/components/token-calculator.ts +380 -0
  46. package/lib/components/tooltip.ts +244 -0
  47. package/lib/components/view.ts +36 -20
  48. package/lib/components/write.ts +284 -0
  49. package/lib/globals.d.ts +21 -0
  50. package/lib/jux.ts +172 -68
  51. package/lib/presets/notion.css +521 -0
  52. package/lib/presets/notion.jux +27 -0
  53. package/lib/reactivity/state.ts +364 -0
  54. package/machinery/compiler.js +126 -38
  55. package/machinery/generators/html.js +2 -3
  56. package/machinery/server.js +2 -2
  57. package/package.json +29 -3
  58. package/lib/components/import.ts +0 -430
  59. package/lib/components/node.ts +0 -200
  60. package/lib/components/reactivity.js +0 -104
  61. package/lib/components/theme.ts +0 -97
  62. package/lib/layouts/notion.css +0 -258
  63. package/lib/styles/base-theme.css +0 -186
  64. package/lib/styles/dark-theme.css +0 -144
  65. package/lib/styles/light-theme.css +0 -144
  66. package/lib/styles/tokens/dark.css +0 -86
  67. package/lib/styles/tokens/light.css +0 -86
  68. package/lib/templates/index.juxt +0 -33
  69. package/lib/themes/dark.css +0 -86
  70. package/lib/themes/light.css +0 -86
  71. /package/lib/{styles → presets}/global.css +0 -0
@@ -0,0 +1,521 @@
1
+ /**
2
+ * Notion Preset - Combined Layout + Theming
3
+ * Light/Dark mode via [data-theme] attribute
4
+ */
5
+
6
+ /* ============================================
7
+ BASE TOKENS (Theme-independent)
8
+ ============================================ */
9
+ :root {
10
+ /* Typography */
11
+ --font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
12
+ --font-family-mono: 'Courier New', monospace;
13
+
14
+ --font-size-xs: 0.75rem;
15
+ --font-size-sm: 0.875rem;
16
+ --font-size-base: 1rem;
17
+ --font-size-lg: 1.125rem;
18
+ --font-size-xl: 1.25rem;
19
+ --font-size-2xl: 1.5rem;
20
+ --font-size-3xl: 2rem;
21
+
22
+ --font-weight-normal: 400;
23
+ --font-weight-medium: 500;
24
+ --font-weight-semibold: 600;
25
+ --font-weight-bold: 700;
26
+
27
+ --line-height-tight: 1.25;
28
+ --line-height-normal: 1.5;
29
+ --line-height-relaxed: 1.75;
30
+
31
+ /* Spacing */
32
+ --space-xs: 0.25rem;
33
+ --space-sm: 0.5rem;
34
+ --space-md: 1rem;
35
+ --space-lg: 1.5rem;
36
+ --space-xl: 2rem;
37
+ --space-2xl: 3rem;
38
+ --space-3xl: 4rem;
39
+
40
+ /* Borders */
41
+ --radius-sm: 4px;
42
+ --radius-md: 8px;
43
+ --radius-lg: 12px;
44
+ --radius-xl: 16px;
45
+ --radius-full: 9999px;
46
+
47
+ --border-width: 1px;
48
+
49
+ /* Transitions */
50
+ --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
51
+ --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
52
+ --transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
53
+
54
+ /* Semantic colors (theme-independent) */
55
+ --color-success: #10b981;
56
+ --color-warning: #f59e0b;
57
+ --color-danger: #ef4444;
58
+ --color-info: #3b82f6;
59
+ }
60
+
61
+ /* ============================================
62
+ LIGHT THEME (Default)
63
+ ============================================ */
64
+ :root,
65
+ [data-theme="light"] {
66
+ --color-brand: #0a9ca5;
67
+ --color-brand-hover: #088892;
68
+
69
+ --color-text-primary: #111827;
70
+ --color-text-secondary: #6b7280;
71
+ --color-text-tertiary: #9ca3af;
72
+ --color-text-inverse: #ffffff;
73
+
74
+ --color-surface-base: #f9fafb;
75
+ --color-surface-elevated: #ffffff;
76
+ --color-surface-hover: #f3f4f6;
77
+ --color-background: #ffffff;
78
+
79
+ --color-border: rgba(0, 0, 0, 0.06);
80
+ --color-border-hover: rgba(0, 0, 0, 0.12);
81
+
82
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
83
+ --shadow-md: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
84
+ --shadow-lg: 0 4px 8px 0 rgba(0, 0, 0, 0.12);
85
+ --shadow-xl: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
86
+ }
87
+
88
+ /* ============================================
89
+ DARK THEME
90
+ ============================================ */
91
+ [data-theme="dark"] {
92
+ --color-brand: #14b8a6;
93
+ --color-brand-hover: #0d9488;
94
+
95
+ --color-text-primary: #f9fafb;
96
+ --color-text-secondary: #d1d5db;
97
+ --color-text-tertiary: #9ca3af;
98
+ --color-text-inverse: #111827;
99
+
100
+ --color-surface-base: #1f2937;
101
+ --color-surface-elevated: #374151;
102
+ --color-surface-hover: #4b5563;
103
+ --color-background: #111827;
104
+
105
+ --color-border: rgba(255, 255, 255, 0.08);
106
+ --color-border-hover: rgba(255, 255, 255, 0.16);
107
+
108
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
109
+ --shadow-md: 0 2px 4px 0 rgba(0, 0, 0, 0.4);
110
+ --shadow-lg: 0 4px 8px 0 rgba(0, 0, 0, 0.5);
111
+ --shadow-xl: 0 8px 16px 0 rgba(0, 0, 0, 0.6);
112
+ }
113
+
114
+ /* ============================================
115
+ GLOBAL STYLES
116
+ ============================================ */
117
+ * {
118
+ margin: 0;
119
+ padding: 0;
120
+ box-sizing: border-box;
121
+ }
122
+
123
+ body {
124
+ font-family: var(--font-family-base);
125
+ font-size: var(--font-size-base);
126
+ line-height: var(--line-height-normal);
127
+ color: var(--color-text-primary);
128
+ background: var(--color-background);
129
+ transition: background-color var(--transition-base), color var(--transition-base);
130
+ }
131
+
132
+ /* ============================================
133
+ NOTION LAYOUT GRID
134
+ ============================================ */
135
+ #app {
136
+ display: grid;
137
+ grid-template-areas:
138
+ "header header"
139
+ "sidebar main"
140
+ "footer footer";
141
+ grid-template-columns: 250px 1fr;
142
+ grid-template-rows: auto 1fr auto;
143
+ min-height: 100vh;
144
+ }
145
+
146
+ /* ============================================
147
+ HEADER
148
+ ============================================ */
149
+ #appheader {
150
+ grid-area: header;
151
+ position: sticky;
152
+ top: 0;
153
+ z-index: 100;
154
+ background: var(--color-surface-elevated);
155
+ border-bottom: var(--border-width) solid var(--color-border);
156
+ display: flex;
157
+ align-items: center;
158
+ padding: var(--space-md) var(--space-lg);
159
+ gap: var(--space-lg);
160
+ transition: background-color var(--transition-base), border-color var(--transition-base);
161
+ }
162
+
163
+ #appheader-content {
164
+ display: flex;
165
+ align-items: center;
166
+ width: 100%;
167
+ gap: var(--space-lg);
168
+ }
169
+
170
+ #appheader-logo {
171
+ flex-shrink: 0;
172
+ }
173
+
174
+ #appheader-nav {
175
+ flex: 1;
176
+ display: flex;
177
+ gap: var(--space-md);
178
+ }
179
+
180
+ #appheader-actions {
181
+ flex-shrink: 0;
182
+ display: flex;
183
+ gap: var(--space-sm);
184
+ align-items: center;
185
+ }
186
+
187
+ /* Subheader - Hidden in notion layout */
188
+ #appsubheader,
189
+ #appsubheader-breadcrumbs,
190
+ #appsubheader-tabs,
191
+ #appsubheader-actions {
192
+ display: none;
193
+ }
194
+
195
+ /* ============================================
196
+ SIDEBAR
197
+ ============================================ */
198
+ #appsidebar {
199
+ grid-area: sidebar;
200
+ overflow-y: auto;
201
+ background: var(--color-surface-base);
202
+ border-right: var(--border-width) solid var(--color-border);
203
+ transition: transform var(--transition-base),
204
+ background-color var(--transition-base),
205
+ border-color var(--transition-base);
206
+ display: flex;
207
+ flex-direction: column;
208
+ }
209
+
210
+ #appsidebar-header {
211
+ padding: var(--space-md);
212
+ border-bottom: var(--border-width) solid var(--color-border);
213
+ flex-shrink: 0;
214
+ }
215
+
216
+ #appsidebar-content {
217
+ flex: 1;
218
+ overflow-y: auto;
219
+ padding: var(--space-sm);
220
+ }
221
+
222
+ #appsidebar-footer {
223
+ padding: var(--space-md);
224
+ border-top: var(--border-width) solid var(--color-border);
225
+ flex-shrink: 0;
226
+ }
227
+
228
+ /* ============================================
229
+ MAIN
230
+ ============================================ */
231
+ #appmain {
232
+ grid-area: main;
233
+ overflow-y: auto;
234
+ padding: var(--space-xl);
235
+ background: var(--color-background);
236
+ transition: background-color var(--transition-base);
237
+ }
238
+
239
+ #appmain-content {
240
+ max-width: 100%;
241
+ }
242
+
243
+ /* ============================================
244
+ ASIDE (Hidden in Notion layout)
245
+ ============================================ */
246
+ #appaside,
247
+ #appaside-header,
248
+ #appaside-content,
249
+ #appaside-footer {
250
+ display: none;
251
+ }
252
+
253
+ /* ============================================
254
+ FOOTER
255
+ ============================================ */
256
+ #appfooter {
257
+ grid-area: footer;
258
+ background: var(--color-surface-elevated);
259
+ border-top: var(--border-width) solid var(--color-border);
260
+ padding: var(--space-lg) var(--space-xl);
261
+ display: flex;
262
+ justify-content: space-between;
263
+ align-items: center;
264
+ transition: background-color var(--transition-base), border-color var(--transition-base);
265
+ }
266
+
267
+ #appfooter-content {
268
+ flex: 1;
269
+ }
270
+
271
+ #appfooter-legal {
272
+ flex-shrink: 0;
273
+ font-size: var(--font-size-sm);
274
+ color: var(--color-text-secondary);
275
+ }
276
+
277
+ /* ============================================
278
+ MODAL
279
+ ============================================ */
280
+ #appmodal {
281
+ position: fixed;
282
+ top: 0;
283
+ left: 0;
284
+ right: 0;
285
+ bottom: 0;
286
+ z-index: 2000;
287
+ display: none;
288
+ }
289
+
290
+ #appmodal[aria-hidden="false"] {
291
+ display: flex;
292
+ align-items: center;
293
+ justify-content: center;
294
+ }
295
+
296
+ #appmodal-backdrop {
297
+ position: absolute;
298
+ inset: 0;
299
+ background: rgba(0, 0, 0, 0.6);
300
+ backdrop-filter: blur(4px);
301
+ }
302
+
303
+ #appmodal-container {
304
+ position: relative;
305
+ background: var(--color-surface-elevated);
306
+ border-radius: var(--radius-lg);
307
+ box-shadow: var(--shadow-xl);
308
+ max-width: 90vw;
309
+ max-height: 90vh;
310
+ display: flex;
311
+ flex-direction: column;
312
+ overflow: hidden;
313
+ transition: background-color var(--transition-base);
314
+ }
315
+
316
+ #appmodal-header {
317
+ padding: var(--space-lg);
318
+ border-bottom: var(--border-width) solid var(--color-border);
319
+ flex-shrink: 0;
320
+ }
321
+
322
+ #appmodal-content {
323
+ flex: 1;
324
+ overflow-y: auto;
325
+ padding: var(--space-lg);
326
+ }
327
+
328
+ #appmodal-footer {
329
+ padding: var(--space-lg);
330
+ border-top: var(--border-width) solid var(--color-border);
331
+ flex-shrink: 0;
332
+ display: flex;
333
+ gap: var(--space-sm);
334
+ justify-content: flex-end;
335
+ }
336
+
337
+ /* ============================================
338
+ THEME TOGGLE - CLEAN & MINIMAL
339
+ ============================================ */
340
+
341
+ .jux-theme-toggle {
342
+ display: inline-flex;
343
+ align-items: center;
344
+ gap: var(--space-sm);
345
+ }
346
+
347
+ .jux-theme-toggle-button {
348
+ /* Remove all borders and backgrounds */
349
+ padding: var(--space-sm);
350
+ background: transparent;
351
+ border: none;
352
+ border-radius: var(--radius-md);
353
+ cursor: pointer;
354
+ font-size: 1.5rem; /* Bigger icons */
355
+ line-height: 1;
356
+ transition: all var(--transition-fast);
357
+ color: var(--color-text-secondary);
358
+
359
+ /* Smooth icon transition */
360
+ display: flex;
361
+ align-items: center;
362
+ justify-content: center;
363
+ width: 2.5rem;
364
+ height: 2.5rem;
365
+ }
366
+
367
+ .jux-theme-toggle-button:hover {
368
+ background: var(--color-surface-hover);
369
+ color: var(--color-text-primary);
370
+ transform: scale(1.05);
371
+ }
372
+
373
+ .jux-theme-toggle-button:active {
374
+ transform: scale(0.95);
375
+ }
376
+
377
+ /* Light mode icon styling */
378
+ [data-theme="light"] .jux-theme-toggle-button {
379
+ color: #f59e0b; /* Warm sun color */
380
+ }
381
+
382
+ [data-theme="light"] .jux-theme-toggle-button:hover {
383
+ color: #d97706;
384
+ }
385
+
386
+ /* Dark mode icon styling */
387
+ [data-theme="dark"] .jux-theme-toggle-button {
388
+ color: #fbbf24; /* Bright moon color */
389
+ }
390
+
391
+ [data-theme="dark"] .jux-theme-toggle-button:hover {
392
+ color: #fcd34d;
393
+ }
394
+
395
+ /* Dropdown variant (if needed) */
396
+ .jux-theme-toggle-select {
397
+ padding: var(--space-sm) var(--space-md);
398
+ background: transparent;
399
+ border: var(--border-width) solid var(--color-border);
400
+ border-radius: var(--radius-md);
401
+ cursor: pointer;
402
+ font-size: var(--font-size-base);
403
+ color: var(--color-text-primary);
404
+ transition: all var(--transition-fast);
405
+ }
406
+
407
+ .jux-theme-toggle-select:hover {
408
+ border-color: var(--color-border-hover);
409
+ background: var(--color-surface-hover);
410
+ }
411
+
412
+ .jux-theme-toggle-select:focus {
413
+ outline: none;
414
+ border-color: var(--color-brand);
415
+ }
416
+
417
+ /* ============================================
418
+ RESPONSIVE BREAKPOINTS
419
+ ============================================ */
420
+
421
+ /* Tablet (portrait) */
422
+ @media (max-width: 1024px) {
423
+ #app {
424
+ grid-template-columns: 200px 1fr;
425
+ }
426
+
427
+ #appmain {
428
+ padding: var(--space-lg);
429
+ }
430
+
431
+ #appheader {
432
+ padding: var(--space-sm) var(--space-md);
433
+ gap: var(--space-md);
434
+ }
435
+ }
436
+
437
+ /* Mobile */
438
+ @media (max-width: 768px) {
439
+ #app {
440
+ grid-template-areas:
441
+ "header"
442
+ "main"
443
+ "footer";
444
+ grid-template-columns: 1fr;
445
+ }
446
+
447
+ #appsidebar {
448
+ position: fixed;
449
+ top: 60px;
450
+ left: 0;
451
+ bottom: 0;
452
+ width: 280px;
453
+ max-width: 80vw;
454
+ z-index: 99;
455
+ transform: translateX(-100%);
456
+ box-shadow: var(--shadow-xl);
457
+ }
458
+
459
+ #appsidebar.visible {
460
+ transform: translateX(0);
461
+ }
462
+
463
+ #appmain {
464
+ padding: var(--space-md);
465
+ }
466
+
467
+ #appheader {
468
+ padding: var(--space-xs) var(--space-md);
469
+ }
470
+
471
+ #appfooter {
472
+ padding: var(--space-md) var(--space-lg);
473
+ flex-direction: column;
474
+ gap: var(--space-sm);
475
+ text-align: center;
476
+ }
477
+
478
+ .jux-theme-toggle-button {
479
+ width: 2.25rem;
480
+ height: 2.25rem;
481
+ font-size: 1.25rem;
482
+ }
483
+ }
484
+
485
+ /* Small mobile */
486
+ @media (max-width: 480px) {
487
+ #appsidebar {
488
+ width: 100%;
489
+ max-width: 100vw;
490
+ }
491
+
492
+ #appmain {
493
+ padding: var(--space-sm);
494
+ }
495
+
496
+ #appfooter {
497
+ padding: var(--space-sm) var(--space-md);
498
+ font-size: var(--font-size-sm);
499
+ }
500
+
501
+ #appmodal-container {
502
+ max-width: 95vw;
503
+ max-height: 95vh;
504
+ }
505
+ }
506
+
507
+ /* ============================================
508
+ SMOOTH TRANSITIONS
509
+ ============================================ */
510
+ body,
511
+ #app,
512
+ #appheader,
513
+ #appsidebar,
514
+ #appmain,
515
+ #appfooter,
516
+ #appmodal-container,
517
+ .jux-theme-toggle-button {
518
+ transition: background-color var(--transition-base),
519
+ border-color var(--transition-base),
520
+ color var(--transition-base);
521
+ }
@@ -0,0 +1,27 @@
1
+ // muse: notion layout preset
2
+ export function layout() {
3
+ /* styles */
4
+ jux.include('/examples/presets/notion.css');
5
+
6
+ /* regions */
7
+ jux.header('appheader').render("#app");
8
+ jux.header('appsubheader').render("#app");
9
+ jux.sidebar('appsidebar').render("#app");
10
+ jux.main('appmain').render("#app");
11
+ jux.sidebar('appaside').render("#app");
12
+ jux.footer('appfooter').render("#app");
13
+ jux.modal('appmodal').render("#app");
14
+
15
+ /* theme toggle in header */
16
+ jux.themeToggle('theme-toggle', {
17
+ themes: [
18
+ { id: 'light', label: 'Light', icon: '☀️' },
19
+ { id: 'dark', label: 'Dark', icon: '🌙' }
20
+ ],
21
+ variant: 'button',
22
+ showLabel: false
23
+ }).render('#appheader');
24
+ }
25
+
26
+ // Auto-run on import
27
+ layout();