juxscript 1.1.4 → 1.1.6

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 (205) hide show
  1. package/index.d.ts +10 -10
  2. package/index.d.ts.map +1 -0
  3. package/lib/components/alert.d.ts +32 -0
  4. package/lib/components/alert.d.ts.map +1 -0
  5. package/lib/components/alert.js +153 -0
  6. package/lib/components/alert.ts +200 -0
  7. package/lib/components/app.d.ts +89 -0
  8. package/lib/components/app.d.ts.map +1 -0
  9. package/lib/components/app.js +175 -0
  10. package/lib/components/app.ts +247 -0
  11. package/lib/components/badge.d.ts +27 -0
  12. package/lib/components/badge.d.ts.map +1 -0
  13. package/lib/components/badge.js +70 -0
  14. package/lib/components/badge.ts +101 -0
  15. package/lib/components/base/BaseComponent.d.ts +142 -0
  16. package/lib/components/base/BaseComponent.d.ts.map +1 -0
  17. package/lib/components/base/BaseComponent.js +363 -0
  18. package/lib/components/base/BaseComponent.ts +421 -0
  19. package/lib/components/base/FormInput.d.ts +73 -0
  20. package/lib/components/base/FormInput.d.ts.map +1 -0
  21. package/lib/components/base/FormInput.js +163 -0
  22. package/lib/components/base/FormInput.ts +227 -0
  23. package/lib/components/button.d.ts +48 -0
  24. package/lib/components/button.d.ts.map +1 -0
  25. package/lib/components/button.js +121 -0
  26. package/lib/components/button.ts +178 -0
  27. package/lib/components/card.d.ts +34 -0
  28. package/lib/components/card.d.ts.map +1 -0
  29. package/lib/components/card.js +127 -0
  30. package/lib/components/card.ts +173 -0
  31. package/lib/components/chart.d.ts +45 -0
  32. package/lib/components/chart.d.ts.map +1 -0
  33. package/lib/components/chart.js +186 -0
  34. package/lib/components/chart.ts +231 -0
  35. package/lib/components/checkbox.d.ts +31 -0
  36. package/lib/components/checkbox.d.ts.map +1 -0
  37. package/lib/components/checkbox.js +185 -0
  38. package/lib/components/checkbox.ts +242 -0
  39. package/lib/components/code.d.ts +24 -0
  40. package/lib/components/code.d.ts.map +1 -0
  41. package/lib/components/code.js +88 -0
  42. package/lib/components/code.ts +123 -0
  43. package/lib/components/container.d.ts +42 -0
  44. package/lib/components/container.d.ts.map +1 -0
  45. package/lib/components/container.js +93 -0
  46. package/lib/components/container.ts +140 -0
  47. package/lib/components/data.d.ts +36 -0
  48. package/lib/components/data.d.ts.map +1 -0
  49. package/lib/components/data.js +110 -0
  50. package/lib/components/data.ts +135 -0
  51. package/lib/components/datepicker.d.ts +38 -0
  52. package/lib/components/datepicker.d.ts.map +1 -0
  53. package/lib/components/datepicker.js +177 -0
  54. package/lib/components/datepicker.ts +234 -0
  55. package/lib/components/dialog.d.ts +38 -0
  56. package/lib/components/dialog.d.ts.map +1 -0
  57. package/lib/components/dialog.js +126 -0
  58. package/lib/components/dialog.ts +172 -0
  59. package/lib/components/divider.d.ts +30 -0
  60. package/lib/components/divider.d.ts.map +1 -0
  61. package/lib/components/divider.js +69 -0
  62. package/lib/components/divider.ts +100 -0
  63. package/lib/components/dropdown.d.ts +39 -0
  64. package/lib/components/dropdown.d.ts.map +1 -0
  65. package/lib/components/dropdown.js +133 -0
  66. package/lib/components/dropdown.ts +186 -0
  67. package/lib/components/element.d.ts +50 -0
  68. package/lib/components/element.d.ts.map +1 -0
  69. package/lib/components/element.js +206 -0
  70. package/lib/components/element.ts +267 -0
  71. package/lib/components/fileupload.d.ts +40 -0
  72. package/lib/components/fileupload.d.ts.map +1 -0
  73. package/lib/components/fileupload.js +241 -0
  74. package/lib/components/fileupload.ts +309 -0
  75. package/lib/components/grid.d.ts +87 -0
  76. package/lib/components/grid.d.ts.map +1 -0
  77. package/lib/components/grid.js +205 -0
  78. package/lib/components/grid.ts +291 -0
  79. package/lib/components/guard.d.ts +41 -0
  80. package/lib/components/guard.d.ts.map +1 -0
  81. package/lib/components/guard.js +56 -0
  82. package/lib/components/guard.ts +92 -0
  83. package/lib/components/heading.d.ts +24 -0
  84. package/lib/components/heading.d.ts.map +1 -0
  85. package/lib/components/heading.js +67 -0
  86. package/lib/components/heading.ts +96 -0
  87. package/lib/components/helpers.d.ts +9 -0
  88. package/lib/components/helpers.d.ts.map +1 -0
  89. package/lib/components/helpers.js +30 -0
  90. package/lib/components/helpers.ts +41 -0
  91. package/lib/components/hero.d.ts +45 -0
  92. package/lib/components/hero.d.ts.map +1 -0
  93. package/lib/components/hero.js +165 -0
  94. package/lib/components/hero.ts +224 -0
  95. package/lib/components/icon.d.ts +35 -0
  96. package/lib/components/icon.d.ts.map +1 -0
  97. package/lib/components/icon.js +132 -0
  98. package/lib/components/icon.ts +178 -0
  99. package/lib/components/icons.d.ts +25 -0
  100. package/lib/components/icons.d.ts.map +1 -0
  101. package/lib/components/icons.js +440 -0
  102. package/lib/components/icons.ts +464 -0
  103. package/lib/components/include.d.ts +120 -0
  104. package/lib/components/include.d.ts.map +1 -0
  105. package/lib/components/include.js +350 -0
  106. package/lib/components/include.ts +410 -0
  107. package/lib/components/input.d.ts +83 -0
  108. package/lib/components/input.d.ts.map +1 -0
  109. package/lib/components/input.js +348 -0
  110. package/lib/components/input.ts +457 -0
  111. package/lib/components/list.d.ts +82 -0
  112. package/lib/components/list.d.ts.map +1 -0
  113. package/lib/components/list.js +311 -0
  114. package/lib/components/list.ts +419 -0
  115. package/lib/components/loading.d.ts +24 -0
  116. package/lib/components/loading.d.ts.map +1 -0
  117. package/lib/components/loading.js +73 -0
  118. package/lib/components/loading.ts +100 -0
  119. package/lib/components/menu.d.ts +37 -0
  120. package/lib/components/menu.d.ts.map +1 -0
  121. package/lib/components/menu.js +202 -0
  122. package/lib/components/menu.ts +275 -0
  123. package/lib/components/modal.d.ts +51 -0
  124. package/lib/components/modal.d.ts.map +1 -0
  125. package/lib/components/modal.js +227 -0
  126. package/lib/components/modal.ts +284 -0
  127. package/lib/components/nav.d.ts +45 -0
  128. package/lib/components/nav.d.ts.map +1 -0
  129. package/lib/components/nav.js +190 -0
  130. package/lib/components/nav.ts +257 -0
  131. package/lib/components/paragraph.d.ts +21 -0
  132. package/lib/components/paragraph.d.ts.map +1 -0
  133. package/lib/components/paragraph.js +70 -0
  134. package/lib/components/paragraph.ts +97 -0
  135. package/lib/components/progress.d.ts +39 -0
  136. package/lib/components/progress.d.ts.map +1 -0
  137. package/lib/components/progress.js +113 -0
  138. package/lib/components/progress.ts +159 -0
  139. package/lib/components/radio.d.ts +41 -0
  140. package/lib/components/radio.d.ts.map +1 -0
  141. package/lib/components/radio.js +203 -0
  142. package/lib/components/radio.ts +278 -0
  143. package/lib/components/req.d.ts +155 -0
  144. package/lib/components/req.d.ts.map +1 -0
  145. package/lib/components/req.js +253 -0
  146. package/lib/components/req.ts +303 -0
  147. package/lib/components/script.d.ts +14 -0
  148. package/lib/components/script.d.ts.map +1 -0
  149. package/lib/components/script.js +33 -0
  150. package/lib/components/script.ts +41 -0
  151. package/lib/components/select.d.ts +40 -0
  152. package/lib/components/select.d.ts.map +1 -0
  153. package/lib/components/select.js +183 -0
  154. package/lib/components/select.ts +252 -0
  155. package/lib/components/sidebar.d.ts +48 -0
  156. package/lib/components/sidebar.d.ts.map +1 -0
  157. package/lib/components/sidebar.js +207 -0
  158. package/lib/components/sidebar.ts +275 -0
  159. package/lib/components/style.d.ts +14 -0
  160. package/lib/components/style.d.ts.map +1 -0
  161. package/lib/components/style.js +33 -0
  162. package/lib/components/style.ts +41 -0
  163. package/lib/components/switch.d.ts +32 -0
  164. package/lib/components/switch.d.ts.map +1 -0
  165. package/lib/components/switch.js +186 -0
  166. package/lib/components/switch.ts +246 -0
  167. package/lib/components/table.d.ts +137 -0
  168. package/lib/components/table.d.ts.map +1 -0
  169. package/lib/components/table.js +1045 -0
  170. package/lib/components/table.ts +1249 -0
  171. package/lib/components/tabs.d.ts +36 -0
  172. package/lib/components/tabs.d.ts.map +1 -0
  173. package/lib/components/tabs.js +198 -0
  174. package/lib/components/tabs.ts +250 -0
  175. package/lib/components/theme-toggle.d.ts +44 -0
  176. package/lib/components/theme-toggle.d.ts.map +1 -0
  177. package/lib/components/theme-toggle.js +215 -0
  178. package/lib/components/theme-toggle.ts +293 -0
  179. package/lib/components/tooltip.d.ts +30 -0
  180. package/lib/components/tooltip.d.ts.map +1 -0
  181. package/lib/components/tooltip.js +109 -0
  182. package/lib/components/tooltip.ts +144 -0
  183. package/lib/components/view.d.ts +48 -0
  184. package/lib/components/view.d.ts.map +1 -0
  185. package/lib/components/view.js +149 -0
  186. package/lib/components/view.ts +190 -0
  187. package/lib/components/write.d.ts +107 -0
  188. package/lib/components/write.d.ts.map +1 -0
  189. package/lib/components/write.js +222 -0
  190. package/lib/components/write.ts +272 -0
  191. package/lib/layouts/default.css +260 -0
  192. package/lib/layouts/figma.css +334 -0
  193. package/lib/reactivity/state.d.ts +36 -0
  194. package/lib/reactivity/state.d.ts.map +1 -0
  195. package/lib/reactivity/state.js +67 -0
  196. package/lib/reactivity/state.ts +78 -0
  197. package/lib/utils/fetch.d.ts +176 -0
  198. package/lib/utils/fetch.d.ts.map +1 -0
  199. package/lib/utils/fetch.js +427 -0
  200. package/lib/utils/fetch.ts +553 -0
  201. package/machinery/compiler3.js +78 -0
  202. package/machinery/doc-generator.js +136 -0
  203. package/machinery/imports.js +155 -0
  204. package/machinery/ts-shim.js +46 -0
  205. package/package.json +9 -15
