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,303 @@
1
+ /**
2
+ * Request information and utilities
3
+ * Provides access to URL, query params, path, referrer, etc.
4
+ */
5
+
6
+ export interface RequestInfo {
7
+ url: string;
8
+ path: string;
9
+ query: Record<string, string>;
10
+ params: Record<string, string>;
11
+ hash: string;
12
+ referrer: string;
13
+ method: string;
14
+ headers: Record<string, string>;
15
+ }
16
+
17
+ export class Req {
18
+ private static _instance: Req | null = null;
19
+ private _info: RequestInfo;
20
+
21
+ private constructor() {
22
+ this._info = this._parseRequest();
23
+ }
24
+
25
+ /**
26
+ * Singleton instance
27
+ */
28
+ static get instance(): Req {
29
+ if (!Req._instance) {
30
+ Req._instance = new Req();
31
+ }
32
+ return Req._instance;
33
+ }
34
+
35
+ /**
36
+ * Parse current request information
37
+ */
38
+ private _parseRequest(): RequestInfo {
39
+ const url = new URL(window.location.href);
40
+
41
+ // Parse query string
42
+ const query: Record<string, string> = {};
43
+ url.searchParams.forEach((value, key) => {
44
+ query[key] = value;
45
+ });
46
+
47
+ // Parse path segments as params (basic routing)
48
+ const pathSegments = url.pathname.split('/').filter(s => s);
49
+ const params: Record<string, string> = {};
50
+ pathSegments.forEach((segment, index) => {
51
+ params[`${index}`] = segment;
52
+ });
53
+
54
+ return {
55
+ url: url.href,
56
+ path: url.pathname,
57
+ query,
58
+ params,
59
+ hash: url.hash.slice(1), // Remove leading #
60
+ referrer: document.referrer,
61
+ method: 'GET', // Browser requests are always GET initially
62
+ headers: {
63
+ 'user-agent': navigator.userAgent,
64
+ 'accept-language': navigator.language
65
+ }
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Get full URL
71
+ */
72
+ get url(): string {
73
+ return this._info.url;
74
+ }
75
+
76
+ /**
77
+ * Get current path (e.g., "/examples/sample/dashboards")
78
+ */
79
+ get path(): string {
80
+ // Always get fresh path from current URL
81
+ return window.location.pathname;
82
+ }
83
+
84
+ /**
85
+ * Get query string parameters
86
+ */
87
+ get query(): Record<string, string> {
88
+ return { ...this._info.query };
89
+ }
90
+
91
+ /**
92
+ * Get path parameters
93
+ */
94
+ get params(): Record<string, string> {
95
+ return { ...this._info.params };
96
+ }
97
+
98
+ /**
99
+ * Get URL hash (without #)
100
+ */
101
+ get hash(): string {
102
+ return this._info.hash;
103
+ }
104
+
105
+ /**
106
+ * Get referrer URL
107
+ */
108
+ get referrer(): string {
109
+ return this._info.referrer;
110
+ }
111
+
112
+ /**
113
+ * Get request method (always GET for browser)
114
+ */
115
+ get method(): string {
116
+ return this._info.method;
117
+ }
118
+
119
+ /**
120
+ * Get request headers
121
+ */
122
+ get headers(): Record<string, string> {
123
+ return { ...this._info.headers };
124
+ }
125
+
126
+ /**
127
+ * Check if current path matches a pattern
128
+ * @param pattern - Path pattern (supports wildcards)
129
+ *
130
+ * Examples:
131
+ * req.matches('/examples/sample/*')
132
+ * req.matches('/examples/sample/dashboards')
133
+ * req.matches('/examples/*\/dashboards')
134
+ */
135
+ matches(pattern: string): boolean {
136
+ const regexPattern = pattern
137
+ .replace(/\*/g, '.*')
138
+ .replace(/\//g, '\\/');
139
+ const regex = new RegExp(`^${regexPattern}$`);
140
+ return regex.test(this.path);
141
+ }
142
+
143
+ /**
144
+ * Check if current path starts with prefix
145
+ */
146
+ startsWith(prefix: string): boolean {
147
+ return this.path.startsWith(prefix);
148
+ }
149
+
150
+ /**
151
+ * Check if current path ends with suffix
152
+ */
153
+ endsWith(suffix: string): boolean {
154
+ return this.path.endsWith(suffix);
155
+ }
156
+
157
+ /**
158
+ * Get query parameter value
159
+ */
160
+ getQuery(key: string, defaultValue?: string): string | undefined {
161
+ return this.query[key] ?? defaultValue;
162
+ }
163
+
164
+ /**
165
+ * Get path parameter value
166
+ */
167
+ getParam(key: string, defaultValue?: string): string | undefined {
168
+ return this.params[key] ?? defaultValue;
169
+ }
170
+
171
+ /**
172
+ * Check if query parameter exists
173
+ */
174
+ hasQuery(key: string): boolean {
175
+ return key in this.query;
176
+ }
177
+
178
+ /**
179
+ * Get all query parameters as URLSearchParams
180
+ */
181
+ getSearchParams(): URLSearchParams {
182
+ return new URLSearchParams(this.query);
183
+ }
184
+
185
+ /**
186
+ * Refresh request info (call after navigation)
187
+ */
188
+ refresh(): void {
189
+ this._info = this._parseRequest();
190
+ }
191
+
192
+ /**
193
+ * Set active state on nav items based on current path
194
+ * @param items - Nav items to update
195
+ * @returns Updated nav items with active state set
196
+ */
197
+ setActiveNavItems(items: Array<{ href: string; active?: boolean }>): Array<{ href: string; active: boolean }> {
198
+ return items.map(item => ({
199
+ ...item,
200
+ active: this.isActiveNavItem(item.href)
201
+ }));
202
+ }
203
+
204
+ /**
205
+ * Check if a nav item should be active based on current path
206
+ * @param href - The nav item's href
207
+ */
208
+ isActiveNavItem(href: string): boolean {
209
+ // Exact match
210
+ if (href === this.path) {
211
+ return true;
212
+ }
213
+
214
+ // Starts with match (for parent routes)
215
+ // Must be followed by a path separator or end of string
216
+ // e.g., "/examples/sample" matches "/examples/sample/dashboards"
217
+ // but "/examples/sam" does NOT match "/examples/sample/dashboards"
218
+ if (href !== '/' && (this.path === href || this.path.startsWith(href + '/'))) {
219
+ return true;
220
+ }
221
+
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * Get breadcrumbs from current path
227
+ * @returns Array of breadcrumb objects with label and href
228
+ */
229
+ getBreadcrumbs(): Array<{ label: string; href: string }> {
230
+ const segments = this.path.split('/').filter(s => s);
231
+ const breadcrumbs: Array<{ label: string; href: string }> = [
232
+ { label: 'Home', href: '/' }
233
+ ];
234
+
235
+ let currentPath = '';
236
+ segments.forEach(segment => {
237
+ currentPath += `/${segment}`;
238
+ breadcrumbs.push({
239
+ label: this._formatBreadcrumbLabel(segment),
240
+ href: currentPath
241
+ });
242
+ });
243
+
244
+ return breadcrumbs;
245
+ }
246
+
247
+ /**
248
+ * Format segment into readable breadcrumb label
249
+ */
250
+ private _formatBreadcrumbLabel(segment: string): string {
251
+ return segment
252
+ .split('-')
253
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
254
+ .join(' ');
255
+ }
256
+
257
+ /**
258
+ * Check if this is the home/root path
259
+ */
260
+ get isHome(): boolean {
261
+ return this.path === '/' || this.path === '';
262
+ }
263
+
264
+ /**
265
+ * Get current domain
266
+ */
267
+ get domain(): string {
268
+ return window.location.hostname;
269
+ }
270
+
271
+ /**
272
+ * Get current port
273
+ */
274
+ get port(): string {
275
+ return window.location.port;
276
+ }
277
+
278
+ /**
279
+ * Get current protocol
280
+ */
281
+ get protocol(): string {
282
+ return window.location.protocol.replace(':', '');
283
+ }
284
+
285
+ /**
286
+ * Check if HTTPS
287
+ */
288
+ get isSecure(): boolean {
289
+ return this.protocol === 'https';
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Global request instance
295
+ */
296
+ export const req = Req.instance;
297
+
298
+ /**
299
+ * Factory function (returns singleton)
300
+ */
301
+ export function request(): Req {
302
+ return Req.instance;
303
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Script - Inject inline JavaScript into the document
3
+ * For external scripts, use Import component instead
4
+ * Auto-renders when created or modified
5
+ */
6
+ export declare class Script {
7
+ private _id;
8
+ private code;
9
+ constructor(code: string, id?: string);
10
+ render(): this;
11
+ remove(): void;
12
+ }
13
+ export declare function script(code: string, id?: string): Script;
14
+ //# sourceMappingURL=script.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script.d.ts","sourceRoot":"","sources":["script.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM;IAMrC,MAAM,IAAI,IAAI;IAcd,MAAM,IAAI,IAAI;CAMf;AAGD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Script - Inject inline JavaScript into the document
3
+ * For external scripts, use Import component instead
4
+ * Auto-renders when created or modified
5
+ */
6
+ export class Script {
7
+ constructor(code, id) {
8
+ // ID only for deduplication, auto-generate if not provided
9
+ this._id = id || `jux-script-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
10
+ this.code = code;
11
+ }
12
+ render() {
13
+ // Check if script with this ID already exists
14
+ if (document.getElementById(this._id)) {
15
+ return this;
16
+ }
17
+ const script = document.createElement('script');
18
+ script.id = this._id;
19
+ script.textContent = this.code;
20
+ document.head.appendChild(script);
21
+ return this;
22
+ }
23
+ remove() {
24
+ const existing = document.getElementById(this._id);
25
+ if (existing) {
26
+ existing.remove();
27
+ }
28
+ }
29
+ }
30
+ // ✅ ID is optional
31
+ export function script(code, id) {
32
+ return new Script(code, id);
33
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Script - Inject inline JavaScript into the document
3
+ * For external scripts, use Import component instead
4
+ * Auto-renders when created or modified
5
+ */
6
+ export class Script {
7
+ private _id: string;
8
+ private code: string;
9
+
10
+ constructor(code: string, id?: string) {
11
+ // ID only for deduplication, auto-generate if not provided
12
+ this._id = id || `jux-script-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
13
+ this.code = code;
14
+ }
15
+
16
+ render(): this {
17
+ // Check if script with this ID already exists
18
+ if (document.getElementById(this._id)) {
19
+ return this;
20
+ }
21
+
22
+ const script = document.createElement('script');
23
+ script.id = this._id;
24
+ script.textContent = this.code;
25
+ document.head.appendChild(script);
26
+
27
+ return this;
28
+ }
29
+
30
+ remove(): void {
31
+ const existing = document.getElementById(this._id);
32
+ if (existing) {
33
+ existing.remove();
34
+ }
35
+ }
36
+ }
37
+
38
+ // ✅ ID is optional
39
+ export function script(code: string, id?: string): Script {
40
+ return new Script(code, id);
41
+ }
@@ -0,0 +1,40 @@
1
+ import { FormInput, FormInputState } from './base/FormInput.js';
2
+ export interface SelectOption {
3
+ label: string;
4
+ value: string;
5
+ disabled?: boolean;
6
+ }
7
+ export interface SelectOptions {
8
+ options?: SelectOption[];
9
+ value?: string;
10
+ label?: string;
11
+ placeholder?: string;
12
+ required?: boolean;
13
+ disabled?: boolean;
14
+ name?: string;
15
+ style?: string;
16
+ class?: string;
17
+ onValidate?: (value: string) => boolean | string;
18
+ }
19
+ interface SelectState extends FormInputState {
20
+ options: SelectOption[];
21
+ value: string;
22
+ placeholder: string;
23
+ }
24
+ export declare class Select extends FormInput<SelectState> {
25
+ constructor(id: string, options?: SelectOptions);
26
+ protected getTriggerEvents(): readonly string[];
27
+ protected getCallbackEvents(): readonly string[];
28
+ options(value: SelectOption[]): this;
29
+ value(value: string): this;
30
+ placeholder(value: string): this;
31
+ addOption(option: SelectOption): this;
32
+ getValue(): string;
33
+ setValue(value: string): this;
34
+ protected _validateValue(value: string): boolean | string;
35
+ protected _buildInputElement(): HTMLElement;
36
+ render(targetId?: string): this;
37
+ }
38
+ export declare function select(id: string, options?: SelectOptions): Select;
39
+ export {};
40
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMhE,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC;CACpD;AAED,UAAU,WAAY,SAAQ,cAAc;IACxC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,MAAO,SAAQ,SAAS,CAAC,WAAW,CAAC;gBAClC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;IAmBnD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAehD,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI;IAKpC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhC,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IASrC,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAU7B,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM;IAsBzD,SAAS,CAAC,kBAAkB,IAAI,WAAW;IAqC3C,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;CAiFlC;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAEtE"}
@@ -0,0 +1,183 @@
1
+ import { FormInput } from './base/FormInput.js';
2
+ // Event definitions
3
+ const TRIGGER_EVENTS = [];
4
+ const CALLBACK_EVENTS = ['change'];
5
+ export class Select extends FormInput {
6
+ constructor(id, options = {}) {
7
+ super(id, {
8
+ options: options.options ?? [],
9
+ value: options.value ?? '',
10
+ placeholder: options.placeholder ?? 'Select an option',
11
+ label: options.label ?? '',
12
+ required: options.required ?? false,
13
+ disabled: options.disabled ?? false,
14
+ name: options.name ?? id,
15
+ style: options.style ?? '',
16
+ class: options.class ?? '',
17
+ errorMessage: undefined
18
+ });
19
+ if (options.onValidate) {
20
+ this._onValidate = options.onValidate;
21
+ }
22
+ }
23
+ getTriggerEvents() {
24
+ return TRIGGER_EVENTS;
25
+ }
26
+ getCallbackEvents() {
27
+ return CALLBACK_EVENTS;
28
+ }
29
+ /* ═════════════════════════════════════════════════════════════════
30
+ * FLUENT API
31
+ * ═════════════════════════════════════════════════════════════════ */
32
+ // ✅ Inherited from FormInput/BaseComponent:
33
+ // - label(), required(), name(), onValidate()
34
+ // - validate(), isValid()
35
+ // - style(), class()
36
+ // - bind(), sync(), renderTo()
37
+ // - disabled(), enable(), disable()
38
+ options(value) {
39
+ this.state.options = value;
40
+ return this;
41
+ }
42
+ value(value) {
43
+ return this.setValue(value);
44
+ }
45
+ placeholder(value) {
46
+ this.state.placeholder = value;
47
+ return this;
48
+ }
49
+ addOption(option) {
50
+ this.state.options = [...this.state.options, option];
51
+ return this;
52
+ }
53
+ /* ═════════════════════════════════════════════════════════════════
54
+ * FORM INPUT IMPLEMENTATION
55
+ * ═════════════════════════════════════════════════════════════════ */
56
+ getValue() {
57
+ return this.state.value;
58
+ }
59
+ setValue(value) {
60
+ this.state.value = value;
61
+ if (this._inputElement) {
62
+ this._inputElement.value = value;
63
+ }
64
+ return this;
65
+ }
66
+ _validateValue(value) {
67
+ const { required, options } = this.state;
68
+ if (required && !value) {
69
+ return 'Please select an option';
70
+ }
71
+ // Validate that value is one of the options
72
+ if (value && !options.some(opt => opt.value === value)) {
73
+ return 'Invalid option selected';
74
+ }
75
+ if (this._onValidate) {
76
+ const result = this._onValidate(value);
77
+ if (result !== true) {
78
+ return result || 'Invalid value';
79
+ }
80
+ }
81
+ return true;
82
+ }
83
+ _buildInputElement() {
84
+ const { options, value, placeholder, required, disabled, name } = this.state;
85
+ const select = document.createElement('select');
86
+ select.className = 'jux-input-element jux-select-element';
87
+ select.id = `${this._id}-input`;
88
+ select.name = name;
89
+ select.required = required;
90
+ select.disabled = disabled;
91
+ // Placeholder option
92
+ if (placeholder) {
93
+ const placeholderOption = document.createElement('option');
94
+ placeholderOption.value = '';
95
+ placeholderOption.textContent = placeholder;
96
+ placeholderOption.disabled = true;
97
+ placeholderOption.selected = !value;
98
+ select.appendChild(placeholderOption);
99
+ }
100
+ // Options
101
+ options.forEach(option => {
102
+ const optionEl = document.createElement('option');
103
+ optionEl.value = option.value;
104
+ optionEl.textContent = option.label;
105
+ optionEl.disabled = option.disabled || false;
106
+ optionEl.selected = option.value === value;
107
+ select.appendChild(optionEl);
108
+ });
109
+ return select;
110
+ }
111
+ /* ═════════════════════════════════════════════════════════════════
112
+ * RENDER
113
+ * ═════════════════════════════════════════════════════════════════ */
114
+ render(targetId) {
115
+ const container = this._setupContainer(targetId);
116
+ const { style, class: className } = this.state;
117
+ // Build wrapper
118
+ const wrapper = document.createElement('div');
119
+ wrapper.className = 'jux-input jux-select';
120
+ wrapper.id = this._id;
121
+ if (className)
122
+ wrapper.className += ` ${className}`;
123
+ if (style)
124
+ wrapper.setAttribute('style', style);
125
+ // Label
126
+ if (this.state.label) {
127
+ wrapper.appendChild(this._renderLabel());
128
+ }
129
+ // Select container
130
+ const selectContainer = document.createElement('div');
131
+ selectContainer.className = 'jux-input-container jux-select-container';
132
+ // Select element
133
+ const selectEl = this._buildInputElement();
134
+ this._inputElement = selectEl;
135
+ selectContainer.appendChild(selectEl);
136
+ wrapper.appendChild(selectContainer);
137
+ // Error element
138
+ wrapper.appendChild(this._renderError());
139
+ // Wire events
140
+ this._wireStandardEvents(wrapper);
141
+ this._wireFormSync(selectEl, 'change');
142
+ // Sync label changes
143
+ const labelSync = this._syncBindings.find(b => b.property === 'label');
144
+ if (labelSync) {
145
+ const transform = labelSync.toComponent || ((v) => String(v));
146
+ labelSync.stateObj.subscribe((val) => {
147
+ this.label(transform(val));
148
+ });
149
+ }
150
+ // Sync options changes
151
+ const optionsSync = this._syncBindings.find(b => b.property === 'options');
152
+ if (optionsSync) {
153
+ const transform = optionsSync.toComponent || ((v) => v);
154
+ optionsSync.stateObj.subscribe((val) => {
155
+ const transformed = transform(val);
156
+ this.state.options = transformed;
157
+ // Rebuild select options
158
+ selectEl.innerHTML = '';
159
+ if (this.state.placeholder) {
160
+ const placeholderOption = document.createElement('option');
161
+ placeholderOption.value = '';
162
+ placeholderOption.textContent = this.state.placeholder;
163
+ placeholderOption.disabled = true;
164
+ placeholderOption.selected = !this.state.value;
165
+ selectEl.appendChild(placeholderOption);
166
+ }
167
+ transformed.forEach((option) => {
168
+ const optionEl = document.createElement('option');
169
+ optionEl.value = option.value;
170
+ optionEl.textContent = option.label;
171
+ optionEl.disabled = option.disabled || false;
172
+ optionEl.selected = option.value === this.state.value;
173
+ selectEl.appendChild(optionEl);
174
+ });
175
+ });
176
+ }
177
+ container.appendChild(wrapper);
178
+ return this;
179
+ }
180
+ }
181
+ export function select(id, options = {}) {
182
+ return new Select(id, options);
183
+ }