juxscript 1.1.252 → 1.1.254

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.
@@ -0,0 +1,62 @@
1
+ interface CheckboxOption {
2
+ label: string;
3
+ value: string;
4
+ disabled?: boolean;
5
+ checked?: boolean;
6
+ }
7
+ interface CheckboxOptions {
8
+ label?: string;
9
+ checked?: boolean;
10
+ disabled?: boolean;
11
+ class?: string;
12
+ style?: string;
13
+ }
14
+ interface CheckboxGroupOptions {
15
+ label?: string;
16
+ options?: CheckboxOption[];
17
+ values?: string[];
18
+ direction?: 'vertical' | 'horizontal';
19
+ disabled?: boolean;
20
+ class?: string;
21
+ style?: string;
22
+ }
23
+ declare class Checkbox {
24
+ id: string;
25
+ opts: CheckboxOptions;
26
+ private _element;
27
+ private _wrapper;
28
+ private _onChange;
29
+ constructor(id: string, options?: CheckboxOptions);
30
+ label(value: string): this;
31
+ checked(value?: boolean): this;
32
+ disabled(value?: boolean): this;
33
+ style(value: string): this;
34
+ class(value: string): this;
35
+ onChange(fn: (checked: boolean, event: Event) => void): this;
36
+ getValue(): boolean;
37
+ render(target?: string | HTMLElement): this;
38
+ }
39
+ declare class CheckboxGroup {
40
+ id: string;
41
+ opts: CheckboxGroupOptions;
42
+ private _wrapper;
43
+ private _inputs;
44
+ private _onChange;
45
+ constructor(id: string, options?: CheckboxGroupOptions);
46
+ label(value: string): this;
47
+ direction(value: 'vertical' | 'horizontal'): this;
48
+ disabled(value?: boolean): this;
49
+ style(value: string): this;
50
+ class(value: string): this;
51
+ options(opts: CheckboxOption[]): this;
52
+ values(vals: string[]): this;
53
+ onChange(fn: (values: string[], event: Event) => void): this;
54
+ getValues(): string[];
55
+ private _rebuild;
56
+ private _buildOptions;
57
+ render(target?: string | HTMLElement): this;
58
+ }
59
+ export declare function checkbox(id: string, options?: CheckboxOptions): Checkbox;
60
+ export declare function checkboxGroup(id: string, options?: CheckboxGroupOptions): CheckboxGroup;
61
+ export { Checkbox, CheckboxGroup, CheckboxOption, CheckboxOptions, CheckboxGroupOptions };
62
+ //# sourceMappingURL=checkbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../lib/components/checkbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,175 @@
1
+ import generateId from '../utils/idgen.js';
2
+ // ═══════════════════════════════════════════════════════════
3
+ // Standalone Checkbox (boolean toggle)
4
+ // ═══════════════════════════════════════════════════════════
5
+ class Checkbox {
6
+ constructor(id, options = {}) {
7
+ this._element = null;
8
+ this._wrapper = null;
9
+ this._onChange = null;
10
+ this.id = id || generateId();
11
+ this.opts = options;
12
+ }
13
+ label(value) { this.opts.label = value; return this; }
14
+ checked(value = true) { this.opts.checked = value; if (this._element)
15
+ this._element.checked = value; return this; }
16
+ disabled(value = true) { this.opts.disabled = value; if (this._element)
17
+ this._element.disabled = value; return this; }
18
+ style(value) { this.opts.style = value; return this; }
19
+ class(value) { this.opts.class = value; return this; }
20
+ onChange(fn) {
21
+ this._onChange = fn;
22
+ return this;
23
+ }
24
+ getValue() {
25
+ return this._element?.checked ?? this.opts.checked ?? false;
26
+ }
27
+ render(target) {
28
+ const wrapper = document.createElement('label');
29
+ wrapper.className = 'jux-checkbox';
30
+ wrapper.id = `${this.id}-wrapper`;
31
+ if (this.opts.class)
32
+ wrapper.className += ` ${this.opts.class}`;
33
+ if (this.opts.style)
34
+ wrapper.setAttribute('style', this.opts.style);
35
+ const inp = document.createElement('input');
36
+ inp.type = 'checkbox';
37
+ inp.id = this.id;
38
+ inp.className = 'jux-checkbox-input';
39
+ if (this.opts.checked)
40
+ inp.checked = true;
41
+ if (this.opts.disabled)
42
+ inp.disabled = true;
43
+ inp.addEventListener('change', (e) => {
44
+ if (this._onChange)
45
+ this._onChange(inp.checked, e);
46
+ });
47
+ wrapper.appendChild(inp);
48
+ if (this.opts.label) {
49
+ const text = document.createElement('span');
50
+ text.className = 'jux-checkbox-label';
51
+ text.textContent = this.opts.label;
52
+ wrapper.appendChild(text);
53
+ }
54
+ this._element = inp;
55
+ this._wrapper = wrapper;
56
+ const container = target
57
+ ? (typeof target === 'string' ? document.getElementById(target) || document.querySelector(target) : target)
58
+ : document.getElementById('app');
59
+ container?.appendChild(wrapper);
60
+ return this;
61
+ }
62
+ }
63
+ // ═══════════════════════════════════════════════════════════
64
+ // CheckboxGroup (multi-select from options)
65
+ // ═══════════════════════════════════════════════════════════
66
+ class CheckboxGroup {
67
+ constructor(id, options = {}) {
68
+ this._wrapper = null;
69
+ this._inputs = [];
70
+ this._onChange = null;
71
+ this.id = id || generateId();
72
+ this.opts = {
73
+ options: [],
74
+ values: [],
75
+ direction: 'vertical',
76
+ ...options
77
+ };
78
+ }
79
+ label(value) { this.opts.label = value; return this; }
80
+ direction(value) { this.opts.direction = value; return this; }
81
+ disabled(value = true) { this.opts.disabled = value; return this; }
82
+ style(value) { this.opts.style = value; return this; }
83
+ class(value) { this.opts.class = value; return this; }
84
+ options(opts) {
85
+ this.opts.options = opts;
86
+ if (this._wrapper)
87
+ this._rebuild();
88
+ return this;
89
+ }
90
+ values(vals) {
91
+ this.opts.values = vals;
92
+ this._inputs.forEach(inp => {
93
+ inp.checked = vals.includes(inp.value);
94
+ });
95
+ return this;
96
+ }
97
+ onChange(fn) {
98
+ this._onChange = fn;
99
+ return this;
100
+ }
101
+ getValues() {
102
+ return this._inputs.filter(i => i.checked).map(i => i.value);
103
+ }
104
+ _rebuild() {
105
+ if (!this._wrapper)
106
+ return;
107
+ const group = this._wrapper.querySelector('.jux-checkbox-options');
108
+ if (!group)
109
+ return;
110
+ group.innerHTML = '';
111
+ this._inputs = [];
112
+ this._buildOptions(group);
113
+ }
114
+ _buildOptions(container) {
115
+ for (const opt of this.opts.options || []) {
116
+ const item = document.createElement('label');
117
+ item.className = 'jux-checkbox-item';
118
+ const inp = document.createElement('input');
119
+ inp.type = 'checkbox';
120
+ inp.value = opt.value;
121
+ inp.className = 'jux-checkbox-input';
122
+ if (opt.checked || this.opts.values?.includes(opt.value))
123
+ inp.checked = true;
124
+ if (opt.disabled || this.opts.disabled)
125
+ inp.disabled = true;
126
+ inp.addEventListener('change', (e) => {
127
+ if (this._onChange)
128
+ this._onChange(this.getValues(), e);
129
+ });
130
+ const text = document.createElement('span');
131
+ text.className = 'jux-checkbox-label';
132
+ text.textContent = opt.label;
133
+ item.appendChild(inp);
134
+ item.appendChild(text);
135
+ container.appendChild(item);
136
+ this._inputs.push(inp);
137
+ }
138
+ }
139
+ render(target) {
140
+ const wrapper = document.createElement('fieldset');
141
+ wrapper.className = 'jux-checkbox-group';
142
+ wrapper.id = this.id;
143
+ if (this.opts.class)
144
+ wrapper.className += ` ${this.opts.class}`;
145
+ if (this.opts.style)
146
+ wrapper.setAttribute('style', this.opts.style);
147
+ if (this.opts.label) {
148
+ const legend = document.createElement('legend');
149
+ legend.textContent = this.opts.label;
150
+ legend.className = 'jux-checkbox-group-label';
151
+ wrapper.appendChild(legend);
152
+ }
153
+ const optionsDiv = document.createElement('div');
154
+ optionsDiv.className = `jux-checkbox-options jux-checkbox-${this.opts.direction}`;
155
+ this._buildOptions(optionsDiv);
156
+ wrapper.appendChild(optionsDiv);
157
+ this._wrapper = wrapper;
158
+ const container = target
159
+ ? (typeof target === 'string' ? document.getElementById(target) || document.querySelector(target) : target)
160
+ : document.getElementById('app');
161
+ container?.appendChild(wrapper);
162
+ return this;
163
+ }
164
+ }
165
+ export function checkbox(id, options = {}) {
166
+ const c = new Checkbox(id, options);
167
+ c.render();
168
+ return c;
169
+ }
170
+ export function checkboxGroup(id, options = {}) {
171
+ const g = new CheckboxGroup(id, options);
172
+ g.render();
173
+ return g;
174
+ }
175
+ export { Checkbox, CheckboxGroup };
@@ -0,0 +1,43 @@
1
+ type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'time' | 'datetime-local' | 'color' | 'range' | 'file' | 'hidden';
2
+ interface InputOptions {
3
+ type?: InputType;
4
+ label?: string;
5
+ placeholder?: string;
6
+ value?: string;
7
+ name?: string;
8
+ required?: boolean;
9
+ disabled?: boolean;
10
+ readonly?: boolean;
11
+ min?: string | number;
12
+ max?: string | number;
13
+ step?: string | number;
14
+ pattern?: string;
15
+ autocomplete?: string;
16
+ class?: string;
17
+ style?: string;
18
+ }
19
+ declare class Input {
20
+ id: string;
21
+ options: InputOptions;
22
+ private _element;
23
+ private _wrapper;
24
+ private _onChange;
25
+ constructor(id: string, options?: InputOptions);
26
+ type(value: InputType): this;
27
+ label(value: string): this;
28
+ placeholder(value: string): this;
29
+ value(value: string): this;
30
+ name(value: string): this;
31
+ required(value?: boolean): this;
32
+ disabled(value?: boolean): this;
33
+ readonly(value?: boolean): this;
34
+ style(value: string): this;
35
+ class(value: string): this;
36
+ onChange(fn: (value: string, event: Event) => void): this;
37
+ getValue(): string;
38
+ setValue(val: string): this;
39
+ render(target?: string | HTMLElement): this;
40
+ }
41
+ export declare function input(id: string, options?: InputOptions): Input;
42
+ export { Input, InputOptions };
43
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../lib/components/input.ts"],"names":[],"mappings":"AAEA,KAAK,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAElK,UAAU,YAAY;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,KAAK;IACP,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IASlD,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAC5B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAChC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IACzB,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAE1B,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM3B,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;CA8CvC;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAInE;AAED,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,99 @@
1
+ import generateId from '../utils/idgen.js';
2
+ class Input {
3
+ constructor(id, options = {}) {
4
+ this._element = null;
5
+ this._wrapper = null;
6
+ this._onChange = null;
7
+ this.id = id || generateId();
8
+ this.options = {
9
+ type: 'text',
10
+ ...options
11
+ };
12
+ }
13
+ // Fluent API
14
+ type(value) { this.options.type = value; return this; }
15
+ label(value) { this.options.label = value; return this; }
16
+ placeholder(value) { this.options.placeholder = value; return this; }
17
+ value(value) { this.options.value = value; if (this._element)
18
+ this._element.value = value; return this; }
19
+ name(value) { this.options.name = value; return this; }
20
+ required(value = true) { this.options.required = value; return this; }
21
+ disabled(value = true) { this.options.disabled = value; if (this._element)
22
+ this._element.disabled = value; return this; }
23
+ readonly(value = true) { this.options.readonly = value; return this; }
24
+ style(value) { this.options.style = value; return this; }
25
+ class(value) { this.options.class = value; return this; }
26
+ onChange(fn) {
27
+ this._onChange = fn;
28
+ return this;
29
+ }
30
+ getValue() {
31
+ return this._element?.value ?? this.options.value ?? '';
32
+ }
33
+ setValue(val) {
34
+ if (this._element)
35
+ this._element.value = val;
36
+ this.options.value = val;
37
+ return this;
38
+ }
39
+ render(target) {
40
+ const wrapper = document.createElement('div');
41
+ wrapper.className = 'jux-input';
42
+ wrapper.id = `${this.id}-wrapper`;
43
+ if (this.options.class)
44
+ wrapper.className += ` ${this.options.class}`;
45
+ if (this.options.style)
46
+ wrapper.setAttribute('style', this.options.style);
47
+ if (this.options.label) {
48
+ const labelEl = document.createElement('label');
49
+ labelEl.htmlFor = this.id;
50
+ labelEl.textContent = this.options.label;
51
+ labelEl.className = 'jux-input-label';
52
+ wrapper.appendChild(labelEl);
53
+ }
54
+ const input = document.createElement('input');
55
+ input.id = this.id;
56
+ input.type = this.options.type || 'text';
57
+ input.className = 'jux-input-element';
58
+ if (this.options.placeholder)
59
+ input.placeholder = this.options.placeholder;
60
+ if (this.options.value)
61
+ input.value = this.options.value;
62
+ if (this.options.name)
63
+ input.name = this.options.name;
64
+ if (this.options.required)
65
+ input.required = true;
66
+ if (this.options.disabled)
67
+ input.disabled = true;
68
+ if (this.options.readonly)
69
+ input.readOnly = true;
70
+ if (this.options.min != null)
71
+ input.min = String(this.options.min);
72
+ if (this.options.max != null)
73
+ input.max = String(this.options.max);
74
+ if (this.options.step != null)
75
+ input.step = String(this.options.step);
76
+ if (this.options.pattern)
77
+ input.pattern = this.options.pattern;
78
+ if (this.options.autocomplete)
79
+ input.autocomplete = this.options.autocomplete;
80
+ input.addEventListener('input', (e) => {
81
+ if (this._onChange)
82
+ this._onChange(input.value, e);
83
+ });
84
+ wrapper.appendChild(input);
85
+ this._element = input;
86
+ this._wrapper = wrapper;
87
+ const container = target
88
+ ? (typeof target === 'string' ? document.getElementById(target) || document.querySelector(target) : target)
89
+ : document.getElementById('app');
90
+ container?.appendChild(wrapper);
91
+ return this;
92
+ }
93
+ }
94
+ export function input(id, options = {}) {
95
+ const inp = new Input(id, options);
96
+ inp.render();
97
+ return inp;
98
+ }
99
+ export { Input };
@@ -0,0 +1,40 @@
1
+ interface RadioOption {
2
+ label: string;
3
+ value: string;
4
+ disabled?: boolean;
5
+ }
6
+ interface RadioGroupOptions {
7
+ label?: string;
8
+ name?: string;
9
+ options?: RadioOption[];
10
+ value?: string;
11
+ direction?: 'vertical' | 'horizontal';
12
+ required?: boolean;
13
+ disabled?: boolean;
14
+ class?: string;
15
+ style?: string;
16
+ }
17
+ declare class RadioGroup {
18
+ id: string;
19
+ opts: RadioGroupOptions;
20
+ private _wrapper;
21
+ private _inputs;
22
+ private _onChange;
23
+ constructor(id: string, options?: RadioGroupOptions);
24
+ label(value: string): this;
25
+ direction(value: 'vertical' | 'horizontal'): this;
26
+ required(value?: boolean): this;
27
+ disabled(value?: boolean): this;
28
+ style(value: string): this;
29
+ class(value: string): this;
30
+ options(opts: RadioOption[]): this;
31
+ value(val: string): this;
32
+ onChange(fn: (value: string, event: Event) => void): this;
33
+ getValue(): string;
34
+ private _rebuild;
35
+ private _buildOptions;
36
+ render(target?: string | HTMLElement): this;
37
+ }
38
+ export declare function radio(id: string, options?: RadioGroupOptions): RadioGroup;
39
+ export { RadioGroup, RadioOption, RadioGroupOptions };
40
+ //# sourceMappingURL=radio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../../lib/components/radio.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,iBAAiB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,UAAU;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAWvD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI;IACjD,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAE1B,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI;IAMlC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMxB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAKlB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,aAAa;IA6BrB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;CA4B9C;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAI7E;AAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,110 @@
1
+ import generateId from '../utils/idgen.js';
2
+ class RadioGroup {
3
+ constructor(id, options = {}) {
4
+ this._wrapper = null;
5
+ this._inputs = [];
6
+ this._onChange = null;
7
+ this.id = id || generateId();
8
+ this.opts = {
9
+ options: [],
10
+ direction: 'vertical',
11
+ name: id,
12
+ ...options
13
+ };
14
+ }
15
+ // Fluent API
16
+ label(value) { this.opts.label = value; return this; }
17
+ direction(value) { this.opts.direction = value; return this; }
18
+ required(value = true) { this.opts.required = value; return this; }
19
+ disabled(value = true) { this.opts.disabled = value; return this; }
20
+ style(value) { this.opts.style = value; return this; }
21
+ class(value) { this.opts.class = value; return this; }
22
+ options(opts) {
23
+ this.opts.options = opts;
24
+ if (this._wrapper)
25
+ this._rebuild();
26
+ return this;
27
+ }
28
+ value(val) {
29
+ this.opts.value = val;
30
+ this._inputs.forEach(inp => { inp.checked = inp.value === val; });
31
+ return this;
32
+ }
33
+ onChange(fn) {
34
+ this._onChange = fn;
35
+ return this;
36
+ }
37
+ getValue() {
38
+ const checked = this._inputs.find(i => i.checked);
39
+ return checked?.value ?? this.opts.value ?? '';
40
+ }
41
+ _rebuild() {
42
+ if (!this._wrapper)
43
+ return;
44
+ const group = this._wrapper.querySelector('.jux-radio-options');
45
+ if (!group)
46
+ return;
47
+ group.innerHTML = '';
48
+ this._inputs = [];
49
+ this._buildOptions(group);
50
+ }
51
+ _buildOptions(container) {
52
+ for (const opt of this.opts.options || []) {
53
+ const item = document.createElement('label');
54
+ item.className = 'jux-radio-item';
55
+ const inp = document.createElement('input');
56
+ inp.type = 'radio';
57
+ inp.name = this.opts.name || this.id;
58
+ inp.value = opt.value;
59
+ inp.className = 'jux-radio-input';
60
+ if (opt.value === this.opts.value)
61
+ inp.checked = true;
62
+ if (opt.disabled || this.opts.disabled)
63
+ inp.disabled = true;
64
+ if (this.opts.required)
65
+ inp.required = true;
66
+ inp.addEventListener('change', (e) => {
67
+ if (this._onChange)
68
+ this._onChange(inp.value, e);
69
+ });
70
+ const text = document.createElement('span');
71
+ text.className = 'jux-radio-label';
72
+ text.textContent = opt.label;
73
+ item.appendChild(inp);
74
+ item.appendChild(text);
75
+ container.appendChild(item);
76
+ this._inputs.push(inp);
77
+ }
78
+ }
79
+ render(target) {
80
+ const wrapper = document.createElement('fieldset');
81
+ wrapper.className = 'jux-radio-group';
82
+ wrapper.id = this.id;
83
+ if (this.opts.class)
84
+ wrapper.className += ` ${this.opts.class}`;
85
+ if (this.opts.style)
86
+ wrapper.setAttribute('style', this.opts.style);
87
+ if (this.opts.label) {
88
+ const legend = document.createElement('legend');
89
+ legend.textContent = this.opts.label;
90
+ legend.className = 'jux-radio-group-label';
91
+ wrapper.appendChild(legend);
92
+ }
93
+ const optionsDiv = document.createElement('div');
94
+ optionsDiv.className = `jux-radio-options jux-radio-${this.opts.direction}`;
95
+ this._buildOptions(optionsDiv);
96
+ wrapper.appendChild(optionsDiv);
97
+ this._wrapper = wrapper;
98
+ const container = target
99
+ ? (typeof target === 'string' ? document.getElementById(target) || document.querySelector(target) : target)
100
+ : document.getElementById('app');
101
+ container?.appendChild(wrapper);
102
+ return this;
103
+ }
104
+ }
105
+ export function radio(id, options = {}) {
106
+ const r = new RadioGroup(id, options);
107
+ r.render();
108
+ return r;
109
+ }
110
+ export { RadioGroup };
@@ -0,0 +1,41 @@
1
+ interface SelectOption {
2
+ label: string;
3
+ value: string;
4
+ disabled?: boolean;
5
+ }
6
+ interface SelectOptions {
7
+ label?: string;
8
+ placeholder?: string;
9
+ options?: SelectOption[];
10
+ value?: string;
11
+ required?: boolean;
12
+ disabled?: boolean;
13
+ multiple?: boolean;
14
+ class?: string;
15
+ style?: string;
16
+ }
17
+ declare class Select {
18
+ id: string;
19
+ opts: SelectOptions;
20
+ private _element;
21
+ private _wrapper;
22
+ private _onChange;
23
+ constructor(id: string, options?: SelectOptions);
24
+ label(value: string): this;
25
+ placeholder(value: string): this;
26
+ required(value?: boolean): this;
27
+ disabled(value?: boolean): this;
28
+ multiple(value?: boolean): this;
29
+ style(value: string): this;
30
+ class(value: string): this;
31
+ options(opts: SelectOption[]): this;
32
+ value(val: string): this;
33
+ onChange(fn: (value: string, event: Event) => void): this;
34
+ getValue(): string;
35
+ getSelectedValues(): string[];
36
+ private _rebuildOptions;
37
+ render(target?: string | HTMLElement): this;
38
+ }
39
+ export declare function select(id: string, options?: SelectOptions): Select;
40
+ export { Select, SelectOption, SelectOptions };
41
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../lib/components/select.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,aAAa;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,MAAM;IACR,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;IAMnD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAChC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAE1B,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI;IAMnC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMxB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAIlB,iBAAiB,IAAI,MAAM,EAAE;IAK7B,OAAO,CAAC,eAAe;IAuBvB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;CAuC9C;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAItE;AAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,109 @@
1
+ import generateId from '../utils/idgen.js';
2
+ class Select {
3
+ constructor(id, options = {}) {
4
+ this._element = null;
5
+ this._wrapper = null;
6
+ this._onChange = null;
7
+ this.id = id || generateId();
8
+ this.opts = { options: [], ...options };
9
+ }
10
+ // Fluent API
11
+ label(value) { this.opts.label = value; return this; }
12
+ placeholder(value) { this.opts.placeholder = value; return this; }
13
+ required(value = true) { this.opts.required = value; return this; }
14
+ disabled(value = true) { this.opts.disabled = value; return this; }
15
+ multiple(value = true) { this.opts.multiple = value; return this; }
16
+ style(value) { this.opts.style = value; return this; }
17
+ class(value) { this.opts.class = value; return this; }
18
+ options(opts) {
19
+ this.opts.options = opts;
20
+ if (this._element)
21
+ this._rebuildOptions();
22
+ return this;
23
+ }
24
+ value(val) {
25
+ this.opts.value = val;
26
+ if (this._element)
27
+ this._element.value = val;
28
+ return this;
29
+ }
30
+ onChange(fn) {
31
+ this._onChange = fn;
32
+ return this;
33
+ }
34
+ getValue() {
35
+ return this._element?.value ?? this.opts.value ?? '';
36
+ }
37
+ getSelectedValues() {
38
+ if (!this._element)
39
+ return [];
40
+ return Array.from(this._element.selectedOptions).map(o => o.value);
41
+ }
42
+ _rebuildOptions() {
43
+ if (!this._element)
44
+ return;
45
+ this._element.innerHTML = '';
46
+ if (this.opts.placeholder) {
47
+ const ph = document.createElement('option');
48
+ ph.value = '';
49
+ ph.textContent = this.opts.placeholder;
50
+ ph.disabled = true;
51
+ ph.selected = !this.opts.value;
52
+ this._element.appendChild(ph);
53
+ }
54
+ for (const opt of this.opts.options || []) {
55
+ const o = document.createElement('option');
56
+ o.value = opt.value;
57
+ o.textContent = opt.label;
58
+ if (opt.disabled)
59
+ o.disabled = true;
60
+ if (opt.value === this.opts.value)
61
+ o.selected = true;
62
+ this._element.appendChild(o);
63
+ }
64
+ }
65
+ render(target) {
66
+ const wrapper = document.createElement('div');
67
+ wrapper.className = 'jux-select';
68
+ wrapper.id = `${this.id}-wrapper`;
69
+ if (this.opts.class)
70
+ wrapper.className += ` ${this.opts.class}`;
71
+ if (this.opts.style)
72
+ wrapper.setAttribute('style', this.opts.style);
73
+ if (this.opts.label) {
74
+ const labelEl = document.createElement('label');
75
+ labelEl.htmlFor = this.id;
76
+ labelEl.textContent = this.opts.label;
77
+ labelEl.className = 'jux-select-label';
78
+ wrapper.appendChild(labelEl);
79
+ }
80
+ const sel = document.createElement('select');
81
+ sel.id = this.id;
82
+ sel.className = 'jux-select-element';
83
+ if (this.opts.required)
84
+ sel.required = true;
85
+ if (this.opts.disabled)
86
+ sel.disabled = true;
87
+ if (this.opts.multiple)
88
+ sel.multiple = true;
89
+ this._element = sel;
90
+ this._rebuildOptions();
91
+ sel.addEventListener('change', (e) => {
92
+ if (this._onChange)
93
+ this._onChange(sel.value, e);
94
+ });
95
+ wrapper.appendChild(sel);
96
+ this._wrapper = wrapper;
97
+ const container = target
98
+ ? (typeof target === 'string' ? document.getElementById(target) || document.querySelector(target) : target)
99
+ : document.getElementById('app');
100
+ container?.appendChild(wrapper);
101
+ return this;
102
+ }
103
+ }
104
+ export function select(id, options = {}) {
105
+ const s = new Select(id, options);
106
+ s.render();
107
+ return s;
108
+ }
109
+ export { Select };
@@ -1,5 +1,9 @@
1
- import { tag, div, h1, h2, h3, h4, h5, h6, p, span, pre } from "./components/tag";
2
- import { include } from "./components/include";
1
+ import { tag, div, h1, h2, h3, h4, h5, h6, p, span, pre } from "./components/tag.js";
2
+ import { include } from "./components/include.js";
3
+ import { input } from "./components/input.js";
4
+ import { select } from "./components/select.js";
5
+ import { radio } from "./components/radio.js";
6
+ import { checkbox, checkboxGroup } from "./components/checkbox.js";
3
7
  export declare const jux: {
4
8
  tag: typeof tag;
5
9
  div: typeof div;
@@ -13,5 +17,10 @@ export declare const jux: {
13
17
  span: typeof span;
14
18
  pre: typeof pre;
15
19
  include: typeof include;
20
+ input: typeof input;
21
+ select: typeof select;
22
+ radio: typeof radio;
23
+ checkbox: typeof checkbox;
24
+ checkboxGroup: typeof checkboxGroup;
16
25
  };
17
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,eAAO,MAAM,GAAG;;;;;;;;;;;;;CASf,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEnE,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;CAaf,CAAA"}
package/dist/lib/index.js CHANGED
@@ -1,5 +1,9 @@
1
- import { tag, div, h1, h2, h3, h4, h5, h6, p, span, pre } from "./components/tag";
2
- import { include } from "./components/include";
1
+ import { tag, div, h1, h2, h3, h4, h5, h6, p, span, pre } from "./components/tag.js";
2
+ import { include } from "./components/include.js";
3
+ import { input } from "./components/input.js";
4
+ import { select } from "./components/select.js";
5
+ import { radio } from "./components/radio.js";
6
+ import { checkbox, checkboxGroup } from "./components/checkbox.js";
3
7
  export const jux = {
4
8
  tag,
5
9
  div,
@@ -7,5 +11,10 @@ export const jux = {
7
11
  p,
8
12
  span,
9
13
  pre,
10
- include
14
+ include,
15
+ input,
16
+ select,
17
+ radio,
18
+ checkbox,
19
+ checkboxGroup
11
20
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.252",
3
+ "version": "1.1.254",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "./dist/lib/index.js",