@martinsura/ui 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -61,6 +61,21 @@ Important:
61
61
  - example: `package.json` = `0.1.1`, Git tag = `v0.1.1`
62
62
  - the npm publish runs only when the tag is pushed
63
63
 
64
+ ### Emergency local publish
65
+
66
+ If you ever need an emergency hotfix without waiting for GitHub Actions, you can publish directly from your machine:
67
+
68
+ ```bash
69
+ npm run build
70
+ npm publish --access public
71
+ ```
72
+
73
+ Important:
74
+
75
+ - always bump the version in `package.json` first
76
+ - npm does not allow publishing the same version twice
77
+ - this should be used only as a fallback, not as the default release workflow
78
+
64
79
  ## GitHub Actions Setup
65
80
 
66
81
  Before the first npm release, add this repository secret in GitHub:
package/dist/index.cjs CHANGED
@@ -648,9 +648,28 @@ var SwitchInput = ({
648
648
  errorDisplay && /* @__PURE__ */ jsxRuntime.jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
649
649
  ] });
650
650
  };
651
+
652
+ // src/floating/layerStack.ts
653
+ var FLOATING_ROOT_SELECTOR = "[data-ui-floating-root]";
654
+ var DRAWER_ROOT_SELECTOR = "[data-ui-drawer-root]";
655
+ function getTopmostElement(selector) {
656
+ const elements = document.querySelectorAll(selector);
657
+ return elements.length > 0 ? elements[elements.length - 1] : null;
658
+ }
659
+ function hasFloatingRootOpen() {
660
+ return getTopmostElement(FLOATING_ROOT_SELECTOR) !== null;
661
+ }
662
+ function isTopmostFloatingRoot(element) {
663
+ return element !== null && getTopmostElement(FLOATING_ROOT_SELECTOR) === element;
664
+ }
665
+ function isTopmostDrawerRoot(element) {
666
+ return element !== null && getTopmostElement(DRAWER_ROOT_SELECTOR) === element;
667
+ }
668
+ function isTargetInsideFloatingRoot(target) {
669
+ return target instanceof Element && target.closest(FLOATING_ROOT_SELECTOR) !== null;
670
+ }
651
671
  var GAP = 6;
652
672
  var VIEWPORT_MARGIN = 8;
