@pk-design/react-tailwind 1.5.0 → 1.5.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.
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { useId, useMemo, useState, forwardRef, Children, isValidElement, cloneElement, useRef, useEffect, Fragment as Fragment$1, useCallback, useImperativeHandle, createContext, useContext } from 'react';
3
+ import React__default, { useId, useMemo, useState, forwardRef, Children, isValidElement, cloneElement, useCallback, useRef, useEffect, Fragment as Fragment$1, useImperativeHandle, createContext, useContext } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { Dialog, DialogBackdrop, DialogPanel, DialogTitle, Menu, MenuButton, MenuItems, MenuItem, RadioGroup as RadioGroup$1, Radio as Radio$1, Combobox, ComboboxInput, ComboboxButton, ComboboxOptions, ComboboxOption, TabGroup, TabList, Tab, TabPanels, TabPanel, Transition } from '@headlessui/react';
6
6
  import { FixedSizeList } from 'react-window';
@@ -770,6 +770,48 @@ const updateSortQuery = (sortQuery, name, type = 'string') => {
770
770
  }
771
771
  return updated;
772
772
  };
773
+ /**
774
+ * Shared row-selection state/behaviour used by DataTable and VirtualizedDataTable.
775
+ * Supports controlled (`selectedRowKeys`) and uncontrolled (`defaultSelectedRowKeys`) usage.
776
+ */
777
+ const useRowSelection = ({ items, getKey, selectedRowKeys, defaultSelectedRowKeys = [], onSelectionChange, isRowSelectable, }) => {
778
+ const [internalKeys, setInternalKeys] = useState(defaultSelectedRowKeys);
779
+ const isControlled = selectedRowKeys !== undefined;
780
+ const keys = isControlled ? selectedRowKeys : internalKeys;
781
+ const keySet = useMemo(() => new Set(keys), [keys]);
782
+ const selectableEntries = useMemo(() => items
783
+ .map((item, idx) => ({ item, key: getKey(item, idx) }))
784
+ .filter(({ item }) => !isRowSelectable || isRowSelectable(item)), [items, getKey, isRowSelectable]);
785
+ const emit = useCallback((nextKeys) => {
786
+ if (!isControlled)
787
+ setInternalKeys(nextKeys);
788
+ const nextKeySet = new Set(nextKeys);
789
+ const nextItems = items.filter((item, idx) => nextKeySet.has(getKey(item, idx)));
790
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(nextKeys, nextItems);
791
+ }, [isControlled, items, getKey, onSelectionChange]);
792
+ const toggleRow = useCallback((key) => {
793
+ emit(keySet.has(key) ? keys.filter((k) => k !== key) : [...keys, key]);
794
+ }, [keys, keySet, emit]);
795
+ const allSelected = selectableEntries.length > 0 && selectableEntries.every(({ key }) => keySet.has(key));
796
+ const someSelected = !allSelected && selectableEntries.some(({ key }) => keySet.has(key));
797
+ const toggleAll = useCallback(() => {
798
+ const selectableKeySet = new Set(selectableEntries.map(({ key }) => key));
799
+ if (allSelected) {
800
+ emit(keys.filter((k) => !selectableKeySet.has(k)));
801
+ }
802
+ else {
803
+ emit(Array.from(new Set([...keys, ...selectableKeySet])));
804
+ }
805
+ }, [allSelected, selectableEntries, keys, emit]);
806
+ return {
807
+ selectedKeys: keys,
808
+ isSelected: (key) => keySet.has(key),
809
+ toggleRow,
810
+ toggleAll,
811
+ allSelected,
812
+ someSelected,
813
+ };
814
+ };
773
815
 
774
816
  var _path$7;
775
817
  function _extends$7() { return _extends$7 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$7.apply(null, arguments); }
@@ -903,7 +945,7 @@ const autoSortItems = (items, column, sort) => {
903
945
  return 0;
904
946
  });
905
947
  };
