react-auto-smart-table 1.0.2 → 1.0.4

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
@@ -490,7 +490,7 @@ var generateInsights = (dataset, schema) => {
490
490
  };
491
491
 
492
492
  // src/components/SmartTable.tsx
493
- import React3, { useMemo as useMemo5 } from "react";
493
+ import React3, { useMemo as useMemo6 } from "react";
494
494
 
495
495
  // src/components/TableHeader.tsx
496
496
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -531,7 +531,7 @@ var TableHeader = ({
531
531
  };
532
532
 
533
533
  // src/components/TableBody.tsx
534
- import React, { useRef } from "react";
534
+ import { useMemo as useMemo4, useCallback } from "react";
535
535
 
536
536
  // src/renderers/numberRenderer.tsx
537
537
  import { jsx as jsx2 } from "react/jsx-runtime";
@@ -665,7 +665,7 @@ var DefaultRenderer = ({ value }) => {
665
665
  // src/plugins/currencyPlugin.tsx
666
666
  import { jsx as jsx10 } from "react/jsx-runtime";
667
667
  var currencyPlugin = {
668
- detect: (columnKey, sample) => {
668
+ detect: (columnKey, _sample) => {
669
669
  const lowerKey = columnKey.toLowerCase();
670
670
  if (lowerKey.includes("amount") || lowerKey.includes("price") || lowerKey.includes("revenue")) {
671
671
  return "currency";
@@ -689,7 +689,7 @@ var currencyPlugin = {
689
689
  // src/plugins/percentagePlugin.tsx
690
690
  import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
691
691
  var percentagePlugin = {
692
- detect: (columnKey, sample) => {
692
+ detect: (columnKey, _sample) => {
693
693
  const lowerKey = columnKey.toLowerCase();
694
694
  if (lowerKey.includes("percent") || lowerKey.includes("rate")) {
695
695
  return "percentage";
@@ -759,76 +759,94 @@ var getCellRenderer = (type, registry) => {
759
759
  };
760
760
 
761
761
  // src/components/TableBody.tsx
762
- import { useVirtual } from "react-virtual";
762
+ import { useVirtualizer } from "@tanstack/react-virtual";
763
763
  import { jsx as jsx12 } from "react/jsx-runtime";
764
- var TableBody = ({ data, schema, registry }) => {
765
- const columns = Object.keys(schema);
766
- const parentRef = useRef(null);
767
- const rowVirtualizer = useVirtual({
768
- size: data.length,
769
- parentRef,
770
- estimateSize: React.useCallback(() => 45, []),
771
- overscan: 5
772
- });
764
+ var TableRow = ({ row, index, columns, schema, registry, style }) => {
765
+ return /* @__PURE__ */ jsx12("tr", { className: "rst-row", style, children: columns.map((colKey) => {
766
+ const colInfo = schema[colKey];
767
+ const Renderer = getCellRenderer(colInfo.type, registry);
768
+ const widthClass = getColumnWidthClass(colKey, colInfo.type);
769
+ const val = row[colKey];
770
+ return /* @__PURE__ */ jsx12(
771
+ "td",
772
+ {
773
+ className: `rst-td rst-td-col-${colKey} rst-td-type-${colInfo.type} ${widthClass}`,
774
+ children: colInfo.type === "boolean" ? /* @__PURE__ */ jsx12(
775
+ "span",
776
+ {
777
+ className: `rst-badge ${val ? "rst-badge-yes" : "rst-badge-no"}`,
778
+ children: val ? "Yes" : "No"
779
+ }
780
+ ) : /* @__PURE__ */ jsx12(Renderer, { value: val })
781
+ },
782
+ colKey
783
+ );
784
+ }) });
785
+ };
786
+ var TableBody = ({
787
+ data,
788
+ schema,
789
+ registry,
790
+ scrollRef
791
+ }) => {
792
+ const columns = useMemo4(() => Object.keys(schema), [schema]);
773
793
  const isVirtualized = data.length > 20;
774
- if (!isVirtualized) {
775
- return /* @__PURE__ */ jsx12("tbody", { className: "rst-body", children: data.map((row, index) => /* @__PURE__ */ jsx12("tr", { className: "rst-row", children: columns.map((colKey) => {
776
- const colInfo = schema[colKey];
777
- const Renderer = getCellRenderer(colInfo.type, registry);
778
- const widthClass = getColumnWidthClass(colKey, colInfo.type);
779
- const val = row[colKey];
780
- return /* @__PURE__ */ jsx12(
781
- "td",
782
- {
783
- className: `rst-td rst-td-col-${colKey} rst-td-type-${colInfo.type} ${widthClass}`,
784
- children: colInfo.type === "boolean" ? /* @__PURE__ */ jsx12("span", { className: `rst-badge ${val ? "rst-badge-yes" : "rst-badge-no"}`, children: val ? "Yes" : "No" }) : /* @__PURE__ */ jsx12(Renderer, { value: val })
785
- },
786
- colKey
787
- );
788
- }) }, index)) });
794
+ const rowVirtualizer = useVirtualizer({
795
+ count: data.length,
796
+ getScrollElement: () => scrollRef?.current || null,
797
+ estimateSize: useCallback(() => 45, []),
798
+ overscan: 5,
799
+ enabled: isVirtualized,
800
+ // Provide an initialRect to ensure virtualization works in JSDOM
801
+ // and during the very first render before ResizeObserver kicks in.
802
+ initialRect: { width: 0, height: 600 }
803
+ });
804
+ if (!isVirtualized || !scrollRef) {
805
+ return /* @__PURE__ */ jsx12("tbody", { className: "rst-body", children: data.map((row, index) => /* @__PURE__ */ jsx12(
806
+ TableRow,
807
+ {
808
+ row,
809
+ index,
810
+ columns,
811
+ schema,
812
+ registry
813
+ },
814
+ index
815
+ )) });
789
816
  }
817
+ const virtualRows = rowVirtualizer.getVirtualItems();
818
+ const totalSize = rowVirtualizer.getTotalSize();
790
819
  return /* @__PURE__ */ jsx12(
791
820
  "tbody",
792
821
  {
793
- className: "rst-body",
794
- ref: parentRef,
822
+ className: "rst-body rst-body-virtualized",
795
823
  style: {
796
- height: `${rowVirtualizer.totalSize}px`,
824
+ height: `${totalSize}px`,
797
825
  width: "100%",
798
826
  position: "relative"
799
827
  },
800
- children: rowVirtualizer.virtualItems.map((virtualRow) => {
801
- const row = data[virtualRow.index];
802
- return /* @__PURE__ */ jsx12(
803
- "tr",
804
- {
805
- className: "rst-row",
806
- style: {
807
- position: "absolute",
808
- top: 0,
809
- left: 0,
810
- width: "100%",
811
- height: `${virtualRow.size}px`,
812
- transform: `translateY(${virtualRow.start}px)`
813
- },
814
- children: columns.map((colKey) => {
815
- const val = row[colKey];
816
- const colInfo = schema[colKey];
817
- const Renderer = getCellRenderer(colInfo.type, registry);
818
- const widthClass = getColumnWidthClass(colKey, colInfo.type);
819
- return /* @__PURE__ */ jsx12(
820
- "td",
821
- {
822
- className: `rst-td rst-td-col-${colKey} rst-td-type-${colInfo.type} ${widthClass}`,
823
- children: colInfo.type === "boolean" ? /* @__PURE__ */ jsx12("span", { className: `rst-badge ${val ? "rst-badge-yes" : "rst-badge-no"}`, children: val ? "Yes" : "No" }) : /* @__PURE__ */ jsx12(Renderer, { value: val })
824
- },
825
- colKey
826
- );
827
- })
828
- },
829
- virtualRow.index
830
- );
831
- })
828
+ children: virtualRows.length > 0 ? virtualRows.map((virtualRow) => /* @__PURE__ */ jsx12(
829
+ TableRow,
830
+ {
831
+ row: data[virtualRow.index],
832
+ index: virtualRow.index,
833
+ columns,
834
+ schema,
835
+ registry,
836
+ style: {
837
+ position: "absolute",
838
+ top: 0,
839
+ left: 0,
840
+ width: "100%",
841
+ height: `${virtualRow.size}px`,
842
+ transform: `translateY(${virtualRow.start}px)`
843
+ }
844
+ },
845
+ virtualRow.key
846
+ )) : (
847
+ // Fallback for edge cases where virtualizer might be settling
848
+ /* @__PURE__ */ jsx12("tr", { style: { height: `${totalSize}px` }, children: /* @__PURE__ */ jsx12("td", { colSpan: columns.length }) })
849
+ )
832
850
  }
833
851
  );
834
852
  };
@@ -961,7 +979,7 @@ var FilterPanel = ({ schema, filters, onFilterChange, onClear }) => {
961
979
  };
962
980
 
963
981
  // src/components/InsightsPanel.tsx
964
- import { useMemo as useMemo4 } from "react";
982
+ import { useMemo as useMemo5 } from "react";
965
983
  import {
966
984
  BarChart,
967
985
  Bar,
@@ -980,7 +998,7 @@ import {
980
998
  import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
981
999
  var COLORS = ["#8884d8", "#82ca9d", "#ffc658", "#ff8042", "#a4de6c", "#d0ed57"];
982
1000
  var InsightsPanel = ({ data, schema }) => {
983
- const insights = useMemo4(() => {
1001
+ const insights = useMemo5(() => {
984
1002
  return generateInsights(data, schema);
985
1003
  }, [data, schema]);
986
1004
  if (!insights || insights.length === 0) {
@@ -1026,7 +1044,7 @@ var InsightsPanel = ({ data, schema }) => {
1026
1044
  dataKey: widget.yAxisKeys[0],
1027
1045
  nameKey: widget.xAxisKey,
1028
1046
  label: false,
1029
- children: widget.data.map((entry, index) => /* @__PURE__ */ jsx14(Cell, { fill: COLORS[index % COLORS.length] }, `cell-${index}`))
1047
+ children: widget.data.map((_entry, index) => /* @__PURE__ */ jsx14(Cell, { fill: COLORS[index % COLORS.length] }, `cell-${index}`))
1030
1048
  }
1031
1049
  )
1032
1050
  ] }) }) })
@@ -1062,8 +1080,6 @@ var PluginRegistry = class {
1062
1080
  }
1063
1081
  getRenderers() {
1064
1082
  const renderers = {};
1065
- for (const plugin of this.plugins) {
1066
- }
1067
1083
  return renderers;
1068
1084
  }
1069
1085
  getPlugins() {
@@ -1082,14 +1098,14 @@ var SmartTable = ({
1082
1098
  insights = false,
1083
1099
  plugins = []
1084
1100
  }) => {
1085
- const registry = useMemo5(() => {
1101
+ const registry = useMemo6(() => {
1086
1102
  const reg = new PluginRegistry();
1087
1103
  if (plugins && plugins.length > 0) {
1088
1104
  reg.register(plugins);
1089
1105
  }
1090
1106
  return reg;
1091
1107
  }, [plugins]);
1092
- const schema = useMemo5(() => {
1108
+ const schema = useMemo6(() => {
1093
1109
  return buildSchema(data, registry);
1094
1110
  }, [data, registry]);
1095
1111
  const { filteredData, filters, setFilter, clearFilters } = useFilters(data, schema);
@@ -1099,6 +1115,7 @@ var SmartTable = ({
1099
1115
  const { paginatedData, currentPage, totalPages, setPage } = usePagination(dataToRenderOrPaginate, 10);
1100
1116
  const finalData = pagination ? paginatedData : dataToRenderOrPaginate;
1101
1117
  const [showFilters, setShowFilters] = React3.useState(true);
1118
+ const scrollRef = React3.useRef(null);
1102
1119
  if (!data || data.length === 0) {
1103
1120
  return /* @__PURE__ */ jsx15("div", { className: "rst-container", children: /* @__PURE__ */ jsx15("div", { className: "rst-empty", children: "No data to display." }) });
1104
1121
  }
@@ -1154,7 +1171,7 @@ var SmartTable = ({
1154
1171
  /* @__PURE__ */ jsx15("button", { className: "btn btn-primary", onClick: clearFilters, children: "Clear All Filters" })
1155
1172
  ] }),
1156
1173
  data.length > 0 && finalData.length > 0 && /* @__PURE__ */ jsxs6("section", { className: "rst-card", children: [
1157
- /* @__PURE__ */ jsx15("div", { className: "rst-table-container", children: /* @__PURE__ */ jsxs6("table", { className: "rst-table", children: [
1174
+ /* @__PURE__ */ jsx15("div", { className: "rst-table-container", ref: scrollRef, children: /* @__PURE__ */ jsxs6("table", { className: "rst-table", children: [
1158
1175
  /* @__PURE__ */ jsx15(
1159
1176
  TableHeader,
1160
1177
  {
@@ -1165,7 +1182,15 @@ var SmartTable = ({
1165
1182
  onSort: handleSort
1166
1183
  }
1167
1184
  ),
1168
- /* @__PURE__ */ jsx15(TableBody, { data: finalData, schema, registry })
1185
+ /* @__PURE__ */ jsx15(
1186
+ TableBody,
1187
+ {
1188
+ data: finalData,
1189
+ schema,
1190
+ registry,
1191
+ scrollRef
1192
+ }
1193
+ )
1169
1194
  ] }) }),
1170
1195
  pagination && /* @__PURE__ */ jsxs6("div", { className: "rst-pagination", children: [
1171
1196
  /* @__PURE__ */ jsx15(