@pos-360/horizon 0.13.0 → 0.15.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.
@@ -1,10 +1,11 @@
1
1
  import { cn, Label } from './chunk-E3UN74IA.mjs';
2
2
  import * as React9 from 'react';
3
+ import { useState, useEffect, useCallback } from 'react';
3
4
  import { Slot } from '@radix-ui/react-slot';
4
5
  import { cva } from 'class-variance-authority';
5
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
7
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
7
- import { Check, X, ChevronRight, Circle, ChevronDown, ChevronUp, Search } from 'lucide-react';
8
+ import { Check, X, ChevronRight, Circle, ChevronDown, ChevronUp, Search, SlidersHorizontal } from 'lucide-react';
8
9
  import * as DialogPrimitive from '@radix-ui/react-dialog';
9
10
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
10
11
  import * as PopoverPrimitive from '@radix-ui/react-popover';
@@ -652,7 +653,8 @@ var Select = ({
652
653
  ) });
653
654
  };
654
655
  var SelectGroup = SelectPrimitive.Group;
655
- var SelectValue = SelectPrimitive.Value;
656
+ var SelectValue = React9.forwardRef(({ children, placeholder, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Value, { ref, placeholder, ...props, children }));
657
+ SelectValue.displayName = SelectPrimitive.Value.displayName;
656
658
  var SelectTrigger = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
657
659
  SelectPrimitive.Trigger,
658
660
  {
@@ -723,8 +725,10 @@ var SelectContent = React9.forwardRef(({ className, children, position = "popper
723
725
  sticky,
724
726
  hideWhenDetached
725
727
  } = props;
726
- return /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(
727
- SelectPrimitive.Content,
728
+ const ForceMountPortal = SelectPrimitive.Portal;
729
+ const ForceMountContent = SelectPrimitive.Content;
730
+ return /* @__PURE__ */ jsx(ForceMountPortal, { forceMount: true, children: /* @__PURE__ */ jsx(
731
+ ForceMountContent,
728
732
  {
729
733
  ref,
730
734
  position,
@@ -742,12 +746,12 @@ var SelectContent = React9.forwardRef(({ className, children, position = "popper
742
746
  onEscapeKeyDown,
743
747
  onPointerDownOutside,
744
748
  asChild: true,
749
+ ...{ forceMount: true },
745
750
  children: /* @__PURE__ */ jsxs(
746
751
  motion.div,
747
752
  {
748
- initial: { opacity: 0, scale: 0.96, y: -8 },
749
- animate: { opacity: 1, scale: 1, y: 0 },
750
- exit: { opacity: 0, scale: 0.96, y: -8 },
753
+ initial: false,
754
+ animate: open ? { opacity: 1, scale: 1, y: 0, pointerEvents: "auto" } : { opacity: 0, scale: 0.96, y: -8, pointerEvents: "none" },
751
755
  transition: {
752
756
  type: "spring",
753
757
  stiffness: 400,
@@ -792,7 +796,7 @@ var SelectContent = React9.forwardRef(({ className, children, position = "popper
792
796
  }
793
797
  )
794
798
  }
795
- ) }) });
799
+ ) });
796
800
  });
797
801
  SelectContent.displayName = SelectPrimitive.Content.displayName;
798
802
  var SelectLabel = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
@@ -936,7 +940,7 @@ var useTableContext = () => {
936
940
  const context = React9.useContext(TableContext);
937
941
  return context;
938
942
  };
939
- var Table = React9.forwardRef(
943
+ var TableInner = React9.forwardRef(
940
944
  ({
941
945
  className,
942
946
  selectable = false,
@@ -945,10 +949,18 @@ var Table = React9.forwardRef(
945
949
  onSelectionChange,
946
950
  getRowId,
947
951
  rows,
952
+ columns,
953
+ data,
954
+ visibleColumns,
955
+ showDividers = false,
956
+ highlightMode = "row",
957
+ children,
948
958
  ...props
949
959
  }, ref) => {
950
960
  const [internalSelectedRows, setInternalSelectedRows] = React9.useState(/* @__PURE__ */ new Set());
951
961
  const [registeredRowIds, setRegisteredRowIds] = React9.useState(/* @__PURE__ */ new Set());
962
+ const [hoveredCol, setHoveredCol] = React9.useState(null);
963
+ const [hoveredRowIndex, setHoveredRowIndex] = React9.useState(null);
952
964
  const isControlled = controlledSelectedRows !== void 0;
953
965
  const selectedRowsSet = isControlled ? new Set(controlledSelectedRows) : internalSelectedRows;
954
966
  const defaultGetRowId = React9.useCallback((row) => {
@@ -1065,17 +1077,82 @@ var Table = React9.forwardRef(
1065
1077
  registerRowId,
1066
1078
  unregisterRowId
1067
1079
  ]);
1068
- return /* @__PURE__ */ jsx(TableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
1069
- "table",
1080
+ return /* @__PURE__ */ jsx(TableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
1081
+ "div",
1070
1082
  {
1071
- ref,
1072
- className: cn("w-full caption-bottom text-sm", className),
1073
- ...props
1083
+ className: "relative w-full overflow-auto",
1084
+ onMouseLeave: () => {
1085
+ setHoveredCol(null);
1086
+ setHoveredRowIndex(null);
1087
+ },
1088
+ children: /* @__PURE__ */ jsx(
1089
+ "table",
1090
+ {
1091
+ ref,
1092
+ className: cn("w-full caption-bottom text-sm", className),
1093
+ ...props,
1094
+ children: columns && data ? /* @__PURE__ */ jsx(Fragment, { children: (() => {
1095
+ const visibleCols = columns.filter(
1096
+ (col) => col.sticky || !visibleColumns || visibleColumns.includes(col.key)
1097
+ );
1098
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1099
+ /* @__PURE__ */ jsx("thead", { className: "[&_tr]:border-b [&_tr]:border-gray-200 dark:[&_tr]:border-gray-700", children: /* @__PURE__ */ jsx("tr", { className: "border-b border-gray-200 transition-colors dark:border-neutral-700", children: visibleCols.map((col) => {
1100
+ const isColHovered = (highlightMode === "column" || highlightMode === "cross") && hoveredCol === col.key;
1101
+ return /* @__PURE__ */ jsx(
1102
+ "th",
1103
+ {
1104
+ style: col.minWidth ? { minWidth: col.minWidth } : void 0,
1105
+ onMouseEnter: () => {
1106
+ if (highlightMode === "column" || highlightMode === "cross") setHoveredCol(col.key);
1107
+ },
1108
+ className: cn(
1109
+ "h-12 px-4 text-left align-middle font-medium text-gray-500 dark:text-gray-400 transition-colors",
1110
+ col.sticky ? cn("sticky left-0 z-20", isColHovered ? "bg-gray-50 dark:bg-neutral-800/50" : "bg-white dark:bg-neutral-900") : isColHovered ? "bg-gray-50 dark:bg-neutral-800/50" : void 0,
1111
+ showDividers && "border-r border-gray-200 dark:border-neutral-700"
1112
+ ),
1113
+ children: col.label
1114
+ },
1115
+ col.key
1116
+ );
1117
+ }) }) }),
1118
+ /* @__PURE__ */ jsx("tbody", { className: "[&_tr:last-child]:border-0", children: data.map((row, rowIndex) => /* @__PURE__ */ jsx(
1119
+ "tr",
1120
+ {
1121
+ className: "border-b border-gray-200 transition-colors dark:border-neutral-700",
1122
+ children: visibleCols.map((col) => {
1123
+ const isRowHovered = (highlightMode === "row" || highlightMode === "cross") && rowIndex === hoveredRowIndex;
1124
+ const isColHovered = (highlightMode === "column" || highlightMode === "cross") && hoveredCol === col.key;
1125
+ const isHighlighted = isRowHovered || isColHovered;
1126
+ return /* @__PURE__ */ jsx(
1127
+ "td",
1128
+ {
1129
+ onMouseEnter: () => {
1130
+ if (highlightMode === "column" || highlightMode === "cross") setHoveredCol(col.key);
1131
+ if (highlightMode === "row" || highlightMode === "cross") setHoveredRowIndex(rowIndex);
1132
+ },
1133
+ className: cn(
1134
+ "p-4 align-middle transition-colors",
1135
+ col.sticky ? cn("sticky left-0 z-20", isHighlighted ? "bg-gray-50 dark:bg-neutral-800/50" : "bg-white dark:bg-neutral-900") : isHighlighted ? "bg-gray-50 dark:bg-neutral-800/50" : void 0,
1136
+ showDividers && "border-r border-gray-200 dark:border-neutral-700"
1137
+ ),
1138
+ children: col.cell(row)
1139
+ },
1140
+ col.key
1141
+ );
1142
+ })
1143
+ },
1144
+ finalGetRowId ? finalGetRowId(row) : rowIndex
1145
+ )) })
1146
+ ] });
1147
+ })() }) : children
1148
+ }
1149
+ )
1074
1150
  }
1075
- ) }) });
1151
+ ) });
1076
1152
  }
