@marcoschwartz/lite-ui 0.7.0 → 0.7.1

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.mjs CHANGED
@@ -927,7 +927,8 @@ TextInput.displayName = "TextInput";
927
927
 
928
928
  // src/components/ActionMenu.tsx
929
929
  import { useState as useState5, useRef as useRef2, useEffect as useEffect5 } from "react";
930
- import { jsx as jsx41, jsxs as jsxs10 } from "react/jsx-runtime";
930
+ import { createPortal } from "react-dom";
931
+ import { Fragment as Fragment6, jsx as jsx41, jsxs as jsxs10 } from "react/jsx-runtime";
931
932
  var ActionMenu = ({
932
933
  items,
933
934
  trigger,
@@ -935,10 +936,16 @@ var ActionMenu = ({
935
936
  }) => {
936
937
  const { themeName } = useTheme();
937
938
  const [isOpen, setIsOpen] = useState5(false);
939
+ const [menuPosition, setMenuPosition] = useState5(null);
940
+ const [mounted, setMounted] = useState5(false);
938
941
  const menuRef = useRef2(null);
942
+ const triggerRef = useRef2(null);
943
+ useEffect5(() => {
944
+ setMounted(true);
945
+ }, []);
939
946
  useEffect5(() => {
940
947
  const handleClickOutside = (event) => {
941
- if (menuRef.current && !menuRef.current.contains(event.target)) {
948
+ if (menuRef.current && !menuRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
942
949
  setIsOpen(false);
943
950
  }
944
951
  };
@@ -947,7 +954,20 @@ var ActionMenu = ({
947
954
  return () => document.removeEventListener("mousedown", handleClickOutside);
948
955
  }
949
956
  }, [isOpen]);
957
+ useEffect5(() => {
958
+ if (isOpen && triggerRef.current) {
959
+ const rect = triggerRef.current.getBoundingClientRect();
960
+ const menuWidth = 224;
961
+ setMenuPosition({
962
+ top: rect.bottom + 8,
963
+ left: position === "left" ? rect.left : rect.right - menuWidth
964
+ });
965
+ } else {
966
+ setMenuPosition(null);
967
+ }
968
+ }, [isOpen, position]);
950
969
  const handleItemClick = (item) => {
970
+ if (item.type === "divider") return;
951
971
  if (!item.disabled) {
952
972
  item.onClick();
953
973
  setIsOpen(false);
@@ -963,15 +983,27 @@ var ActionMenu = ({
963
983
  );
964
984
  const menuBaseStyles = themeName === "minimalistic" ? "bg-black border-2 border-white" : "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-lg";
965
985
  const itemBaseStyles = themeName === "minimalistic" ? "text-white hover:bg-white hover:text-black transition-colors duration-200" : "text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors";
966
- const positionClass = position === "left" ? "left-0" : "right-0";
967
- return /* @__PURE__ */ jsxs10("div", { className: "relative inline-block", ref: menuRef, children: [
968
- /* @__PURE__ */ jsx41("div", { onClick: () => setIsOpen(!isOpen), children: trigger || defaultTrigger }),
969
- isOpen && /* @__PURE__ */ jsx41(
970
- "div",
971
- {
972
- className: `absolute ${positionClass} mt-2 w-56 rounded-lg ${menuBaseStyles} z-50 overflow-hidden`,
973
- style: { minWidth: "14rem" },
974
- children: items.map((item, index) => /* @__PURE__ */ jsxs10(
986
+ const menu = isOpen && mounted && menuPosition ? /* @__PURE__ */ jsx41(
987
+ "div",
988
+ {
989
+ ref: menuRef,
990
+ className: `fixed w-56 rounded-lg ${menuBaseStyles} z-[9999] max-h-[80vh] overflow-auto`,
991
+ style: {
992
+ minWidth: "14rem",
993
+ top: `${menuPosition.top}px`,
994
+ left: `${menuPosition.left}px`
995
+ },
996
+ children: items.map((item, index) => {
997
+ if (item.type === "divider") {
998
+ return /* @__PURE__ */ jsx41(
999
+ "div",
1000
+ {
1001
+ className: "my-1 border-t border-gray-200 dark:border-gray-700"
1002
+ },
1003
+ index
1004
+ );
1005
+ }
1006
+ return /* @__PURE__ */ jsxs10(
975
1007
  "button",
976
1008
  {
977
1009
  onClick: () => handleItemClick(item),
@@ -983,9 +1015,13 @@ var ActionMenu = ({
983
1015
  ]
984
1016
  },
985
1017
  index
986
- ))
987
- }
988
- )
1018
+ );
1019
+ })
1020
+ }
1021
+ ) : null;
1022
+ return /* @__PURE__ */ jsxs10(Fragment6, { children: [
1023
+ /* @__PURE__ */ jsx41("div", { className: "relative inline-block", ref: triggerRef, children: /* @__PURE__ */ jsx41("div", { onClick: () => setIsOpen(!isOpen), children: trigger || defaultTrigger }) }),
1024
+ mounted && createPortal(menu, document.body)
989
1025
  ] });
990
1026
  };
991
1027
 
@@ -1245,33 +1281,42 @@ function Table({
1245
1281
  const { theme } = useTheme();
1246
1282
  return /* @__PURE__ */ jsxs15("div", { className: `overflow-x-auto ${className}`, children: [
1247
1283
  /* @__PURE__ */ jsxs15("table", { className: "w-full text-left", children: [
1248
- /* @__PURE__ */ jsx49("thead", { className: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsx49("tr", { children: columns.map((column) => /* @__PURE__ */ jsx49(
1249
- "th",
1250
- {
1251
- className: "px-6 py-3 text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider",
1252
- style: { width: column.width },
1253
- children: column.title
1254
- },
1255
- column.key
1256
- )) }) }),
1257
- /* @__PURE__ */ jsx49("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: data.map((row, rowIndex) => /* @__PURE__ */ jsx49(
1258
- "tr",
1259
- {
1260
- className: `
1261
- ${striped && rowIndex % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : ""}
1262
- ${hoverable ? "hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" : ""}
1263
- `,
1264
- children: columns.map((column) => /* @__PURE__ */ jsx49(
1265
- "td",
1266
- {
1267
- className: "px-6 py-4 text-sm text-gray-900 dark:text-gray-100",
1268
- children: column.render ? column.render(row[column.key], row, rowIndex) : row[column.key]
1269
- },
1270
- column.key
1271
- ))
1272
- },
1273
- row[keyField] || rowIndex
1274
- )) })
1284
+ /* @__PURE__ */ jsx49("thead", { className: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsx49("tr", { children: columns.map((column, colIndex) => {
1285
+ const isLast = colIndex === columns.length - 1;
1286
+ return /* @__PURE__ */ jsx49(
1287
+ "th",
1288
+ {
1289
+ className: isLast ? "px-6 py-3 text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider relative" : "px-6 py-3 text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider",
1290
+ style: { width: column.width },
1291
+ children: column.title
1292
+ },
1293
+ column.key
1294
+ );
1295
+ }) }) }),
1296
+ /* @__PURE__ */ jsx49("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: data.map((row, rowIndex) => {
1297
+ const rowClasses = [
1298
+ striped && rowIndex % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : "",
1299
+ hoverable ? "hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" : ""
1300
+ ].filter(Boolean).join(" ");
1301
+ return /* @__PURE__ */ jsx49(
1302
+ "tr",
1303
+ {
1304
+ className: rowClasses,
1305
+ children: columns.map((column, colIndex) => {
1306
+ const isLast = colIndex === columns.length - 1;
1307
+ return /* @__PURE__ */ jsx49(
1308
+ "td",
1309
+ {
1310
+ className: isLast ? "px-6 py-4 text-sm text-gray-900 dark:text-gray-100 overflow-visible" : "px-6 py-4 text-sm text-gray-900 dark:text-gray-100",
1311
+ children: column.render ? column.render(row[column.key], row, rowIndex) : row[column.key]
1312
+ },
1313
+ column.key
1314
+ );
1315
+ })
1316
+ },
1317
+ row[keyField] || rowIndex
1318
+ );
1319
+ }) })
1275
1320
  ] }),
1276
1321
  data.length === 0 && /* @__PURE__ */ jsx49("div", { className: "text-center py-8 text-gray-500 dark:text-gray-400", children: "No data available" })
1277
1322
  ] });