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,113 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ // Event definitions
3
+ const TRIGGER_EVENTS = [];
4
+ const CALLBACK_EVENTS = [];
5
+ export class Progress extends BaseComponent {
6
+ constructor(id, options = {}) {
7
+ super(id, {
8
+ value: options.value ?? 0,
9
+ max: options.max ?? 100,
10
+ variant: options.variant ?? 'default',
11
+ showPercentage: options.showPercentage ?? false,
12
+ label: options.label ?? '',
13
+ size: options.size ?? 'md',
14
+ style: options.style ?? '',
15
+ class: options.class ?? ''
16
+ });
17
+ this._bar = null;
18
+ this._label = null;
19
+ }
20
+ getTriggerEvents() {
21
+ return TRIGGER_EVENTS;
22
+ }
23
+ getCallbackEvents() {
24
+ return CALLBACK_EVENTS;
25
+ }
26
+ /* ═════════════════════════════════════════════════════════════════
27
+ * FLUENT API
28
+ * ═════════════════════════════════════════════════════════════════ */
29
+ value(val) {
30
+ this.state.value = Math.max(0, Math.min(val, this.state.max));
31
+ this._updateProgress();
32
+ return this;
33
+ }
34
+ max(val) {
35
+ this.state.max = val;
36
+ this._updateProgress();
37
+ return this;
38
+ }
39
+ variant(value) {
40
+ this.state.variant = value;
41
+ return this;
42
+ }
43
+ showPercentage(value) {
44
+ this.state.showPercentage = value;
45
+ return this;
46
+ }
47
+ label(value) {
48
+ this.state.label = value;
49
+ if (this._label) {
50
+ this._label.textContent = value;
51
+ }
52
+ return this;
53
+ }
54
+ size(value) {
55
+ this.state.size = value;
56
+ return this;
57
+ }
58
+ _updateProgress() {
59
+ if (this._bar) {
60
+ const percentage = (this.state.value / this.state.max) * 100;
61
+ this._bar.style.width = `${percentage}%`;
62
+ if (this._label) {
63
+ // Use custom label if set, otherwise show percentage
64
+ this._label.textContent = this.state.label || `${Math.round(percentage)}%`;
65
+ }
66
+ }
67
+ }
68
+ /* ═════════════════════════════════════════════════════════════════
69
+ * RENDER
70
+ * ═════════════════════════════════════════════════════════════════ */
71
+ render(targetId) {
72
+ const container = this._setupContainer(targetId);
73
+ const { value, max, variant, showPercentage, label, size, style, class: className } = this.state;
74
+ const wrapper = document.createElement('div');
75
+ wrapper.className = `jux-progress jux-progress-${size}`;
76
+ wrapper.id = this._id;
77
+ if (className)
78
+ wrapper.className += ` ${className}`;
79
+ if (style)
80
+ wrapper.setAttribute('style', style);
81
+ const track = document.createElement('div');
82
+ track.className = 'jux-progress-track';
83
+ const bar = document.createElement('div');
84
+ bar.className = `jux-progress-bar jux-progress-bar-${variant}`;
85
+ const percentage = (value / max) * 100;
86
+ bar.style.width = `${percentage}%`;
87
+ this._bar = bar;
88
+ if (showPercentage || label) {
89
+ const labelEl = document.createElement('span');
90
+ labelEl.className = 'jux-progress-label';
91
+ labelEl.textContent = label || `${Math.round(percentage)}%`;
92
+ bar.appendChild(labelEl);
93
+ this._label = labelEl;
94
+ }
95
+ track.appendChild(bar);
96
+ wrapper.appendChild(track);
97
+ this._wireStandardEvents(wrapper);
98
+ // Wire sync for value
99
+ this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
100
+ if (property === 'value') {
101
+ const transform = toComponent || ((v) => Number(v));
102
+ stateObj.subscribe((val) => {
103
+ this.value(transform(val));
104
+ });
105
+ }
106
+ });
107
+ container.appendChild(wrapper);
108
+ return this;
109
+ }
110
+ }
111
+ export function progress(id, options = {}) {
112
+ return new Progress(id, options);
113
+ }
@@ -0,0 +1,159 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+
3
+ // Event definitions
4
+ const TRIGGER_EVENTS = [] as const;
5
+ const CALLBACK_EVENTS = [] as const;
6
+
7
+ export interface ProgressOptions {
8
+ value?: number;
9
+ max?: number;
10
+ variant?: 'default' | 'success' | 'warning' | 'error';
11
+ showPercentage?: boolean;
12
+ label?: string;
13
+ size?: 'sm' | 'md' | 'lg';
14
+ style?: string;
15
+ class?: string;
16
+ }
17
+
18
+ type ProgressState = {
19
+ value: number;
20
+ max: number;
21
+ variant: string;
22
+ showPercentage: boolean;
23
+ label: string;
24
+ size: string;
25
+ style: string;
26
+ class: string;
27
+ };
28
+
29
+ export class Progress extends BaseComponent<ProgressState> {
30
+ private _bar: HTMLElement | null = null;
31
+ private _label: HTMLElement | null = null;
32
+
33
+ constructor(id: string, options: ProgressOptions = {}) {
34
+ super(id, {
35
+ value: options.value ?? 0,
36
+ max: options.max ?? 100,
37
+ variant: options.variant ?? 'default',
38
+ showPercentage: options.showPercentage ?? false,
39
+ label: options.label ?? '',
40
+ size: options.size ?? 'md',
41
+ style: options.style ?? '',
42
+ class: options.class ?? ''
43
+ });
44
+ }
45
+
46
+ protected getTriggerEvents(): readonly string[] {
47
+ return TRIGGER_EVENTS;
48
+ }
49
+
50
+ protected getCallbackEvents(): readonly string[] {
51
+ return CALLBACK_EVENTS;
52
+ }
53
+
54
+ /* ═════════════════════════════════════════════════════════════════
55
+ * FLUENT API
56
+ * ═════════════════════════════════════════════════════════════════ */
57
+
58
+ value(val: number): this {
59
+ this.state.value = Math.max(0, Math.min(val, this.state.max));
60
+ this._updateProgress();
61
+ return this;
62
+ }
63
+
64
+ max(val: number): this {
65
+ this.state.max = val;
66
+ this._updateProgress();
67
+ return this;
68
+ }
69
+
70
+ variant(value: 'default' | 'success' | 'warning' | 'error'): this {
71
+ this.state.variant = value;
72
+ return this;
73
+ }
74
+
75
+ showPercentage(value: boolean): this {
76
+ this.state.showPercentage = value;
77
+ return this;
78
+ }
79
+
80
+ label(value: string): this {
81
+ this.state.label = value;
82
+ if (this._label) {
83
+ this._label.textContent = value;
84
+ }
85
+ return this;
86
+ }
87
+
88
+ size(value: 'sm' | 'md' | 'lg'): this {
89
+ this.state.size = value;
90
+ return this;
91
+ }
92
+
93
+ private _updateProgress(): void {
94
+ if (this._bar) {
95
+ const percentage = (this.state.value / this.state.max) * 100;
96
+ this._bar.style.width = `${percentage}%`;
97
+ if (this._label) {
98
+ // Use custom label if set, otherwise show percentage
99
+ this._label.textContent = this.state.label || `${Math.round(percentage)}%`;
100
+ }
101
+ }
102
+ }
103
+
104
+ /* ═════════════════════════════════════════════════════════════════
105
+ * RENDER
106
+ * ═════════════════════════════════════════════════════════════════ */
107
+
108
+ render(targetId?: string): this {
109
+ const container = this._setupContainer(targetId);
110
+
111
+ const { value, max, variant, showPercentage, label, size, style, class: className } = this.state;
112
+
113
+ const wrapper = document.createElement('div');
114
+ wrapper.className = `jux-progress jux-progress-${size}`;
115
+ wrapper.id = this._id;
116
+ if (className) wrapper.className += ` ${className}`;
117
+ if (style) wrapper.setAttribute('style', style);
118
+
119
+ const track = document.createElement('div');
120
+ track.className = 'jux-progress-track';
121
+
122
+ const bar = document.createElement('div');
123
+ bar.className = `jux-progress-bar jux-progress-bar-${variant}`;
124
+ const percentage = (value / max) * 100;
125
+ bar.style.width = `${percentage}%`;
126
+ this._bar = bar;
127
+
128
+ if (showPercentage || label) {
129
+ const labelEl = document.createElement('span');
130
+ labelEl.className = 'jux-progress-label';
131
+ labelEl.textContent = label || `${Math.round(percentage)}%`;
132
+ bar.appendChild(labelEl);
133
+ this._label = labelEl;
134
+ }
135
+
136
+ track.appendChild(bar);
137
+ wrapper.appendChild(track);
138
+
139
+ this._wireStandardEvents(wrapper);
140
+
141
+ // Wire sync for value
142
+ this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
143
+ if (property === 'value') {
144
+ const transform = toComponent || ((v: any) => Number(v));
145
+ stateObj.subscribe((val: any) => {
146
+ this.value(transform(val));
147
+ });
148
+ }
149
+ });
150
+
151
+ container.appendChild(wrapper);
152
+
153
+ return this;
154
+ }
155
+ }
156
+
157
+ export function progress(id: string, options: ProgressOptions = {}): Progress {
158
+ return new Progress(id, options);
159
+ }
@@ -0,0 +1,41 @@
1
+ import { FormInput, FormInputState } from './base/FormInput.js';
2
+ export interface RadioOption {
3
+ label: string;
4
+ value: string;
5
+ disabled?: boolean;
6
+ }
7
+ export interface RadioOptions {
8
+ options?: RadioOption[];
9
+ value?: string;
10
+ label?: string;
11
+ required?: boolean;
12
+ disabled?: boolean;
13
+ name?: string;
14
+ orientation?: 'vertical' | 'horizontal';
15
+ style?: string;
16
+ class?: string;
17
+ onValidate?: (value: string) => boolean | string;
18
+ }
19
+ interface RadioState extends FormInputState {
20
+ options: RadioOption[];
21
+ value: string;
22
+ orientation: 'vertical' | 'horizontal';
23
+ }
24
+ export declare class Radio extends FormInput<RadioState> {
25
+ private _radioInputs;
26
+ constructor(id: string, options?: RadioOptions);
27
+ protected getTriggerEvents(): readonly string[];
28
+ protected getCallbackEvents(): readonly string[];
29
+ options(value: RadioOption[]): this;
30
+ value(value: string): this;
31
+ addOption(option: RadioOption): this;
32
+ orientation(value: 'vertical' | 'horizontal'): this;
33
+ getValue(): string;
34
+ setValue(value: string): this;
35
+ protected _validateValue(value: string): boolean | string;
36
+ protected _buildInputElement(): HTMLElement;
37
+ render(targetId?: string): this;
38
+ }
39
+ export declare function radio(id: string, options?: RadioOptions): Radio;
40
+ export {};
41
+ //# sourceMappingURL=radio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["radio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMhE,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,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,UAAW,SAAQ,cAAc;IACvC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,UAAU,GAAG,YAAY,CAAC;CAC1C;AAED,qBAAa,KAAM,SAAQ,SAAS,CAAC,UAAU,CAAC;IAC5C,OAAO,CAAC,YAAY,CAA0B;gBAElC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IAmBlD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAehD,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI;IAKnC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1B,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAKpC,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI;IASnD,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAW7B,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM;IAsBzD,SAAS,CAAC,kBAAkB,IAAI,WAAW;IAW3C,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;CAkIlC;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAEnE"}
@@ -0,0 +1,203 @@
1
+ import { FormInput } from './base/FormInput.js';
2
+ // Event definitions
3
+ const TRIGGER_EVENTS = [];
4
+ const CALLBACK_EVENTS = ['change'];
5
+ export class Radio extends FormInput {
6
+ constructor(id, options = {}) {
7
+ super(id, {
8
+ options: options.options ?? [],
9
+ value: options.value ?? '',
10
+ label: options.label ?? '',
11
+ required: options.required ?? false,
12
+ disabled: options.disabled ?? false,
13
+ name: options.name ?? id,
14
+ orientation: options.orientation ?? 'vertical', // ✅ Default to vertical
15
+ style: options.style ?? '',
16
+ class: options.class ?? '',
17
+ errorMessage: undefined
18
+ });
19
+ this._radioInputs = [];
20
+ if (options.onValidate) {
21
+ this._onValidate = options.onValidate;
22
+ }
23
+ }
24
+ getTriggerEvents() {
25
+ return TRIGGER_EVENTS;
26
+ }
27
+ getCallbackEvents() {
28
+ return CALLBACK_EVENTS;
29
+ }
30
+ /* ═════════════════════════════════════════════════════════════════
31
+ * FLUENT API
32
+ * ═════════════════════════════════════════════════════════════════ */
33
+ // ✅ Inherited from FormInput/BaseComponent:
34
+ // - label(), required(), name(), onValidate()
35
+ // - validate(), isValid()
36
+ // - style(), class()
37
+ // - bind(), sync(), renderTo()
38
+ // - disabled(), enable(), disable()
39
+ options(value) {
40
+ this.state.options = value;
41
+ return this;
42
+ }
43
+ value(value) {
44
+ return this.setValue(value);
45
+ }
46
+ addOption(option) {
47
+ this.state.options = [...this.state.options, option];
48
+ return this;
49
+ }
50
+ orientation(value) {
51
+ this.state.orientation = value;
52
+ return this;
53
+ }
54
+ /* ═════════════════════════════════════════════════════════════════
55
+ * FORM INPUT IMPLEMENTATION
56
+ * ═════════════════════════════════════════════════════════════════ */
57
+ getValue() {
58
+ return this.state.value;
59
+ }
60
+ setValue(value) {
61
+ this.state.value = value;
62
+ // Update all radio inputs
63
+ this._radioInputs.forEach(input => {
64
+ input.checked = input.value === value;
65
+ });
66
+ return this;
67
+ }
68
+ _validateValue(value) {
69
+ const { required, options } = this.state;
70
+ if (required && !value) {
71
+ return 'Please select an option';
72
+ }
73
+ // Validate that value is one of the options
74
+ if (value && !options.some(opt => opt.value === value)) {
75
+ return 'Invalid option selected';
76
+ }
77
+ if (this._onValidate) {
78
+ const result = this._onValidate(value);
79
+ if (result !== true) {
80
+ return result || 'Invalid value';
81
+ }
82
+ }
83
+ return true;
84
+ }
85
+ _buildInputElement() {
86
+ // Radio uses a container, not a single input
87
+ const container = document.createElement('div');
88
+ container.className = 'jux-radio-options';
89
+ return container;
90
+ }
91
+ /* ═════════════════════════════════════════════════════════════════
92
+ * RENDER
93
+ * ═════════════════════════════════════════════════════════════════ */
94
+ render(targetId) {
95
+ const container = this._setupContainer(targetId);
96
+ const { options, value, name, disabled, orientation, style, class: className } = this.state; // ✅ Destructure orientation
97
+ // Build wrapper
98
+ const wrapper = document.createElement('div');
99
+ wrapper.className = 'jux-radio';
100
+ wrapper.id = this._id;
101
+ if (className)
102
+ wrapper.className += ` ${className}`;
103
+ if (style)
104
+ wrapper.setAttribute('style', style);
105
+ // Label
106
+ if (this.state.label) {
107
+ wrapper.appendChild(this._renderLabel());
108
+ }
109
+ // Radio options container
110
+ const optionsContainer = document.createElement('div');
111
+ optionsContainer.className = `jux-radio-options jux-radio-${orientation}`; // ✅ Add orientation class
112
+ this._inputElement = optionsContainer;
113
+ this._radioInputs = [];
114
+ options.forEach((option, index) => {
115
+ const radioWrapper = document.createElement('label');
116
+ radioWrapper.className = 'jux-radio-option';
117
+ const input = document.createElement('input');
118
+ input.type = 'radio';
119
+ input.className = 'jux-radio-input';
120
+ input.id = `${this._id}-option-${index}`;
121
+ input.name = name;
122
+ input.value = option.value;
123
+ input.checked = option.value === value;
124
+ input.disabled = disabled || option.disabled || false;
125
+ this._radioInputs.push(input);
126
+ const radioMark = document.createElement('span');
127
+ radioMark.className = 'jux-radio-mark';
128
+ const labelText = document.createElement('span');
129
+ labelText.className = 'jux-radio-label-text';
130
+ labelText.textContent = option.label;
131
+ radioWrapper.appendChild(input);
132
+ radioWrapper.appendChild(radioMark);
133
+ radioWrapper.appendChild(labelText);
134
+ optionsContainer.appendChild(radioWrapper);
135
+ });
136
+ wrapper.appendChild(optionsContainer);
137
+ // Error element
138
+ wrapper.appendChild(this._renderError());
139
+ // Wire events
140
+ this._wireStandardEvents(wrapper);
141
+ // Wire radio-specific sync
142
+ const valueSync = this._syncBindings.find(b => b.property === 'value');
143
+ if (valueSync) {
144
+ const { stateObj, toState, toComponent } = valueSync;
145
+ const transformToState = toState || ((v) => v);
146
+ const transformToComponent = toComponent || ((v) => String(v));
147
+ let isUpdating = false;
148
+ // State → Component
149
+ stateObj.subscribe((val) => {
150
+ if (isUpdating)
151
+ return;
152
+ const transformed = transformToComponent(val);
153
+ this.setValue(transformed);
154
+ });
155
+ // Component → State
156
+ this._radioInputs.forEach(input => {
157
+ input.addEventListener('change', () => {
158
+ if (isUpdating)
159
+ return;
160
+ isUpdating = true;
161
+ const selectedValue = input.value;
162
+ this.state.value = selectedValue;
163
+ this._clearError();
164
+ const transformed = transformToState(selectedValue);
165
+ stateObj.set(transformed);
166
+ // 🎯 Fire the change callback event
167
+ this._triggerCallback('change', selectedValue);
168
+ setTimeout(() => { isUpdating = false; }, 0);
169
+ });
170
+ });
171
+ }
172
+ else {
173
+ // Default behavior without sync
174
+ this._radioInputs.forEach(input => {
175
+ input.addEventListener('change', () => {
176
+ this.state.value = input.value;
177
+ this._clearError();
178
+ // 🎯 Fire the change callback event
179
+ this._triggerCallback('change', input.value);
180
+ });
181
+ });
182
+ }
183
+ // Always add blur validation
184
+ this._radioInputs.forEach(input => {
185
+ input.addEventListener('blur', () => {
186
+ this.validate();
187
+ });
188
+ });
189
+ // Sync label changes
190
+ const labelSync = this._syncBindings.find(b => b.property === 'label');
191
+ if (labelSync) {
192
+ const transform = labelSync.toComponent || ((v) => String(v));
193
+ labelSync.stateObj.subscribe((val) => {
194
+ this.label(transform(val));
195
+ });
196
+ }
197
+ container.appendChild(wrapper);
198
+ return this;
199
+ }
200
+ }
201
+ export function radio(id, options = {}) {
202
+ return new Radio(id, options);
203
+ }