1077
1153
  );
1078
- Table.displayName = "Table";
1154
+ TableInner.displayName = "Table";
1155
+ var Table = TableInner;
1079
1156
  var TableHeader = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1080
1157
  "thead",
1081
1158
  {
@@ -1162,14 +1239,20 @@ var TableHead = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1162
1239
  }
1163
1240
  ));
1164
1241
  TableHead.displayName = "TableHead";
1165
- var TableCell = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1166
- "td",
1167
- {
1168
- ref,
1169
- className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className),
1170
- ...props
1171
- }
1172
- ));
1242
+ var TableCell = React9.forwardRef(
1243
+ ({ className, variant = "default", ...props }, ref) => /* @__PURE__ */ jsx(
1244
+ "td",
1245
+ {
1246
+ ref,
1247
+ className: cn(
1248
+ "align-middle [&:has([role=checkbox])]:pr-0",
1249
+ variant === "embed" ? "p-1.5" : "p-4",
1250
+ className
1251
+ ),
1252
+ ...props
1253
+ }
1254
+ )
1255
+ );
1173
1256
  TableCell.displayName = "TableCell";
1174
1257
  var TableCaption = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1175
1258
  "caption",
@@ -1238,6 +1321,108 @@ var useTableSelection = () => {
1238
1321
  }
