@eml-payments/ui-kit 1.2.2 → 1.2.3

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.
@@ -8,17 +8,20 @@ import { DropdownWrapper } from '../DropdownWrapper';
8
8
  import { FiMoreHorizontal } from 'react-icons/fi';
9
9
  import { Button } from '../Button';
10
10
  export function Table(props) {
11
- var _a, _b, _c, _d, _e, _f;
12
- const { table, setPageSize, showHeader, height, virtualizationEnabled, rowVirtualizer, hasNextPage, parentScrollRef, loaderRef, ...pagination } = useTableController(props);
11
+ var _a, _b, _c, _d, _e, _f, _g;
12
+ const { table, setPageSize, showHeader, height, virtualizationEnabled, rowVirtualizer, hasNextPage, parentScrollRef, loaderRef, infiniteScroll, ...pagination } = useTableController(props);
13
13
  let tableContent;
14
+ const noResultsMessage = props.isSearchActive
15
+ ? ((_a = props.noSearchResultsMessage) !== null && _a !== void 0 ? _a : 'No results meet your search criteria')
16
+ : ((_b = props.noRowsMessage) !== null && _b !== void 0 ? _b : 'No rows to display');
14
17
  if (props.isLoading && props.showSkeletonRows) {
15
18
  tableContent = Array.from({ length: 3 }).map(() => (_jsx("tr", { className: "border-t animate-pulse", children: table.getVisibleFlatColumns().map((__c) => (_jsx("td", { className: "px-4 py-2", children: _jsx("div", { className: "h-4 w-3/4 bg-(--uikit-tertiary) rounded" }) }, `skeleton-cell-${__c.id}`))) }, "skeleton-row")));
16
19
  }
17
- else if (!virtualizationEnabled && table.getRowModel().rows.length === 0) {
18
- const noResultsMessage = props.isSearchActive
19
- ? ((_a = props.noSearchResultsMessage) !== null && _a !== void 0 ? _a : 'No results meet your search criteria')
20
- : ((_b = props.noRowsMessage) !== null && _b !== void 0 ? _b : 'No rows to display');
21
- tableContent = (_jsx("tr", { children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length, className: "px-4 py-8 text-center text-muted-foreground", children: noResultsMessage }) }));
20
+ else if (!virtualizationEnabled &&
21
+ table.getRowModel().rows.length === 0 &&
22
+ !props.isLoading &&
23
+ (!(infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.enabled) || !hasNextPage)) {
24
+ tableContent = (_jsx("tr", { children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length + (props.tableActionsDropdown ? 1 : 0), className: "px-4 py-8 text-center text-muted-foreground", children: noResultsMessage }) }));
22
25
  }
