juxscript 1.1.324 → 1.1.333

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.
@@ -0,0 +1,40 @@
1
+ interface MenuItem {
2
+ id: string;
3
+ label: string;
4
+ path: string;
5
+ icon?: string;
6
+ }
7
+ interface MenuOptions {
8
+ title?: string;
9
+ logo?: string;
10
+ footer?: string;
11
+ width?: string;
12
+ target?: string;
13
+ density?: 'dense' | 'normal' | 'inflated';
14
+ }
15
+ interface MenuApi {
16
+ id: string;
17
+ title: (val: string) => MenuApi;
18
+ logo: (val: string) => MenuApi;
19
+ footer: (val: string) => MenuApi;
20
+ width: (val: string) => MenuApi;
21
+ target: (val: string) => MenuApi;
22
+ density: (val: 'dense' | 'normal' | 'inflated') => MenuApi;
23
+ section: (label: string, items: (string | MenuItem)[]) => MenuApi;
24
+ items: (items: (string | MenuItem)[]) => MenuApi;
25
+ render: () => MenuApi;
26
+ addSection: (label: string, items: (string | MenuItem)[]) => MenuApi;
27
+ setTitle: (val: string) => MenuApi;
28
+ setFooter: (val: string) => MenuApi;
29
+ show: () => MenuApi;
30
+ hide: () => MenuApi;
31
+ toggle: () => MenuApi;
32
+ getElement: () => HTMLElement | null;
33
+ }
34
+ type SectionInput = string | {
35
+ label?: string;
36
+ items?: (string | MenuItem)[];
37
+ };
38
+ export declare function menu(id: string, sections?: SectionInput[], options?: MenuOptions): MenuApi;
39
+ export {};
40
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../../lib/components/blocks/menu.ts"],"names":[],"mappings":"AAEA,UAAU,QAAQ;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,UAAU,WAAW;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC7C;AAYD,UAAU,OAAO;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,KAAK,OAAO,CAAC;IAC3D,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,OAAO,CAAC;IAClE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,OAAO,CAAC;IACjD,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,OAAO,CAAC;IACrE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,IAAI,EAAE,MAAM,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;CACxC;AAED,KAAK,YAAY,GAAG,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAA;CAAE,CAAC;AAE/E,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CA4I1F"}
@@ -0,0 +1,136 @@
1
+ import { jux, pageState } from '../../index.js';
2
+ export function menu(id, sections, options) {
3
+ const opts = options || {};
4
+ let _title = opts.title || 'App';
5
+ let _logo = opts.logo || _title.charAt(0).toUpperCase();
6
+ let _footer = opts.footer || '';
7
+ let _width = opts.width || '260px';
8
+ let _target = opts.target;
9
+ let _density = opts.density || 'normal';
10
+ let _sectionCount = 0;
11
+ let _rendered = false;
12
+ let _footerRendered = false;
13
+ const DENSITY = {
14
+ dense: { headerPad: '10px', itemPad: '4px 10px', labelPad: '6px 10px 2px', footerPad: '8px 12px', gap: '0px', fontSize: '12px', iconSize: '13px' },
15
+ normal: { headerPad: '16px', itemPad: '8px 12px', labelPad: '8px 12px 4px', footerPad: '12px 16px', gap: '1px', fontSize: '13px', iconSize: '15px' },
16
+ inflated: { headerPad: '20px', itemPad: '12px 16px', labelPad: '12px 16px 6px', footerPad: '16px 20px', gap: '4px', fontSize: '14px', iconSize: '17px' }
17
+ };
18
+ function normalizeItem(item) {
19
+ if (typeof item === 'string') {
20
+ const path = item.startsWith('/') ? item : '/' + item;
21
+ const seg = path.split('/').filter(Boolean).pop() || 'Home';
22
+ return { id: id + '-' + seg.toLowerCase().replace(/[^a-z0-9]/g, '-'), label: seg.charAt(0).toUpperCase() + seg.slice(1), path: path };
23
+ }
24
+ return item;
25
+ }
26
+ function normalizeSections(input) {
27
+ if (!input || !Array.isArray(input) || input.length === 0)
28
+ return [];
29
+ const isFlat = input.every((i) => typeof i === 'string' || (typeof i === 'object' && !('items' in i)));
30
+ if (isFlat)
31
+ return [{ items: input.map(normalizeItem) }];
32
+ return input.map((s) => {
33
+ if (typeof s === 'string')
34
+ return { items: [normalizeItem(s)] };
35
+ return { label: s.label, items: (s.items || []).map(normalizeItem) };
36
+ });
37
+ }
38
+ function ensureShell() {
39
+ if (_rendered)
40
+ return;
41
+ _rendered = true;
42
+ injectStyles();
43
+ jux.div(id, { class: 'jux-sidebar jux-sidebar--' + _density, style: 'width:' + _width, target: _target });
44
+ jux.div(id + '-header', { class: 'jux-sidebar-header', target: id });
45
+ jux.div(id + '-logo', { class: 'jux-sidebar-logo', content: _logo, target: id + '-header' });
46
+ jux.span(id + '-title', { content: _title, target: id + '-header' });
47
+ }
48
+ function renderSection(section) {
49
+ ensureShell();
50
+ const i = _sectionCount++;
51
+ if (i > 0)
52
+ jux.div(id + '-divider-' + i, { class: 'jux-sidebar-divider', target: id });
53
+ if (section.label)
54
+ jux.div(id + '-label-' + i, { class: 'jux-sidebar-label', content: section.label, target: id });
55
+ jux.nav(id + '-nav-' + i, { target: id, items: section.items });
56
+ }
57
+ function renderFooter() {
58
+ if (_footerRendered || !_footer)
59
+ return;
60
+ _footerRendered = true;
61
+ jux.div(id + '-footer', { class: 'jux-sidebar-footer', content: _footer, target: id });
62
+ }
63
+ function injectStyles() {
64
+ jux.style('menu-styles', '\
65
+ body { margin: 0; }\
66
+ .jux-sidebar { display:flex; flex-direction:column; min-height:100vh; background:hsl(var(--card)); color:hsl(var(--card-foreground)); border-right:1px solid hsl(var(--border)); font-family:var(--font-sans,system-ui,sans-serif); }\
67
+ .jux-sidebar-header { display:flex; align-items:center; gap:8px; font-size:14px; font-weight:600; border-bottom:1px solid hsl(var(--border)); }\
68
+ .jux-sidebar-logo { width:20px; height:20px; border-radius:6px; background:hsl(var(--primary)); display:flex; align-items:center; justify-content:center; color:hsl(var(--primary-foreground)); font-size:11px; font-weight:700; }\
69
+ .jux-sidebar-label { font-size:11px; font-weight:500; color:hsl(var(--muted-foreground)); text-transform:uppercase; letter-spacing:0.05em; }\
70
+ .jux-sidebar-footer { margin-top:auto; border-top:1px solid hsl(var(--border)); font-size:11px; color:hsl(var(--muted-foreground)); }\
71
+ .jux-sidebar-divider { height:1px; background:hsl(var(--border)); margin:4px 8px; }\
72
+ .jux-nav-item { display:flex; align-items:center; border-radius:var(--radius,6px); font-weight:500; color:hsl(var(--foreground)); cursor:pointer; transition:background 0.15s; user-select:none; text-decoration:none; }\
73
+ .jux-nav-item:hover { background:hsl(var(--accent)); color:hsl(var(--accent-foreground)); }\
74
+ .jux-nav-item--active { background:hsl(var(--accent)); color:hsl(var(--accent-foreground)); font-weight:600; }\
75
+ .jux-nav-item-icon { text-align:center; flex-shrink:0; }\
76
+ \
77
+ .jux-sidebar--dense .jux-sidebar-header { padding:' + DENSITY.dense.headerPad + '; }\
78
+ .jux-sidebar--dense .jux-sidebar-label { padding:' + DENSITY.dense.labelPad + '; }\
79
+ .jux-sidebar--dense .jux-sidebar-footer { padding:' + DENSITY.dense.footerPad + '; }\
80
+ .jux-sidebar--dense .jux-nav-item { padding:' + DENSITY.dense.itemPad + '; margin:' + DENSITY.dense.gap + ' 0; font-size:' + DENSITY.dense.fontSize + '; gap:8px; }\
81
+ .jux-sidebar--dense .jux-nav-item-icon { width:16px; font-size:' + DENSITY.dense.iconSize + '; }\
82
+ \
83
+ .jux-sidebar--normal .jux-sidebar-header { padding:' + DENSITY.normal.headerPad + '; }\
84
+ .jux-sidebar--normal .jux-sidebar-label { padding:' + DENSITY.normal.labelPad + '; }\
85
+ .jux-sidebar--normal .jux-sidebar-footer { padding:' + DENSITY.normal.footerPad + '; }\
86
+ .jux-sidebar--normal .jux-nav-item { padding:' + DENSITY.normal.itemPad + '; margin:' + DENSITY.normal.gap + ' 0; font-size:' + DENSITY.normal.fontSize + '; gap:10px; }\
87
+ .jux-sidebar--normal .jux-nav-item-icon { width:18px; font-size:' + DENSITY.normal.iconSize + '; }\
88
+ \
89
+ .jux-sidebar--inflated .jux-sidebar-header { padding:' + DENSITY.inflated.headerPad + '; }\
90
+ .jux-sidebar--inflated .jux-sidebar-label { padding:' + DENSITY.inflated.labelPad + '; }\
91
+ .jux-sidebar--inflated .jux-sidebar-footer { padding:' + DENSITY.inflated.footerPad + '; }\
92
+ .jux-sidebar--inflated .jux-nav-item { padding:' + DENSITY.inflated.itemPad + '; margin:' + DENSITY.inflated.gap + ' 0; font-size:' + DENSITY.inflated.fontSize + '; gap:12px; }\
93
+ .jux-sidebar--inflated .jux-nav-item-icon { width:20px; font-size:' + DENSITY.inflated.iconSize + '; }\
94
+ ');
95
+ }
96
+ const api = {
97
+ id: id,
98
+ title: function (val) { _title = val; return api; },
99
+ logo: function (val) { _logo = val; return api; },
100
+ footer: function (val) {
101
+ _footer = val;
102
+ if (_rendered)
103
+ renderFooter();
104
+ return api;
105
+ },
106
+ width: function (val) { _width = val; return api; },
107
+ target: function (val) { _target = val; return api; },
108
+ density: function (val) { _density = val; return api; },
109
+ section: function (label, items) {
110
+ renderSection({ label: label, items: (items || []).map(normalizeItem) });
111
+ return api;
112
+ },
113
+ items: function (items) {
114
+ renderSection({ items: (items || []).map(normalizeItem) });
115
+ return api;
116
+ },
117
+ render: function () {
118
+ ensureShell();
119
+ renderFooter();
120
+ return api;
121
+ },
122
+ addSection: function (label, items) { return api.section(label, items); },
123
+ setTitle: function (val) { pageState[id + '-title'].content = val; return api; },
124
+ setFooter: function (val) { pageState[id + '-footer'].content = val; return api; },
125
+ show: function () { pageState[id].visible = true; return api; },
126
+ hide: function () { pageState[id].visible = false; return api; },
127
+ toggle: function () { pageState[id].visible = !pageState[id].visible; return api; },
128
+ getElement: function () { return document.getElementById(id); }
129
+ };
130
+ if (sections && Array.isArray(sections) && sections.length > 0) {
131
+ const normalized = normalizeSections(sections);
132
+ normalized.forEach(renderSection);
133
+ renderFooter();
134
+ }
135
+ return api;
136
+ }
@@ -17,6 +17,7 @@ import { button, btn } from "./components/button.js";
17
17
  import { link, a } from "./components/link.js";
18
18
  import { container } from "./components/container.js";
19
19
  import { grid } from "./components/grid.js";
20
+ import { menu } from "./components/blocks/menu.js";
20
21
  export declare const jux: {
21
22
  tag: typeof tag;
22
23
  div: typeof div;
@@ -63,6 +64,7 @@ export declare const jux: {
63
64
  a: typeof a;
64
65
  container: typeof container;
65
66
  grid: typeof grid;
67
+ menu: typeof menu;
66
68
  };
67
69
  export { pageState };
68
70
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC3I,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCf,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC3I,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAEnD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Cf,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
package/dist/lib/index.js CHANGED
@@ -17,6 +17,7 @@ import { button, btn } from "./components/button.js";
17
17
  import { link, a } from "./components/link.js";
18
18
  import { container } from "./components/container.js";
19
19
  import { grid } from "./components/grid.js";
20
+ import { menu } from "./components/blocks/menu.js";
20
21
  export const jux = {
21
22
  tag,
22
23
  div,
@@ -57,7 +58,8 @@ export const jux = {
57
58
  link,
58
59
  a,
59
60
  container,
60
- grid
61
+ grid,
62
+ menu
61
63
  };
62
64
  export { pageState };
63
65
  jux.watch = pageState.__watch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.324",
3
+ "version": "1.1.333",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "./dist/lib/index.js",