653
- var FLOATING_ROOT_SELECTOR = "[data-ui-floating-root]";
654
673
  function calcPosition(triggerRect, panelRect, placement) {
655
674
  const spaceBelow = window.innerHeight - triggerRect.bottom - VIEWPORT_MARGIN;
656
675
  const spaceAbove = triggerRect.top - VIEWPORT_MARGIN;
@@ -757,7 +776,7 @@ var Dropdown = ({
757
776
  }
758
777
  };
759
778
  const handleKeyDown = (e) => {
760
- if (e.key === "Escape") {
779
+ if (e.key === "Escape" && isTopmostFloatingRoot(popupRef.current)) {
761
780
  setOpen(false);
762
781
  }
763
782
  };
@@ -1403,7 +1422,7 @@ var Table = ({
1403
1422
  sc.td,
1404
1423
  "align-middle",
1405
1424
  verticalBorders && tableCellVerticalBorderClass,
1406
- !col.wrap && "max-w-60 truncate",
1425
+ col.ellipsis && "max-w-60 truncate",
1407
1426
  col.wrap && "whitespace-normal",
1408
1427
  col.align === "center" && "text-center",
1409
1428
  col.align === "right" && "text-right",
@@ -1705,7 +1724,7 @@ var Grid = (props) => {
1705
1724
  sc.td,
1706
1725
  "align-middle",
1707
1726
  verticalBorders && tableCellVerticalBorderClass,
1708
- !col.wrap && "max-w-60 truncate",
1727
+ col.ellipsis && "max-w-60 truncate",
1709
1728
  col.wrap && "whitespace-normal",
1710
1729
  col.align === "center" && "text-center",
1711
1730
  col.align === "right" && "text-right",
@@ -1921,6 +1940,19 @@ var SelectDropdown = (props) => {
1921
1940
  react.useEffect(() => {
1922
1941
  if (props.isOpen) {
1923
1942
  document.addEventListener("mousedown", handleMouseDown);
1943
+ const handleKeyDown = (e) => {
1944
+ if (e.key === "Escape" && isTopmostFloatingRoot(popupRef.current)) {
1945
+ e.preventDefault();
1946
+ e.stopPropagation();
1947
+ e.stopImmediatePropagation();
1948
+ props.onClose();
1949
+ }
1950
+ };
1951
+ document.addEventListener("keydown", handleKeyDown);
1952
+ return () => {
1953
+ document.removeEventListener("mousedown", handleMouseDown);
1954
+ document.removeEventListener("keydown", handleKeyDown);
1955
+ };
1924
1956
  }
1925
1957
  return () => document.removeEventListener("mousedown", handleMouseDown);
1926
1958
  }, [props.isOpen, handleMouseDown]);
@@ -2270,6 +2302,19 @@ var CalendarPopup = (props) => {
2270
2302
  react.useEffect(() => {
2271
2303
  if (props.isOpen) {
2272
2304
  document.addEventListener("mousedown", handleMouseDown);
2305
+ const handleKeyDown = (e) => {
2306
+ if (e.key === "Escape" && isTopmostFloatingRoot(popupRef.current)) {
2307
+ e.preventDefault();
2308
+ e.stopPropagation();
2309
+ e.stopImmediatePropagation();
2310
+ props.onClose();
2311
+ }
2312
+ };
2313
+ document.addEventListener("keydown", handleKeyDown);
2314
+ return () => {
2315
+ document.removeEventListener("mousedown", handleMouseDown);
2316
+ document.removeEventListener("keydown", handleKeyDown);
2317
+ };
2273
2318
  }
2274
2319
  return () => document.removeEventListener("mousedown", handleMouseDown);
2275
2320
  }, [props.isOpen, handleMouseDown]);
@@ -2322,7 +2367,7 @@ var CalendarPopup = (props) => {
2322
2367
  ref: popupRef,
2323
2368
  "data-ui-floating-root": "",
2324
2369
  style: { top: pos.top, left: pos.left },
2325
- className: "fixed z-1000 bg-white border border-(--ui-border) rounded-(--ui-radius-lg) shadow-lg w-68",
2370
+ className: "fixed z-1003 bg-white border border-(--ui-border) rounded-(--ui-radius-lg) shadow-lg w-68",
2326
2371
  children: [
2327
2372
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-(--ui-border)", children: [
2328
2373
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2821,6 +2866,7 @@ var Drawer = ({ placement = "top", ...props }) => {
2821
2866
  const [footer, setFooter] = react.useState(null);
2822
2867
  const [loading, setLoading] = react.useState(false);
2823
2868
  const frameRef = react.useRef(0);
2869
+ const panelRef = react.useRef(null);
2824
2870
  react.useEffect(() => {
2825
2871
  if (props.isOpen) {
2826
2872
  setRendered(true);
@@ -2839,9 +2885,19 @@ var Drawer = ({ placement = "top", ...props }) => {
2839
2885
  return;
2840
2886
  }
2841
2887
  const handleKeyDown = (e) => {
2842
- if (e.key === "Escape") {
2843
- props.onClose(false);
2888
+ if (e.key !== "Escape" || e.defaultPrevented) {
2889
+ return;
2890
+ }
2891
+ if (hasFloatingRootOpen()) {
2892
+ return;
2893
+ }
2894
+ if (isTargetInsideFloatingRoot(e.target)) {
2895
+ return;
2896
+ }
2897
+ if (!isTopmostDrawerRoot(panelRef.current)) {
2898
+ return;
2844
2899
  }
2900
+ props.onClose(false);
2845
2901
  };
2846
2902
  document.body.style.overflow = "hidden";
2847
2903
  document.addEventListener("keydown", handleKeyDown);
@@ -2878,6 +2934,8 @@ var Drawer = ({ placement = "top", ...props }) => {
2878
2934
  /* @__PURE__ */ jsxRuntime.jsxs(
2879
2935
  "div",
2880
2936
  {
2937
+ ref: panelRef,
2938
+ "data-ui-drawer-root": "",
2881
2939
  className: tailwindMerge.twMerge(
2882
2940
  panelBase[placement],
2883
2941
  "bg-white shadow-xl transition-transform duration-220 ease-out",