23
26
  else if (!virtualizationEnabled) {
24
27
  const renderRow = (row) => {
@@ -48,12 +51,14 @@ export function Table(props) {
48
51
  tableContent = table.getRowModel().rows.flatMap(renderRow);
49
52
  }
50
53
  const virtualItems = virtualizationEnabled && rowVirtualizer ? rowVirtualizer.getVirtualItems() : [];
54
+ const colSpanFull = table.getVisibleFlatColumns().length + (props.tableActionsDropdown ? 1 : 0);
51
55
  const paddingTop = virtualItems.length ? virtualItems[0].start : 0;
52
56
  const lastVirtual = virtualItems[virtualItems.length - 1];
53
57
  const totalSize = (_d = (_c = rowVirtualizer === null || rowVirtualizer === void 0 ? void 0 : rowVirtualizer.getTotalSize) === null || _c === void 0 ? void 0 : _c.call(rowVirtualizer)) !== null && _d !== void 0 ? _d : 0;
54
58
  const end = lastVirtual ? lastVirtual.end : 0;
55
59
  const paddingBottom = Math.max(totalSize - end, 0);
56
60
  const tableRows = table.getRowModel().rows;
61
+ const isTrulyEmpty = tableRows.length === 0 && !props.isLoading && !hasNextPage;
57
62
  return (_jsxs("div", { ref: parentScrollRef, style: { height }, className: "relative w-full overflow-auto", children: [props.isLoading && _jsx("div", { className: "mui-loader mt-4" }), _jsx("div", { className: "rounded-t-(--uikit-radius) overflow-y-hidden overflow-x-auto", children: _jsxs("table", { className: classNames('min-w-full text-sm table-fixed bg-[#ffffff]', props.className), role: "table", id: props.id, children: [showHeader && (_jsx("thead", { className: "bg-(--uikit-tertiary)", children: table.getHeaderGroups().map((headerGroup) => (_jsxs("tr", { className: "p-4", children: [headerGroup.headers.map((header) => {
58
63
  return (_jsx("th", { scope: "col", style: { width: header.getSize() }, className: classNames('select-none text-[14px] font-bold ', header.id === 'select' ? 'p-0' : ' p-4 text-left cursor-pointer'), onClick: header.column.getCanSort()
59
64
  ? header.column.getToggleSortingHandler()
@@ -63,24 +68,26 @@ export function Table(props) {
63
68
  asc: _jsx(FaChevronUp, {}),
64
69
  desc: _jsx(FaChevronDown, {}),
65
70
  }[header.column.getIsSorted()] || null }))] }) }, header.id));
66
- }), props.tableActionsDropdown && _jsx("th", { className: "w-[40px] px-2 py-2 text-right" })] }, headerGroup.id))) })), _jsx("tbody", { children: virtualizationEnabled && rowVirtualizer ? (_jsxs(_Fragment, { children: [_jsx("tr", { style: { height: `${paddingTop}px` }, children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length + (props.tableActionsDropdown ? 1 : 0) }) }), virtualItems.map((vi) => {
67
- var _a, _b, _c, _d, _e, _f;
71
+ }), props.tableActionsDropdown && _jsx("th", { className: "w-[40px] px-2 py-2 text-right" })] }, headerGroup.id))) })), _jsx("tbody", { children: virtualizationEnabled && rowVirtualizer ? (_jsxs(_Fragment, { children: [_jsx("tr", { style: { height: `${paddingTop}px` }, children: _jsx("td", { colSpan: colSpanFull }) }), isTrulyEmpty && (_jsx("tr", { children: _jsx("td", { colSpan: colSpanFull, className: "px-4 py-8 text-center text-muted-foreground", children: noResultsMessage }) })), virtualItems.map((vi) => {
72
+ var _a, _b, _c, _d, _e, _f, _g, _h;
68
73
  const isLoaderRow = vi.index >= tableRows.length;
69
74
  if (isLoaderRow) {
70
- return (_jsx("tr", { className: "border-t", children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length +
71
- (props.tableActionsDropdown ? 1 : 0), className: "px-4 py-2", children: hasNextPage ? 'Loading more...' : 'Nothing more to load' }) }, `loader-${vi.key}`));
75
+ return (_jsx("tr", { className: "border-t", children: _jsx("td", { colSpan: colSpanFull, className: "px-4 py-2", children: hasNextPage
76
+ ? ((_a = infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.loadingMoreMessage) !== null && _a !== void 0 ? _a : 'Loading more...')
77
+ : ((_b = infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.noMoreDataMessage) !== null && _b !== void 0 ? _b : 'Nothing more to load') }) }, `loader-${vi.key}`));
72
78
  }
73
79
  const row = tableRows[vi.index];
74
- const isRowClickable = (_a = props.isRowClickable) === null || _a === void 0 ? void 0 : _a.call(props, row.original);
80
+ const isRowClickable = (_c = props.isRowClickable) === null || _c === void 0 ? void 0 : _c.call(props, row.original);
75
81
  return (_jsxs("tr", { className: classNames('border-t', isRowClickable && 'cursor-pointer', (row === null || row === void 0 ? void 0 : row.getIsSelected()) && 'bg-(--uikit-primary-10)'), onClick: () => { var _a; return isRowClickable && ((_a = props.onRowClick) === null || _a === void 0 ? void 0 : _a.call(props, row.original)); }, children: [row === null || row === void 0 ? void 0 : row.getVisibleCells().map((cell) => {
76
82
  const width = cell.column.getSize();
77
83
  return (_jsx("td", { style: { width }, className: cell.column.id === 'select' ? 'p-1' : 'p-4', children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
78
- }), props.tableActionsDropdown && (_jsx("td", { className: "w-[40px] px-2 py-2 text-right", children: _jsx(DropdownWrapper, { structure: (_b = props.tableActionsDropdown.structure) !== null && _b !== void 0 ? _b : 'default', options: props.tableActionsDropdown.getOptions(row.original), menuAlignment: props.tableActionsDropdown.menuAlignment, isTriggerElementDisabled: typeof props.tableActionsDropdown.isDisabled === 'function'
84
+ }), props.tableActionsDropdown && (_jsx("td", { className: "w-[40px] px-2 py-2 text-right", children: _jsx(DropdownWrapper, { structure: (_d = props.tableActionsDropdown.structure) !== null && _d !== void 0 ? _d : 'default', options: props.tableActionsDropdown.getOptions(row.original), menuAlignment: props.tableActionsDropdown.menuAlignment, isTriggerElementDisabled: typeof props.tableActionsDropdown.isDisabled === 'function'
79
85
  ? props.tableActionsDropdown.isDisabled(row.original)
80
- : props.tableActionsDropdown.isDisabled, triggerElement: (_e = (_d = (_c = props.tableActionsDropdown).renderCustomTrigger) === null || _d === void 0 ? void 0 : _d.call(_c, row.original)) !== null && _e !== void 0 ? _e : (_jsx(Button, { "aria-label": "Open actions menu", title: "Open actions menu", size: "icon", variant: "ghost", disabled: typeof props.tableActionsDropdown.isDisabled ===
86
+ : props.tableActionsDropdown.isDisabled, triggerElement: (_g = (_f = (_e = props.tableActionsDropdown).renderCustomTrigger) === null || _f === void 0 ? void 0 : _f.call(_e, row.original)) !== null && _g !== void 0 ? _g : (_jsx(Button, { "aria-label": "Open actions menu", title: "Open actions menu", size: "icon", variant: "ghost", disabled: typeof props.tableActionsDropdown.isDisabled ===
81
87
  'function'
82
88
  ? props.tableActionsDropdown.isDisabled(row.original)
83
- : ((_f = props.tableActionsDropdown.isDisabled) !== null && _f !== void 0 ? _f : false), className: "p-1 focus-visible:outline-hidden focus-visible:ring-0", children: _jsx(FiMoreHorizontal, { size: 16 }) })) }) }))] }, row.id));
84
- }), _jsx("tr", { style: { height: `${paddingBottom}px` }, children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length + (props.tableActionsDropdown ? 1 : 0) }) })] })) : (_jsxs(_Fragment, { children: [tableContent, ((_e = props.infiniteScroll) === null || _e === void 0 ? void 0 : _e.enabled) && (_jsx("tr", { ref: loaderRef, className: "border-t", children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length +
85
- (props.tableActionsDropdown ? 1 : 0), className: "px-4 py-2", children: hasNextPage ? 'Loading more...' : 'Nothing more to load' }) }))] })) })] }) }), !((_f = props.infiniteScroll) === null || _f === void 0 ? void 0 : _f.enabled) && (_jsx(PaginationFooter, { tableId: props.id, table: table, paginationMode: props.paginationMode, totalServerRows: props.totalServerRows, onPageSizeChange: setPageSize, ...pagination }))] }));
89
+ : ((_h = props.tableActionsDropdown.isDisabled) !== null && _h !== void 0 ? _h : false), className: "p-1 focus-visible:outline-hidden focus-visible:ring-0", children: _jsx(FiMoreHorizontal, { size: 16 }) })) }) }))] }, row.id));
90
+ }), _jsx("tr", { style: { height: `${paddingBottom}px` }, children: _jsx("td", { colSpan: colSpanFull }) })] })) : (_jsxs(_Fragment, { children: [tableContent, (infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.enabled) && !isTrulyEmpty && (_jsx("tr", { ref: loaderRef, className: "border-t", children: _jsx("td", { colSpan: colSpanFull, className: "px-4 py-2", children: props.isLoading || hasNextPage
91
+ ? ((_e = infiniteScroll.loadingMoreMessage) !== null && _e !== void 0 ? _e : 'Loading more...')
92
+ : ((_f = infiniteScroll.noMoreDataMessage) !== null && _f !== void 0 ? _f : 'Nothing more to load') }) }))] })) })] }) }), !((_g = props.infiniteScroll) === null || _g === void 0 ? void 0 : _g.enabled) && (_jsx(PaginationFooter, { tableId: props.id, table: table, paginationMode: props.paginationMode, totalServerRows: props.totalServerRows, onPageSizeChange: setPageSize, ...pagination }))] }));
86
93
  }
