@ktjs/mui 0.17.8 → 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 +23 -14
- package/dist/index.iife.js +146 -44
- package/dist/index.mjs +146 -44
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ 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
|
|
16
16
|
*/
|
|
17
17
|
declare function Alert(props: AlertProps): KTHTMLElement;
|
|
@@ -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
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**s
|
|
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, onClose, sx } = props;
|
|
9
|
-
const classes =
|
|
10
|
-
.filter(Boolean)
|
|
11
|
-
.join(' ');
|
|
8
|
+
const { children, severity = 'info', variant = 'standard', icon, 'kt:close': onClose, sx } = props;
|
|
9
|
+
const classes = `mui-alert mui-alert-${severity} mui-alert-${variant} ${props.class ? props.class : ''}`;
|
|
12
10
|
// Convert sx object to style string
|
|
13
11
|
let styleString = props.style || '';
|
|
14
12
|
if (sx) {
|
|
@@ -46,12 +44,12 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
46
44
|
return alert;
|
|
47
45
|
}
|
|
48
46
|
|
|
49
|
-
const emptyFn$
|
|
47
|
+
const emptyFn$3 = () => { };
|
|
50
48
|
/**
|
|
51
49
|
* Button component - mimics MUI Button appearance and behavior
|
|
52
50
|
*/
|
|
53
51
|
function Button(props) {
|
|
54
|
-
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;
|
|
55
53
|
const classes = [
|
|
56
54
|
'mui-button',
|
|
57
55
|
`mui-button-${variant}`,
|
|
@@ -93,7 +91,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
93
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" })] }));
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
const emptyFn$
|
|
94
|
+
const emptyFn$2 = () => { };
|
|
97
95
|
/**
|
|
98
96
|
* Checkbox component - mimics MUI Checkbox appearance and behavior
|
|
99
97
|
*/
|
|
@@ -120,7 +118,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
120
118
|
toggleIcon(checked, indeterminate);
|
|
121
119
|
onChange(checked, value);
|
|
122
120
|
};
|
|
123
|
-
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;
|
|
124
122
|
const inputRef = kt_js.ref();
|
|
125
123
|
// Unchecked icon
|
|
126
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" }) }) }));
|
|
@@ -149,7 +147,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
149
147
|
* CheckboxGroup component - groups multiple checkboxes together
|
|
150
148
|
*/
|
|
151
149
|
function CheckboxGroup(props) {
|
|
152
|
-
let { value = [], size = 'medium', '
|
|
150
|
+
let { value = [], size = 'medium', 'kt:change': onChange = emptyFn$2, row = false } = props;
|
|
153
151
|
let selectedValues = new Set(value);
|
|
154
152
|
const changeHandler = (checked, checkboxValue) => {
|
|
155
153
|
if (checked) {
|
|
@@ -163,15 +161,15 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
163
161
|
const checkboxes = props.options.map((o) => {
|
|
164
162
|
o.size = size;
|
|
165
163
|
o.checked = selectedValues.has(o.value);
|
|
166
|
-
const originalChange = o['
|
|
164
|
+
const originalChange = o['kt:change'];
|
|
167
165
|
if (originalChange) {
|
|
168
|
-
o['
|
|
166
|
+
o['kt:change'] = (checked, value) => {
|
|
169
167
|
originalChange(checked, value);
|
|
170
168
|
changeHandler(checked, value);
|
|
171
169
|
};
|
|
172
170
|
}
|
|
173
171
|
else {
|
|
174
|
-
o['
|
|
172
|
+
o['kt:change'] = changeHandler;
|
|
175
173
|
}
|
|
176
174
|
return Checkbox(o);
|
|
177
175
|
});
|
|
@@ -191,13 +189,13 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
191
189
|
return container;
|
|
192
190
|
}
|
|
193
191
|
|
|
194
|
-
const noop = () => { };
|
|
192
|
+
const noop$1 = () => { };
|
|
195
193
|
/**
|
|
196
194
|
* Dialog component - mimics MUI Dialog appearance and behavior
|
|
197
195
|
* Only handles open/close state, title and content are passed as props
|
|
198
196
|
*/
|
|
199
197
|
function Dialog(props) {
|
|
200
|
-
let { open = false, '
|
|
198
|
+
let { open = false, 'kt:close': onClose = noop$1, title, children, actions, maxWidth = 'sm', fullWidth = false, } = props;
|
|
201
199
|
// Handle ESC key - store handler for cleanup
|
|
202
200
|
const keyDownHandler = (e) => {
|
|
203
201
|
if (e.key === 'Escape') {
|
|
@@ -282,8 +280,42 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
282
280
|
* - can alse be used to store normal values, but it is not reactive.
|
|
283
281
|
* @param value mostly an HTMLElement
|
|
284
282
|
*/
|
|
285
|
-
function ref(value) {
|
|
286
|
-
|
|
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
|
+
};
|
|
287
319
|
}
|
|
288
320
|
|
|
289
321
|
/**
|
|
@@ -327,64 +359,134 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
327
359
|
return container;
|
|
328
360
|
}
|
|
329
361
|
|
|
330
|
-
const
|
|
362
|
+
const noop = () => { };
|
|
331
363
|
/**
|
|
332
364
|
* TextField component - mimics MUI TextField appearance and behavior
|
|
333
365
|
*/
|
|
334
366
|
function TextField(props) {
|
|
335
|
-
|
|
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;
|
|
336
368
|
let isFocused = false;
|
|
337
|
-
const
|
|
369
|
+
const helperTextEl = jsxRuntime.jsx("p", { class: "mui-textfield-helper-text", children: helperText });
|
|
338
370
|
// Update container classes
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
const classes = [
|
|
371
|
+
const updateContainerClass = () => {
|
|
372
|
+
container.className = [
|
|
342
373
|
'mui-textfield-root',
|
|
343
374
|
`mui-textfield-size-${size}`,
|
|
344
375
|
isFocused ? 'mui-textfield-focused' : '',
|
|
345
376
|
error ? 'mui-textfield-error' : '',
|
|
346
377
|
disabled ? 'mui-textfield-disabled' : '',
|
|
347
378
|
fullWidth ? 'mui-textfield-fullwidth' : '',
|
|
348
|
-
label &&
|
|
379
|
+
label && isFocused && inputEl.value ? 'mui-textfield-has-value' : '',
|
|
349
380
|
label ? '' : 'mui-textfield-no-label',
|
|
350
|
-
];
|
|
351
|
-
container.className = classes.join(' ');
|
|
381
|
+
].join(' ');
|
|
352
382
|
};
|
|
353
383
|
const handleInput = (e) => {
|
|
354
384
|
const target = e.target;
|
|
355
|
-
|
|
385
|
+
updateContainerClass();
|
|
356
386
|
onInput(target.value, e);
|
|
387
|
+
onInputTrim(target.value.trim(), e);
|
|
357
388
|
};
|
|
358
389
|
const handleChange = (e) => {
|
|
359
390
|
const target = e.target;
|
|
360
391
|
onChange(target.value, e);
|
|
392
|
+
onChangeTrim(target.value.trim(), e);
|
|
361
393
|
};
|
|
362
394
|
const handleFocus = (e) => {
|
|
363
395
|
isFocused = true;
|
|
364
|
-
|
|
396
|
+
updateContainerClass();
|
|
365
397
|
const target = e.target;
|
|
366
398
|
onFocus(target.value, e);
|
|
367
399
|
};
|
|
368
400
|
const handleBlur = (e) => {
|
|
369
401
|
isFocused = false;
|
|
370
|
-
|
|
402
|
+
updateContainerClass();
|
|
371
403
|
const target = e.target;
|
|
372
404
|
onBlur(target.value, e);
|
|
373
405
|
};
|
|
374
406
|
// Create input or textarea element
|
|
375
407
|
// Only show placeholder when label is floating (focused or has value)
|
|
376
408
|
const getPlaceholder = () => (label && !isFocused && !value ? '' : placeholder);
|
|
377
|
-
const
|
|
378
|
-
|
|
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] }));
|
|
379
414
|
// Initialize classes
|
|
380
|
-
setTimeout(() =>
|
|
381
|
-
Object.
|
|
382
|
-
|
|
383
|
-
|
|
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
|
+
},
|
|
384
425
|
},
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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
|
+
},
|
|
388
490
|
},
|
|
389
491
|
});
|
|
390
492
|
return container;
|
|
@@ -408,7 +510,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
408
510
|
toggleIcon(checked);
|
|
409
511
|
onChange(checked, value);
|
|
410
512
|
};
|
|
411
|
-
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;
|
|
412
514
|
const inputRef = kt_js.ref();
|
|
413
515
|
let checked = initChecked;
|
|
414
516
|
let disabled = initDisabled;
|
|
@@ -428,7 +530,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
428
530
|
* RadioGroup component - groups multiple radios together
|
|
429
531
|
*/
|
|
430
532
|
function RadioGroup(props) {
|
|
431
|
-
const { value = '', size = 'small', '
|
|
533
|
+
const { value = '', size = 'small', 'kt:change': onChange = emptyFn$1, row = false } = props;
|
|
432
534
|
const changeHandler = (checked, value) => {
|
|
433
535
|
if (checked) {
|
|
434
536
|
onChange(value);
|
|
@@ -438,15 +540,15 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
438
540
|
const radios = props.options.map((o) => {
|
|
439
541
|
o.size = size;
|
|
440
542
|
o.checked = value === o.value;
|
|
441
|
-
const originalChange = o['
|
|
543
|
+
const originalChange = o['kt:change'];
|
|
442
544
|
if (originalChange) {
|
|
443
|
-
o['
|
|
545
|
+
o['kt:change'] = (checked, newValue) => {
|
|
444
546
|
originalChange(checked, newValue);
|
|
445
547
|
changeHandler(checked, newValue);
|
|
446
548
|
};
|
|
447
549
|
}
|
|
448
550
|
else {
|
|
449
|
-
o['
|
|
551
|
+
o['kt:change'] = changeHandler;
|
|
450
552
|
}
|
|
451
553
|
return Radio(o);
|
|
452
554
|
});
|
|
@@ -458,7 +560,7 @@ var __ktjs_mui__ = (function (exports, jsxRuntime, kt_js) {
|
|
|
458
560
|
* Select component - mimics MUI Select appearance and behavior
|
|
459
561
|
*/
|
|
460
562
|
function Select(props) {
|
|
461
|
-
let { value = '', options = [], label = '', placeholder = '', size = 'medium', '
|
|
563
|
+
let { value = '', options = [], label = '', placeholder = '', size = 'medium', 'kt:change': onChange = emptyFn, fullWidth = false, disabled = false, } = props;
|
|
462
564
|
let isOpen = false;
|
|
463
565
|
let isFocused = false;
|
|
464
566
|
const selectRef = kt_js.ref();
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'kt.js/jsx-runtime';
|
|
2
2
|
import { ref as ref$1, createRedrawable } from 'kt.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**s
|
|
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, onClose, sx } = props;
|
|
9
|
-
const classes =
|
|
10
|
-
.filter(Boolean)
|
|
11
|
-
.join(' ');
|
|
8
|
+
const { children, severity = 'info', variant = 'standard', icon, 'kt:close': onClose, sx } = props;
|
|
9
|
+
const classes = `mui-alert mui-alert-${severity} mui-alert-${variant} ${props.class ? props.class : ''}`;
|
|
12
10
|
// Convert sx object to style string
|
|
13
11
|
let styleString = props.style || '';
|
|
14
12
|
if (sx) {
|
|
@@ -46,12 +44,12 @@ function Alert(props) {
|
|
|
46
44
|
return alert;
|
|
47
45
|
}
|
|
48
46
|
|
|
49
|
-
const emptyFn$
|
|
47
|
+
const emptyFn$3 = () => { };
|
|
50
48
|
/**
|
|
51
49
|
* Button component - mimics MUI Button appearance and behavior
|
|
52
50
|
*/
|
|
53
51
|
function Button(props) {
|
|
54
|
-
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;
|
|
55
53
|
const classes = [
|
|
56
54
|
'mui-button',
|
|
57
55
|
`mui-button-${variant}`,
|
|
@@ -93,7 +91,7 @@ function Button(props) {
|
|
|
93
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" })] }));
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
const emptyFn$
|
|
94
|
+
const emptyFn$2 = () => { };
|
|
97
95
|
/**
|
|
98
96
|
* Checkbox component - mimics MUI Checkbox appearance and behavior
|
|
99
97
|
*/
|
|
@@ -120,7 +118,7 @@ function Checkbox(props) {
|
|
|
120
118
|
toggleIcon(checked, indeterminate);
|
|
121
119
|
onChange(checked, value);
|
|
122
120
|
};
|
|
123
|
-
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;
|
|
124
122
|
const inputRef = ref$1();
|
|
125
123
|
// Unchecked icon
|
|
126
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" }) }) }));
|
|
@@ -149,7 +147,7 @@ function Checkbox(props) {
|
|
|
149
147
|
* CheckboxGroup component - groups multiple checkboxes together
|
|
150
148
|
*/
|
|
151
149
|
function CheckboxGroup(props) {
|
|
152
|
-
let { value = [], size = 'medium', '
|
|
150
|
+
let { value = [], size = 'medium', 'kt:change': onChange = emptyFn$2, row = false } = props;
|
|
153
151
|
let selectedValues = new Set(value);
|
|
154
152
|
const changeHandler = (checked, checkboxValue) => {
|
|
155
153
|
if (checked) {
|
|
@@ -163,15 +161,15 @@ function CheckboxGroup(props) {
|
|
|
163
161
|
const checkboxes = props.options.map((o) => {
|
|
164
162
|
o.size = size;
|
|
165
163
|
o.checked = selectedValues.has(o.value);
|
|
166
|
-
const originalChange = o['
|
|
164
|
+
const originalChange = o['kt:change'];
|
|
167
165
|
if (originalChange) {
|
|
168
|
-
o['
|
|
166
|
+
o['kt:change'] = (checked, value) => {
|
|
169
167
|
originalChange(checked, value);
|
|
170
168
|
changeHandler(checked, value);
|
|
171
169
|
};
|
|
172
170
|
}
|
|
173
171
|
else {
|
|
174
|
-
o['
|
|
172
|
+
o['kt:change'] = changeHandler;
|
|
175
173
|
}
|
|
176
174
|
return Checkbox(o);
|
|
177
175
|
});
|
|
@@ -191,13 +189,13 @@ function CheckboxGroup(props) {
|
|
|
191
189
|
return container;
|
|
192
190
|
}
|
|
193
191
|
|
|
194
|
-
const noop = () => { };
|
|
192
|
+
const noop$1 = () => { };
|
|
195
193
|
/**
|
|
196
194
|
* Dialog component - mimics MUI Dialog appearance and behavior
|
|
197
195
|
* Only handles open/close state, title and content are passed as props
|
|
198
196
|
*/
|
|
199
197
|
function Dialog(props) {
|
|
200
|
-
let { open = false, '
|
|
198
|
+
let { open = false, 'kt:close': onClose = noop$1, title, children, actions, maxWidth = 'sm', fullWidth = false, } = props;
|
|
201
199
|
// Handle ESC key - store handler for cleanup
|
|
202
200
|
const keyDownHandler = (e) => {
|
|
203
201
|
if (e.key === 'Escape') {
|
|
@@ -282,8 +280,42 @@ document.createElement('div');
|
|
|
282
280
|
* - can alse be used to store normal values, but it is not reactive.
|
|
283
281
|
* @param value mostly an HTMLElement
|
|
284
282
|
*/
|
|
285
|
-
function ref(value) {
|
|
286
|
-
|
|
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
|
+
};
|
|
287
319
|
}
|
|
288
320
|
|
|
289
321
|
/**
|
|
@@ -327,64 +359,134 @@ function LinearProgress(props) {
|
|
|
327
359
|
return container;
|
|
328
360
|
}
|
|
329
361
|
|
|
330
|
-
const
|
|
362
|
+
const noop = () => { };
|
|
331
363
|
/**
|
|
332
364
|
* TextField component - mimics MUI TextField appearance and behavior
|
|
333
365
|
*/
|
|
334
366
|
function TextField(props) {
|
|
335
|
-
|
|
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;
|
|
336
368
|
let isFocused = false;
|
|
337
|
-
const
|
|
369
|
+
const helperTextEl = jsx("p", { class: "mui-textfield-helper-text", children: helperText });
|
|
338
370
|
// Update container classes
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
const classes = [
|
|
371
|
+
const updateContainerClass = () => {
|
|
372
|
+
container.className = [
|
|
342
373
|
'mui-textfield-root',
|
|
343
374
|
`mui-textfield-size-${size}`,
|
|
344
375
|
isFocused ? 'mui-textfield-focused' : '',
|
|
345
376
|
error ? 'mui-textfield-error' : '',
|
|
346
377
|
disabled ? 'mui-textfield-disabled' : '',
|
|
347
378
|
fullWidth ? 'mui-textfield-fullwidth' : '',
|
|
348
|
-
label &&
|
|
379
|
+
label && isFocused && inputEl.value ? 'mui-textfield-has-value' : '',
|
|
349
380
|
label ? '' : 'mui-textfield-no-label',
|
|
350
|
-
];
|
|
351
|
-
container.className = classes.join(' ');
|
|
381
|
+
].join(' ');
|
|
352
382
|
};
|
|
353
383
|
const handleInput = (e) => {
|
|
354
384
|
const target = e.target;
|
|
355
|
-
|
|
385
|
+
updateContainerClass();
|
|
356
386
|
onInput(target.value, e);
|
|
387
|
+
onInputTrim(target.value.trim(), e);
|
|
357
388
|
};
|
|
358
389
|
const handleChange = (e) => {
|
|
359
390
|
const target = e.target;
|
|
360
391
|
onChange(target.value, e);
|
|
392
|
+
onChangeTrim(target.value.trim(), e);
|
|
361
393
|
};
|
|
362
394
|
const handleFocus = (e) => {
|
|
363
395
|
isFocused = true;
|
|
364
|
-
|
|
396
|
+
updateContainerClass();
|
|
365
397
|
const target = e.target;
|
|
366
398
|
onFocus(target.value, e);
|
|
367
399
|
};
|
|
368
400
|
const handleBlur = (e) => {
|
|
369
401
|
isFocused = false;
|
|
370
|
-
|
|
402
|
+
updateContainerClass();
|
|
371
403
|
const target = e.target;
|
|
372
404
|
onBlur(target.value, e);
|
|
373
405
|
};
|
|
374
406
|
// Create input or textarea element
|
|
375
407
|
// Only show placeholder when label is floating (focused or has value)
|
|
376
408
|
const getPlaceholder = () => (label && !isFocused && !value ? '' : placeholder);
|
|
377
|
-
const
|
|
378
|
-
|
|
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] }));
|
|
379
414
|
// Initialize classes
|
|
380
|
-
setTimeout(() =>
|
|
381
|
-
Object.
|
|
382
|
-
|
|
383
|
-
|
|
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
|
+
},
|
|
384
425
|
},
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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
|
+
},
|
|
388
490
|
},
|
|
389
491
|
});
|
|
390
492
|
return container;
|
|
@@ -408,7 +510,7 @@ function Radio(props) {
|
|
|
408
510
|
toggleIcon(checked);
|
|
409
511
|
onChange(checked, value);
|
|
410
512
|
};
|
|
411
|
-
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;
|
|
412
514
|
const inputRef = ref$1();
|
|
413
515
|
let checked = initChecked;
|
|
414
516
|
let disabled = initDisabled;
|
|
@@ -428,7 +530,7 @@ function Radio(props) {
|
|
|
428
530
|
* RadioGroup component - groups multiple radios together
|
|
429
531
|
*/
|
|
430
532
|
function RadioGroup(props) {
|
|
431
|
-
const { value = '', size = 'small', '
|
|
533
|
+
const { value = '', size = 'small', 'kt:change': onChange = emptyFn$1, row = false } = props;
|
|
432
534
|
const changeHandler = (checked, value) => {
|
|
433
535
|
if (checked) {
|
|
434
536
|
onChange(value);
|
|
@@ -438,15 +540,15 @@ function RadioGroup(props) {
|
|
|
438
540
|
const radios = props.options.map((o) => {
|
|
439
541
|
o.size = size;
|
|
440
542
|
o.checked = value === o.value;
|
|
441
|
-
const originalChange = o['
|
|
543
|
+
const originalChange = o['kt:change'];
|
|
442
544
|
if (originalChange) {
|
|
443
|
-
o['
|
|
545
|
+
o['kt:change'] = (checked, newValue) => {
|
|
444
546
|
originalChange(checked, newValue);
|
|
445
547
|
changeHandler(checked, newValue);
|
|
446
548
|
};
|
|
447
549
|
}
|
|
448
550
|
else {
|
|
449
|
-
o['
|
|
551
|
+
o['kt:change'] = changeHandler;
|
|
450
552
|
}
|
|
451
553
|
return Radio(o);
|
|
452
554
|
});
|
|
@@ -458,7 +560,7 @@ const emptyFn = () => { };
|
|
|
458
560
|
* Select component - mimics MUI Select appearance and behavior
|
|
459
561
|
*/
|
|
460
562
|
function Select(props) {
|
|
461
|
-
let { value = '', options = [], label = '', placeholder = '', size = 'medium', '
|
|
563
|
+
let { value = '', options = [], label = '', placeholder = '', size = 'medium', 'kt:change': onChange = emptyFn, fullWidth = false, disabled = false, } = props;
|
|
462
564
|
let isOpen = false;
|
|
463
565
|
let isFocused = false;
|
|
464
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.
|
|
38
|
+
"@ktjs/core": "0.18.4"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "rollup -c rollup.config.mjs",
|