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,227 @@
1
+ import { BaseComponent } from './BaseComponent.js';
2
+
3
+ /**
4
+ * Base state interface for all form inputs
5
+ */
6
+ export interface FormInputState extends Record<string, any> {
7
+ label: string;
8
+ required: boolean;
9
+ disabled: boolean;
10
+ name: string;
11
+ style: string;
12
+ class: string;
13
+ errorMessage?: string;
14
+ }
15
+
16
+ /**
17
+ * Abstract base class for all form input components
18
+ * Extends BaseComponent with form-specific functionality
19
+ */
20
+ export abstract class FormInput<TState extends FormInputState> extends BaseComponent<TState> {
21
+ protected _inputElement: HTMLElement | null = null;
22
+ protected _labelElement: HTMLLabelElement | null = null;
23
+ protected _errorElement: HTMLElement | null = null;
24
+ protected _onValidate?: (value: any) => boolean | string;
25
+ protected _hasBeenValidated: boolean = false; // NEW: Track if user has submitted/validated
26
+
27
+ /* ═════════════════════════════════════════════════════════════════
28
+ * ABSTRACT METHODS (Child must implement)
29
+ * ═════════════════════════════════════════════════════════════════ */
30
+
31
+ /**
32
+ * Get the current value of the input
33
+ */
34
+ abstract getValue(): any;
35
+
36
+ /**
37
+ * Set the value of the input
38
+ */
39
+ abstract setValue(value: any): this;
40
+
41
+ /**
42
+ * Build the actual input element (input, select, textarea, etc.)
43
+ */
44
+ protected abstract _buildInputElement(): HTMLElement;
45
+
46
+ /**
47
+ * Validate the current value
48
+ */
49
+ protected abstract _validateValue(value: any): boolean | string;
50
+
51
+ /* ═════════════════════════════════════════════════════════════════
52
+ * COMMON FORM INPUT API
53
+ * ═════════════════════════════════════════════════════════════════ */
54
+
55
+ label(value: string): this {
56
+ this.state.label = value;
57
+ if (this._labelElement) {
58
+ this._labelElement.textContent = value;
59
+ }
60
+ return this;
61
+ }
62
+
63
+ required(value: boolean): this {
64
+ this.state.required = value;
65
+ return this;
66
+ }
67
+
68
+ name(value: string): this {
69
+ this.state.name = value;
70
+ return this;
71
+ }
72
+
73
+ onValidate(handler: (value: any) => boolean | string): this {
74
+ this._onValidate = handler;
75
+ return this;
76
+ }
77
+
78
+ /* ═════════════════════════════════════════════════════════════════
79
+ * VALIDATION
80
+ * ═════════════════════════════════════════════════════════════════ */
81
+
82
+ /**
83
+ * Validate the current value and show/hide errors
84
+ */
85
+ validate(): boolean {
86
+ this._hasBeenValidated = true; // Mark as validated
87
+ const value = this.getValue();
88
+ const result = this._validateValue(value);
89
+
90
+ if (result === true) {
91
+ this._clearError();
92
+ return true;
93
+ } else {
94
+ this._showError(result as string);
95
+ return false;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Check if current value is valid without showing errors
101
+ */
102
+ isValid(): boolean {
103
+ const value = this.getValue();
104
+ return this._validateValue(value) === true;
105
+ }
106
+
107
+ /**
108
+ * Show error message
109
+ */
110
+ protected _showError(message: string): void {
111
+ if (this._errorElement) {
112
+ this._errorElement.textContent = message;
113
+ this._errorElement.style.display = 'block';
114
+ }
115
+
116
+ if (this._inputElement) {
117
+ this._inputElement.classList.add('jux-input-invalid');
118
+ }
119
+
120
+ this.state.errorMessage = message;
121
+ }
122
+
123
+ /**
124
+ * Clear error message
125
+ */
126
+ protected _clearError(): void {
127
+ if (this._errorElement) {
128
+ this._errorElement.textContent = '';
129
+ this._errorElement.style.display = 'none';
130
+ }
131
+
132
+ if (this._inputElement) {
133
+ this._inputElement.classList.remove('jux-input-invalid');
134
+ }
135
+
136
+ this.state.errorMessage = undefined;
137
+ }
138
+
139
+ /* ═════════════════════════════════════════════════════════════════
140
+ * COMMON RENDER HELPERS
141
+ * ═════════════════════════════════════════════════════════════════ */
142
+
143
+ /**
144
+ * Build label element
145
+ */
146
+ protected _renderLabel(): HTMLLabelElement {
147
+ const { label, required } = this.state;
148
+
149
+ const labelEl = document.createElement('label');
150
+ labelEl.className = 'jux-input-label';
151
+ labelEl.htmlFor = `${this._id}-input`;
152
+ labelEl.textContent = label;
153
+
154
+ if (required) {
155
+ const requiredSpan = document.createElement('span');
156
+ requiredSpan.className = 'jux-input-required';
157
+ requiredSpan.textContent = ' *';
158
+ labelEl.appendChild(requiredSpan);
159
+ }
160
+
161
+ this._labelElement = labelEl;
162
+ return labelEl;
163
+ }
164
+
165
+ /**
166
+ * Build error element
167
+ */
168
+ protected _renderError(): HTMLElement {
169
+ const errorEl = document.createElement('div');
170
+ errorEl.className = 'jux-input-error';
171
+ errorEl.id = `${this._id}-error`;
172
+ errorEl.style.display = 'none';
173
+
174
+ this._errorElement = errorEl;
175
+ return errorEl;
176
+ }
177
+
178
+ /**
179
+ * Wire up two-way sync for value property
180
+ */
181
+ protected _wireFormSync(inputElement: HTMLElement, eventName: string = 'input'): void {
182
+ const valueSync = this._syncBindings.find(b => b.property === 'value');
183
+
184
+ if (valueSync) {
185
+ const { stateObj, toState, toComponent } = valueSync;
186
+
187
+ // Default transforms
188
+ const transformToState = toState || ((v: any) => v);
189
+ const transformToComponent = toComponent || ((v: any) => v);
190
+
191
+ let isUpdating = false;
192
+
193
+ // State → Component
194
+ stateObj.subscribe((val: any) => {
195
+ if (isUpdating) return;
196
+ const transformed = transformToComponent(val);
197
+ this.setValue(transformed);
198
+ });
199
+
200
+ // Component → State
201
+ inputElement.addEventListener(eventName, () => {
202
+ if (isUpdating) return;
203
+ isUpdating = true;
204
+
205
+ const value = this.getValue();
206
+ const transformed = transformToState(value);
207
+ this._clearError();
208
+
209
+ stateObj.set(transformed);
210
+
211
+ setTimeout(() => { isUpdating = false; }, 0);
212
+ });
213
+ } else {
214
+ // Default behavior without sync
215
+ inputElement.addEventListener(eventName, () => {
216
+ this._clearError();
217
+ });
218
+ }
219
+
220
+ // Only validate on blur IF the field has been validated before (e.g., after submit)
221
+ inputElement.addEventListener('blur', () => {
222
+ if (this._hasBeenValidated) {
223
+ this.validate();
224
+ }
225
+ });
226
+ }
227
+ }
@@ -0,0 +1,48 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ export interface ButtonOptions {
3
+ label?: string;
4
+ icon?: string;
5
+ variant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning' | 'info' | 'link' | string;
6
+ size?: 'small' | 'medium' | 'large';
7
+ disabled?: boolean;
8
+ loading?: boolean;
9
+ iconPosition?: 'left' | 'right';
10
+ fullWidth?: boolean;
11
+ type?: 'button' | 'submit' | 'reset';
12
+ style?: string;
13
+ class?: string;
14
+ }
15
+ type ButtonState = {
16
+ label: string;
17
+ icon: string;
18
+ variant: string;
19
+ size: string;
20
+ disabled: boolean;
21
+ loading: boolean;
22
+ iconPosition: string;
23
+ fullWidth: boolean;
24
+ type: 'button' | 'submit' | 'reset';
25
+ style: string;
26
+ class: string;
27
+ };
28
+ export declare class Button extends BaseComponent<ButtonState> {
29
+ private _buttonElement;
30
+ constructor(id: string, options?: ButtonOptions);
31
+ protected getTriggerEvents(): readonly string[];
32
+ protected getCallbackEvents(): readonly string[];
33
+ label(value: string): this;
34
+ icon(value: string): this;
35
+ variant(value: 'primary' | 'secondary' | 'danger' | 'success' | 'warning' | 'info' | 'link' | string): this;
36
+ size(value: 'small' | 'medium' | 'large'): this;
37
+ iconPosition(value: 'left' | 'right'): this;
38
+ fullWidth(value: boolean): this;
39
+ type(value: 'button' | 'submit' | 'reset'): this;
40
+ /**
41
+ * Override visible() to update the actual button element
42
+ */
43
+ visible(value: boolean): this;
44
+ render(targetId?: string): this;
45
+ }
46
+ export declare function button(id: string, options?: ButtonOptions): Button;
47
+ export {};
48
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAOxD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAChG,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,MAAO,SAAQ,aAAa,CAAC,WAAW,CAAC;IACpD,OAAO,CAAC,cAAc,CAAkC;gBAE5C,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAkB/C,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAUhD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;IAK3G,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI;IAK/C,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAK3C,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK/B,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI;IAShD;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAW7B,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;CAkDhC;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAElE"}
@@ -0,0 +1,121 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ import { renderIcon } from './icons.js';
3
+ // Event definitions
4
+ const TRIGGER_EVENTS = [];
5
+ const CALLBACK_EVENTS = ['click']; // ✅ Button fires click events
6
+ export class Button extends BaseComponent {
7
+ constructor(id, options) {
8
+ const opts = options || {};
9
+ super(id, {
10
+ label: opts.label ?? 'Button',
11
+ icon: opts.icon ?? '',
12
+ variant: opts.variant ?? 'primary',
13
+ size: opts.size ?? 'medium',
14
+ disabled: opts.disabled ?? false,
15
+ loading: opts.loading ?? false,
16
+ iconPosition: opts.iconPosition ?? 'left',
17
+ fullWidth: opts.fullWidth ?? false,
18
+ type: opts.type ?? 'button',
19
+ style: opts.style ?? '',
20
+ class: opts.class ?? ''
21
+ });
22
+ this._buttonElement = null; // ✅ Store button reference
23
+ }
24
+ getTriggerEvents() {
25
+ return TRIGGER_EVENTS;
26
+ }
27
+ getCallbackEvents() {
28
+ return CALLBACK_EVENTS;
29
+ }
30
+ /* ═════════════════════════════════════════════════════════════════
31
+ * FLUENT API
32
+ * ═════════════════════════════════════════════════════════════════ */
33
+ // ✅ Inherited from BaseComponent
34
+ label(value) {
35
+ this.state.label = value;
36
+ return this;
37
+ }
38
+ icon(value) {
39
+ this.state.icon = value;
40
+ return this;
41
+ }
42
+ variant(value) {
43
+ this.state.variant = value;
44
+ return this;
45
+ }
46
+ size(value) {
47
+ this.state.size = value;
48
+ return this;
49
+ }
50
+ iconPosition(value) {
51
+ this.state.iconPosition = value;
52
+ return this;
53
+ }
54
+ fullWidth(value) {
55
+ this.state.fullWidth = value;
56
+ return this;
57
+ }
58
+ type(value) {
59
+ this.state.type = value;
60
+ return this;
61
+ }
62
+ /* ═════════════════════════════════════════════════════════════════
63
+ * RENDER
64
+ * ═════════════════════════════════════════════════════════════════ */
65
+ /**
66
+ * Override visible() to update the actual button element
67
+ */
68
+ visible(value) {
69
+ this.state.visible = value;
70
+ // Update the button element directly, not the container
71
+ if (this._buttonElement) {
72
+ this._buttonElement.style.display = value ? '' : 'none';
73
+ }
74
+ return this;
75
+ }
76
+ render(targetId) {
77
+ const container = this._setupContainer(targetId);
78
+ const { label, variant, size, disabled, icon, iconPosition, loading, style, class: className } = this.state;
79
+ const button = document.createElement('button');
80
+ this._buttonElement = button; // ✅ Store reference
81
+ button.className = `jux-button jux-button-${variant} jux-button-${size}`;
82
+ button.id = this._id;
83
+ button.disabled = disabled || loading;
84
+ if (className)
85
+ button.className += ` ${className}`;
86
+ if (style)
87
+ button.setAttribute('style', style);
88
+ if (icon && iconPosition === 'left') {
89
+ const iconEl = document.createElement('span');
90
+ iconEl.className = 'jux-button-icon';
91
+ iconEl.appendChild(renderIcon(icon));
92
+ button.appendChild(iconEl);
93
+ }
94
+ const textEl = document.createElement('span');
95
+ textEl.textContent = loading ? 'Loading...' : label;
96
+ button.appendChild(textEl);
97
+ if (icon && iconPosition === 'right') {
98
+ const iconEl = document.createElement('span');
99
+ iconEl.className = 'jux-button-icon';
100
+ iconEl.appendChild(renderIcon(icon));
101
+ button.appendChild(iconEl);
102
+ }
103
+ button.addEventListener('click', (e) => {
104
+ if (!disabled && !loading) {
105
+ this._triggerCallback('click', e);
106
+ }
107
+ });
108
+ this._wireStandardEvents(button);
109
+ this._wireAllSyncs();
110
+ container.appendChild(button);
111
+ requestAnimationFrame(() => {
112
+ if (window.lucide) {
113
+ window.lucide.createIcons();
114
+ }
115
+ });
116
+ return this;
117
+ }
118
+ }
119
+ export function button(id, options) {
120
+ return new Button(id, options);
121
+ }
@@ -0,0 +1,178 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ import { renderIcon } from './icons.js';
3
+
4
+ // Event definitions
5
+ const TRIGGER_EVENTS = [] as const;
6
+ const CALLBACK_EVENTS = ['click'] as const; // ✅ Button fires click events
7
+
8
+ export interface ButtonOptions {
9
+ label?: string;
10
+ icon?: string;
11
+ variant?: 'primary' | 'secondary' | 'danger' | 'success' | 'warning' | 'info' | 'link' | string;
12
+ size?: 'small' | 'medium' | 'large';
13
+ disabled?: boolean;
14
+ loading?: boolean;
15
+ iconPosition?: 'left' | 'right';
16
+ fullWidth?: boolean;
17
+ type?: 'button' | 'submit' | 'reset';
18
+ style?: string;
19
+ class?: string;
20
+ }
21
+
22
+ type ButtonState = {
23
+ label: string;
24
+ icon: string;
25
+ variant: string;
26
+ size: string;
27
+ disabled: boolean;
28
+ loading: boolean;
29
+ iconPosition: string;
30
+ fullWidth: boolean;
31
+ type: 'button' | 'submit' | 'reset';
32
+ style: string;
33
+ class: string;
34
+ };
35
+
36
+ export class Button extends BaseComponent<ButtonState> {
37
+ private _buttonElement: HTMLButtonElement | null = null; // ✅ Store button reference
38
+
39
+ constructor(id: string, options?: ButtonOptions) {
40
+ const opts = options || {};
41
+
42
+ super(id, {
43
+ label: opts.label ?? 'Button',
44
+ icon: opts.icon ?? '',
45
+ variant: opts.variant ?? 'primary',
46
+ size: opts.size ?? 'medium',
47
+ disabled: opts.disabled ?? false,
48
+ loading: opts.loading ?? false,
49
+ iconPosition: opts.iconPosition ?? 'left',
50
+ fullWidth: opts.fullWidth ?? false,
51
+ type: opts.type ?? 'button',
52
+ style: opts.style ?? '',
53
+ class: opts.class ?? ''
54
+ });
55
+ }
56
+
57
+ protected getTriggerEvents(): readonly string[] {
58
+ return TRIGGER_EVENTS;
59
+ }
60
+
61
+ protected getCallbackEvents(): readonly string[] {
62
+ return CALLBACK_EVENTS;
63
+ }
64
+
65
+ /* ═════════════════════════════════════════════════════════════════
66
+ * FLUENT API
67
+ * ═════════════════════════════════════════════════════════════════ */
68
+
69
+ // ✅ Inherited from BaseComponent
70
+
71
+ label(value: string): this {
72
+ this.state.label = value;
73
+ return this;
74
+ }
75
+
76
+ icon(value: string): this {
77
+ this.state.icon = value;
78
+ return this;
79
+ }
80
+
81
+ variant(value: 'primary' | 'secondary' | 'danger' | 'success' | 'warning' | 'info' | 'link' | string): this {
82
+ this.state.variant = value;
83
+ return this;
84
+ }
85
+
86
+ size(value: 'small' | 'medium' | 'large'): this {
87
+ this.state.size = value;
88
+ return this;
89
+ }
90
+
91
+ iconPosition(value: 'left' | 'right'): this {
92
+ this.state.iconPosition = value;
93
+ return this;
94
+ }
95
+
96
+ fullWidth(value: boolean): this {
97
+ this.state.fullWidth = value;
98
+ return this;
99
+ }
100
+
101
+ type(value: 'button' | 'submit' | 'reset'): this {
102
+ this.state.type = value;
103
+ return this;
104
+ }
105
+
106
+ /* ═════════════════════════════════════════════════════════════════
107
+ * RENDER
108
+ * ═════════════════════════════════════════════════════════════════ */
109
+
110
+ /**
111
+ * Override visible() to update the actual button element
112
+ */
113
+ visible(value: boolean): this {
114
+ (this.state as any).visible = value;
115
+
116
+ // Update the button element directly, not the container
117
+ if (this._buttonElement) {
118
+ this._buttonElement.style.display = value ? '' : 'none';
119
+ }
120
+
121
+ return this;
122
+ }
123
+
124
+ render(targetId?: string): this {
125
+ const container = this._setupContainer(targetId);
126
+ const { label, variant, size, disabled, icon, iconPosition, loading, style, class: className } = this.state;
127
+
128
+ const button = document.createElement('button');
129
+ this._buttonElement = button; // ✅ Store reference
130
+ button.className = `jux-button jux-button-${variant} jux-button-${size}`;
131
+ button.id = this._id;
132
+ button.disabled = disabled || loading;
133
+
134
+ if (className) button.className += ` ${className}`;
135
+ if (style) button.setAttribute('style', style);
136
+
137
+ if (icon && iconPosition === 'left') {
138
+ const iconEl = document.createElement('span');
139
+ iconEl.className = 'jux-button-icon';
140
+ iconEl.appendChild(renderIcon(icon));
141
+ button.appendChild(iconEl);
142
+ }
143
+
144
+ const textEl = document.createElement('span');
145
+ textEl.textContent = loading ? 'Loading...' : label;
146
+ button.appendChild(textEl);
147
+
148
+ if (icon && iconPosition === 'right') {
149
+ const iconEl = document.createElement('span');
150
+ iconEl.className = 'jux-button-icon';
151
+ iconEl.appendChild(renderIcon(icon));
152
+ button.appendChild(iconEl);
153
+ }
154
+
155
+ button.addEventListener('click', (e) => {
156
+ if (!disabled && !loading) {
157
+ this._triggerCallback('click', e);
158
+ }
159
+ });
160
+
161
+ this._wireStandardEvents(button);
162
+ this._wireAllSyncs();
163
+
164
+ container.appendChild(button);
165
+
166
+ requestAnimationFrame(() => {
167
+ if ((window as any).lucide) {
168
+ (window as any).lucide.createIcons();
169
+ }
170
+ });
171
+
172
+ return this;
173
+ }
174
+ }
175
+
176
+ export function button(id: string, options?: ButtonOptions): Button {
177
+ return new Button(id, options);
178
+ }
@@ -0,0 +1,34 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ export interface CardOptions {
3
+ title?: string;
4
+ content?: string;
5
+ footer?: string;
6
+ variant?: string;
7
+ hoverable?: boolean;
8
+ icon?: string;
9
+ style?: string;
10
+ class?: string;
11
+ }
12
+ type CardState = {
13
+ title: string;
14
+ content: string;
15
+ footer: string;
16
+ variant: string;
17
+ hoverable: boolean;
18
+ icon: string;
19
+ style: string;
20
+ class: string;
21
+ };
22
+ export declare class Card extends BaseComponent<CardState> {
23
+ constructor(id: string, options?: CardOptions);
24
+ protected getTriggerEvents(): readonly string[];
25
+ protected getCallbackEvents(): readonly string[];
26
+ title(value: string): this;
27
+ content(value: string): this;
28
+ footer(value: string): this;
29
+ icon(value: string): this;
30
+ render(targetId?: string): this;
31
+ }
32
+ export declare function card(id: string, options?: CardOptions): Card;
33
+ export {};
34
+ //# sourceMappingURL=card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAOxD,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,SAAS,GAAG;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,IAAK,SAAQ,aAAa,CAAC,SAAS,CAAC;gBACpC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAajD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAUhD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK3B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IASzB,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;CAuFhC;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAEhE"}