1239
1322
  return context;
1240
1323
  };
1324
+ function getDefaultColumns(columns, isMobile) {
1325
+ return columns.filter((col) => {
1326
+ if (col.sticky) return true;
1327
+ if (isMobile) return col.mobileVisible === true;
1328
+ return col.defaultVisible !== false;
1329
+ }).map((col) => col.key);
1330
+ }
1331
+ function useColumnVisibility(columns, options = {}) {
1332
+ const { storageKey } = options;
1333
+ const [visibleColumns, setVisibleColumnsState] = useState(() => {
1334
+ if (storageKey && typeof window !== "undefined") {
1335
+ try {
1336
+ const saved = localStorage.getItem(storageKey);
1337
+ if (saved) {
1338
+ const parsed = JSON.parse(saved);
1339
+ const stickyKeys = columns.filter((c) => c.sticky).map((c) => c.key);
1340
+ return Array.from(/* @__PURE__ */ new Set([...stickyKeys, ...parsed]));
1341
+ }
1342
+ } catch {
1343
+ }
1344
+ }
1345
+ return getDefaultColumns(columns, false);
1346
+ });
1347
+ useEffect(() => {
1348
+ if (storageKey) {
1349
+ try {
1350
+ const saved = localStorage.getItem(storageKey);
1351
+ if (saved) return;
1352
+ } catch {
1353
+ }
1354
+ }
1355
+ const isMobile = window.innerWidth < 768;
1356
+ if (isMobile) {
1357
+ setVisibleColumnsState(getDefaultColumns(columns, true));
1358
+ }
1359
+ }, []);
1360
+ const setVisibleColumns = useCallback((cols) => {
1361
+ const stickyKeys = columns.filter((c) => c.sticky).map((c) => c.key);
1362
+ const merged = Array.from(/* @__PURE__ */ new Set([...stickyKeys, ...cols]));
1363
+ setVisibleColumnsState(merged);
1364
+ if (storageKey) {
1365
+ try {
1366
+ localStorage.setItem(storageKey, JSON.stringify(merged));
1367
+ } catch {
1368
+ }
1369
+ }
1370
+ }, [columns, storageKey]);
1371
+ return { visibleColumns, setVisibleColumns };
1372
+ }
1373
+ function ColumnPicker({
1374
+ columns,
1375
+ visibleColumns,
1376
+ onVisibleColumnsChange,
1377
+ triggerLabel = "Edit Fields"
1378
+ }) {
1379
+ const handleToggle = React9.useCallback((key, checked) => {
1380
+ if (checked) {
1381
+ if (!visibleColumns.includes(key)) {
1382
+ onVisibleColumnsChange([...visibleColumns, key]);
1383
+ }
1384
+ } else {
1385
+ onVisibleColumnsChange(visibleColumns.filter((k) => k !== key));
1386
+ }
1387
+ }, [visibleColumns, onVisibleColumnsChange]);
1388
+ return /* @__PURE__ */ jsxs(Popover, { children: [
1389
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", children: [
1390
+ /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-4 w-4", "aria-hidden": "true" }),
1391
+ triggerLabel
1392
+ ] }) }),
1393
+ /* @__PURE__ */ jsxs(PopoverContent, { align: "end", className: "w-56 p-2", children: [
1394
+ /* @__PURE__ */ jsx("p", { className: "px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide", children: "Columns" }),
1395
+ /* @__PURE__ */ jsx("div", { className: "space-y-1 mt-1", children: columns.map((col) => {
1396
+ const isSticky = !!col.sticky;
1397
+ const isChecked = isSticky || visibleColumns.includes(col.key);
1398
+ return /* @__PURE__ */ jsxs(
1399
+ "label",
1400
+ {
1401
+ className: cn(
1402
+ "flex items-center gap-2.5 rounded-hz-md px-2 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-neutral-800",
1403
+ isSticky && "opacity-50 cursor-not-allowed"
1404
+ ),
1405
+ children: [
1406
+ /* @__PURE__ */ jsx(
1407
+ Checkbox,
1408
+ {
1409
+ "aria-label": col.label,
1410
+ checked: isChecked,
1411
+ disabled: isSticky,
1412
+ onCheckedChange: (checked) => {
1413
+ if (!isSticky) handleToggle(col.key, !!checked);
1414
+ }
1415
+ }
1416
+ ),
1417
+ /* @__PURE__ */ jsx("span", { className: "text-gray-700 dark:text-gray-300", children: col.label })
1418
+ ]
1419
+ },
1420
+ col.key
1421
+ );
1422
+ }) })
1423
+ ] })
1424
+ ] });
1425
+ }
1241
1426
  var TabsContext = React9.createContext(null);
