luxtable 0.3.3 → 0.3.5

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
@@ -1,7 +1,7 @@
1
1
  // src/components/lux-table/lux-table.tsx
2
2
  import * as React7 from "react";
3
3
  import {
4
- flexRender,
4
+ flexRender as flexRender2,
5
5
  getCoreRowModel,
6
6
  useReactTable,
7
7
  getPaginationRowModel,
@@ -840,15 +840,51 @@ function TableToolbar({
840
840
  );
841
841
  }
842
842
 
843
+ // src/components/lux-table/sortable-header.tsx
844
+ import { flexRender } from "@tanstack/react-table";
845
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
846
+ function SortableHeader({
847
+ header,
848
+ showSortIndex = false
849
+ }) {
850
+ const column = header.column;
851
+ const canSort = column.getCanSort();
852
+ const isSorted = column.getIsSorted();
853
+ const sortIndex = column.getSortIndex();
854
+ const headerContent = header.isPlaceholder ? null : flexRender(column.columnDef.header, header.getContext());
855
+ if (!canSort) {
856
+ return /* @__PURE__ */ jsx10(Fragment2, { children: headerContent });
857
+ }
858
+ return /* @__PURE__ */ jsxs6(
859
+ "button",
860
+ {
861
+ type: "button",
862
+ className: cn(
863
+ "flex items-center gap-1.5 w-full text-left font-medium group",
864
+ "hover:text-slate-900 dark:hover:text-slate-100",
865
+ "transition-colors duration-150",
866
+ "-ml-2 px-2 py-1 rounded-md",
867
+ "hover:bg-slate-100 dark:hover:bg-slate-800",
868
+ isSorted && "text-blue-600 dark:text-blue-400"
869
+ ),
870
+ onClick: header.column.getToggleSortingHandler(),
871
+ children: [
872
+ headerContent,
873
+ showSortIndex && isSorted && sortIndex > 0 && /* @__PURE__ */ jsx10("span", { className: "ml-0.5 text-[10px] font-bold text-blue-500 dark:text-blue-400 bg-blue-100 dark:bg-blue-900/50 rounded-full w-4 h-4 flex items-center justify-center", children: sortIndex + 1 })
874
+ ]
875
+ }
876
+ );
877
+ }
878
+
843
879
  // src/components/ui/checkbox.tsx
844
880
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
845
881
  import { CheckIcon } from "lucide-react";
846
- import { jsx as jsx10 } from "react/jsx-runtime";
882
+ import { jsx as jsx11 } from "react/jsx-runtime";
847
883
  function Checkbox({
848
884
  className,
849
885
  ...props
850
886
  }) {
851
- return /* @__PURE__ */ jsx10(
887
+ return /* @__PURE__ */ jsx11(
852
888
  CheckboxPrimitive.Root,
853
889
  {
854
890
  "data-slot": "checkbox",
@@ -857,12 +893,12 @@ function Checkbox({
857
893
  className
858
894
  ),
859
895
  ...props,
860
- children: /* @__PURE__ */ jsx10(
896
+ children: /* @__PURE__ */ jsx11(
861
897
  CheckboxPrimitive.Indicator,
862
898
  {
863
899
  "data-slot": "checkbox-indicator",
864
900
  className: "grid place-content-center text-current transition-none",
865
- children: /* @__PURE__ */ jsx10(CheckIcon, { className: "size-3.5" })
901
+ children: /* @__PURE__ */ jsx11(CheckIcon, { className: "size-3.5" })
866
902
  }
867
903
  )
868
904
  }
@@ -870,11 +906,11 @@ function Checkbox({
870
906
  }
871
907
 
872
908
  // src/components/lux-table/lux-table.tsx
873
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
909
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
874
910
  function createSelectionColumn() {
875
911
  return {
876
912
  id: "__selection__",
877
- header: ({ table }) => /* @__PURE__ */ jsx11(
913
+ header: ({ table }) => /* @__PURE__ */ jsx12(
878
914
  Checkbox,
879
915
  {
880
916
  checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
@@ -882,7 +918,7 @@ function createSelectionColumn() {
882
918
  "aria-label": "Select all rows"
883
919
  }
884
920
  ),
885
- cell: ({ row }) => /* @__PURE__ */ jsx11(
921
+ cell: ({ row }) => /* @__PURE__ */ jsx12(
886
922
  Checkbox,
887
923
  {
888
924
  checked: row.getIsSelected(),
@@ -938,9 +974,17 @@ function LuxTable({
938
974
  },
939
975
  [isControlledRowSelection, onRowSelectionChange, rowSelection]
940
976
  );
977
+ const enableSorting = options?.sorting !== false;
978
+ const enableMultiSort = options?.multiSort !== false;
941
979
  const table = useReactTable({
942
980
  data,
943
981
  columns: tableColumns,
982
+ enableSorting,
983
+ enableMultiSort,
984
+ // Shift+Click for multi-sort (default behavior)
985
+ isMultiSortEvent: (e) => e.shiftKey,
986
+ // Max columns for multi-sort (undefined = unlimited)
987
+ maxMultiSortColCount: options?.maxMultiSortColCount,
944
988
  state: {
945
989
  sorting,
946
990
  columnFilters,
@@ -987,8 +1031,8 @@ function LuxTable({
987
1031
  const showToolbar = options?.showToolbar ?? false;
988
1032
  const showGlobalSearch = options?.showGlobalSearch ?? true;
989
1033
  const showColumnVisibility = options?.showColumnVisibility ?? true;
990
- return /* @__PURE__ */ jsxs6("div", { className: cn("w-full space-y-4", className), children: [
991
- showToolbar && /* @__PURE__ */ jsx11(
1034
+ return /* @__PURE__ */ jsxs7("div", { className: cn("w-full space-y-4", className), children: [
1035
+ showToolbar && /* @__PURE__ */ jsx12(
992
1036
  TableToolbar,
993
1037
  {
994
1038
  table,
@@ -999,18 +1043,18 @@ function LuxTable({
999
1043
  showColumnVisibility
1000
1044
  }
1001
1045
  ),
1002
- enableRowSelection && Object.keys(rowSelection).length > 0 && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 px-4 py-2 text-sm bg-blue-50 dark:bg-blue-950/50 text-blue-700 dark:text-blue-300 rounded-lg border border-blue-200 dark:border-blue-800", children: [
1003
- /* @__PURE__ */ jsx11(CheckCircle2, { className: "w-4 h-4" }),
1004
- /* @__PURE__ */ jsxs6("span", { children: [
1005
- /* @__PURE__ */ jsx11("strong", { children: Object.keys(rowSelection).length }),
1046
+ enableRowSelection && Object.keys(rowSelection).length > 0 && /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 px-4 py-2 text-sm bg-blue-50 dark:bg-blue-950/50 text-blue-700 dark:text-blue-300 rounded-lg border border-blue-200 dark:border-blue-800", children: [
1047
+ /* @__PURE__ */ jsx12(CheckCircle2, { className: "w-4 h-4" }),
1048
+ /* @__PURE__ */ jsxs7("span", { children: [
1049
+ /* @__PURE__ */ jsx12("strong", { children: Object.keys(rowSelection).length }),
1006
1050
  " rows selected",
1007
- table.getFilteredRowModel().rows.length > 0 && /* @__PURE__ */ jsxs6("span", { className: "text-blue-500 dark:text-blue-400", children: [
1051
+ table.getFilteredRowModel().rows.length > 0 && /* @__PURE__ */ jsxs7("span", { className: "text-blue-500 dark:text-blue-400", children: [
1008
1052
  " / ",
1009
1053
  table.getFilteredRowModel().rows.length,
1010
1054
  " total"
1011
1055
  ] })
1012
1056
  ] }),
1013
- /* @__PURE__ */ jsx11(
1057
+ /* @__PURE__ */ jsx12(
1014
1058
  "button",
1015
1059
  {
1016
1060
  type: "button",
@@ -1020,28 +1064,34 @@ function LuxTable({
1020
1064
  }
1021
1065
  )
1022
1066
  ] }),
1023
- /* @__PURE__ */ jsx11("div", { className: "rounded-md border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 overflow-hidden", children: /* @__PURE__ */ jsxs6(Table, { children: [
1024
- /* @__PURE__ */ jsxs6(TableHeader, { children: [
1025
- table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx11(TableRow, { children: headerGroup.headers.map((header) => {
1067
+ /* @__PURE__ */ jsx12("div", { className: "rounded-md border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 overflow-hidden", children: /* @__PURE__ */ jsxs7(Table, { children: [
1068
+ /* @__PURE__ */ jsxs7(TableHeader, { children: [
1069
+ table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx12(TableRow, { children: headerGroup.headers.map((header) => {
1026
1070
  const isSelectionColumn = header.id === "__selection__";
1027
- return /* @__PURE__ */ jsx11(
1071
+ return /* @__PURE__ */ jsx12(
1028
1072
  TableHead,
1029
1073
  {
1030
1074
  style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
1031
- children: header.isPlaceholder ? null : flexRender(
1075
+ children: header.isPlaceholder ? null : isSelectionColumn ? flexRender2(
1032
1076
  header.column.columnDef.header,
1033
1077
  header.getContext()
1078
+ ) : /* @__PURE__ */ jsx12(
1079
+ SortableHeader,
1080
+ {
1081
+ header,
1082
+ showSortIndex: enableMultiSort && sorting.length > 1
1083
+ }
1034
1084
  )
1035
1085
  },
1036
1086
  header.id
1037
1087
  );
1038
1088
  }) }, headerGroup.id)),
1039
- filteringVisible && /* @__PURE__ */ jsx11(TableRow, { className: "bg-slate-50/50 dark:bg-slate-900/50", children: table.getHeaderGroups()[0]?.headers.map((header) => {
1089
+ filteringVisible && /* @__PURE__ */ jsx12(TableRow, { className: "bg-slate-50/50 dark:bg-slate-900/50", children: table.getHeaderGroups()[0]?.headers.map((header) => {
1040
1090
  const isSelectionColumn = header.id === "__selection__";
1041
- return /* @__PURE__ */ jsx11(TableHead, { className: "py-2", children: !isSelectionColumn && header.column.getCanFilter() ? /* @__PURE__ */ jsx11(ColumnFilter, { column: header.column }) : null }, `filter-${header.id}`);
1091
+ return /* @__PURE__ */ jsx12(TableHead, { className: "py-2", children: !isSelectionColumn && header.column.getCanFilter() ? /* @__PURE__ */ jsx12(ColumnFilter, { column: header.column }) : null }, `filter-${header.id}`);
1042
1092
  }) })
1043
1093
  ] }),
1044
- /* @__PURE__ */ jsx11(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx11(
1094
+ /* @__PURE__ */ jsx12(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx12(
1045
1095
  TableRow,
1046
1096
  {
1047
1097
  "data-state": row.getIsSelected() && "selected",
@@ -1058,21 +1108,21 @@ function LuxTable({
1058
1108
  } : void 0,
1059
1109
  children: row.getVisibleCells().map((cell) => {
1060
1110
  const isSelectionColumn = cell.column.id === "__selection__";
1061
- return /* @__PURE__ */ jsx11(
1111
+ return /* @__PURE__ */ jsx12(
1062
1112
  TableCell,
1063
1113
  {
1064
1114
  style: isSelectionColumn ? { width: 40, padding: "0 12px" } : void 0,
1065
1115
  onClick: isSelectionColumn ? (e) => e.stopPropagation() : void 0,
1066
- children: flexRender(cell.column.columnDef.cell, cell.getContext())
1116
+ children: flexRender2(cell.column.columnDef.cell, cell.getContext())
1067
1117
  },
1068
1118
  cell.id
1069
1119
  );
1070
1120
  })
1071
1121
  },
1072
1122
  row.id
1073
- )) : /* @__PURE__ */ jsx11(TableRow, { children: /* @__PURE__ */ jsx11(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
1123
+ )) : /* @__PURE__ */ jsx12(TableRow, { children: /* @__PURE__ */ jsx12(TableCell, { colSpan: visibleColumnCount, className: "h-24 text-center", children: "No results." }) }) })
1074
1124
  ] }) }),
1075
- options?.pagination && /* @__PURE__ */ jsx11(TablePagination, { table })
1125
+ options?.pagination && /* @__PURE__ */ jsx12(TablePagination, { table })
1076
1126
  ] });
1077
1127
  }
1078
1128
 
@@ -1080,67 +1130,81 @@ function LuxTable({
1080
1130
  import {
1081
1131
  ArrowDown,
1082
1132
  ArrowUp,
1083
- ChevronsUpDown as ChevronsUpDown2,
1133
+ ArrowUpDown,
1084
1134
  EyeOff as EyeOff2,
1085
1135
  MoreVertical,
1086
1136
  X
1087
1137
  } from "lucide-react";
1088
- import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
1138
+ import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
1089
1139
  function LuxDataTableColumnHeader({
1090
1140
  column,
1091
1141
  title,
1092
1142
  className
1093
1143
  }) {
1094
1144
  const isSorted = column.getIsSorted();
1095
- if (!column.getCanSort()) {
1096
- return /* @__PURE__ */ jsx12("div", { className: cn("flex items-center justify-between", className), children: /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: title }) });
1145
+ const canSort = column.getCanSort();
1146
+ const SortIndicator = () => {
1147
+ if (isSorted === "desc") {
1148
+ return /* @__PURE__ */ jsx13(ArrowDown, { className: "h-4 w-4 text-blue-600 dark:text-blue-400" });
1149
+ }
1150
+ if (isSorted === "asc") {
1151
+ return /* @__PURE__ */ jsx13(ArrowUp, { className: "h-4 w-4 text-blue-600 dark:text-blue-400" });
1152
+ }
1153
+ if (canSort) {
1154
+ return /* @__PURE__ */ jsx13(ArrowUpDown, { className: "h-4 w-4 text-slate-400 dark:text-slate-500" });
1155
+ }
1156
+ return null;
1157
+ };
1158
+ if (!canSort) {
1159
+ return /* @__PURE__ */ jsx13("span", { className: cn("text-sm font-medium", className), children: title });
1097
1160
  }
1098
- return /* @__PURE__ */ jsxs7("div", { className: cn("flex items-center justify-between gap-1", className), children: [
1099
- /* @__PURE__ */ jsxs7(
1100
- Button,
1101
- {
1102
- variant: "ghost",
1103
- size: "sm",
1104
- className: "-ml-3 h-8 hover:bg-accent",
1105
- onClick: () => column.toggleSorting(isSorted === "asc"),
1106
- children: [
1107
- /* @__PURE__ */ jsx12("span", { children: title }),
1108
- isSorted === "desc" ? /* @__PURE__ */ jsx12(ArrowDown, { className: "ml-1.5 h-4 w-4 text-primary" }) : isSorted === "asc" ? /* @__PURE__ */ jsx12(ArrowUp, { className: "ml-1.5 h-4 w-4 text-primary" }) : /* @__PURE__ */ jsx12(ChevronsUpDown2, { className: "ml-1.5 h-4 w-4 text-muted-foreground/50" })
1109
- ]
1110
- }
1111
- ),
1112
- /* @__PURE__ */ jsxs7(DropdownMenu, { children: [
1113
- /* @__PURE__ */ jsx12(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs7(
1161
+ return /* @__PURE__ */ jsxs8("div", { className: cn("flex items-center gap-2", className), children: [
1162
+ /* @__PURE__ */ jsx13(SortIndicator, {}),
1163
+ /* @__PURE__ */ jsx13("span", { className: "text-sm font-medium", children: title }),
1164
+ /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
1165
+ /* @__PURE__ */ jsx13(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(
1114
1166
  Button,
1115
1167
  {
1116
1168
  variant: "ghost",
1117
1169
  size: "icon",
1118
- className: "h-6 w-6 opacity-0 group-hover:opacity-100 hover:opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
1170
+ className: "h-6 w-6 ml-auto opacity-0 group-hover:opacity-100 hover:opacity-100 focus:opacity-100 data-[state=open]:opacity-100 transition-opacity",
1119
1171
  children: [
1120
- /* @__PURE__ */ jsx12(MoreVertical, { className: "h-3.5 w-3.5" }),
1121
- /* @__PURE__ */ jsx12("span", { className: "sr-only", children: "Column actions" })
1172
+ /* @__PURE__ */ jsx13(MoreVertical, { className: "h-3.5 w-3.5" }),
1173
+ /* @__PURE__ */ jsx13("span", { className: "sr-only", children: "Column actions" })
1122
1174
  ]
1123
1175
  }
1124
1176
  ) }),
1125
- /* @__PURE__ */ jsxs7(DropdownMenuContent, { align: "end", children: [
1126
- /* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.toggleSorting(false), children: [
1127
- /* @__PURE__ */ jsx12(ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1177
+ /* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", children: [
1178
+ /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1179
+ e.stopPropagation();
1180
+ column.toggleSorting(false);
1181
+ }, children: [
1182
+ /* @__PURE__ */ jsx13(ArrowUp, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1128
1183
  "Sort Ascending"
1129
1184
  ] }),
1130
- /* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.toggleSorting(true), children: [
1131
- /* @__PURE__ */ jsx12(ArrowDown, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1185
+ /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1186
+ e.stopPropagation();
1187
+ column.toggleSorting(true);
1188
+ }, children: [
1189
+ /* @__PURE__ */ jsx13(ArrowDown, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1132
1190
  "Sort Descending"
1133
1191
  ] }),
1134
- isSorted && /* @__PURE__ */ jsxs7(Fragment2, { children: [
1135
- /* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
1136
- /* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.clearSorting(), children: [
1137
- /* @__PURE__ */ jsx12(X, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1192
+ isSorted && /* @__PURE__ */ jsxs8(Fragment3, { children: [
1193
+ /* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
1194
+ /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1195
+ e.stopPropagation();
1196
+ column.clearSorting();
1197
+ }, children: [
1198
+ /* @__PURE__ */ jsx13(X, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1138
1199
  "Clear sorting"
1139
1200
  ] })
1140
1201
  ] }),
1141
- /* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
1142
- /* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => column.toggleVisibility(false), children: [
1143
- /* @__PURE__ */ jsx12(EyeOff2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1202
+ /* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
1203
+ /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: (e) => {
1204
+ e.stopPropagation();
1205
+ column.toggleVisibility(false);
1206
+ }, children: [
1207
+ /* @__PURE__ */ jsx13(EyeOff2, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground/70" }),
1144
1208
  "Hide column"
1145
1209
  ] })
1146
1210
  ] })
@@ -1149,7 +1213,7 @@ function LuxDataTableColumnHeader({
1149
1213
  }
1150
1214
 
1151
1215
  // src/components/cell-renderers/status-cell.tsx
1152
- import { jsx as jsx13 } from "react/jsx-runtime";
1216
+ import { jsx as jsx14 } from "react/jsx-runtime";
1153
1217
  var defaultStatusColors = {
1154
1218
  Active: {
1155
1219
  bg: "bg-green-100",
@@ -1186,14 +1250,14 @@ function StatusCell({ value, colors, className }) {
1186
1250
  const mergedColors = { ...defaultStatusColors, ...colors };
1187
1251
  const colorConfig = mergedColors[value];
1188
1252
  if (!colorConfig) {
1189
- return /* @__PURE__ */ jsx13("span", { className: `px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300 ${className || ""}`, children: value });
1253
+ return /* @__PURE__ */ jsx14("span", { className: `px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300 ${className || ""}`, children: value });
1190
1254
  }
1191
1255
  const { bg, text, darkBg, darkText } = colorConfig;
1192
- return /* @__PURE__ */ jsx13("span", { className: `px-2 py-1 rounded-full text-xs font-medium ${bg} ${text} ${darkBg || ""} ${darkText || ""} ${className || ""}`, children: value });
1256
+ return /* @__PURE__ */ jsx14("span", { className: `px-2 py-1 rounded-full text-xs font-medium ${bg} ${text} ${darkBg || ""} ${darkText || ""} ${className || ""}`, children: value });
1193
1257
  }
1194
1258
 
1195
1259
  // src/components/cell-renderers/progress-cell.tsx
1196
- import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1260
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1197
1261
  function ProgressCell({
1198
1262
  value,
1199
1263
  barColor = "bg-blue-600",
@@ -1202,15 +1266,15 @@ function ProgressCell({
1202
1266
  className
1203
1267
  }) {
1204
1268
  const clampedValue = Math.min(100, Math.max(0, value));
1205
- return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
1206
- /* @__PURE__ */ jsx14("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ jsx14(
1269
+ return /* @__PURE__ */ jsxs9("div", { className: `flex items-center gap-2 ${className || ""}`, children: [
1270
+ /* @__PURE__ */ jsx15("div", { className: `w-full rounded-full h-2.5 ${bgColor}`, children: /* @__PURE__ */ jsx15(
1207
1271
  "div",
1208
1272
  {
1209
1273
  className: `${barColor} h-2.5 rounded-full transition-all`,
1210
1274
  style: { width: `${clampedValue}%` }
1211
1275
  }
1212
1276
  ) }),
1213
- showLabel && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-gray-500 dark:text-gray-400 w-8", children: [
1277
+ showLabel && /* @__PURE__ */ jsxs9("span", { className: "text-xs text-gray-500 dark:text-gray-400 w-8", children: [
1214
1278
  value,
1215
1279
  "%"
1216
1280
  ] })
@@ -1218,7 +1282,7 @@ function ProgressCell({
1218
1282
  }
1219
1283
 
1220
1284
  // src/components/cell-renderers/boolean-cell.tsx
1221
- import { jsx as jsx15 } from "react/jsx-runtime";
1285
+ import { jsx as jsx16 } from "react/jsx-runtime";
1222
1286
  function BooleanCell({
1223
1287
  value,
1224
1288
  trueLabel = "Yes",
@@ -1226,15 +1290,15 @@ function BooleanCell({
1226
1290
  trueColor = "text-green-600 dark:text-green-400",
1227
1291
  falseColor = "text-red-600 dark:text-red-400"
1228
1292
  }) {
1229
- return /* @__PURE__ */ jsx15("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
1293
+ return /* @__PURE__ */ jsx16("span", { className: `font-medium ${value ? trueColor : falseColor}`, children: value ? trueLabel : falseLabel });
1230
1294
  }
1231
1295
 
1232
1296
  // src/components/cell-renderers/date-cell.tsx
1233
- import { jsx as jsx16 } from "react/jsx-runtime";
1297
+ import { jsx as jsx17 } from "react/jsx-runtime";
1234
1298
  function DateCell({ value, format = "short", locale = "en-US" }) {
1235
1299
  const date = typeof value === "string" ? new Date(value) : value;
1236
1300
  if (isNaN(date.getTime())) {
1237
- return /* @__PURE__ */ jsx16("span", { className: "text-gray-400", children: "-" });
1301
+ return /* @__PURE__ */ jsx17("span", { className: "text-gray-400", children: "-" });
1238
1302
  }
1239
1303
  let formatted;
1240
1304
  switch (format) {
@@ -1258,23 +1322,23 @@ function DateCell({ value, format = "short", locale = "en-US" }) {
1258
1322
  default:
1259
1323
  formatted = date.toLocaleDateString(locale);
1260
1324
  }
1261
- return /* @__PURE__ */ jsx16("span", { children: formatted });
1325
+ return /* @__PURE__ */ jsx17("span", { children: formatted });
1262
1326
  }
1263
1327
 
1264
1328
  // src/components/cell-renderers/currency-cell.tsx
1265
- import { jsx as jsx17 } from "react/jsx-runtime";
1329
+ import { jsx as jsx18 } from "react/jsx-runtime";
1266
1330
  function CurrencyCell({ value, currency = "TRY", locale = "tr-TR" }) {
1267
1331
  const formatted = new Intl.NumberFormat(locale, {
1268
1332
  style: "currency",
1269
1333
  currency
1270
1334
  }).format(value);
1271
- return /* @__PURE__ */ jsx17("span", { className: "font-medium", children: formatted });
1335
+ return /* @__PURE__ */ jsx18("span", { className: "font-medium", children: formatted });
1272
1336
  }
1273
1337
 
1274
1338
  // src/components/cell-renderers/copyable-cell.tsx
1275
1339
  import * as React8 from "react";
1276
1340
  import { Copy, Check as Check3 } from "lucide-react";
1277
- import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
1341
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
1278
1342
  function CopyableCell({
1279
1343
  value,
1280
1344
  feedbackDuration = 2e3,
@@ -1299,7 +1363,7 @@ function CopyableCell({
1299
1363
  console.error("Copy error:", err);
1300
1364
  }
1301
1365
  };
1302
- return /* @__PURE__ */ jsxs9(
1366
+ return /* @__PURE__ */ jsxs10(
1303
1367
  "button",
1304
1368
  {
1305
1369
  type: "button",
@@ -1318,8 +1382,8 @@ function CopyableCell({
1318
1382
  ${className || ""}
1319
1383
  `,
1320
1384
  children: [
1321
- /* @__PURE__ */ jsx18("span", { className: "select-none", children: value }),
1322
- /* @__PURE__ */ jsx18(
1385
+ /* @__PURE__ */ jsx19("span", { className: "select-none", children: value }),
1386
+ /* @__PURE__ */ jsx19(
1323
1387
  "span",
1324
1388
  {
1325
1389
  className: `
@@ -1327,7 +1391,7 @@ function CopyableCell({
1327
1391
  transition-all duration-200
1328
1392
  ${alwaysShowIcon || isHovered || copied ? "opacity-100" : "opacity-0"}
1329
1393
  `,
1330
- children: copied ? /* @__PURE__ */ jsx18(Check3, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx18(Copy, { className: "h-3.5 w-3.5 text-slate-400 dark:text-slate-500 group-hover:text-slate-600 dark:group-hover:text-slate-300" })
1394
+ children: copied ? /* @__PURE__ */ jsx19(Check3, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }) : /* @__PURE__ */ jsx19(Copy, { className: "h-3.5 w-3.5 text-slate-400 dark:text-slate-500 group-hover:text-slate-600 dark:group-hover:text-slate-300" })
1331
1395
  }
1332
1396
  )
1333
1397
  ]
@@ -1335,18 +1399,18 @@ function CopyableCell({
1335
1399
  );
1336
1400
  }
1337
1401
  function createCopyableCell(value, options) {
1338
- return /* @__PURE__ */ jsx18(CopyableCell, { value, ...options });
1402
+ return /* @__PURE__ */ jsx19(CopyableCell, { value, ...options });
1339
1403
  }
1340
1404
 
1341
1405
  // src/components/ui/label.tsx
1342
1406
  import * as React9 from "react";
1343
1407
  import * as LabelPrimitive from "@radix-ui/react-label";
1344
1408
  import { cva as cva2 } from "class-variance-authority";
1345
- import { jsx as jsx19 } from "react/jsx-runtime";
1409
+ import { jsx as jsx20 } from "react/jsx-runtime";
1346
1410
  var labelVariants = cva2(
1347
1411
  "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
1348
1412
  );
1349
- var Label3 = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
1413
+ var Label3 = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
1350
1414
  LabelPrimitive.Root,
1351
1415
  {
1352
1416
  ref,
@@ -1359,11 +1423,11 @@ Label3.displayName = LabelPrimitive.Root.displayName;
1359
1423
  // src/components/ui/popover.tsx
1360
1424
  import * as React10 from "react";
1361
1425
  import * as PopoverPrimitive from "@radix-ui/react-popover";
1362
- import { jsx as jsx20 } from "react/jsx-runtime";
1426
+ import { jsx as jsx21 } from "react/jsx-runtime";
1363
1427
  var Popover = PopoverPrimitive.Root;
1364
1428
  var PopoverTrigger = PopoverPrimitive.Trigger;
1365
1429
  var PopoverAnchor = PopoverPrimitive.Anchor;
1366
- var PopoverContent = React10.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx20(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx20(
1430
+ var PopoverContent = React10.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx21(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx21(
1367
1431
  PopoverPrimitive.Content,
1368
1432
  {
1369
1433
  ref,
@@ -1381,9 +1445,9 @@ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
1381
1445
  // src/components/ui/separator.tsx
1382
1446
  import * as React11 from "react";
1383
1447
  import * as SeparatorPrimitive from "@radix-ui/react-separator";
1384
- import { jsx as jsx21 } from "react/jsx-runtime";
1448
+ import { jsx as jsx22 } from "react/jsx-runtime";
1385
1449
  var Separator3 = React11.forwardRef(
1386
- ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx21(
1450
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx22(
1387
1451
  SeparatorPrimitive.Root,
1388
1452
  {
1389
1453
  ref,
@@ -1402,7 +1466,7 @@ Separator3.displayName = SeparatorPrimitive.Root.displayName;
1402
1466
 
1403
1467
  // src/lib/column-helper.tsx
1404
1468
  import { createColumnHelper as tanstackCreateColumnHelper } from "@tanstack/react-table";
1405
- import { jsx as jsx22 } from "react/jsx-runtime";
1469
+ import { jsx as jsx23 } from "react/jsx-runtime";
1406
1470
  var toTitleCase = (str) => {
1407
1471
  return str.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
1408
1472
  };
@@ -1421,7 +1485,7 @@ function createColumnHelper() {
1421
1485
  // Pass meta information (filterVariant etc.)
1422
1486
  meta: column?.meta,
1423
1487
  // Use LuxDataTableColumnHeader if header is string or undefined
1424
- header: typeof headerContent === "function" ? headerContent : ({ column: colParam }) => /* @__PURE__ */ jsx22(
1488
+ header: typeof headerContent === "function" ? headerContent : ({ column: colParam }) => /* @__PURE__ */ jsx23(
1425
1489
  LuxDataTableColumnHeader,
1426
1490
  {
1427
1491
  column: colParam,
@@ -1465,7 +1529,7 @@ function createColumnHelper() {
1465
1529
  auto: (columns) => {
1466
1530
  return columns.map((col) => {
1467
1531
  return helper.accessor(col.accessor, {
1468
- header: ({ column }) => /* @__PURE__ */ jsx22(LuxDataTableColumnHeader, { column, title: col.header }),
1532
+ header: ({ column }) => /* @__PURE__ */ jsx23(LuxDataTableColumnHeader, { column, title: col.header }),
1469
1533
  cell: col.cell || ((info) => {
1470
1534
  const value = info.getValue();
1471
1535
  if (value === null || value === void 0) return "-";
@@ -1491,7 +1555,7 @@ function createColumnsFromData(data, options) {
1491
1555
  const headerText = options?.headers?.[key] || toTitleCase(key);
1492
1556
  const cellRenderer = options?.cells?.[key];
1493
1557
  return helper.accessor(key, {
1494
- header: ({ column }) => /* @__PURE__ */ jsx22(LuxDataTableColumnHeader, { column, title: headerText }),
1558
+ header: ({ column }) => /* @__PURE__ */ jsx23(LuxDataTableColumnHeader, { column, title: headerText }),
1495
1559
  cell: cellRenderer || ((info) => {
1496
1560
  const value = info.getValue();
1497
1561
  if (value === null || value === void 0) return "-";
@@ -1503,7 +1567,7 @@ function createColumnsFromData(data, options) {
1503
1567
 
1504
1568
  // src/index.ts
1505
1569
  import {
1506
- flexRender as flexRender2,
1570
+ flexRender as flexRender3,
1507
1571
  getCoreRowModel as getCoreRowModel2,
1508
1572
  getPaginationRowModel as getPaginationRowModel2,
1509
1573
  getSortedRowModel as getSortedRowModel2,
@@ -1570,7 +1634,7 @@ export {
1570
1634
  createColumnsFromData,
1571
1635
  createCopyableCell,
1572
1636
  defaultStatusColors,
1573
- flexRender2 as flexRender,
1637
+ flexRender3 as flexRender,
1574
1638
  getCoreRowModel2 as getCoreRowModel,
1575
1639
  getFilteredRowModel2 as getFilteredRowModel,
1576
1640
  getPaginationRowModel2 as getPaginationRowModel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luxtable",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "private": false,
5
5
  "description": "Enterprise-Grade Data Management. Minimalist Aesthetics.",
6
6
  "keywords": [
@@ -18,7 +18,7 @@
18
18
  "license": "MIT",
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "https://github.com/luxtable/luxtable.git"
21
+ "url": "https://github.com/Huseyin-altun/luxtable.git"
22
22
  },
23
23
  "main": "./dist/index.js",
24
24
  "module": "./dist/index.mjs",
@@ -35,6 +35,7 @@
35
35
  "dist",
36
36
  "registry",
37
37
  "README.md",
38
+ "USAGE.md",
38
39
  "EXAMPLE.md"
39
40
  ],
40
41
  "publishConfig": {
@@ -13,6 +13,7 @@
13
13
  "table",
14
14
  "data-display"
15
15
  ],
16
+ "docs": "# LuxTable Cell Renderers\n\nPre-built cell renderers for common data types.\n\n## Available Renderers\n\n### StatusCell\nDisplays status badges with customizable colors.\n\n```tsx\nimport { StatusCell } from 'luxtable';\n\n<StatusCell \n value=\"active\" \n colorMap={{\n 'active': '#10b981',\n 'inactive': '#ef4444',\n 'pending': '#f59e0b'\n }}\n labelMap={{\n 'active': 'Active',\n 'inactive': 'Inactive',\n 'pending': 'Pending'\n }}\n/>\n```\n\n### ProgressCell\nDisplays progress bars with percentage.\n\n```tsx\nimport { ProgressCell } from 'luxtable';\n\n<ProgressCell value={75} showLabel={true} />\n```\n\n### DateCell\nFormats date values with locale support.\n\n```tsx\nimport { DateCell } from 'luxtable';\n\n<DateCell value=\"2024-01-15\" format=\"long\" locale=\"en-US\" />\n```\n\n### CopyableCell\nText with copy-to-clipboard functionality.\n\n```tsx\nimport { CopyableCell } from 'luxtable';\n\n<CopyableCell value=\"TASK-001\" />\n```\n\n### CurrencyCell\nFormats currency values.\n\n```tsx\nimport { CurrencyCell } from 'luxtable';\n\n<CurrencyCell value={1234.56} currency=\"USD\" locale=\"en-US\" />\n```\n\n### BooleanCell\nDisplays boolean values as icons or text.\n\n```tsx\nimport { BooleanCell } from 'luxtable';\n\n<BooleanCell value={true} />\n```\n",
16
17
  "files": [
17
18
  {
18
19
  "path": "components/cell-renderers/status-cell.tsx",
@@ -15,6 +15,7 @@
15
15
  "table",
16
16
  "utility"
17
17
  ],
18
+ "docs": "# LuxTable Column Helper\n\nType-safe column definition helper for TanStack Table.\n\n## Usage\n\n```tsx\nimport { createColumnHelper } from 'luxtable';\n\ninterface User {\n id: number;\n name: string;\n email: string;\n role: string;\n}\n\nconst columnHelper = createColumnHelper<User>();\n\nconst columns = [\n // Accessor column - display data from a field\n columnHelper.accessor('name', {\n header: 'Name',\n cell: (info) => info.getValue(),\n }),\n\n // Accessor with custom cell renderer\n columnHelper.accessor('email', {\n header: 'Email',\n cell: (info) => <a href={`mailto:${info.getValue()}`}>{info.getValue()}</a>,\n }),\n\n // Display column - for custom content like actions\n columnHelper.display({\n id: 'actions',\n header: 'Actions',\n cell: ({ row }) => (\n <div className=\"flex gap-2\">\n <button onClick={() => handleEdit(row.original)}>Edit</button>\n <button onClick={() => handleDelete(row.original.id)}>Delete</button>\n </div>\n ),\n }),\n];\n```\n\n## Column Options\n\n- `header` - Column header text or render function\n- `cell` - Cell render function\n- `size` - Column width in pixels\n- `enableSorting` - Enable/disable sorting (default: true)\n- `enableHiding` - Enable/disable column hiding (default: true)\n- `meta` - Custom metadata (e.g., filterVariant: 'select')\n",
18
19
  "files": [
19
20
  {
20
21
  "path": "lib/column-helper.tsx",
@@ -22,7 +22,7 @@
22
22
  "table",
23
23
  "data-display"
24
24
  ],
25
- "docs": "Visit https://luxtable.dev/docs for full documentation and examples.",
25
+ "docs": "# LuxTable - Enterprise Data Table\n\n## Installation\n\n```bash\nnpm install luxtable\n# or\npnpm add luxtable\n```\n\n## Quick Start (Vite + React + TypeScript)\n\n### 1. Configure TailwindCSS\n\nAdd to your `tailwind.config.js`:\n```js\ncontent: [\n \"./node_modules/luxtable/**/*.{js,ts,jsx,tsx}\",\n]\n```\n\n### 2. Add CSS Variables\n\nAdd to your `index.css`:\n```css\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n:root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n --border: 214.3 31.8% 91.4%;\n --radius: 0.5rem;\n}\n```\n\n### 3. Basic Usage\n\n```tsx\nimport { LuxTable, createColumnHelper } from 'luxtable';\n\ninterface User {\n id: number;\n name: string;\n email: string;\n status: 'Active' | 'Inactive';\n}\n\nconst data: User[] = [\n { id: 1, name: 'John Doe', email: 'john@example.com', status: 'Active' },\n { id: 2, name: 'Jane Smith', email: 'jane@example.com', status: 'Inactive' },\n];\n\nconst columnHelper = createColumnHelper<User>();\n\nconst columns = [\n columnHelper.accessor('name', { header: 'Name' }),\n columnHelper.accessor('email', { header: 'Email' }),\n columnHelper.accessor('status', { header: 'Status' }),\n];\n\nfunction App() {\n return (\n <LuxTable\n data={data}\n columns={columns}\n options={{\n pagination: true,\n sorting: true,\n filtering: true,\n showToolbar: true,\n selection: 'multiple',\n }}\n />\n );\n}\n```\n\n## Features\n\n- ✅ Sorting (single & multi-column)\n- ✅ Pagination with page size options\n- ✅ Column filtering (text & select)\n- ✅ Global search\n- ✅ Row selection (single & multiple)\n- ✅ Column visibility toggle\n- ✅ Dark mode support\n- ✅ TypeScript support\n- ✅ TanStack Table v8\n\n## Cell Renderers\n\n```tsx\nimport { StatusCell, DateCell, ProgressCell, CopyableCell } from 'luxtable';\n\n// Use in column definitions\ncolumnHelper.accessor('status', {\n header: 'Status',\n cell: (info) => <StatusCell value={info.getValue()} />\n});\n```\n\n## Links\n\n- Documentation: https://luxtable.dev/docs\n- GitHub: https://github.com/luxtable/luxtable\n- npm: https://www.npmjs.com/package/luxtable\n",
26
26
  "files": [
27
27
  {
28
28
  "path": "components/lux-table/lux-table.tsx",