@@ -0,0 +1,202 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ import { renderIcon } from './icons.js';
3
+ import { req } from './req.js';
4
+ // Event definitions
5
+ const TRIGGER_EVENTS = [];
6
+ const CALLBACK_EVENTS = ['itemClick']; // ✅ Fire when menu item is clicked
7
+ export class Menu extends BaseComponent {
8
+ constructor(id, options = {}) {
9
+ super(id, {
10
+ items: options.items ?? [],
11
+ orientation: options.orientation ?? 'vertical',
12
+ style: options.style ?? '',
13
+ class: options.class ?? ''
14
+ });
15
+ this._setActiveStates();
16
+ }
17
+ getTriggerEvents() {
18
+ return TRIGGER_EVENTS;
19
+ }
20
+ getCallbackEvents() {
21
+ return CALLBACK_EVENTS;
22
+ }
23
+ _setActiveStates() {
24
+ this.state.items = this.state.items.map(item => ({
25
+ ...item,
26
+ active: item.href ? req.isActiveNavItem(item.href) : false,
27
+ items: item.items?.map(subItem => ({
28
+ ...subItem,
29
+ active: subItem.href ? req.isActiveNavItem(subItem.href) : false
30
+ }))
31
+ }));
32
+ }
33
+ /* ═════════════════════════════════════════════════════════════════
34
+ * FLUENT API
35
+ * ═════════════════════════════════════════════════════════════════ */
36
+ // ✅ Inherited from BaseComponent
37
+ items(value) {
38
+ this.state.items = value;
39
+ this._setActiveStates();
40
+ return this;
41
+ }
42
+ addItem(item) {
43
+ this.state.items = [...this.state.items, item];
44
+ this._setActiveStates();
45
+ return this;
46
+ }
47
+ itemClass(className) {
48
+ this.state.items = this.state.items.map(item => ({
49
+ ...item,
50
+ itemClass: className,
51
+ items: item.items?.map(subItem => ({
52
+ ...subItem,
53
+ itemClass: className
54
+ }))
55
+ }));
56
+ return this;
57
+ }
58
+ orientation(value) {
59
+ this.state.orientation = value;
60
+ return this;
61
+ }
62
+ /* ═════════════════════════════════════════════════════════════════
63
+ * HELPERS
64
+ * ═════════════════════════════════════════════════════════════════ */
65
+ _renderMenuItem(item) {
66
+ const menuItem = document.createElement('div');
67
+ menuItem.className = 'jux-menu-item';
68
+ if (item.itemClass) {
69
+ menuItem.className += ` ${item.itemClass}`;
70
+ }
71
+ if (item.active) {
72
+ menuItem.classList.add('jux-menu-item-active');
73
+ }
74
+ if (item.href) {
75
+ const link = document.createElement('a');
76
+ link.className = 'jux-menu-link';
77
+ link.href = item.href;
78
+ if (item.active) {
79
+ link.classList.add('jux-menu-link-active');
80
+ }
81
+ if (item.icon) {
82
+ const icon = document.createElement('span');
83
+ icon.className = 'jux-menu-icon';
84
+ icon.appendChild(renderIcon(item.icon));
85
+ link.appendChild(icon);
86
+ }
87
+ const label = document.createElement('span');
88
+ label.className = 'jux-menu-label';
89
+ label.textContent = item.label;
90
+ link.appendChild(label);
91
+ // ✅ Fire itemClick callback when link is clicked
92
+ link.addEventListener('click', (e) => {
93
+ this._triggerCallback('itemClick', { item, event: e });
94
+ });
95
+ menuItem.appendChild(link);
96
+ }
97
+ else {
98
+ const button = document.createElement('button');
99
+ button.className = 'jux-menu-button';
100
+ if (item.icon) {
101
+ const icon = document.createElement('span');
102
+ icon.className = 'jux-menu-icon';
103
+ icon.appendChild(renderIcon(item.icon));
104
+ button.appendChild(icon);
105
+ }
106
+ const label = document.createElement('span');
107
+ label.className = 'jux-menu-label';
108
+ label.textContent = item.label;
109
+ button.appendChild(label);
110
+ menuItem.appendChild(button);
111
+ // ✅ Fire both the item's click handler AND the callback event
112
+ button.addEventListener('click', (e) => {
113
+ if (item.click) {
114
+ item.click();
115
+ }
116
+ this._triggerCallback('itemClick', { item, event: e });
117
+ });
118
+ }
119
+ if (item.items && item.items.length > 0) {
120
+ // Mark item as having submenu
121
+ menuItem.classList.add('jux-menu-item-has-submenu');
122
+ const submenu = document.createElement('div');
123
+ submenu.className = 'jux-menu-submenu';
124
+ item.items.forEach(subItem => {
125
+ submenu.appendChild(this._renderMenuItem(subItem));
126
+ });
127
+ menuItem.appendChild(submenu);
128
+ // Add click handler to toggle submenu expansion
129
+ const clickTarget = menuItem.querySelector('a, button');
130
+ if (clickTarget) {
131
+ clickTarget.addEventListener('click', (e) => {
132
+ // Prevent default link behavior if it has submenus
133
+ if (!item.href) {
134
+ e.preventDefault();
135
+ }
136
+ menuItem.classList.toggle('jux-menu-item-expanded');
137
+ });
138
+ }
139
+ }
140
+ return menuItem;
141
+ }
142
+ /* ═════════════════════════════════════════════════════════════════
143
+ * RENDER
144
+ * ═════════════════════════════════════════════════════════════════ */
145
+ render(targetId) {
146
+ const container = this._setupContainer(targetId);
147
+ const { items, orientation, style, class: className } = this.state;
148
+ const menu = document.createElement('nav');
149
+ menu.className = `jux-menu jux-menu-${orientation}`;
150
+ menu.id = this._id;
151
+ if (className) {
152
+ menu.className += ` ${className}`;
153
+ }
154
+ if (style) {
155
+ menu.setAttribute('style', style);
156
+ }
157
+ items.forEach(item => {
158
+ menu.appendChild(this._renderMenuItem(item));
159
+ });
160
+ this._wireStandardEvents(menu);
161
+ // Wire sync bindings
162
+ this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
163
+ if (property === 'items') {
164
+ const transform = toComponent || ((v) => v);
165
+ stateObj.subscribe((val) => {
166
+ const transformed = transform(val);
167
+ this.state.items = transformed;
168
+ this._setActiveStates();
169
+ const existingItems = menu.querySelectorAll('.jux-menu-item');
170
+ existingItems.forEach(item => item.remove());
171
+ this.state.items.forEach(item => {
172
+ menu.appendChild(this._renderMenuItem(item));
173
+ });
174
+ requestAnimationFrame(() => {
175
+ if (window.lucide) {
176
+ window.lucide.createIcons();
177
+ }
178
+ });
179
+ });
180
+ }
181
+ else if (property === 'orientation') {
182
+ const transform = toComponent || ((v) => String(v));
183
+ stateObj.subscribe((val) => {
184
+ const transformed = transform(val);
185
+ menu.classList.remove(`jux-menu-${this.state.orientation}`);
186
+ this.state.orientation = transformed;
187
+ menu.classList.add(`jux-menu-${transformed}`);
188
+ });
189
+ }
190
+ });
191
+ container.appendChild(menu);
192
+ requestAnimationFrame(() => {
193
+ if (window.lucide) {
194
+ window.lucide.createIcons();
195
+ }
196
+ });
197
+ return this;
198
+ }
199
+ }
200
+ export function menu(id, options = {}) {
201
+ return new Menu(id, options);
202
+ }
@@ -0,0 +1,275 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ import { renderIcon } from './icons.js';
3
+ import { req } from './req.js';
4
+
5
+ // Event definitions
6
+ const TRIGGER_EVENTS = [] as const;
7
+ const CALLBACK_EVENTS = ['itemClick'] as const; // ✅ Fire when menu item is clicked
8
+
9
+ export interface MenuItem {
10
+ label: string;
11
+ href?: string;
12
+ click?: () => void;
13
+ icon?: string;
14
+ items?: MenuItem[];
15
+ active?: boolean;
16
+ itemClass?: string;
17
+ }
18
+
19
+ export interface MenuOptions {
20
+ items?: MenuItem[];
21
+ orientation?: 'vertical' | 'horizontal';
22
+ style?: string;
23
+ class?: string;
24
+ }
25
+
26
+ type MenuState = {
27
+ items: MenuItem[];
28
+ orientation: string;
29
+ style: string;
30
+ class: string;
31
+ };
32
+
33
+ export class Menu extends BaseComponent<MenuState> {
34
+ constructor(id: string, options: MenuOptions = {}) {
35
+ super(id, {
36
+ items: options.items ?? [],
37
+ orientation: options.orientation ?? 'vertical',
38
+ style: options.style ?? '',
39
+ class: options.class ?? ''
40
+ });
41
+
42
+ this._setActiveStates();
43
+ }
44
+
45
+ protected getTriggerEvents(): readonly string[] {
46
+ return TRIGGER_EVENTS;
47
+ }
48
+
49
+ protected getCallbackEvents(): readonly string[] {
50
+ return CALLBACK_EVENTS;
51
+ }
52
+
53
+ private _setActiveStates(): void {
54
+ this.state.items = this.state.items.map(item => ({
55
+ ...item,
56
+ active: item.href ? req.isActiveNavItem(item.href) : false,
57
+ items: item.items?.map(subItem => ({
58
+ ...subItem,
59
+ active: subItem.href ? req.isActiveNavItem(subItem.href) : false
60
+ }))
61
+ }));
62
+ }
63
+
64
+ /* ═════════════════════════════════════════════════════════════════
65
+ * FLUENT API
66
+ * ═════════════════════════════════════════════════════════════════ */
67
+
68
+ // ✅ Inherited from BaseComponent
69
+
70
+ items(value: MenuItem[]): this {
71
+ this.state.items = value;
72
+ this._setActiveStates();
73
+ return this;
74
+ }
75
+
76
+ addItem(item: MenuItem): this {
77
+ this.state.items = [...this.state.items, item];
78
+ this._setActiveStates();
79
+ return this;
80
+ }
81
+
82
+ itemClass(className: string): this {
83
+ this.state.items = this.state.items.map(item => ({
84
+ ...item,
85
+ itemClass: className,
86
+ items: item.items?.map(subItem => ({
87
+ ...subItem,
88
+ itemClass: className
89
+ }))
90
+ }));
91
+ return this;
92
+ }
93
+
94
+ orientation(value: 'vertical' | 'horizontal'): this {
95
+ this.state.orientation = value;
96
+ return this;
97
+ }
98
+
99
+ /* ═════════════════════════════════════════════════════════════════
100
+ * HELPERS
101
+ * ═════════════════════════════════════════════════════════════════ */
102
+
103
+ private _renderMenuItem(item: MenuItem): HTMLElement {
104
+ const menuItem = document.createElement('div');
105
+ menuItem.className = 'jux-menu-item';
106
+
107
+ if (item.itemClass) {
108
+ menuItem.className += ` ${item.itemClass}`;
109
+ }
110
+
111
+ if (item.active) {
112
+ menuItem.classList.add('jux-menu-item-active');
113
+ }
114
+
115
+ if (item.href) {
116
+ const link = document.createElement('a');
117
+ link.className = 'jux-menu-link';
118
+ link.href = item.href;
119
+
120
+ if (item.active) {
121
+ link.classList.add('jux-menu-link-active');
122
+ }
123
+
124
+ if (item.icon) {
125
+ const icon = document.createElement('span');
126
+ icon.className = 'jux-menu-icon';
127
+ icon.appendChild(renderIcon(item.icon));
128
+ link.appendChild(icon);
129
+ }
130
+
131
+ const label = document.createElement('span');
132
+ label.className = 'jux-menu-label';
133
+ label.textContent = item.label;
134
+ link.appendChild(label);
135
+
136
+ // ✅ Fire itemClick callback when link is clicked
137
+ link.addEventListener('click', (e) => {
138
+ this._triggerCallback('itemClick', { item, event: e });
139
+ });
140
+
141
+ menuItem.appendChild(link);
142
+ } else {
143
+ const button = document.createElement('button');
144
+ button.className = 'jux-menu-button';
145
+
146
+ if (item.icon) {
147
+ const icon = document.createElement('span');
148
+ icon.className = 'jux-menu-icon';
149
+ icon.appendChild(renderIcon(item.icon));
150
+ button.appendChild(icon);
151
+ }
152
+
153
+ const label = document.createElement('span');
154
+ label.className = 'jux-menu-label';
155
+ label.textContent = item.label;
156
+ button.appendChild(label);
157
+
158
+ menuItem.appendChild(button);
159
+
160
+ // ✅ Fire both the item's click handler AND the callback event
161
+ button.addEventListener('click', (e) => {
162
+ if (item.click) {
163
+ item.click();
164
+ }
165
+ this._triggerCallback('itemClick', { item, event: e });
166
+ });
167
+ }
168
+
169
+ if (item.items && item.items.length > 0) {
170
+ // Mark item as having submenu
171
+ menuItem.classList.add('jux-menu-item-has-submenu');
172
+
173
+ const submenu = document.createElement('div');
174
+ submenu.className = 'jux-menu-submenu';
175
+
176
+ item.items.forEach(subItem => {
177
+ submenu.appendChild(this._renderMenuItem(subItem));
178
+ });
179
+
180
+ menuItem.appendChild(submenu);
181
+
182
+ // Add click handler to toggle submenu expansion
183
+ const clickTarget = menuItem.querySelector('a, button');
184
+ if (clickTarget) {
185
+ clickTarget.addEventListener('click', (e) => {
186
+ // Prevent default link behavior if it has submenus
187
+ if (!item.href) {
188
+ e.preventDefault();
189
+ }
190
+ menuItem.classList.toggle('jux-menu-item-expanded');
191
+ });
192
+ }
193
+ }
194
+
195
+ return menuItem;
196
+ }
197
+
198
+ /* ═════════════════════════════════════════════════════════════════
199
+ * RENDER
200
+ * ═════════════════════════════════════════════════════════════════ */
201
+
202
+ render(targetId?: string): this {
203
+ const container = this._setupContainer(targetId);
204
+
205
+ const { items, orientation, style, class: className } = this.state;
206
+
207
+ const menu = document.createElement('nav');
208
+ menu.className = `jux-menu jux-menu-${orientation}`;
209
+ menu.id = this._id;
210
+
211
+ if (className) {
212
+ menu.className += ` ${className}`;
213
+ }
214
+
215
+ if (style) {
216
+ menu.setAttribute('style', style);
217
+ }
218
+
219
+ items.forEach(item => {
220
+ menu.appendChild(this._renderMenuItem(item));
221
+ });
222
+
223
+ this._wireStandardEvents(menu);
224
+
225
+ // Wire sync bindings
226
+ this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
227
+ if (property === 'items') {
228
+ const transform = toComponent || ((v: any) => v);
229
+
230
+ stateObj.subscribe((val: any) => {
231
+ const transformed = transform(val);
232
+ this.state.items = transformed;
233
+ this._setActiveStates();
234
+
235
+ const existingItems = menu.querySelectorAll('.jux-menu-item');
236
+ existingItems.forEach(item => item.remove());
237
+
238
+ this.state.items.forEach(item => {
239
+ menu.appendChild(this._renderMenuItem(item));
240
+ });
241
+
242
+ requestAnimationFrame(() => {
243
+ if ((window as any).lucide) {
244
+ (window as any).lucide.createIcons();
245
+ }
246
+ });
247
+ });
248
+ }
249
+ else if (property === 'orientation') {
250
+ const transform = toComponent || ((v: any) => String(v));
251
+
252
+ stateObj.subscribe((val: any) => {
253
+ const transformed = transform(val);
254
+ menu.classList.remove(`jux-menu-${this.state.orientation}`);
255
+ this.state.orientation = transformed;
256
+ menu.classList.add(`jux-menu-${transformed}`);
257
+ });
258
+ }
259
+ });
260
+
261
+ container.appendChild(menu);
262
+
263
+ requestAnimationFrame(() => {
264
+ if ((window as any).lucide) {
265
+ (window as any).lucide.createIcons();
266
+ }
267
+ });
268
+
269
+ return this;
270
+ }
271
+ }
272
+
273
+ export function menu(id: string, options: MenuOptions = {}): Menu {
274
+ return new Menu(id, options);
275
+ }
@@ -0,0 +1,51 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ export interface ModalOptions {
3
+ title?: string;
4
+ content?: string;
5
+ showCloseButton?: boolean;
6
+ closeOnBackdropClick?: boolean;
7
+ size?: 'small' | 'medium' | 'large';
8
+ style?: string;
9
+ class?: string;
10
+ }
11
+ type ModalState = {
12
+ title: string;
13
+ content: string;
14
+ showCloseButton: boolean;
15
+ closeOnBackdropClick: boolean;
16
+ size: string;
17
+ open: boolean;
18
+ style: string;
19
+ class: string;
20
+ };
21
+ export declare class Modal extends BaseComponent<ModalState> {
22
+ private _overlay;
23
+ constructor(id: string, options?: ModalOptions);
24
+ protected getTriggerEvents(): readonly string[];
25
+ protected getCallbackEvents(): readonly string[];
26
+ title(value: string): this;
27
+ content(value: string): this;
28
+ showCloseButton(value: boolean): this;
29
+ closeOnBackdropClick(value: boolean): this;
30
+ size(value: 'small' | 'medium' | 'large'): this;
31
+ open(): this;
32
+ close(): this;
33
+ /**
34
+ * Get the modal body element ID for rendering child components
35
+ * @returns The ID of the modal body element (e.g., 'mymodal-body')
36
+ *
37
+ * Usage:
38
+ * const modal = jux.modal('files-modal', { title: 'Files' }).render('body').open();
39
+ * jux.table('files-table', {...}).render(modal.bodyId());
40
+ */
41
+ bodyId(): string;
42
+ /**
43
+ * Get the modal body element (only available after render)
44
+ * @returns The modal body element or null if not rendered
45
+ */
46
+ getBodyElement(): HTMLElement | null;
47
+ render(targetId?: string): this;
48
+ }
49
+ export declare function modal(id: string, options?: ModalOptions): Modal;
50
+ export {};
51
+ //# sourceMappingURL=modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAMxD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,KAAM,SAAQ,aAAa,CAAC,UAAU,CAAC;IAClD,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IAalD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAehD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAY1B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAW5B,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKrC,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK1C,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI;IAW/C,IAAI,IAAI,IAAI;IAUZ,KAAK,IAAI,IAAI;IAUb;;;;;;;OAOG;IACH,MAAM,IAAI,MAAM;IAIhB;;;OAGG;IACH,cAAc,IAAI,WAAW,GAAG,IAAI;IAQpC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;CAiIhC;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAEnE"}