@colletdev/core 0.1.6 → 0.1.8

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.
@@ -23,7 +23,7 @@
23
23
  import { initWasm, loadSharedStyles, loadInlineSharedStyles, loadMotionStyles, loadInlineMotionStyles, injectTokensToHead, injectFoucPrevention, CxElement, CxFormElement } from '../src/runtime.js';
24
24
 
25
25
  // Package version — used for CDN fallback URL
26
- const PKG_VERSION = '0.1.5';
26
+ const PKG_VERSION = '0.1.7';
27
27
 
28
28
  // ─── Lazy WASM + CSS ───
29
29
  // WASM glue and CSS strings are NOT imported at module level.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colletdev/core",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Rust/WASM Custom Elements — 48 production-grade UI components",
5
5
  "type": "module",
6
6
  "main": "generated/index.js",
package/src/runtime.js CHANGED
@@ -694,23 +694,38 @@ export class CxElement extends HTMLElementBase {
694
694
  const rect = trigger.getBoundingClientRect();
695
695
  const gap = opts?.gap ?? 4;
696
696
  const vh = window.innerHeight;
697
+ const vw = window.innerWidth;
697
698
  const below = vh - rect.bottom - gap;
698
699
  const above = rect.top - gap;
699
700
  const openAbove = below < 120 && above > below;
700
701
 
701
702
  panel.style.position = 'fixed';
702
703
  panel.style.zIndex = '50';
703
- panel.style.left = rect.left + 'px';
704
+
705
+ // Width: match trigger or use min-width
704
706
  if (opts?.matchWidth) panel.style.width = rect.width + 'px';
705
707
  else panel.style.minWidth = rect.width + 'px';
706
708
 
709
+ // Horizontal: clamp left edge so panel doesn't overflow right viewport edge.
710
+ // Also prevent negative left (overflow left edge).
711
+ const panelWidth = opts?.matchWidth ? rect.width : Math.max(rect.width, panel.offsetWidth || 200);
712
+ let left = rect.left;
713
+ if (left + panelWidth > vw - 8) left = Math.max(8, vw - panelWidth - 8);
714
+ if (left < 8) left = 8;
715
+ panel.style.left = left + 'px';
716
+
717
+ // Vertical: position above or below with max-height constraint.
718
+ // Reserves 8px margin from viewport edge so panels never touch the edge.
707
719
  if (openAbove) {
708
720
  panel.style.top = '';
709
721
  panel.style.bottom = (vh - rect.top + gap) + 'px';
722
+ panel.style.maxHeight = (above - 8) + 'px';
710
723
  } else {
711
724
  panel.style.top = (rect.bottom + gap) + 'px';
712
725
  panel.style.bottom = '';
726
+ panel.style.maxHeight = (below - 8) + 'px';
713
727
  }
728
+ panel.style.overflowY = 'auto';
714
729
 
715
730
  panel.setAttribute('data-placement', openAbove ? 'top' : 'bottom');
716
731
  return openAbove ? 'top' : 'bottom';
@@ -726,6 +741,8 @@ export class CxElement extends HTMLElementBase {
726
741
  panel.style.bottom = '';
727
742
  panel.style.width = '';
728
743
  panel.style.minWidth = '';
744
+ panel.style.maxHeight = '';
745
+ panel.style.overflowY = '';
729
746
  panel.removeAttribute('data-placement');
730
747
  }
731
748
  }
@@ -785,9 +802,11 @@ export class CxFormElement extends CxElement {
785
802
  get value() { return this.getAttribute?.('value') ?? ''; }
786
803
  set value(v) { if (v == null) this.removeAttribute('value'); else this.setAttribute('value', String(v)); }
787
804
  get disabled() { return this.hasAttribute('disabled'); }
788
- set disabled(v) { if (v) this.setAttribute('disabled', ''); else this.removeAttribute('disabled'); }
805
+ // React 19 sets boolean DOM properties directly (element.disabled = "").
806
+ // Empty string "" is falsy — must check explicitly for false/null/undefined.
807
+ set disabled(v) { if (v === false || v == null) this.removeAttribute('disabled'); else this.setAttribute('disabled', ''); }
789
808
  get required() { return this.hasAttribute('required'); }
790
- set required(v) { if (v) this.setAttribute('required', ''); else this.removeAttribute('required'); }
809
+ set required(v) { if (v === false || v == null) this.removeAttribute('required'); else this.setAttribute('required', ''); }
791
810
  get validity() { return this.#internals?.validity ?? null; }
792
811
  get validationMessage() { return this.#internals?.validationMessage ?? ''; }
793
812
  get willValidate() { return this.#internals?.willValidate ?? false; }