@ktjs/mui 0.17.9 → 0.18.0
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.
- package/dist/index.d.ts +22 -13
- package/dist/index.iife.js +144 -40
- package/dist/index.mjs +144 -40
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ interface AlertProps {
|
|
|
9
9
|
severity?: 'error' | 'warning' | 'info' | 'success';
|
|
10
10
|
variant?: 'standard' | 'filled' | 'outlined';
|
|
11
11
|
icon?: HTMLElement | KTHTMLElement | false;
|
|
12
|
-
'
|
|
12
|
+
'kt:close'?: () => void;
|
|
13
13
|
}
|
|
14
14
|
/**s
|
|
15
15
|
* Alert component - mimics MUI Alert appearance and behavior
|
|
@@ -41,7 +41,7 @@ interface CheckboxProps {
|
|
|
41
41
|
label?: string | KTHTMLElement | HTMLElement;
|
|
42
42
|
checked?: boolean;
|
|
43
43
|
size?: 'small' | 'medium';
|
|
44
|
-
'
|
|
44
|
+
'kt:change'?: (checked: boolean, value: string) => void;
|
|
45
45
|
disabled?: boolean;
|
|
46
46
|
color?: 'primary' | 'secondary' | 'default' | 'success' | 'error' | 'warning';
|
|
47
47
|
indeterminate?: boolean;
|
|
@@ -63,7 +63,7 @@ interface CheckboxGroupProps {
|
|
|
63
63
|
value?: string[];
|
|
64
64
|
size?: 'small' | 'medium';
|
|
65
65
|
options: CheckboxProps[];
|
|
66
|
-
'
|
|
66
|
+
'kt:change'?: (values: string[]) => void;
|
|
67
67
|
row?: boolean;
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
@@ -73,7 +73,7 @@ declare function CheckboxGroup(props: CheckboxGroupProps): KTMuiCheckboxGroup;
|
|
|
73
73
|
|
|
74
74
|
interface DialogProps {
|
|
75
75
|
open?: boolean;
|
|
76
|
-
'
|
|
76
|
+
'kt:close'?: () => void;
|
|
77
77
|
title?: string;
|
|
78
78
|
children?: HTMLElement | HTMLElement[] | string;
|
|
79
79
|
actions?: HTMLElement | HTMLElement[];
|
|
@@ -138,15 +138,24 @@ interface TextFieldProps {
|
|
|
138
138
|
fullWidth?: boolean;
|
|
139
139
|
multiline?: boolean;
|
|
140
140
|
rows?: number;
|
|
141
|
-
maxRows?: number;
|
|
142
141
|
size?: 'small' | 'medium';
|
|
143
|
-
'
|
|
144
|
-
'
|
|
145
|
-
'
|
|
146
|
-
'
|
|
142
|
+
'kt:input'?: (value: string, event: Event) => void;
|
|
143
|
+
'kt-trim:input'?: (value: string, event: Event) => void;
|
|
144
|
+
'kt:change'?: (value: string, event: Event) => void;
|
|
145
|
+
'kt-trim:change'?: (value: string, event: Event) => void;
|
|
146
|
+
'kt:blur'?: (value: string, event: Event) => void;
|
|
147
|
+
'kt:focus'?: (value: string, event: Event) => void;
|
|
147
148
|
}
|
|
148
149
|
type KTMuiTextField = KTHTMLElement & {
|
|
149
150
|
value: string;
|
|
151
|
+
label: string;
|
|
152
|
+
placeholder: string;
|
|
153
|
+
type: string;
|
|
154
|
+
disabled: boolean;
|
|
155
|
+
readonly: boolean;
|
|
156
|
+
required: boolean;
|
|
157
|
+
error: boolean;
|
|
158
|
+
helperText: string;
|
|
150
159
|
};
|
|
151
160
|
/**
|
|
152
161
|
* TextField component - mimics MUI TextField appearance and behavior
|
|
@@ -158,7 +167,7 @@ interface RadioProps {
|
|
|
158
167
|
text: string | KTHTMLElement | HTMLElement;
|
|
159
168
|
checked?: boolean;
|
|
160
169
|
size?: 'small' | 'medium';
|
|
161
|
-
'
|
|
170
|
+
'kt:change'?: (checked: boolean, value: string) => void;
|
|
162
171
|
disabled?: boolean;
|
|
163
172
|
color?: 'primary' | 'secondary' | 'default';
|
|
164
173
|
}
|
|
@@ -176,8 +185,8 @@ interface RadioGroupProps {
|
|
|
176
185
|
name?: string;
|
|
177
186
|
size?: 'small' | 'medium';
|
|
178
187
|
options: RadioProps[];
|
|
179
|
-
'
|
|
180
|
-
'
|
|
188
|
+
'kt:change'?: (value: string) => void;
|
|
189
|
+
'kt:click'?: (checked: boolean) => void;
|
|
181
190
|
row?: boolean;
|
|
182
191
|
}
|
|
183
192
|
/**
|
|
@@ -197,7 +206,7 @@ interface SelectProps {
|
|
|
197
206
|
options: SelectOption[];
|
|
198
207
|
label?: string;
|
|
199
208
|
placeholder?: string;
|
|
200
|
-
'
|
|
209
|
+
'kt:change'?: (value: string) => void;
|
|
201
210
|
fullWidth?: boolean;
|
|
202
211
|
disabled?: boolean;
|
|
203
212
|
}
|
package/dist/index.iife.js
CHANGED
|
@@ -5,7 +5,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
5
5
|
* Alert component - mimics MUI Alert appearance and behavior
|
|
6
6
|
*/
|
|
7
7
|
function Alert(props) {
|
|
8
|
-
const { children, severity = 'info', variant = 'standard', icon, '
|
|
8
|
+
const { children, severity = 'info', variant = 'standard', icon, 'kt:close': onClose, sx } = props;
|
|
9
9
|
const classes = `mui-alert mui-alert-${severity} mui-alert-${variant} ${props.class ? props.class : ''}`;
|
|
10
10
|
// Convert sx object to style string
|
|
11
11
|
let styleString = props.style || '';
|
|
@@ -44,12 +44,12 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
44
44
|
return alert;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const emptyFn$
|
|
47
|
+
const emptyFn$3 = () => { };
|
|
48
48
|
/**
|
|
49
49
|
* Button component - mimics MUI Button appearance and behavior
|
|
50
50
|
*/
|
|
51
51
|
function Button(props) {
|
|
52
|
-
const { children, variant = 'text', color = 'primary', size = 'medium', disabled = false, fullWidth = false, iconOnly = false, startIcon, endIcon, type = 'button', 'on:click': onClick = emptyFn$
|
|
52
|
+
const { children, variant = 'text', color = 'primary', size = 'medium', disabled = false, fullWidth = false, iconOnly = false, startIcon, endIcon, type = 'button', 'on:click': onClick = emptyFn$3, } = props;
|
|
53
53
|
const classes = [
|
|
54
54
|
'mui-button',
|
|
55
55
|
`mui-button-${variant}`,
|
|
@@ -91,7 +91,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
91
91
|
return (jsxRuntime.jsxs("button", { class: classes, style: props.style ? props.style : '', type: type, disabled: disabled, "on:click": handleClick, children: [startIcon && jsxRuntime.jsx("span", { class: "mui-button-start-icon", children: startIcon }), jsxRuntime.jsx("span", { class: "mui-button-label", children: children }), endIcon && jsxRuntime.jsx("span", { class: "mui-button-end-icon", children: endIcon }), jsxRuntime.jsx("span", { class: "mui-button-ripple" })] }));
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
const emptyFn$
|
|
94
|
+
const emptyFn$2 = () => { };
|
|
95
95
|
/**
|
|
96
96
|
* Checkbox component - mimics MUI Checkbox appearance and behavior
|
|
97
97
|
*/
|
|
@@ -118,7 +118,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
118
118
|
toggleIcon(checked, indeterminate);
|
|
119
119
|
onChange(checked, value);
|
|
120
120
|
};
|
|
121
|
-
let { checked = false, value = '', label = '', size = 'medium', '
|
|
121
|
+
let { checked = false, value = '', label = '', size = 'medium', 'kt:change': onChange = emptyFn$2, disabled = false, color = 'primary', indeterminate = false, } = props;
|
|
122
122
|
const inputRef = kt_js.ref();
|
|
123
123
|
// Unchecked icon
|
|
124
124
|
const uncheckedIcon = (jsxRuntime.jsx("span", { class: "mui-checkbox-icon-unchecked", children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", children: jsxRuntime.jsx("path", { d: "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z" }) }) }));
|
|
@@ -147,7 +147,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
147
147
|
* CheckboxGroup component - groups multiple checkboxes together
|
|
148
148
|
*/
|
|
149
149
|
function CheckboxGroup(props) {
|
|
150
|
-
let { value = [], size = 'medium', '
|
|
150
|
+
let { value = [], size = 'medium', 'kt:change': onChange = emptyFn$2, row = false } = props;
|
|
151
151
|
let selectedValues = new Set(value);
|
|
152
152
|
const changeHandler = (checked, checkboxValue) => {
|
|
153
153
|
if (checked) {
|
|
@@ -161,15 +161,15 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
161
161
|
const checkboxes = props.options.map((o) => {
|
|
162
162
|
o.size = size;
|
|
163
163
|
o.checked = selectedValues.has(o.value);
|
|
164
|
-
const originalChange = o['
|
|
164
|
+
const originalChange = o['kt:change'];
|
|
165
165
|
if (originalChange) {
|
|
166
|
-
o['
|
|
166
|
+
o['kt:change'] = (checked, value) => {
|
|
167
167
|
originalChange(checked, value);
|
|
168
168
|
changeHandler(checked, value);
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
else {
|
|
172
|
-
o['
|
|
172
|
+
o['kt:change'] = changeHandler;
|
|
173
173
|
}
|
|
174
174
|
return Checkbox(o);
|
|
175
175
|
});
|
|
@@ -189,13 +189,13 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
189
189
|
return container;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
const noop = () => { };
|
|
192
|
+
const noop$1 = () => { };
|
|
193
193
|
/**
|
|
194
194
|
* Dialog component - mimics MUI Dialog appearance and behavior
|
|
195
195
|
* Only handles open/close state, title and content are passed as props
|
|
196
196
|
*/
|
|
197
197
|
function Dialog(props) {
|
|
198
|
-
let { open = false, '
|
|
198
|
+
let { open = false, 'kt:close': onClose = noop$1, title, children, actions, maxWidth = 'sm', fullWidth = false, } = props;
|
|
199
199
|
// Handle ESC key - store handler for cleanup
|
|
200
200
|
const keyDownHandler = (e) => {
|
|
201
201
|
if (e.key === 'Escape') {
|
|
@@ -280,8 +280,42 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
280
280
|
* - can alse be used to store normal values, but it is not reactive.
|
|
281
281
|
* @param value mostly an HTMLElement
|
|
282
282
|
*/
|
|
283
|
-
function ref(value) {
|
|
284
|
-
|
|
283
|
+
function ref(value, onChange) {
|
|
284
|
+
let _value = value;
|
|
285
|
+
let _onChanges = [];
|
|
286
|
+
return {
|
|
287
|
+
isKT: true,
|
|
288
|
+
get value() {
|
|
289
|
+
return _value;
|
|
290
|
+
},
|
|
291
|
+
set value(newValue) {
|
|
292
|
+
if (newValue === _value) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
// replace the old node with the new one in the DOM if both are nodes
|
|
296
|
+
if (_value instanceof Node && newValue instanceof Node) {
|
|
297
|
+
if (newValue.contains(_value)) {
|
|
298
|
+
_value.remove();
|
|
299
|
+
}
|
|
300
|
+
_value.replaceWith(newValue);
|
|
301
|
+
}
|
|
302
|
+
const oldValue = _value;
|
|
303
|
+
_value = newValue;
|
|
304
|
+
for (let i = 0; i < _onChanges.length; i++) {
|
|
305
|
+
_onChanges[i](newValue, oldValue);
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
addOnChange: (callback) => _onChanges.push(callback),
|
|
309
|
+
removeOnChange: (callback) => {
|
|
310
|
+
for (let i = _onChanges.length - 1; i >= 0; i--) {
|
|
311
|
+
if (_onChanges[i] === callback) {
|
|
312
|
+
_onChanges.splice(i, 1);
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
},
|
|
318
|
+
};
|
|
285
319
|
}
|
|
286
320
|
|
|
287
321
|
/**
|
|
@@ -325,64 +359,134 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
325
359
|
return container;
|
|
326
360
|
}
|
|
327
361
|
|
|
328
|
-
const
|
|
362
|
+
const noop = () => { };
|
|
329
363
|
/**
|
|
330
364
|
* TextField component - mimics MUI TextField appearance and behavior
|
|
331
365
|
*/
|
|
332
366
|
function TextField(props) {
|
|
333
|
-
|
|
367
|
+
let { label = '', placeholder = '', value = '', type = 'text', disabled = false, readonly = false, required = false, error = false, helperText = '', fullWidth = false, multiline = false, rows = 3, size = 'medium', 'kt:input': onInput = noop, 'kt-trim:input': onInputTrim = noop, 'kt:change': onChange = noop, 'kt-trim:change': onChangeTrim = noop, 'kt:blur': onBlur = noop, 'kt:focus': onFocus = noop, } = props;
|
|
334
368
|
let isFocused = false;
|
|
335
|
-
const
|
|
369
|
+
const helperTextEl = jsxRuntime.jsx("p", { class: "mui-textfield-helper-text", children: helperText });
|
|
336
370
|
// Update container classes
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
const classes = [
|
|
371
|
+
const updateContainerClass = () => {
|
|
372
|
+
container.className = [
|
|
340
373
|
'mui-textfield-root',
|
|
341
374
|
`mui-textfield-size-${size}`,
|
|
342
375
|
isFocused ? 'mui-textfield-focused' : '',
|
|
343
376
|
error ? 'mui-textfield-error' : '',
|
|
344
377
|
disabled ? 'mui-textfield-disabled' : '',
|
|
345
378
|
fullWidth ? 'mui-textfield-fullwidth' : '',
|
|
346
|
-
label &&
|
|
379
|
+
label && isFocused && inputEl.value ? 'mui-textfield-has-value' : '',
|
|
347
380
|
label ? '' : 'mui-textfield-no-label',
|
|
348
|
-
];
|
|
349
|
-
container.className = classes.join(' ');
|
|
381
|
+
].join(' ');
|
|
350
382
|
};
|
|
351
383
|
const handleInput = (e) => {
|
|
352
384
|
const target = e.target;
|
|
353
|
-
|
|
385
|
+
updateContainerClass();
|
|
354
386
|
onInput(target.value, e);
|
|
387
|
+
onInputTrim(target.value.trim(), e);
|
|
355
388
|
};
|
|
356
389
|
const handleChange = (e) => {
|
|
357
390
|
const target = e.target;
|
|
358
391
|
onChange(target.value, e);
|
|
392
|
+
onChangeTrim(target.value.trim(), e);
|
|
359
393
|
};
|
|
360
394
|
const handleFocus = (e) => {
|
|
361
395
|
isFocused = true;
|
|
362
|
-
|
|
396
|
+
updateContainerClass();
|
|
363
397
|
const target = e.target;
|
|
364
398
|
onFocus(target.value, e);
|
|
365
399
|
};
|
|
366
400
|
const handleBlur = (e) => {
|
|
367
401
|
isFocused = false;
|
|
368
|
-
|
|
402
|
+
updateContainerClass();
|
|
369
403
|
const target = e.target;
|
|
370
404
|
onBlur(target.value, e);
|
|
371
405
|
};
|
|
372
406
|
// Create input or textarea element
|
|
373
407
|
// Only show placeholder when label is floating (focused or has value)
|
|
374
408
|
const getPlaceholder = () => (label && !isFocused && !value ? '' : placeholder);
|
|
375
|
-
const
|
|
376
|
-
|
|
409
|
+
const inputEl = multiline
|
|
410
|
+
? (jsxRuntime.jsx("textarea", { class: "mui-textfield-input", placeholder: getPlaceholder(), value: value, disabled: disabled, readOnly: readonly, required: required, rows: rows, "on:input": handleInput, "on:change": handleChange, "on:focus": handleFocus, "on:blur": handleBlur }))
|
|
411
|
+
: (jsxRuntime.jsx("input", { type: type, class: "mui-textfield-input", placeholder: getPlaceholder(), value: value, disabled: disabled, readOnly: readonly, required: required, "on:input": handleInput, "on:change": handleChange, "on:focus": handleFocus, "on:blur": handleBlur }));
|
|
412
|
+
const wrapperRef = kt_js.createRedrawable(() => (jsxRuntime.jsxs("div", { class: "mui-textfield-wrapper", children: [jsxRuntime.jsxs("label", { "k-if": label, class: "mui-textfield-label", children: [label, required && jsxRuntime.jsx("span", { class: "mui-textfield-required", children: "*" })] }), jsxRuntime.jsx("div", { class: "mui-textfield-input-wrapper", children: inputEl }), jsxRuntime.jsx("fieldset", { class: "mui-textfield-fieldset", children: jsxRuntime.jsx("legend", { "k-if": label, class: "mui-textfield-legend", children: jsxRuntime.jsxs("span", { children: [label, required && '*'] }) }) })] })));
|
|
413
|
+
const container = (jsxRuntime.jsxs("div", { class: 'mui-textfield-root ' + (props.class ? props.class : ''), style: props.style ? props.style : '', children: [wrapperRef, helperTextEl] }));
|
|
377
414
|
// Initialize classes
|
|
378
|
-
setTimeout(() =>
|
|
379
|
-
Object.
|
|
380
|
-
|
|
381
|
-
|
|
415
|
+
setTimeout(() => updateContainerClass(), 0);
|
|
416
|
+
Object.defineProperties(container, {
|
|
417
|
+
value: {
|
|
418
|
+
get() {
|
|
419
|
+
return inputEl.value;
|
|
420
|
+
},
|
|
421
|
+
set(newValue) {
|
|
422
|
+
inputEl.value = newValue;
|
|
423
|
+
updateContainerClass();
|
|
424
|
+
},
|
|
382
425
|
},
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
426
|
+
label: {
|
|
427
|
+
get() {
|
|
428
|
+
return label;
|
|
429
|
+
},
|
|
430
|
+
set(newLabel) {
|
|
431
|
+
label = newLabel;
|
|
432
|
+
wrapperRef.value.redraw(); // label takes too much and should be redrawn
|
|
433
|
+
updateContainerClass();
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
placeholder: {
|
|
437
|
+
get() {
|
|
438
|
+
return placeholder;
|
|
439
|
+
},
|
|
440
|
+
set(newPlaceholder) {
|
|
441
|
+
placeholder = newPlaceholder;
|
|
442
|
+
inputEl.placeholder = getPlaceholder();
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
type: {
|
|
446
|
+
get() {
|
|
447
|
+
return type;
|
|
448
|
+
},
|
|
449
|
+
set(newType) {
|
|
450
|
+
type = newType || 'text';
|
|
451
|
+
inputEl.type = type;
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
disabled: {
|
|
455
|
+
get() {
|
|
456
|
+
return disabled;
|
|
457
|
+
},
|
|
458
|
+
set(val) {
|
|
459
|
+
disabled = !!val;
|
|
460
|
+
inputEl.disabled = disabled;
|
|
461
|
+
container.classList.toggle('mui-textfield-disabled', disabled);
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
readonly: {
|
|
465
|
+
get() {
|
|
466
|
+
return readonly;
|
|
467
|
+
},
|
|
468
|
+
set(val) {
|
|
469
|
+
readonly = Boolean(val);
|
|
470
|
+
inputEl.readOnly = readonly;
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
error: {
|
|
474
|
+
get() {
|
|
475
|
+
return error;
|
|
476
|
+
},
|
|
477
|
+
set(val) {
|
|
478
|
+
error = Boolean(val);
|
|
479
|
+
container.classList.toggle('mui-textfield-error', error);
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
helperText: {
|
|
483
|
+
get() {
|
|
484
|
+
return helperText;
|
|
485
|
+
},
|
|
486
|
+
set(text) {
|
|
487
|
+
helperTextEl.textContent = text;
|
|
488
|
+
helperTextEl.style.display = text ? 'block' : 'none';
|
|
489
|
+
},
|
|
386
490
|
},
|
|
387
491
|
});
|
|
388
492
|
return container;
|
|
@@ -406,7 +510,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
406
510
|
toggleIcon(checked);
|
|
407
511
|
onChange(checked, value);
|
|
408
512
|
};
|
|
409
|
-
const { checked: initChecked = false, value = '', text = '', size = 'small', '
|
|
513
|
+
const { checked: initChecked = false, value = '', text = '', size = 'small', 'kt:change': onChange = emptyFn$1, disabled: initDisabled = false, color = 'primary', } = props;
|
|
410
514
|
const inputRef = kt_js.ref();
|
|
411
515
|
let checked = initChecked;
|
|
412
516
|
let disabled = initDisabled;
|
|
@@ -426,7 +530,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
426
530
|
* RadioGroup component - groups multiple radios together
|
|
427
531
|
*/
|
|
428
532
|
function RadioGroup(props) {
|
|
429
|
-
const { value = '', size = 'small', '
|
|
533
|
+
const { value = '', size = 'small', 'kt:change': onChange = emptyFn$1, row = false } = props;
|
|
430
534
|
const changeHandler = (checked, value) => {
|
|
431
535
|
if (checked) {
|
|
432
536
|
onChange(value);
|
|
@@ -436,15 +540,15 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
436
540
|
const radios = props.options.map((o) => {
|
|
437
541
|
o.size = size;
|
|
438
542
|
o.checked = value === o.value;
|
|
439
|
-
const originalChange = o['
|
|
543
|
+
const originalChange = o['kt:change'];
|
|
440
544
|
if (originalChange) {
|
|
441
|
-
o['
|
|
545
|
+
o['kt:change'] = (checked, newValue) => {
|
|
442
546
|
originalChange(checked, newValue);
|
|
443
547
|
changeHandler(checked, newValue);
|
|
444
548
|
};
|
|
445
549
|
}
|
|
446
550
|
else {
|
|
447
|
-
o['
|
|
551
|
+
o['kt:change'] = changeHandler;
|
|
448
552
|
}
|
|
449
553
|
return Radio(o);
|
|
450
554
|
});
|
|
@@ -456,7 +560,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
456
560
|
* Select component - mimics MUI Select appearance and behavior
|
|
457
561
|
*/
|
|
458
562
|
function Select(props) {
|
|
459
|
-
let { value = '', options = [], label = '', placeholder = '', size = 'medium', '
|
|
563
|
+
let { value = '', options = [], label = '', placeholder = '', size = 'medium', 'kt:change': onChange = emptyFn, fullWidth = false, disabled = false, } = props;
|
|
460
564
|
let isOpen = false;
|
|
461
565
|
let isFocused = false;
|
|
462
566
|
const selectRef = kt_js.ref();
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { ref as ref$1, createRedrawable } from 'kt.js';
|
|
|
5
5
|
* Alert component - mimics MUI Alert appearance and behavior
|
|
6
6
|
*/
|
|
7
7
|
function Alert(props) {
|
|
8
|
-
const { children, severity = 'info', variant = 'standard', icon, '
|
|
8
|
+
const { children, severity = 'info', variant = 'standard', icon, 'kt:close': onClose, sx } = props;
|
|
9
9
|
const classes = `mui-alert mui-alert-${severity} mui-alert-${variant} ${props.class ? props.class : ''}`;
|
|
10
10
|
// Convert sx object to style string
|
|
11
11
|
let styleString = props.style || '';
|
|
@@ -44,12 +44,12 @@ function Alert(props) {
|
|
|
44
44
|
return alert;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const emptyFn$
|
|
47
|
+
const emptyFn$3 = () => { };
|
|
48
48
|
/**
|
|
49
49
|
* Button component - mimics MUI Button appearance and behavior
|
|
50
50
|
*/
|
|
51
51
|
function Button(props) {
|
|
52
|
-
const { children, variant = 'text', color = 'primary', size = 'medium', disabled = false, fullWidth = false, iconOnly = false, startIcon, endIcon, type = 'button', 'on:click': onClick = emptyFn$
|
|
52
|
+
const { children, variant = 'text', color = 'primary', size = 'medium', disabled = false, fullWidth = false, iconOnly = false, startIcon, endIcon, type = 'button', 'on:click': onClick = emptyFn$3, } = props;
|
|
53
53
|
const classes = [
|
|
54
54
|
'mui-button',
|
|
55
55
|
`mui-button-${variant}`,
|
|
@@ -91,7 +91,7 @@ function Button(props) {
|
|
|
91
91
|
return (jsxs("button", { class: classes, style: props.style ? props.style : '', type: type, disabled: disabled, "on:click": handleClick, children: [startIcon && jsx("span", { class: "mui-button-start-icon", children: startIcon }), jsx("span", { class: "mui-button-label", children: children }), endIcon && jsx("span", { class: "mui-button-end-icon", children: endIcon }), jsx("span", { class: "mui-button-ripple" })] }));
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
const emptyFn$
|
|
94
|
+
const emptyFn$2 = () => { };
|
|
95
95
|
/**
|
|
96
96
|
* Checkbox component - mimics MUI Checkbox appearance and behavior
|
|
97
97
|
*/
|
|
@@ -118,7 +118,7 @@ function Checkbox(props) {
|
|
|
118
118
|
toggleIcon(checked, indeterminate);
|
|
119
119
|
onChange(checked, value);
|
|
120
120
|
};
|
|
121
|
-
let { checked = false, value = '', label = '', size = 'medium', '
|
|
121
|
+
let { checked = false, value = '', label = '', size = 'medium', 'kt:change': onChange = emptyFn$2, disabled = false, color = 'primary', indeterminate = false, } = props;
|
|
122
122
|
const inputRef = ref$1();
|
|
123
123
|
// Unchecked icon
|
|
124
124
|
const uncheckedIcon = (jsx("span", { class: "mui-checkbox-icon-unchecked", children: jsx("svg", { viewBox: "0 0 24 24", children: jsx("path", { d: "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z" }) }) }));
|
|
@@ -147,7 +147,7 @@ function Checkbox(props) {
|
|
|
147
147
|
* CheckboxGroup component - groups multiple checkboxes together
|
|
148
148
|
*/
|
|
149
149
|
function CheckboxGroup(props) {
|
|
150
|
-
let { value = [], size = 'medium', '
|
|
150
|
+
let { value = [], size = 'medium', 'kt:change': onChange = emptyFn$2, row = false } = props;
|
|
151
151
|
let selectedValues = new Set(value);
|
|
152
152
|
const changeHandler = (checked, checkboxValue) => {
|
|
153
153
|
if (checked) {
|
|
@@ -161,15 +161,15 @@ function CheckboxGroup(props) {
|
|
|
161
161
|
const checkboxes = props.options.map((o) => {
|
|
162
162
|
o.size = size;
|
|
163
163
|
o.checked = selectedValues.has(o.value);
|
|
164
|
-
const originalChange = o['
|
|
164
|
+
const originalChange = o['kt:change'];
|
|
165
165
|
if (originalChange) {
|
|
166
|
-
o['
|
|
166
|
+
o['kt:change'] = (checked, value) => {
|
|
167
167
|
originalChange(checked, value);
|
|
168
168
|
changeHandler(checked, value);
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
else {
|
|
172
|
-
o['
|
|
172
|
+
o['kt:change'] = changeHandler;
|
|
173
173
|
}
|
|
174
174
|
return Checkbox(o);
|
|
175
175
|
});
|
|
@@ -189,13 +189,13 @@ function CheckboxGroup(props) {
|
|
|
189
189
|
return container;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
const noop = () => { };
|
|
192
|
+
const noop$1 = () => { };
|
|
193
193
|
/**
|
|
194
194
|
* Dialog component - mimics MUI Dialog appearance and behavior
|
|
195
195
|
* Only handles open/close state, title and content are passed as props
|
|
196
196
|
*/
|
|
197
197
|
function Dialog(props) {
|
|
198
|
-
let { open = false, '
|
|
198
|
+
let { open = false, 'kt:close': onClose = noop$1, title, children, actions, maxWidth = 'sm', fullWidth = false, } = props;
|
|
199
199
|
// Handle ESC key - store handler for cleanup
|
|
200
200
|
const keyDownHandler = (e) => {
|
|
201
201
|
if (e.key === 'Escape') {
|
|
@@ -280,8 +280,42 @@ document.createElement('div');
|
|
|
280
280
|
* - can alse be used to store normal values, but it is not reactive.
|
|
281
281
|
* @param value mostly an HTMLElement
|
|
282
282
|
*/
|
|
283
|
-
function ref(value) {
|
|
284
|
-
|
|
283
|
+
function ref(value, onChange) {
|
|
284
|
+
let _value = value;
|
|
285
|
+
let _onChanges = [];
|
|
286
|
+
return {
|
|
287
|
+
isKT: true,
|
|
288
|
+
get value() {
|
|
289
|
+
return _value;
|
|
290
|
+
},
|
|
291
|
+
set value(newValue) {
|
|
292
|
+
if (newValue === _value) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
// replace the old node with the new one in the DOM if both are nodes
|
|
296
|
+
if (_value instanceof Node && newValue instanceof Node) {
|
|
297
|
+
if (newValue.contains(_value)) {
|
|
298
|
+
_value.remove();
|
|
299
|
+
}
|
|
300
|
+
_value.replaceWith(newValue);
|
|
301
|
+
}
|
|
302
|
+
const oldValue = _value;
|
|
303
|
+
_value = newValue;
|
|
304
|
+
for (let i = 0; i < _onChanges.length; i++) {
|
|
305
|
+
_onChanges[i](newValue, oldValue);
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
addOnChange: (callback) => _onChanges.push(callback),
|
|
309
|
+
removeOnChange: (callback) => {
|
|
310
|
+
for (let i = _onChanges.length - 1; i >= 0; i--) {
|
|
311
|
+
if (_onChanges[i] === callback) {
|
|
312
|
+
_onChanges.splice(i, 1);
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
},
|
|
318
|
+
};
|
|
285
319
|
}
|
|
286
320
|
|
|
287
321
|
/**
|
|
@@ -325,64 +359,134 @@ function LinearProgress(props) {
|
|
|
325
359
|
return container;
|
|
326
360
|
}
|
|
327
361
|
|
|
328
|
-
const
|
|
362
|
+
const noop = () => { };
|
|
329
363
|
/**
|
|
330
364
|
* TextField component - mimics MUI TextField appearance and behavior
|
|
331
365
|
*/
|
|
332
366
|
function TextField(props) {
|
|
333
|
-
|
|
367
|
+
let { label = '', placeholder = '', value = '', type = 'text', disabled = false, readonly = false, required = false, error = false, helperText = '', fullWidth = false, multiline = false, rows = 3, size = 'medium', 'kt:input': onInput = noop, 'kt-trim:input': onInputTrim = noop, 'kt:change': onChange = noop, 'kt-trim:change': onChangeTrim = noop, 'kt:blur': onBlur = noop, 'kt:focus': onFocus = noop, } = props;
|
|
334
368
|
let isFocused = false;
|
|
335
|
-
const
|
|
369
|
+
const helperTextEl = jsx("p", { class: "mui-textfield-helper-text", children: helperText });
|
|
336
370
|
// Update container classes
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
const classes = [
|
|
371
|
+
const updateContainerClass = () => {
|
|
372
|
+
container.className = [
|
|
340
373
|
'mui-textfield-root',
|
|
341
374
|
`mui-textfield-size-${size}`,
|
|
342
375
|
isFocused ? 'mui-textfield-focused' : '',
|
|
343
376
|
error ? 'mui-textfield-error' : '',
|
|
344
377
|
disabled ? 'mui-textfield-disabled' : '',
|
|
345
378
|
fullWidth ? 'mui-textfield-fullwidth' : '',
|
|
346
|
-
label &&
|
|
379
|
+
label && isFocused && inputEl.value ? 'mui-textfield-has-value' : '',
|
|
347
380
|
label ? '' : 'mui-textfield-no-label',
|
|
348
|
-
];
|
|
349
|
-
container.className = classes.join(' ');
|
|
381
|
+
].join(' ');
|
|
350
382
|
};
|
|
351
383
|
const handleInput = (e) => {
|
|
352
384
|
const target = e.target;
|
|
353
|
-
|
|
385
|
+
updateContainerClass();
|
|
354
386
|
onInput(target.value, e);
|
|
387
|
+
onInputTrim(target.value.trim(), e);
|
|
355
388
|
};
|
|
356
389
|
const handleChange = (e) => {
|
|
357
390
|
const target = e.target;
|
|
358
391
|
onChange(target.value, e);
|
|
392
|
+
onChangeTrim(target.value.trim(), e);
|
|
359
393
|
};
|
|
360
394
|
const handleFocus = (e) => {
|
|
361
395
|
isFocused = true;
|
|
362
|
-
|
|
396
|
+
updateContainerClass();
|
|
363
397
|
const target = e.target;
|
|
364
398
|
onFocus(target.value, e);
|
|
365
399
|
};
|
|
366
400
|
const handleBlur = (e) => {
|
|
367
401
|
isFocused = false;
|
|
368
|
-
|
|
402
|
+
updateContainerClass();
|
|
369
403
|
const target = e.target;
|
|
370
404
|
onBlur(target.value, e);
|
|
371
405
|
};
|
|
372
406
|
// Create input or textarea element
|
|
373
407
|
// Only show placeholder when label is floating (focused or has value)
|
|
374
408
|
const getPlaceholder = () => (label && !isFocused && !value ? '' : placeholder);
|
|
375
|
-
const
|
|
376
|
-
|
|
409
|
+
const inputEl = multiline
|
|
410
|
+
? (jsx("textarea", { class: "mui-textfield-input", placeholder: getPlaceholder(), value: value, disabled: disabled, readOnly: readonly, required: required, rows: rows, "on:input": handleInput, "on:change": handleChange, "on:focus": handleFocus, "on:blur": handleBlur }))
|
|
411
|
+
: (jsx("input", { type: type, class: "mui-textfield-input", placeholder: getPlaceholder(), value: value, disabled: disabled, readOnly: readonly, required: required, "on:input": handleInput, "on:change": handleChange, "on:focus": handleFocus, "on:blur": handleBlur }));
|
|
412
|
+
const wrapperRef = createRedrawable(() => (jsxs("div", { class: "mui-textfield-wrapper", children: [jsxs("label", { "k-if": label, class: "mui-textfield-label", children: [label, required && jsx("span", { class: "mui-textfield-required", children: "*" })] }), jsx("div", { class: "mui-textfield-input-wrapper", children: inputEl }), jsx("fieldset", { class: "mui-textfield-fieldset", children: jsx("legend", { "k-if": label, class: "mui-textfield-legend", children: jsxs("span", { children: [label, required && '*'] }) }) })] })));
|
|
413
|
+
const container = (jsxs("div", { class: 'mui-textfield-root ' + (props.class ? props.class : ''), style: props.style ? props.style : '', children: [wrapperRef, helperTextEl] }));
|
|
377
414
|
// Initialize classes
|
|
378
|
-
setTimeout(() =>
|
|
379
|
-
Object.
|
|
380
|
-
|
|
381
|
-
|
|
415
|
+
setTimeout(() => updateContainerClass(), 0);
|
|
416
|
+
Object.defineProperties(container, {
|
|
417
|
+
value: {
|
|
418
|
+
get() {
|
|
419
|
+
return inputEl.value;
|
|
420
|
+
},
|
|
421
|
+
set(newValue) {
|
|
422
|
+
inputEl.value = newValue;
|
|
423
|
+
updateContainerClass();
|
|
424
|
+
},
|
|
382
425
|
},
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
426
|
+
label: {
|
|
427
|
+
get() {
|
|
428
|
+
return label;
|
|
429
|
+
},
|
|
430
|
+
set(newLabel) {
|
|
431
|
+
label = newLabel;
|
|
432
|
+
wrapperRef.value.redraw(); // label takes too much and should be redrawn
|
|
433
|
+
updateContainerClass();
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
placeholder: {
|
|
437
|
+
get() {
|
|
438
|
+
return placeholder;
|
|
439
|
+
},
|
|
440
|
+
set(newPlaceholder) {
|
|
441
|
+
placeholder = newPlaceholder;
|
|
442
|
+
inputEl.placeholder = getPlaceholder();
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
type: {
|
|
446
|
+
get() {
|
|
447
|
+
return type;
|
|
448
|
+
},
|
|
449
|
+
set(newType) {
|
|
450
|
+
type = newType || 'text';
|
|
451
|
+
inputEl.type = type;
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
disabled: {
|
|
455
|
+
get() {
|
|
456
|
+
return disabled;
|
|
457
|
+
},
|
|
458
|
+
set(val) {
|
|
459
|
+
disabled = !!val;
|
|
460
|
+
inputEl.disabled = disabled;
|
|
461
|
+
container.classList.toggle('mui-textfield-disabled', disabled);
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
readonly: {
|
|
465
|
+
get() {
|
|
466
|
+
return readonly;
|
|
467
|
+
},
|
|
468
|
+
set(val) {
|
|
469
|
+
readonly = Boolean(val);
|
|
470
|
+
inputEl.readOnly = readonly;
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
error: {
|
|
474
|
+
get() {
|
|
475
|
+
return error;
|
|
476
|
+
},
|
|
477
|
+
set(val) {
|
|
478
|
+
error = Boolean(val);
|
|
479
|
+
container.classList.toggle('mui-textfield-error', error);
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
helperText: {
|
|
483
|
+
get() {
|
|
484
|
+
return helperText;
|
|
485
|
+
},
|
|
486
|
+
set(text) {
|
|
487
|
+
helperTextEl.textContent = text;
|
|
488
|
+
helperTextEl.style.display = text ? 'block' : 'none';
|
|
489
|
+
},
|
|
386
490
|
},
|
|
387
491
|
});
|
|
388
492
|
return container;
|
|
@@ -406,7 +510,7 @@ function Radio(props) {
|
|
|
406
510
|
toggleIcon(checked);
|
|
407
511
|
onChange(checked, value);
|
|
408
512
|
};
|
|
409
|
-
const { checked: initChecked = false, value = '', text = '', size = 'small', '
|
|
513
|
+
const { checked: initChecked = false, value = '', text = '', size = 'small', 'kt:change': onChange = emptyFn$1, disabled: initDisabled = false, color = 'primary', } = props;
|
|
410
514
|
const inputRef = ref$1();
|
|
411
515
|
let checked = initChecked;
|
|
412
516
|
let disabled = initDisabled;
|
|
@@ -426,7 +530,7 @@ function Radio(props) {
|
|
|
426
530
|
* RadioGroup component - groups multiple radios together
|
|
427
531
|
*/
|
|
428
532
|
function RadioGroup(props) {
|
|
429
|
-
const { value = '', size = 'small', '
|
|
533
|
+
const { value = '', size = 'small', 'kt:change': onChange = emptyFn$1, row = false } = props;
|
|
430
534
|
const changeHandler = (checked, value) => {
|
|
431
535
|
if (checked) {
|
|
432
536
|
onChange(value);
|
|
@@ -436,15 +540,15 @@ function RadioGroup(props) {
|
|
|
436
540
|
const radios = props.options.map((o) => {
|
|
437
541
|
o.size = size;
|
|
438
542
|
o.checked = value === o.value;
|
|
439
|
-
const originalChange = o['
|
|
543
|
+
const originalChange = o['kt:change'];
|
|
440
544
|
if (originalChange) {
|
|
441
|
-
o['
|
|
545
|
+
o['kt:change'] = (checked, newValue) => {
|
|
442
546
|
originalChange(checked, newValue);
|
|
443
547
|
changeHandler(checked, newValue);
|
|
444
548
|
};
|
|
445
549
|
}
|
|
446
550
|
else {
|
|
447
|
-
o['
|
|
551
|
+
o['kt:change'] = changeHandler;
|
|
448
552
|
}
|
|
449
553
|
return Radio(o);
|
|
450
554
|
});
|
|
@@ -456,7 +560,7 @@ const emptyFn = () => { };
|
|
|
456
560
|
* Select component - mimics MUI Select appearance and behavior
|
|
457
561
|
*/
|
|
458
562
|
function Select(props) {
|
|
459
|
-
let { value = '', options = [], label = '', placeholder = '', size = 'medium', '
|
|
563
|
+
let { value = '', options = [], label = '', placeholder = '', size = 'medium', 'kt:change': onChange = emptyFn, fullWidth = false, disabled = false, } = props;
|
|
460
564
|
let isOpen = false;
|
|
461
565
|
let isFocused = false;
|
|
462
566
|
const selectRef = ref$1();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ktjs/mui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Material-UI inspired components for kt.js - pre-styled UI components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"directory": "packages/mui"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ktjs/core": "0.18.
|
|
38
|
+
"@ktjs/core": "0.18.4"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "rollup -c rollup.config.mjs",
|