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,278 @@
1
+ import { FormInput, FormInputState } from './base/FormInput.js';
2
+
3
+ // Event definitions
4
+ const TRIGGER_EVENTS = [] as const;
5
+ const CALLBACK_EVENTS = ['change'] as const;
6
+
7
+ export interface RadioOption {
8
+ label: string;
9
+ value: string;
10
+ disabled?: boolean;
11
+ }
12
+
13
+ export interface RadioOptions {
14
+ options?: RadioOption[];
15
+ value?: string;
16
+ label?: string;
17
+ required?: boolean;
18
+ disabled?: boolean;
19
+ name?: string;
20
+ orientation?: 'vertical' | 'horizontal'; // ✅ Add orientation
21
+ style?: string;
22
+ class?: string;
23
+ onValidate?: (value: string) => boolean | string;
24
+ }
25
+
26
+ interface RadioState extends FormInputState {
27
+ options: RadioOption[];
28
+ value: string;
29
+ orientation: 'vertical' | 'horizontal'; // ✅ Add to state
30
+ }
31
+
32
+ export class Radio extends FormInput<RadioState> {
33
+ private _radioInputs: HTMLInputElement[] = [];
34
+
35
+ constructor(id: string, options: RadioOptions = {}) {
36
+ super(id, {
37
+ options: options.options ?? [],
38
+ value: options.value ?? '',
39
+ label: options.label ?? '',
40
+ required: options.required ?? false,
41
+ disabled: options.disabled ?? false,
42
+ name: options.name ?? id,
43
+ orientation: options.orientation ?? 'vertical', // ✅ Default to vertical
44
+ style: options.style ?? '',
45
+ class: options.class ?? '',
46
+ errorMessage: undefined
47
+ });
48
+
49
+ if (options.onValidate) {
50
+ this._onValidate = options.onValidate;
51
+ }
52
+ }
53
+
54
+ protected getTriggerEvents(): readonly string[] {
55
+ return TRIGGER_EVENTS;
56
+ }
57
+
58
+ protected getCallbackEvents(): readonly string[] {
59
+ return CALLBACK_EVENTS;
60
+ }
61
+
62
+ /* ═════════════════════════════════════════════════════════════════
63
+ * FLUENT API
64
+ * ═════════════════════════════════════════════════════════════════ */
65
+
66
+ // ✅ Inherited from FormInput/BaseComponent:
67
+ // - label(), required(), name(), onValidate()
68
+ // - validate(), isValid()
69
+ // - style(), class()
70
+ // - bind(), sync(), renderTo()
71
+ // - disabled(), enable(), disable()
72
+
73
+ options(value: RadioOption[]): this {
74
+ this.state.options = value;
75
+ return this;
76
+ }
77
+
78
+ value(value: string): this {
79
+ return this.setValue(value);
80
+ }
81
+
82
+ addOption(option: RadioOption): this {
83
+ this.state.options = [...this.state.options, option];
84
+ return this;
85
+ }
86
+
87
+ orientation(value: 'vertical' | 'horizontal'): this {
88
+ this.state.orientation = value;
89
+ return this;
90
+ }
91
+
92
+ /* ═════════════════════════════════════════════════════════════════
93
+ * FORM INPUT IMPLEMENTATION
94
+ * ═════════════════════════════════════════════════════════════════ */
95
+
96
+ getValue(): string {
97
+ return this.state.value;
98
+ }
99
+
100
+ setValue(value: string): this {
101
+ this.state.value = value;
102
+
103
+ // Update all radio inputs
104
+ this._radioInputs.forEach(input => {
105
+ input.checked = input.value === value;
106
+ });
107
+
108
+ return this;
109
+ }
110
+
111
+ protected _validateValue(value: string): boolean | string {
112
+ const { required, options } = this.state;
113
+
114
+ if (required && !value) {
115
+ return 'Please select an option';
116
+ }
117
+
118
+ // Validate that value is one of the options
119
+ if (value && !options.some(opt => opt.value === value)) {
120
+ return 'Invalid option selected';
121
+ }
122
+
123
+ if (this._onValidate) {
124
+ const result = this._onValidate(value);
125
+ if (result !== true) {
126
+ return result || 'Invalid value';
127
+ }
128
+ }
129
+
130
+ return true;
131
+ }
132
+
133
+ protected _buildInputElement(): HTMLElement {
134
+ // Radio uses a container, not a single input
135
+ const container = document.createElement('div');
136
+ container.className = 'jux-radio-options';
137
+ return container;
138
+ }
139
+
140
+ /* ═════════════════════════════════════════════════════════════════
141
+ * RENDER
142
+ * ═════════════════════════════════════════════════════════════════ */
143
+
144
+ render(targetId?: string): this {
145
+ const container = this._setupContainer(targetId);
146
+
147
+ const { options, value, name, disabled, orientation, style, class: className } = this.state; // ✅ Destructure orientation
148
+
149
+ // Build wrapper
150
+ const wrapper = document.createElement('div');
151
+ wrapper.className = 'jux-radio';
152
+ wrapper.id = this._id;
153
+ if (className) wrapper.className += ` ${className}`;
154
+ if (style) wrapper.setAttribute('style', style);
155
+
156
+ // Label
157
+ if (this.state.label) {
158
+ wrapper.appendChild(this._renderLabel());
159
+ }
160
+
161
+ // Radio options container
162
+ const optionsContainer = document.createElement('div');
163
+ optionsContainer.className = `jux-radio-options jux-radio-${orientation}`; // ✅ Add orientation class
164
+ this._inputElement = optionsContainer;
165
+
166
+ this._radioInputs = [];
167
+
168
+ options.forEach((option, index) => {
169
+ const radioWrapper = document.createElement('label');
170
+ radioWrapper.className = 'jux-radio-option';
171
+
172
+ const input = document.createElement('input');
173
+ input.type = 'radio';
174
+ input.className = 'jux-radio-input';
175
+ input.id = `${this._id}-option-${index}`;
176
+ input.name = name;
177
+ input.value = option.value;
178
+ input.checked = option.value === value;
179
+ input.disabled = disabled || option.disabled || false;
180
+
181
+ this._radioInputs.push(input);
182
+
183
+ const radioMark = document.createElement('span');
184
+ radioMark.className = 'jux-radio-mark';
185
+
186
+ const labelText = document.createElement('span');
187
+ labelText.className = 'jux-radio-label-text';
188
+ labelText.textContent = option.label;
189
+
190
+ radioWrapper.appendChild(input);
191
+ radioWrapper.appendChild(radioMark);
192
+ radioWrapper.appendChild(labelText);
193
+
194
+ optionsContainer.appendChild(radioWrapper);
195
+ });
196
+
197
+ wrapper.appendChild(optionsContainer);
198
+
199
+ // Error element
200
+ wrapper.appendChild(this._renderError());
201
+
202
+ // Wire events
203
+ this._wireStandardEvents(wrapper);
204
+
205
+ // Wire radio-specific sync
206
+ const valueSync = this._syncBindings.find(b => b.property === 'value');
207
+
208
+ if (valueSync) {
209
+ const { stateObj, toState, toComponent } = valueSync;
210
+
211
+ const transformToState = toState || ((v: string) => v);
212
+ const transformToComponent = toComponent || ((v: any) => String(v));
213
+
214
+ let isUpdating = false;
215
+
216
+ // State → Component
217
+ stateObj.subscribe((val: any) => {
218
+ if (isUpdating) return;
219
+ const transformed = transformToComponent(val);
220
+ this.setValue(transformed);
221
+ });
222
+
223
+ // Component → State
224
+ this._radioInputs.forEach(input => {
225
+ input.addEventListener('change', () => {
226
+ if (isUpdating) return;
227
+ isUpdating = true;
228
+
229
+ const selectedValue = input.value;
230
+ this.state.value = selectedValue;
231
+ this._clearError();
232
+
233
+ const transformed = transformToState(selectedValue);
234
+ stateObj.set(transformed);
235
+
236
+ // 🎯 Fire the change callback event
237
+ this._triggerCallback('change', selectedValue);
238
+
239
+ setTimeout(() => { isUpdating = false; }, 0);
240
+ });
241
+ });
242
+ } else {
243
+ // Default behavior without sync
244
+ this._radioInputs.forEach(input => {
245
+ input.addEventListener('change', () => {
246
+ this.state.value = input.value;
247
+ this._clearError();
248
+
249
+ // 🎯 Fire the change callback event
250
+ this._triggerCallback('change', input.value);
251
+ });
252
+ });
253
+ }
254
+
255
+ // Always add blur validation
256
+ this._radioInputs.forEach(input => {
257
+ input.addEventListener('blur', () => {
258
+ this.validate();
259
+ });
260
+ });
261
+
262
+ // Sync label changes
263
+ const labelSync = this._syncBindings.find(b => b.property === 'label');
264
+ if (labelSync) {
265
+ const transform = labelSync.toComponent || ((v: any) => String(v));
266
+ labelSync.stateObj.subscribe((val: any) => {
267
+ this.label(transform(val));
268
+ });
269
+ }
270
+
271
+ container.appendChild(wrapper);
272
+ return this;
273
+ }
274
+ }
275
+
276
+ export function radio(id: string, options: RadioOptions = {}): Radio {
277
+ return new Radio(id, options);
278
+ }
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Request information and utilities
3
+ * Provides access to URL, query params, path, referrer, etc.
4
+ */
5
+ export interface RequestInfo {
6
+ url: string;
7
+ path: string;
8
+ query: Record<string, string>;
9
+ params: Record<string, string>;
10
+ hash: string;
11
+ referrer: string;
12
+ method: string;
13
+ headers: Record<string, string>;
14
+ }
15
+ export declare class Req {
16
+ private static _instance;
17
+ private _info;
18
+ private constructor();
19
+ /**
20
+ * Singleton instance
21
+ */
22
+ static get instance(): Req;
23
+ /**
24
+ * Parse current request information
25
+ */
26
+ private _parseRequest;
27
+ /**
28
+ * Get full URL
29
+ */
30
+ get url(): string;
31
+ /**
32
+ * Get current path (e.g., "/examples/sample/dashboards")
33
+ */
34
+ get path(): string;
35
+ /**
36
+ * Get query string parameters
37
+ */
38
+ get query(): Record<string, string>;
39
+ /**
40
+ * Get path parameters
41
+ */
42
+ get params(): Record<string, string>;
43
+ /**
44
+ * Get URL hash (without #)
45
+ */
46
+ get hash(): string;
47
+ /**
48
+ * Get referrer URL
49
+ */
50
+ get referrer(): string;
51
+ /**
52
+ * Get request method (always GET for browser)
53
+ */
54
+ get method(): string;
55
+ /**
56
+ * Get request headers
57
+ */
58
+ get headers(): Record<string, string>;
59
+ /**
60
+ * Check if current path matches a pattern
61
+ * @param pattern - Path pattern (supports wildcards)
62
+ *
63
+ * Examples:
64
+ * req.matches('/examples/sample/*')
65
+ * req.matches('/examples/sample/dashboards')
66
+ * req.matches('/examples/*\/dashboards')
67
+ */
68
+ matches(pattern: string): boolean;
69
+ /**
70
+ * Check if current path starts with prefix
71
+ */
72
+ startsWith(prefix: string): boolean;
73
+ /**
74
+ * Check if current path ends with suffix
75
+ */
76
+ endsWith(suffix: string): boolean;
77
+ /**
78
+ * Get query parameter value
79
+ */
80
+ getQuery(key: string, defaultValue?: string): string | undefined;
81
+ /**
82
+ * Get path parameter value
83
+ */
84
+ getParam(key: string, defaultValue?: string): string | undefined;
85
+ /**
86
+ * Check if query parameter exists
87
+ */
88
+ hasQuery(key: string): boolean;
89
+ /**
90
+ * Get all query parameters as URLSearchParams
91
+ */
92
+ getSearchParams(): URLSearchParams;
93
+ /**
94
+ * Refresh request info (call after navigation)
95
+ */
96
+ refresh(): void;
97
+ /**
98
+ * Set active state on nav items based on current path
99
+ * @param items - Nav items to update
100
+ * @returns Updated nav items with active state set
101
+ */
102
+ setActiveNavItems(items: Array<{
103
+ href: string;
104
+ active?: boolean;
105
+ }>): Array<{
106
+ href: string;
107
+ active: boolean;
108
+ }>;
109
+ /**
110
+ * Check if a nav item should be active based on current path
111
+ * @param href - The nav item's href
112
+ */
113
+ isActiveNavItem(href: string): boolean;
114
+ /**
115
+ * Get breadcrumbs from current path
116
+ * @returns Array of breadcrumb objects with label and href
117
+ */
118
+ getBreadcrumbs(): Array<{
119
+ label: string;
120
+ href: string;
121
+ }>;
122
+ /**
123
+ * Format segment into readable breadcrumb label
124
+ */
125
+ private _formatBreadcrumbLabel;
126
+ /**
127
+ * Check if this is the home/root path
128
+ */
129
+ get isHome(): boolean;
130
+ /**
131
+ * Get current domain
132
+ */
133
+ get domain(): string;
134
+ /**
135
+ * Get current port
136
+ */
137
+ get port(): string;
138
+ /**
139
+ * Get current protocol
140
+ */
141
+ get protocol(): string;
142
+ /**
143
+ * Check if HTTPS
144
+ */
145
+ get isSecure(): boolean;
146
+ }
147
+ /**
148
+ * Global request instance
149
+ */
150
+ export declare const req: Req;
151
+ /**
152
+ * Factory function (returns singleton)
153
+ */
154
+ export declare function request(): Req;
155
+ //# sourceMappingURL=req.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"req.d.ts","sourceRoot":"","sources":["req.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Request information and utilities
3
+ * Provides access to URL, query params, path, referrer, etc.
4
+ */
5
+ export class Req {
6
+ constructor() {
7
+ this._info = this._parseRequest();
8
+ }
9
+ /**
10
+ * Singleton instance
11
+ */
12
+ static get instance() {
13
+ if (!Req._instance) {
14
+ Req._instance = new Req();
15
+ }
16
+ return Req._instance;
17
+ }
18
+ /**
19
+ * Parse current request information
20
+ */
21
+ _parseRequest() {
22
+ const url = new URL(window.location.href);
23
+ // Parse query string
24
+ const query = {};
25
+ url.searchParams.forEach((value, key) => {
26
+ query[key] = value;
27
+ });
28
+ // Parse path segments as params (basic routing)
29
+ const pathSegments = url.pathname.split('/').filter(s => s);
30
+ const params = {};
31
+ pathSegments.forEach((segment, index) => {
32
+ params[`${index}`] = segment;
33
+ });
34
+ return {
35
+ url: url.href,
36
+ path: url.pathname,
37
+ query,
38
+ params,
39
+ hash: url.hash.slice(1), // Remove leading #
40
+ referrer: document.referrer,
41
+ method: 'GET', // Browser requests are always GET initially
42
+ headers: {
43
+ 'user-agent': navigator.userAgent,
44
+ 'accept-language': navigator.language
45
+ }
46
+ };
47
+ }
48
+ /**
49
+ * Get full URL
50
+ */
51
+ get url() {
52
+ return this._info.url;
53
+ }
54
+ /**
55
+ * Get current path (e.g., "/examples/sample/dashboards")
56
+ */
57
+ get path() {
58
+ // Always get fresh path from current URL
59
+ return window.location.pathname;
60
+ }
61
+ /**
62
+ * Get query string parameters
63
+ */
64
+ get query() {
65
+ return { ...this._info.query };
66
+ }
67
+ /**
68
+ * Get path parameters
69
+ */
70
+ get params() {
71
+ return { ...this._info.params };
72
+ }
73
+ /**
74
+ * Get URL hash (without #)
75
+ */
76
+ get hash() {
77
+ return this._info.hash;
78
+ }
79
+ /**
80
+ * Get referrer URL
81
+ */
82
+ get referrer() {
83
+ return this._info.referrer;
84
+ }
85
+ /**
86
+ * Get request method (always GET for browser)
87
+ */
88
+ get method() {
89
+ return this._info.method;
90
+ }
91
+ /**
92
+ * Get request headers
93
+ */
94
+ get headers() {
95
+ return { ...this._info.headers };
96
+ }
97
+ /**
98
+ * Check if current path matches a pattern
99
+ * @param pattern - Path pattern (supports wildcards)
100
+ *
101
+ * Examples:
102
+ * req.matches('/examples/sample/*')
103
+ * req.matches('/examples/sample/dashboards')
104
+ * req.matches('/examples/*\/dashboards')
105
+ */
106
+ matches(pattern) {
107
+ const regexPattern = pattern
108
+ .replace(/\*/g, '.*')
109
+ .replace(/\//g, '\\/');
110
+ const regex = new RegExp(`^${regexPattern}$`);
111
+ return regex.test(this.path);
112
+ }
113
+ /**
114
+ * Check if current path starts with prefix
115
+ */
116
+ startsWith(prefix) {
117
+ return this.path.startsWith(prefix);
118
+ }
119
+ /**
120
+ * Check if current path ends with suffix
121
+ */
122
+ endsWith(suffix) {
123
+ return this.path.endsWith(suffix);
124
+ }
125
+ /**
126
+ * Get query parameter value
127
+ */
128
+ getQuery(key, defaultValue) {
129
+ return this.query[key] ?? defaultValue;
130
+ }
131
+ /**
132
+ * Get path parameter value
133
+ */
134
+ getParam(key, defaultValue) {
135
+ return this.params[key] ?? defaultValue;
136
+ }
137
+ /**
138
+ * Check if query parameter exists
139
+ */
140
+ hasQuery(key) {
141
+ return key in this.query;
142
+ }
143
+ /**
144
+ * Get all query parameters as URLSearchParams
145
+ */
146
+ getSearchParams() {
147
+ return new URLSearchParams(this.query);
148
+ }
149
+ /**
150
+ * Refresh request info (call after navigation)
151
+ */
152
+ refresh() {
153
+ this._info = this._parseRequest();
154
+ }
155
+ /**
156
+ * Set active state on nav items based on current path
157
+ * @param items - Nav items to update
158
+ * @returns Updated nav items with active state set
159
+ */
160
+ setActiveNavItems(items) {
161
+ return items.map(item => ({
162
+ ...item,
163
+ active: this.isActiveNavItem(item.href)
164
+ }));
165
+ }
166
+ /**
167
+ * Check if a nav item should be active based on current path
168
+ * @param href - The nav item's href
169
+ */
170
+ isActiveNavItem(href) {
171
+ // Exact match
172
+ if (href === this.path) {
173
+ return true;
174
+ }
175
+ // Starts with match (for parent routes)
176
+ // Must be followed by a path separator or end of string
177
+ // e.g., "/examples/sample" matches "/examples/sample/dashboards"
178
+ // but "/examples/sam" does NOT match "/examples/sample/dashboards"
179
+ if (href !== '/' && (this.path === href || this.path.startsWith(href + '/'))) {
180
+ return true;
181
+ }
182
+ return false;
183
+ }
184
+ /**
185
+ * Get breadcrumbs from current path
186
+ * @returns Array of breadcrumb objects with label and href
187
+ */
188
+ getBreadcrumbs() {
189
+ const segments = this.path.split('/').filter(s => s);
190
+ const breadcrumbs = [
191
+ { label: 'Home', href: '/' }
192
+ ];
193
+ let currentPath = '';
194
+ segments.forEach(segment => {
195
+ currentPath += `/${segment}`;
196
+ breadcrumbs.push({
197
+ label: this._formatBreadcrumbLabel(segment),
198
+ href: currentPath
199
+ });
200
+ });
201
+ return breadcrumbs;
202
+ }
203
+ /**
204
+ * Format segment into readable breadcrumb label
205
+ */
206
+ _formatBreadcrumbLabel(segment) {
207
+ return segment
208
+ .split('-')
209
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
210
+ .join(' ');
211
+ }
212
+ /**
213
+ * Check if this is the home/root path
214
+ */
215
+ get isHome() {
216
+ return this.path === '/' || this.path === '';
217
+ }
218
+ /**
219
+ * Get current domain
220
+ */
221
+ get domain() {
222
+ return window.location.hostname;
223
+ }
224
+ /**
225
+ * Get current port
226
+ */
227
+ get port() {
228
+ return window.location.port;
229
+ }
230
+ /**
231
+ * Get current protocol
232
+ */
233
+ get protocol() {
234
+ return window.location.protocol.replace(':', '');
235
+ }
236
+ /**
237
+ * Check if HTTPS
238
+ */
239
+ get isSecure() {
240
+ return this.protocol === 'https';
241
+ }
242
+ }
243
+ Req._instance = null;
244
+ /**
245
+ * Global request instance
246
+ */
247
+ export const req = Req.instance;
248
+ /**
249
+ * Factory function (returns singleton)
250
+ */
251
+ export function request() {
252
+ return Req.instance;
253
+ }