906
- function DataTable({ items, columns, sorting = {}, onSort, loading, pagination, setPagination = () => { }, emptyMessage = 'No data found', containerClass = '', wrapperClass = '', tableClass = '', headClass = '', footerRow, rowKey = 'id', onRowClick, rowClass, density = 'default', striped = false, layout = 'auto', }) {
948
+ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination, setPagination = () => { }, emptyMessage = 'No data found', containerClass = '', wrapperClass = '', tableClass = '', headClass = '', footerRow, rowKey = 'id', onRowClick, rowClass, density = 'default', striped = false, layout = 'auto', selectable = false, selectedRowKeys, defaultSelectedRowKeys, onSelectionChange, isRowSelectable, }) {
907
949
  const internalSorting = useRef({});
908
950
  const [sortedItems, setSortedItems] = useState(items);
909
951
  useEffect(() => {
@@ -938,17 +980,33 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
938
980
  return column.cellClass(item);
939
981
  return column.cellClass;
940
982
  };
983
+ const { isSelected, toggleRow, toggleAll, allSelected, someSelected } = useRowSelection({
984
+ items: sortedItems,
985
+ getKey,
986
+ selectedRowKeys,
987
+ defaultSelectedRowKeys,
988
+ onSelectionChange,
989
+ isRowSelectable,
990
+ });
941
991
  const densityCellClass = DENSITY_CELL_CLASS$2[density];
942
- return (jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsx("div", { className: buildClassName('overflow-x-auto overflow-y-hidden rounded-lg border border-gray-200 dark:border-gray-800', wrapperClass, pagination && 'rounded-b-none border-b-0'), children: jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsx(TableHead, { className: headClass, children: columns.map((column) => (jsx(TableHeaderCell, { align: column.headerAlign, style: { width: column.width || 'auto' }, className: buildClassName('bg-gray-50 dark:bg-gray-800', densityCellClass, column.sticky === 'left' &&
943
- 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
944
- 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxs(TextContent, { role: column.sortable ? 'button' : undefined, className: buildClassName('group', column.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(column), children: [jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name))) }), jsx(TableBody, { loading: loading, colSize: columns.length, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsx(EmptyTableRow, { colSpan: columns.length, children: emptyMessage })) : (sortedItems.map((item, idx) => (jsx(TableRow, { className: buildClassName('group', onRowClick && 'cursor-pointer', striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', getRowClass(item, idx)), onClick: onRowClick ? () => onRowClick(item, idx) : undefined, children: columns.map((column) => {
945
- var _a;
946
- return (jsx(TableCell, { align: column.align, className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', column.sticky === 'left' &&
947
- 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
948
- 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', getCellClass(column, item)), children: column.render
949
- ? column.render(item)
950
- : ((_a = get(item, column.name)) !== null && _a !== void 0 ? _a : 'Not set') }, column.name));
951
- }) }, getKey(item, idx))))) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx(Pagination, { ...pagination, className: "rounded-b-lg border border-t-0 border-gray-200 dark:border-gray-800", onChange: setPagination }))] }));
992
+ const colSize = columns.length + (selectable ? 1 : 0);
993
+ return (jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsx("div", { className: buildClassName('overflow-x-auto overflow-y-hidden rounded-lg border border-gray-200 dark:border-gray-800', wrapperClass, pagination && 'rounded-b-none border-b-0'), children: jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsxs(TableHead, { className: headClass, children: [selectable && (jsx(TableHeaderCell, { className: buildClassName('bg-gray-50 dark:bg-gray-800 w-px', densityCellClass), children: jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
994
+ if (el)
995
+ el.indeterminate = someSelected;
996
+ }, onChange: toggleAll }) })), columns.map((column) => (jsx(TableHeaderCell, { align: column.headerAlign, style: { width: column.width || 'auto' }, className: buildClassName('bg-gray-50 dark:bg-gray-800', densityCellClass, column.sticky === 'left' &&
997
+ 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
998
+ 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxs(TextContent, { role: column.sortable ? 'button' : undefined, className: buildClassName('group', column.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(column), children: [jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name)))] }), jsx(TableBody, { loading: loading, colSize: colSize, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsx(EmptyTableRow, { colSpan: colSize, children: emptyMessage })) : (sortedItems.map((item, idx) => {
999
+ const key = getKey(item, idx);
1000
+ const rowSelectable = !isRowSelectable || isRowSelectable(item);
1001
+ return (jsxs(TableRow, { className: buildClassName('group', onRowClick && 'cursor-pointer', striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', getRowClass(item, idx)), onClick: onRowClick ? () => onRowClick(item, idx) : undefined, children: [selectable && (jsx(TableCell, { className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40'), children: jsx("span", { onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { "aria-label": "Select row", checked: isSelected(key), disabled: !rowSelectable, onChange: () => toggleRow(key) }) }) })), columns.map((column) => {
1002
+ var _a;
1003
+ return (jsx(TableCell, { align: column.align, className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', column.sticky === 'left' &&
1004
+ 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
1005
+ 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', getCellClass(column, item)), children: column.render
1006
+ ? column.render(item)
1007
+ : ((_a = get(item, column.name)) !== null && _a !== void 0 ? _a : 'Not set') }, column.name));
1008
+ })] }, key));
1009
+ })) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx(Pagination, { ...pagination, className: "rounded-b-lg border border-t-0 border-gray-200 dark:border-gray-800", onChange: setPagination }))] }));
952
1010
  }
953
1011
  DataTable.displayName = 'DataTable';
954
1012
 
@@ -1615,9 +1673,12 @@ const DENSITY_CELL_CLASS$1 = {
1615
1673
  spacious: 'px-4 py-4',
1616
1674
  };
1617
1675
  const VirtualizedRow = ({ index, style, data, }) => {
1618
- const { items, columns, gridTemplate, onRowClick, rowClass, density = 'default', striped } = data;
1676
+ var _a, _b;
1677
+ const { items, columns, gridTemplate, onRowClick, rowClass, density = 'default', striped, selectable, getKey, isSelected, toggleRow, isRowSelectable, } = data;
1619
1678
  const item = items[index];
1620
1679
  const isStriped = striped && index % 2 === 1;
1680
+ const key = (_a = getKey === null || getKey === void 0 ? void 0 : getKey(item, index)) !== null && _a !== void 0 ? _a : index;
1681
+ const rowSelectable = !isRowSelectable || isRowSelectable(item);
1621
1682
  const resolvedRowClass = !rowClass
1622
1683
  ? ''
1623
1684
  : typeof rowClass === 'function'
@@ -1631,20 +1692,21 @@ const VirtualizedRow = ({ index, style, data, }) => {
1631
1692
  return col.cellClass;
1632
1693
  };
1633
1694
  const densityCellClass = DENSITY_CELL_CLASS$1[density];
1634
- return (jsx("div", { role: "row", className: buildClassName('grid border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 group', onRowClick && 'cursor-pointer', isStriped && 'bg-gray-50 dark:bg-gray-800/40', resolvedRowClass), style: {
1695
+ return (jsxs("div", { role: "row", className: buildClassName('grid border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 group', onRowClick && 'cursor-pointer', isStriped && 'bg-gray-50 dark:bg-gray-800/40', resolvedRowClass), style: {
1635
1696
  ...style,
1636
1697
  display: 'grid',
1637
1698
  gridTemplateColumns: gridTemplate,
1638
1699
  minWidth: 'fit-content',
1639
- }, onClick: onRowClick ? () => onRowClick(item, index) : undefined, children: columns.map((col) => {
1640
- var _a;
1641
- const content = col.render ? col.render(item) : ((_a = get(item, col.name)) !== null && _a !== void 0 ? _a : 'Not set');
1642
- return (jsx("div", { role: "cell", className: buildClassName('whitespace-nowrap border-r last:border-r-0 border-gray-200 dark:border-gray-700', densityCellClass, col.align === 'center' && 'text-center', col.align === 'right' && 'text-right', col.sticky === 'left' &&
1643
- 'sticky left-0 z-10 bg-white dark:bg-gray-900 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1644
- 'sticky right-0 z-10 bg-white dark:bg-gray-900 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', isStriped && 'bg-gray-50 dark:bg-gray-800/40', getCellClass(col)), children: content }, col.name));
1645
- }) }));
1700
+ }, onClick: onRowClick ? () => onRowClick(item, index) : undefined, children: [selectable && (jsx("div", { role: "cell", className: buildClassName('flex items-center whitespace-nowrap border-r last:border-r-0 border-gray-200 dark:border-gray-700', densityCellClass, isStriped && 'bg-gray-50 dark:bg-gray-800/40'), onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { "aria-label": "Select row", checked: (_b = isSelected === null || isSelected === void 0 ? void 0 : isSelected(key)) !== null && _b !== void 0 ? _b : false, disabled: !rowSelectable, onChange: () => toggleRow === null || toggleRow === void 0 ? void 0 : toggleRow(key) }) })), columns.map((col) => {
1701
+ var _a;
1702
+ const content = col.render ? col.render(item) : ((_a = get(item, col.name)) !== null && _a !== void 0 ? _a : 'Not set');
1703
+ return (jsx("div", { role: "cell", className: buildClassName('whitespace-nowrap border-r last:border-r-0 border-gray-200 dark:border-gray-700', densityCellClass, col.align === 'center' && 'text-center', col.align === 'right' && 'text-right', col.sticky === 'left' &&
1704
+ 'sticky left-0 z-10 bg-white dark:bg-gray-900 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1705
+ 'sticky right-0 z-10 bg-white dark:bg-gray-900 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', isStriped && 'bg-gray-50 dark:bg-gray-800/40', getCellClass(col)), children: content }, col.name));
1706
+ })] }));
1646
1707
  };
1647
1708
 
1709
+ const SELECTION_COLUMN_WIDTH = '44px';
1648
1710
  const DENSITY_CELL_CLASS = {
1649
1711
  compact: 'px-2 py-1.5',
1650
1712
  default: 'px-3 py-3',
@@ -1657,11 +1719,28 @@ const columnWidth = (col) => {
1657
1719
  return `${col.width}px`;
1658
1720
  return col.width;
1659
1721
  };
1660
- function VirtualizedDataTable({ items, columns, sorting = {}, onSort, loading = false, emptyMessage = 'No data available', containerClass = '', wrapperClass = '', onRowClick, rowClass, density = 'default', striped = false, rowHeight = 48, maxHeight = 400, overscanCount = 3, }) {
1722
+ function VirtualizedDataTable({ items, columns, sorting = {}, onSort, loading = false, emptyMessage = 'No data available', containerClass = '', wrapperClass = '', onRowClick, rowClass, density = 'default', striped = false, rowHeight = 48, maxHeight = 400, overscanCount = 3, rowKey = 'id', selectable = false, selectedRowKeys, defaultSelectedRowKeys, onSelectionChange, isRowSelectable, }) {
1661
1723
  const scrollRef = useRef(null);
1662
1724
  const outerRef = useRef(null);
1663
1725
  const headerRef = useRef(null);
1664
- const gridTemplate = useMemo(() => columns.map((col) => columnWidth(col)).join(' '), [columns]);
1726
+ const getKey = useCallback((item, idx) => {
1727
+ var _a;
1728
+ if (typeof rowKey === 'function')
1729
+ return rowKey(item);
1730
+ return (_a = item[rowKey]) !== null && _a !== void 0 ? _a : idx;
1731
+ }, [rowKey]);
1732
+ const { isSelected, toggleRow, toggleAll, allSelected, someSelected } = useRowSelection({
1733
+ items,
1734
+ getKey,
1735
+ selectedRowKeys,
1736
+ defaultSelectedRowKeys,
1737
+ onSelectionChange,
1738
+ isRowSelectable,
1739
+ });
1740
+ const gridTemplate = useMemo(() => {
1741
+ const widths = columns.map((col) => columnWidth(col));
1742
+ return selectable ? [SELECTION_COLUMN_WIDTH, ...widths].join(' ') : widths.join(' ');
1743
+ }, [columns, selectable]);
1665
1744
  const densityCellClass = DENSITY_CELL_CLASS[density];
1666
1745
  const skeletonRows = Math.max(1, Math.floor(maxHeight / rowHeight));
1667
1746
  useEffect(() => {
@@ -1679,19 +1758,48 @@ function VirtualizedDataTable({ items, columns, sorting = {}, onSort, loading =
1679
1758
  if (column.sortable)
1680
1759
  onSort === null || onSort === void 0 ? void 0 : onSort(column);
1681
1760
  }, [onSort]);
1682
- const itemData = useMemo(() => ({ items, columns, gridTemplate, onRowClick, rowClass, density, striped }), [items, columns, gridTemplate, onRowClick, rowClass, density, striped]);
1761
+ const itemData = useMemo(() => ({
1762
+ items,
1763
+ columns,
1764
+ gridTemplate,
1765
+ onRowClick,
1766
+ rowClass,
1767
+ density,
1768
+ striped,
1769
+ selectable,
1770
+ getKey,
1771
+ isSelected,
1772
+ toggleRow,
1773
+ isRowSelectable,
1774
+ }), [
1775
+ items,
1776
+ columns,
1777
+ gridTemplate,
1778
+ onRowClick,
1779
+ rowClass,
1780
+ density,
1781
+ striped,
1782
+ selectable,
1783
+ getKey,
1784
+ isSelected,
1785
+ toggleRow,
1786
+ isRowSelectable,
1787
+ ]);
1683
1788
  /* -------------------------------------------------------
1684
1789
  * Header
1685
1790
  * ------------------------------------------------------- */
1686
- const Header = (jsx("div", { ref: headerRef, className: "overflow-hidden w-full", children: jsx("div", { className: "grid bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", style: { gridTemplateColumns: gridTemplate, minWidth: 'fit-content' }, children: columns.map((col) => (jsx("div", { role: "columnheader", className: buildClassName('font-semibold text-sm whitespace-nowrap flex items-center', densityCellClass, 'border-r last:border-r-0 border-gray-200 dark:border-gray-700', col.sticky === 'left' &&
1687
- 'sticky left-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1688
- 'sticky right-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', col.headerClass), children: jsxs(TextContent, { role: col.sortable ? 'button' : undefined, className: buildClassName(col.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(col), children: [col.label, col.sortable ? getSortIcon(sorting[col.name]) : null] }) }, col.name))) }) }));
1791
+ const Header = (jsx("div", { ref: headerRef, className: "overflow-hidden w-full", children: jsxs("div", { className: "grid bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", style: { gridTemplateColumns: gridTemplate, minWidth: 'fit-content' }, children: [selectable && (jsx("div", { role: "columnheader", className: buildClassName('flex items-center border-r last:border-r-0 border-gray-200 dark:border-gray-700', densityCellClass), children: jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
1792
+ if (el)
1793
+ el.indeterminate = someSelected;
1794
+ }, onChange: toggleAll }) })), columns.map((col) => (jsx("div", { role: "columnheader", className: buildClassName('font-semibold text-sm whitespace-nowrap flex items-center', densityCellClass, 'border-r last:border-r-0 border-gray-200 dark:border-gray-700', col.sticky === 'left' &&
1795
+ 'sticky left-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1796
+ 'sticky right-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', col.headerClass), children: jsxs(TextContent, { role: col.sortable ? 'button' : undefined, className: buildClassName(col.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(col), children: [col.label, col.sortable ? getSortIcon(sorting[col.name]) : null] }) }, col.name)))] }) }));
1689
1797
  const wrapperCls = buildClassName('rounded-lg border border-gray-200 dark:border-gray-800 overflow-hidden', wrapperClass);
1690
1798
  /* -------------------------------------------------------
1691
1799
  * Loading state
1692
1800
  * ------------------------------------------------------- */
1693
1801
  if (loading) {
1694
- return (jsx("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: jsxs("div", { className: wrapperCls, children: [Header, jsx("div", { style: { height: maxHeight }, className: "flex flex-col", children: Array.from({ length: skeletonRows }).map((_, idx) => (jsx("div", { "data-testid": "skeleton-row", className: "grid animate-pulse bg-white dark:bg-gray-900 border-b border-gray-100 dark:border-gray-800", style: { gridTemplateColumns: gridTemplate, height: rowHeight }, children: columns.map((col) => (jsx("div", { className: densityCellClass, children: jsx("div", { className: "h-4 w-3/4 bg-gray-300 dark:bg-gray-700 rounded" }) }, col.name))) }, idx))) })] }) }));
1802
+ return (jsx("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: jsxs("div", { className: wrapperCls, children: [Header, jsx("div", { style: { height: maxHeight }, className: "flex flex-col", children: Array.from({ length: skeletonRows }).map((_, idx) => (jsxs("div", { "data-testid": "skeleton-row", className: "grid animate-pulse bg-white dark:bg-gray-900 border-b border-gray-100 dark:border-gray-800", style: { gridTemplateColumns: gridTemplate, height: rowHeight }, children: [selectable && jsx("div", { className: densityCellClass }), columns.map((col) => (jsx("div", { className: densityCellClass, children: jsx("div", { className: "h-4 w-3/4 bg-gray-300 dark:bg-gray-700 rounded" }) }, col.name)))] }, idx))) })] }) }));
1695
1803
  }
1696
1804
  /* -------------------------------------------------------
1697
1805
  * Empty state
@@ -1741,5 +1849,5 @@ const useIsTabletOrMobile = () => {
1741
1849
  return isMobile || isTablet;
1742
1850
  };
1743
1851
 
1744
- export { Accordion, Alert, Badge, Banner, BodyText, Breadcrumb, Button, ButtonGroup, Card, Checkbox, CheckboxGroup, DOTS, DataTable, DetailedInformation, Dot, Drawer, Dropdown, EmptyState, EmptyTableRow, HeadingText, Input, Label, Loader, PASSWORD_PLACEHOLDER, PASSWORD_TYPE, Pagination, PasswordInput, Radio, RadioGroup, RadioSwitch, RangeInput, RangeSlider, SelectBox, SortIconMap, Table, TableBody, TableCell, TableFoot, TableHead, TableHeaderCell, TableRow, Tabs, TextContent, Textarea, Toast, ToastProvider, VirtualizedDataTable, buildClassName, buildInputClass, get, getSortIcon, isArray, isEmpty, nextSortDirection, updateSortQuery, useDebounce, useDebounceFn, useIsMobile, useIsTablet, useIsTabletOrMobile, usePagination, useToast };
1852
+ export { Accordion, Alert, Badge, Banner, BodyText, Breadcrumb, Button, ButtonGroup, Card, Checkbox, CheckboxGroup, DOTS, DataTable, DetailedInformation, Dot, Drawer, Dropdown, EmptyState, EmptyTableRow, HeadingText, Input, Label, Loader, PASSWORD_PLACEHOLDER, PASSWORD_TYPE, Pagination, PasswordInput, Radio, RadioGroup, RadioSwitch, RangeInput, RangeSlider, SelectBox, SortIconMap, Table, TableBody, TableCell, TableFoot, TableHead, TableHeaderCell, TableRow, Tabs, TextContent, Textarea, Toast, ToastProvider, VirtualizedDataTable, buildClassName, buildInputClass, get, getSortIcon, isArray, isEmpty, nextSortDirection, updateSortQuery, useDebounce, useDebounceFn, useIsMobile, useIsTablet, useIsTabletOrMobile, usePagination, useRowSelection, useToast };
1745
1853
  //# sourceMappingURL=react-tailwind.es.js.map