1242
1427
  var useTabsContext = () => {
1243
1428
  const context = React9.useContext(TabsContext);
@@ -1688,6 +1873,6 @@ var Switch = React9.forwardRef(({ className, size, label, labelPosition = "right
1688
1873
  });
1689
1874
  Switch.displayName = "Switch";
1690
1875
 
1691
- export { Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormLabel, FormMessage, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Skeleton, SkeletonAvatar, SkeletonBadge, SkeletonButton, SkeletonCard, SkeletonIcon, SkeletonInput, SkeletonSubtitle, SkeletonTableRow, SkeletonTableRows, SkeletonText, SkeletonTitle, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableRowCheckbox, TableSelectAll, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, buttonVariants, segmentedControlItemVariants, segmentedControlVariants, separatorVariants, switchLabelVariants, switchThumbVariants, switchTrackVariants, toggleGroupVariants, toggleItemVariants, useFormContext, useFormFieldContext, useTableSelection };
1692
- //# sourceMappingURL=chunk-E7Q6YGBZ.mjs.map
1693
- //# sourceMappingURL=chunk-E7Q6YGBZ.mjs.map
1876
+ export { Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColumnPicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormLabel, FormMessage, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Skeleton, SkeletonAvatar, SkeletonBadge, SkeletonButton, SkeletonCard, SkeletonIcon, SkeletonInput, SkeletonSubtitle, SkeletonTableRow, SkeletonTableRows, SkeletonText, SkeletonTitle, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableRowCheckbox, TableSelectAll, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, buttonVariants, segmentedControlItemVariants, segmentedControlVariants, separatorVariants, switchLabelVariants, switchThumbVariants, switchTrackVariants, toggleGroupVariants, toggleItemVariants, useColumnVisibility, useFormContext, useFormFieldContext, useTableSelection };
1877
+ //# sourceMappingURL=chunk-6YUIM6WB.mjs.map
1878
+ //# sourceMappingURL=chunk-6YUIM6WB.mjs.map