@@ -27,3 +27,5 @@ export declare const ServerPaginationWithQueryParams: StoryObj;
27
27
  export declare const TwoTablesWithQueryParams: StoryObj;
28
28
  export declare const InfiniteScrollVirtualized: StoryObj;
29
29
  export declare const InfiniteScrollNonVirtual: StoryObj;
30
+ export declare const NoRowsInfiniteScrollNonVirtual: StoryObj;
31
+ export declare const NoRowsInfiniteScrollVirtualized: StoryObj;
@@ -434,3 +434,46 @@ export const InfiniteScrollNonVirtual = {
434
434
  } }) }));
435
435
  },
436
436
  };
437
+ export const NoRowsInfiniteScrollNonVirtual = {
438
+ name: 'Empty State — Infinite Scroll (Non-virtual)',
439
+ render: () => {
440
+ const [rows] = useState([]);
441
+ const [hasNextPage] = useState(false);
442
+ const [isFetchingNextPage] = useState(false);
443
+ const fetchNextPage = useCallback(async () => {
444
+ // no-op: truly empty scenario
445
+ return;
446
+ }, []);
447
+ return (_jsx("div", { children: _jsx(Table, { id: "no-rows-infinite-nonvirtual", height: 500, data: rows, columns: columns, showHeader: true, isSearchActive: false, isLoading: false, noRowsMessage: "No rows to display", infiniteScroll: {
448
+ enabled: true,
449
+ hasNextPage,
450
+ isFetchingNextPage,
451
+ fetchNextPage,
452
+ rootMarginPx: 300,
453
+ }, virtualization: {
454
+ enabled: false,
455
+ } }) }));
456
+ },
457
+ };
458
+ export const NoRowsInfiniteScrollVirtualized = {
459
+ name: 'Empty State — Infinite Scroll (Virtualized)',
460
+ render: () => {
461
+ const [rows] = useState([]);
462
+ const [hasNextPage] = useState(false);
463
+ const [isFetchingNextPage] = useState(false);
464
+ const fetchNextPage = useCallback(async () => {
465
+ // no-op: truly empty scenario
466
+ return;
467
+ }, []);
468
+ return (_jsx("div", { children: _jsx(Table, { id: "no-rows-infinite-virtualized", height: 500, data: rows, columns: columns, showHeader: true, isSearchActive: false, isLoading: false, noRowsMessage: "No rows to display", infiniteScroll: {
469
+ enabled: true,
470
+ hasNextPage,
471
+ isFetchingNextPage,
472
+ fetchNextPage,
473
+ }, virtualization: {
474
+ enabled: true,
475
+ rowEstimate: 48,
476
+ overscan: 6,
477
+ } }) }));
478
+ },
479
+ };
@@ -9,6 +9,8 @@ export type InfiniteScrollOptions = {
9
9
  isFetchingNextPage?: boolean;
10
10
  fetchNextPage: () => void;
11
11
  rootMarginPx?: number;
12
+ loadingMoreMessage?: string;
13
+ noMoreDataMessage?: string;
12
14
  };
13
15
  export type PaginationMode = 'client' | 'server' | 'none';
14
16
  export interface VirtualizationOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eml-payments/ui-kit",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "private": false,
5
5
  "description": "ARLO UIKit",
6
6
  "homepage": "https://github.com/EML-Payments/arlo.npm.uikit#readme",