@ktjs/mui 0.19.0 → 0.20.2

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.
@@ -11,6 +11,7 @@ var __ktjs_mui__ = (function (exports) {
11
11
  };
12
12
 
13
13
  // DOM manipulation utilities
14
+ // # dom natives
14
15
  /**
15
16
  * & Remove `bind` because it is shockingly slower than wrapper
16
17
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -46,10 +47,11 @@ var __ktjs_mui__ = (function (exports) {
46
47
  $appendChild.call(this, fragment);
47
48
  }
48
49
  };
50
+ const { get: $buttonDisabledGetter$2, set: $buttonDisabledSetter$2 } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
49
51
 
50
52
  // Shared utilities and cached native methods for kt.js framework
51
53
  // Re-export all utilities
52
- Object.defineProperty(window, '@ktjs/shared', { value: '0.19.0' });
54
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.20.0' });
53
55
 
54
56
  const booleanHandler = (element, key, value) => {
55
57
  if (key in element) {
@@ -192,7 +194,14 @@ var __ktjs_mui__ = (function (exports) {
192
194
  }
193
195
  }
194
196
 
195
- const svgTempWrapper = document.createElement('div');
197
+ document.createElement('div');
198
+ const htmlCreator = (tag) => document.createElement(tag);
199
+ const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
200
+ const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
201
+ let creator = htmlCreator;
202
+ // # consts
203
+ const SVG_ATTR_FLAG = '__kt_svg__';
204
+ const MATHML_ATTR_FLAG = '__kt_mathml__';
196
205
  /**
197
206
  * Create an enhanced HTMLElement.
198
207
  * - Only supports HTMLElements, **NOT** SVGElements or other Elements.
@@ -203,7 +212,7 @@ var __ktjs_mui__ = (function (exports) {
203
212
  * ## About
204
213
  * @package @ktjs/core
205
214
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
206
- * @version 0.19.0 (Last Update: 2026.01.31 22:50:55.987)
215
+ * @version 0.20.3 (Last Update: 2026.02.01 18:38:02.198)
207
216
  * @license MIT
208
217
  * @link https://github.com/baendlorel/kt.js
209
218
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -214,15 +223,32 @@ var __ktjs_mui__ = (function (exports) {
214
223
  if (typeof tag !== 'string') {
215
224
  $throw('tagName must be a string.');
216
225
  }
226
+ if (attr) {
227
+ if (SVG_ATTR_FLAG in attr) {
228
+ delete attr[SVG_ATTR_FLAG];
229
+ creator = svgCreator;
230
+ }
231
+ else if (MATHML_ATTR_FLAG in attr) {
232
+ delete attr[MATHML_ATTR_FLAG];
233
+ creator = mathMLCreator;
234
+ }
235
+ else {
236
+ creator = htmlCreator;
237
+ }
238
+ }
217
239
  // * start creating the element
218
- const element = document.createElement(tag);
240
+ const element = creator(tag);
219
241
  // * Handle content
220
242
  applyAttr(element, attr);
221
243
  applyContent(element, content);
222
- if (tag === 'svg') {
223
- svgTempWrapper.innerHTML = element.outerHTML;
224
- return svgTempWrapper.firstChild;
225
- }
244
+ // if (tag === 'svg') {
245
+ // tempWrapper.innerHTML = element.outerHTML;
246
+ // return tempWrapper.firstChild as HTML<T>;
247
+ // }
248
+ // if (tag === 'math') {
249
+ // tempWrapper.innerHTML = element.outerHTML;
250
+ // return tempWrapper.firstChild as HTML<T>;
251
+ // }
226
252
  return element;
227
253
  };
228
254
 
@@ -231,21 +257,13 @@ var __ktjs_mui__ = (function (exports) {
231
257
  * @param tag html tag or function component
232
258
  * @param props properties/attributes
233
259
  */
234
- function jsx(tag, props = {}) {
260
+ function jsx(tag, props) {
235
261
  const ref = props.ref?.isKT ? props.ref : dummyRef;
236
262
  let el;
237
- const redraw = (newProps) => {
238
- props = newProps ? { ...props, ...newProps } : props;
239
- el = jsx(tag, props);
240
- if (ref !== dummyRef) {
241
- ref.value = el; // & ref setter automatically replaces old element in DOM
242
- }
243
- return el;
244
- };
245
263
  if ('k-if' in props && !props['k-if']) {
264
+ // & make comment placeholder in case that ref might be redrawn later
246
265
  el = document.createComment('k-if');
247
- ref.value = el; // & ref setter automatically replaces old element in DOM
248
- el.redraw = redraw;
266
+ ref.value = el;
249
267
  return el;
250
268
  }
251
269
  // Handle function components
@@ -255,7 +273,6 @@ var __ktjs_mui__ = (function (exports) {
255
273
  else {
256
274
  el = h(tag, props, props.children);
257
275
  }
258
- el.redraw ??= redraw;
259
276
  ref.value = el;
260
277
  return el;
261
278
  }
@@ -265,57 +282,16 @@ var __ktjs_mui__ = (function (exports) {
265
282
  */
266
283
  const jsxs = jsx;
267
284
 
268
- /**s
269
- * Alert component - mimics MUI Alert appearance and behavior
270
- */
271
- function Alert(props) {
272
- const { children, style = '', severity = 'info', variant = 'standard', icon, 'kt:close': onClose } = props;
273
- const classes = `mui-alert mui-alert-${severity} mui-alert-${variant} ${props.class ? props.class : ''}`;
274
- // Convert sx object to style string
275
- let styleString = typeof style === 'string' ? style : '';
276
- if (style && typeof style === 'object') {
277
- const sxStyles = Object.entries(style)
278
- .map(([key, value]) => {
279
- // Convert camelCase to kebab-case
280
- const cssKey = key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
281
- return `${cssKey}: ${value}`;
282
- })
283
- .join('; ');
284
- styleString = styleString ? `${styleString}; ${sxStyles}` : sxStyles;
285
- }
286
- // Icon SVG paths for different severities
287
- const getIcon = () => {
288
- if (icon === false)
289
- return null;
290
- if (icon)
291
- return icon;
292
- const iconSize = '22px';
293
- const iconClass = 'mui-alert-icon';
294
- switch (severity) {
295
- case 'success':
296
- return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }));
297
- case 'error':
298
- return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" }) }));
299
- case 'warning':
300
- return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" }) }));
301
- case 'info':
302
- default:
303
- return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" }) }));
304
- }
305
- };
306
- const alertIcon = getIcon();
307
- const alert = (jsxs("div", { class: classes, style: styleString, role: "alert", children: [alertIcon && jsx("div", { class: "mui-alert-icon-wrapper", children: alertIcon }), jsx("div", { class: "mui-alert-message", children: children }), onClose && (jsx("button", { class: "mui-alert-close", "on:click": onClose, "aria-label": "Close", children: jsx("svg", { viewBox: "0 0 24 24", width: "18px", height: "18px", children: jsx("path", { fill: "currentColor", d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }))] }));
308
- return alert;
309
- }
310
-
311
285
  // Cached native methods for performance optimization
286
+ const $defines = Object.defineProperties;
312
287
 
313
288
  // String manipulation utilities
314
289
  /**
315
290
  * Default empty function
316
291
  */
317
292
  const $emptyFn = (() => true);
318
- // Style parsing utilities
293
+ const { get: $buttonDisabledGetter$1, set: $buttonDisabledSetter$1 } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
294
+ // # DOM utilities
319
295
  const parseStyle = (style) => {
320
296
  if (typeof style === 'string') {
321
297
  return style;
@@ -344,25 +320,54 @@ var __ktjs_mui__ = (function (exports) {
344
320
 
345
321
  // Shared utilities and cached native methods for kt.js framework
346
322
  // Re-export all utilities
347
- Object.defineProperty(window, '@ktjs/shared', { value: '0.19.0' });
323
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.20.0' });
324
+
325
+ function Alert(props) {
326
+ const { children, severity = 'info', variant = 'standard', icon, 'kt:close': onClose } = props;
327
+ const classes = `mui-alert mui-alert-${severity} mui-alert-${variant} ${props.class ? props.class : ''}`;
328
+ // Icon SVG paths for different severities
329
+ const getIcon = () => {
330
+ if (icon === false) {
331
+ return null;
332
+ }
333
+ if (icon) {
334
+ return icon;
335
+ }
336
+ const iconSize = '22px';
337
+ const iconClass = 'mui-alert-icon';
338
+ switch (severity) {
339
+ case 'success':
340
+ return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }));
341
+ case 'error':
342
+ return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" }) }));
343
+ case 'warning':
344
+ return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" }) }));
345
+ case 'info':
346
+ default:
347
+ return (jsx("svg", { class: iconClass, viewBox: "0 0 24 24", width: iconSize, height: iconSize, children: jsx("path", { fill: "currentColor", d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" }) }));
348
+ }
349
+ };
350
+ const alertIcon = getIcon();
351
+ const alert = (jsxs("div", { class: classes, style: parseStyle(props.style), role: "alert", children: [alertIcon && jsx("div", { class: "mui-alert-icon-wrapper", children: alertIcon }), jsx("div", { class: "mui-alert-message", children: children }), jsx("button", { "k-if": onClose, class: "mui-alert-close", "on:click": onClose, "aria-label": "Close", children: jsx("svg", { viewBox: "0 0 24 24", width: "18px", height: "18px", children: jsx("path", { fill: "currentColor", d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) })] }));
352
+ return alert;
353
+ }
348
354
 
349
355
  /**
350
356
  * Button component - mimics MUI Button appearance and behavior
351
357
  */
352
358
  function Button(props) {
353
- const { children, variant = 'text', color = 'primary', size = 'medium', disabled = false, fullWidth = false, iconOnly = false, startIcon, endIcon, type = 'button', 'on:click': onClick = $emptyFn, } = props;
359
+ let { children, variant = 'text', color = 'primary', size = 'medium', disabled = false, fullWidth = false, iconOnly = false, startIcon, endIcon, type = 'button', 'on:click': onClick = $emptyFn, } = props;
354
360
  const classes = [
355
361
  'mui-button',
356
362
  `mui-button-${variant}`,
357
363
  `mui-button-${variant}-${color}`,
358
364
  `mui-button-size-${size}`,
359
- fullWidth && 'mui-button-fullwidth',
360
- iconOnly && 'mui-button-icon-only',
361
- disabled && 'mui-button-disabled',
365
+ fullWidth ? 'mui-button-fullwidth' : '',
366
+ iconOnly ? 'mui-button-icon-only' : '',
367
+ disabled ? 'mui-button-disabled' : '',
362
368
  props.class ? props.class : '',
363
- ]
364
- .filter(Boolean)
365
- .join(' ');
369
+ ].join(' ');
370
+ const rippleContainer = jsx("span", { class: "mui-button-ripple" });
366
371
  const handleClick = (e) => {
367
372
  if (disabled) {
368
373
  e.preventDefault();
@@ -370,7 +375,6 @@ var __ktjs_mui__ = (function (exports) {
370
375
  }
371
376
  // Create ripple effect
372
377
  const button = e.currentTarget;
373
- const rippleContainer = button.querySelector('.mui-button-ripple');
374
378
  if (rippleContainer) {
375
379
  const rect = button.getBoundingClientRect();
376
380
  const size = Math.max(rect.width, rect.height);
@@ -383,13 +387,21 @@ var __ktjs_mui__ = (function (exports) {
383
387
  ripple.classList.add('mui-button-ripple-effect');
384
388
  rippleContainer.appendChild(ripple);
385
389
  // Remove ripple after animation
386
- setTimeout(() => {
387
- ripple.remove();
388
- }, 600);
390
+ setTimeout(() => ripple.remove(), 600);
389
391
  }
390
392
  onClick(e);
391
393
  };
392
- return (jsxs("button", { class: classes, style: parseStyle(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" })] }));
394
+ const container = (jsxs("button", { class: classes, style: parseStyle(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 }), rippleContainer] }));
395
+ $defines(container, {
396
+ disabled: {
397
+ get: $buttonDisabledGetter$1,
398
+ set: function (value) {
399
+ $buttonDisabledSetter$1.call(this, value);
400
+ this.classList.toggle('mui-button-disabled', value);
401
+ },
402
+ },
403
+ });
404
+ return container;
393
405
  }
394
406
 
395
407
  /**
@@ -430,7 +442,7 @@ var __ktjs_mui__ = (function (exports) {
430
442
  // Initialize icon state
431
443
  toggleIcon(checked, indeterminate);
432
444
  const container = (jsxs("label", { class: `mui-checkbox-wrapper mui-checkbox-size-${size} ${disabled ? 'mui-checkbox-disabled' : ''} mui-checkbox-color-${color}`, children: [inputEl, jsxs("span", { class: "mui-checkbox-icon", children: [uncheckedIcon, checkedIcon, indeterminateIcon] }), jsx("span", { "k-if": label, class: "mui-checkbox-label", children: label })] }));
433
- Object.defineProperties(container, {
445
+ $defines(container, {
434
446
  checked: {
435
447
  get() {
436
448
  return checked;
@@ -496,7 +508,7 @@ var __ktjs_mui__ = (function (exports) {
496
508
  return Checkbox(o);
497
509
  });
498
510
  const container = (jsx("div", { class: `mui-checkbox-group ${row ? 'mui-checkbox-group-row' : ''} ${props.class ? props.class : ''}`, style: props.style ? props.style : '', role: "group", children: checkboxes }));
499
- Object.defineProperties(container, {
511
+ $defines(container, {
500
512
  value: {
501
513
  get() {
502
514
  return Array.from(selectedValues);
@@ -567,26 +579,28 @@ var __ktjs_mui__ = (function (exports) {
567
579
  }
568
580
  return originalRemove.call(container);
569
581
  };
570
- Object.defineProperty(container, 'open', {
571
- get: () => open,
572
- set: (isOpen) => {
573
- if (isOpen === open) {
574
- return;
575
- }
576
- open = isOpen;
577
- if (isOpen) {
578
- // Opening: set display first, then add class with double RAF for animation
579
- container.style.display = 'flex';
580
- setTimeout(() => container.classList.add('kt-dialog-backdrop-open'), 50);
581
- }
582
- else {
583
- container.classList.remove('kt-dialog-backdrop-open');
584
- setTimeout(() => {
585
- if (!open) {
586
- container.style.display = 'none';
587
- }
588
- }, 225);
589
- }
582
+ $defines(container, {
583
+ open: {
584
+ get: () => open,
585
+ set: (isOpen) => {
586
+ if (isOpen === open) {
587
+ return;
588
+ }
589
+ open = isOpen;
590
+ if (isOpen) {
591
+ // Opening: set display first, then add class with double RAF for animation
592
+ container.style.display = 'flex';
593
+ setTimeout(() => container.classList.add('kt-dialog-backdrop-open'), 50);
594
+ }
595
+ else {
596
+ container.classList.remove('kt-dialog-backdrop-open');
597
+ setTimeout(() => {
598
+ if (!open) {
599
+ container.style.display = 'none';
600
+ }
601
+ }, 225);
602
+ }
603
+ },
590
604
  },
591
605
  });
592
606
  return container;
@@ -617,10 +631,11 @@ var __ktjs_mui__ = (function (exports) {
617
631
  }
618
632
 
619
633
  // Cached native methods for performance optimization
634
+ const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
620
635
 
621
636
  // Shared utilities and cached native methods for kt.js framework
622
637
  // Re-export all utilities
623
- Object.defineProperty(window, '@ktjs/shared', { value: '0.19.0' });
638
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.20.0' });
624
639
 
625
640
  document.createElement('div');
626
641
 
@@ -629,7 +644,13 @@ var __ktjs_mui__ = (function (exports) {
629
644
  * Indicates that this is a KTRef instance
630
645
  */
631
646
  isKT = true;
647
+ /**
648
+ * @internal
649
+ */
632
650
  _value;
651
+ /**
652
+ * @internal
653
+ */
633
654
  _onChanges;
634
655
  constructor(_value, _onChanges) {
635
656
  this._value = _value;
@@ -695,13 +716,12 @@ var __ktjs_mui__ = (function (exports) {
695
716
  */
696
717
  function createRedrawable(creator) {
697
718
  const elRef = ref();
698
- elRef.value = creator();
699
719
  const redraw = () => {
700
720
  elRef.value = creator(); // ref setter automatically calls replaceWith
701
- elRef.value.redraw = redraw;
721
+ elRef.redraw = redraw;
702
722
  return elRef.value;
703
723
  };
704
- elRef.value.redraw = redraw;
724
+ redraw();
705
725
  return elRef;
706
726
  }
707
727
 
@@ -721,15 +741,17 @@ var __ktjs_mui__ = (function (exports) {
721
741
  let progressValue = Math.min(Math.max(value, 0), 100);
722
742
  const barRef = ref();
723
743
  const container = (jsx("div", { class: classes, style: styleString, role: "progressbar", "aria-valuenow": progressValue, children: jsx("div", { ref: barRef, class: "mui-linear-progress-bar", style: variant === 'determinate' ? `width: ${progressValue}%` : '' }) }));
724
- Object.defineProperty(container, 'progress', {
725
- get() {
726
- return progressValue;
727
- },
728
- set(newValue) {
729
- progressValue = Math.min(Math.max(newValue, 0), 100);
730
- if (variant === 'determinate') {
731
- barRef.value.style.width = `${progressValue}%`;
732
- }
744
+ $defines(container, {
745
+ progress: {
746
+ get() {
747
+ return progressValue;
748
+ },
749
+ set(newValue) {
750
+ progressValue = Math.min(Math.max(newValue, 0), 100);
751
+ if (variant === 'determinate') {
752
+ barRef.value.style.width = `${progressValue}%`;
753
+ }
754
+ },
733
755
  },
734
756
  });
735
757
  return container;
@@ -792,17 +814,27 @@ var __ktjs_mui__ = (function (exports) {
792
814
  updateContainerClass();
793
815
  onBlur(inputEl.value);
794
816
  };
817
+ const handleWrapperMouseDown = (e) => {
818
+ if (disabled) {
819
+ return;
820
+ }
821
+ const target = e.target;
822
+ if (!target || target === inputEl) {
823
+ return;
824
+ }
825
+ setTimeout(() => inputEl.focus(), 0);
826
+ };
795
827
  const getPlaceholder = () => (label && !isFocused && !value ? '' : placeholder);
796
828
  let isFocused = false;
797
829
  const inputEl = multiline
798
830
  ? (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 }))
799
831
  : (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 }));
800
832
  const helperTextEl = jsx("p", { class: "mui-textfield-helper-text", children: helperText });
801
- 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 && '*'] }) }) })] })));
833
+ const wrapperRef = createRedrawable(() => (jsxs("div", { class: "mui-textfield-wrapper", "on:mousedown": handleWrapperMouseDown, 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 && '*'] }) }) })] })));
802
834
  const container = (jsxs("div", { class: 'mui-textfield-root ' + (props.class ? props.class : ''), style: parseStyle(props.style), children: [wrapperRef, helperTextEl] }));
803
835
  // Initialize classes
804
836
  setTimeout(() => updateContainerClass(), 0);
805
- Object.defineProperties(container, {
837
+ $defines(container, {
806
838
  value: {
807
839
  get() {
808
840
  return inputEl.value;
@@ -818,7 +850,7 @@ var __ktjs_mui__ = (function (exports) {
818
850
  },
819
851
  set(newLabel) {
820
852
  label = newLabel;
821
- wrapperRef.value.redraw(); // label takes too much and should be redrawn
853
+ wrapperRef.redraw(); // label takes too much and should be redrawn
822
854
  updateContainerClass();
823
855
  },
824
856
  },
@@ -906,7 +938,7 @@ var __ktjs_mui__ = (function (exports) {
906
938
  // initialize icon state
907
939
  toggleIcon(checked);
908
940
  const container = (jsxs("label", { class: `mui-radio-wrapper ${props.class ?? ''} mui-radio-size-${size} ${disabled ? 'mui-radio-disabled' : ''} mui-radio-color-${color}`, style: parseStyle(props.style), children: [input, jsxs("span", { class: "mui-radio-icon", children: [uncheckedIcon, checkedIcon] }), jsx("span", { class: "mui-radio-label", children: text })] }));
909
- Object.defineProperties(container, {
941
+ $defines(container, {
910
942
  value: {
911
943
  get() {
912
944
  return value;
@@ -953,7 +985,7 @@ var __ktjs_mui__ = (function (exports) {
953
985
  return Radio(o);
954
986
  });
955
987
  const container = (jsx("div", { class: `mui-radio-group ${row ? 'mui-radio-group-row' : ''} ${props.class ?? ''}`, style: parseStyle(props.style), role: "radiogroup", children: radios }));
956
- Object.defineProperties(container, {
988
+ $defines(container, {
957
989
  value: {
958
990
  get() {
959
991
  return value;
@@ -976,6 +1008,7 @@ var __ktjs_mui__ = (function (exports) {
976
1008
  let isOpen = false;
977
1009
  let isFocused = false;
978
1010
  const selectRef = ref();
1011
+ const selectLabelRef = ref();
979
1012
  // Toggle dropdown
980
1013
  const toggleMenu = () => {
981
1014
  if (disabled) {
@@ -988,12 +1021,9 @@ var __ktjs_mui__ = (function (exports) {
988
1021
  const updateMenu = () => {
989
1022
  if (isOpen) {
990
1023
  menu.value.style.display = 'block';
991
- // Trigger reflow to enable animation
992
- void menu.value.offsetHeight;
993
- menu.value.classList.add('mui-select-menu-open');
1024
+ void menu.value.offsetHeight; // & Trigger reflow to enable animation
994
1025
  }
995
1026
  else {
996
- menu.value.classList.remove('mui-select-menu-open');
997
1027
  // Hide after animation completes
998
1028
  setTimeout(() => {
999
1029
  if (!isOpen) {
@@ -1001,6 +1031,7 @@ var __ktjs_mui__ = (function (exports) {
1001
1031
  }
1002
1032
  }, 200);
1003
1033
  }
1034
+ menu.value.classList.toggle('mui-select-menu-open', isOpen);
1004
1035
  selectRef.value.classList.toggle('mui-select-open', isOpen);
1005
1036
  };
1006
1037
  // Handle option click
@@ -1010,11 +1041,8 @@ var __ktjs_mui__ = (function (exports) {
1010
1041
  onChange(value);
1011
1042
  updateMenu();
1012
1043
  updateLabelState();
1013
- valueDisplay.value.redraw();
1014
- setTimeout(() => {
1015
- // Trigger redraw of parent if needed
1016
- menu.value.redraw();
1017
- }, 200);
1044
+ valueDisplay.redraw();
1045
+ setTimeout(() => menu.redraw(), 200);
1018
1046
  };
1019
1047
  // Close menu when clicking outside
1020
1048
  const handleClickOutside = (e) => {
@@ -1034,15 +1062,7 @@ var __ktjs_mui__ = (function (exports) {
1034
1062
  };
1035
1063
  // Update label focused state
1036
1064
  const updateLabelState = () => {
1037
- const labelElement = selectRef.value.querySelector('.mui-select-label');
1038
- if (labelElement) {
1039
- if (isFocused || value) {
1040
- labelElement.classList.add('focused');
1041
- }
1042
- else {
1043
- labelElement.classList.remove('focused');
1044
- }
1045
- }
1065
+ selectLabelRef.value.classList?.toggle('focused', isFocused || !!value);
1046
1066
  };
1047
1067
  const valueDisplay = createRedrawable(() => {
1048
1068
  const o = options.find((opt) => opt.value === value);
@@ -1056,10 +1076,32 @@ var __ktjs_mui__ = (function (exports) {
1056
1076
  return jsx("div", { class: "mui-select-display", children: inner });
1057
1077
  });
1058
1078
  const menu = createRedrawable(() => {
1059
- return (jsx("div", { class: "mui-select-menu", style: { display: 'none' }, children: options.map((option) => (jsx("div", { class: `mui-select-option ${option.value === value ? 'selected' : ''}`, "on:click": () => handleOptionClick(option.value), children: option.label }))) }));
1079
+ return (jsx("div", { class: "mui-select-menu", style: "display: none;", children: options.map((option) => (jsx("div", { class: `mui-select-option ${option.value === value ? 'selected' : ''}`, "on:click": () => handleOptionClick(option.value), children: option.label }))) }));
1060
1080
  });
1061
1081
  // Create container
1062
- const container = (jsxs("div", { ref: selectRef, class: `mui-select-wrapper mui-select-size-${size} ${props.class ?? ''} ${fullWidth ? 'mui-select-fullWidth' : ''} ${disabled ? 'mui-select-disabled' : ''}`, style: parseStyle(props.style), children: [label && jsx("label", { class: `mui-select-label ${value || isFocused ? 'focused' : ''}`, children: label }), jsxs("div", { class: "mui-select-control mui-select-outlined", "on:click": toggleMenu, "on:focus": handleFocus, "on:blur": handleBlur, tabIndex: disabled ? -1 : 0, children: [valueDisplay, jsx("input", { type: "hidden", value: value }), jsx("fieldset", { class: "mui-select-fieldset", children: jsx("legend", { children: jsx("span", { children: label }) }) }), jsx("svg", { class: "mui-select-icon", focusable: "false", "aria-hidden": "true", viewBox: "0 0 24 24", width: "24", height: "24", children: jsx("path", { d: "M7 10l5 5 5-5Z", fill: "currentColor" }) })] }), menu] }));
1082
+ const container = (jsxs("div", { ref: selectRef, class: `mui-select-wrapper mui-select-size-${size} ${props.class ?? ''} ${fullWidth ? 'mui-select-fullWidth' : ''} ${disabled ? 'mui-select-disabled' : ''}`, style: parseStyle(props.style), children: [jsx("label", { "k-if": label, ref: selectLabelRef, class: `mui-select-label ${value || isFocused ? 'focused' : ''}`, children: label }), jsxs("div", { class: "mui-select-control mui-select-outlined", "on:click": toggleMenu, "on:focus": handleFocus, "on:blur": handleBlur, tabIndex: disabled ? -1 : 0, children: [valueDisplay, jsx("input", { type: "hidden", value: value }), jsx("fieldset", { class: "mui-select-fieldset", children: jsx("legend", { children: jsx("span", { children: label }) }) }), jsx("svg", { class: "mui-select-icon", focusable: "false", "aria-hidden": "true", viewBox: "0 0 24 24", width: "24", height: "24", children: jsx("path", { d: "M7 10l5 5 5-5Z", fill: "currentColor" }) })] }), menu] }));
1083
+ $defines(container, {
1084
+ value: {
1085
+ get: () => value,
1086
+ set: (newValue) => {
1087
+ value = newValue;
1088
+ updateLabelState();
1089
+ valueDisplay.redraw();
1090
+ menu.redraw();
1091
+ },
1092
+ },
1093
+ disabled: {
1094
+ get: () => disabled,
1095
+ set: (newDisabled) => {
1096
+ disabled = newDisabled;
1097
+ if (disabled) {
1098
+ isOpen = false;
1099
+ updateMenu();
1100
+ }
1101
+ container.classList.toggle('mui-select-disabled', disabled);
1102
+ },
1103
+ },
1104
+ });
1063
1105
  // Add global click listener
1064
1106
  setTimeout(() => {
1065
1107
  document.removeEventListener('click', handleClickOutside);
@@ -1169,7 +1211,6 @@ var __ktjs_mui__ = (function (exports) {
1169
1211
  exports.Dialog = Dialog;
1170
1212
  exports.DownloadIcon = DownloadIcon;
1171
1213
  exports.ExpandMoreIcon = ExpandMoreIcon;
1172
- exports.FileOpen = FileOpenIcon;
1173
1214
  exports.FileOpenIcon = FileOpenIcon;
1174
1215
  exports.FolderOpenIcon = FolderOpenIcon;
1175
1216
  exports.FormLabel = FormLabel;