@reactorui/datagrid 1.0.2 → 1.0.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.
@@ -5,7 +5,7 @@ import { SearchInput } from '../Search';
5
5
  import { FilterControls } from '../Filter';
6
6
  import { TableHeader, TableBody } from '../Table';
7
7
  import { getTheme } from '../../themes';
8
- export const DataGrid = ({ data, endpoint, columns: columnsProp = [], enableSearch = true, enableSorting = true, enableFilters = true, enableSelection = true, pageSize = 10, serverPageSize = 100, pageSizeOptions = [5, 10, 25, 50, 100], httpConfig, variant = 'default', size = 'md', className = '', showRefreshButton = true, // New prop
8
+ export const DataGrid = ({ data, endpoint, columns: columnsProp = [], enableSearch = true, enableSorting = true, enableFilters = true, enableSelection = true, pageSize = 10, serverPageSize = 100, pageSizeOptions = [5, 10, 25, 50, 100], httpConfig, variant = 'default', size = 'md', className = '', showRefreshButton = true,
9
9
  // Event callbacks
10
10
  onDataLoad, onDataError, onLoadingStateChange, onPageChange, onPageSizeChange, onSortChange, onFilterChange, onSearchChange, onTableRefresh, onTableRowClick, onTableRowDoubleClick, onRowSelect, onSelectionChange, onTableRowHover, onCellClick, ...rest }) => {
11
11
  const theme = getTheme(variant);
@@ -63,9 +63,9 @@ onDataLoad, onDataError, onLoadingStateChange, onPageChange, onPageSizeChange, o
63
63
  onTableRefresh?.();
64
64
  };
65
65
  if (error) {
66
- return (_jsx("div", { className: `${theme.container} ${className}`, ...rest, children: _jsxs("div", { className: "px-4 py-8 text-center", children: [_jsx("div", { className: "text-red-600 mb-2", children: "Error loading data" }), _jsx("div", { className: "text-sm text-gray-600 mb-4", children: error }), _jsx("button", { onClick: handleRefresh, className: "px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700", children: "Try Again" })] }) }));
66
+ return (_jsx("div", { className: `${theme.container} ${className}`, ...rest, children: _jsxs("div", { className: "px-4 py-8 text-center", children: [_jsx("div", { className: "text-red-600 dark:text-red-400 mb-2", children: "Error loading data" }), _jsx("div", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: error }), _jsx("button", { onClick: handleRefresh, className: theme.button, children: "Try Again" })] }) }));
67
67
  }
68
- return (_jsxs("div", { className: `${theme.container} ${className}`, ...rest, children: [enableFilters && (_jsx("div", { className: "p-4 pb-2", children: _jsxs("div", { className: "flex justify-between items-start gap-4", children: [_jsx("div", { className: "flex-1", children: _jsx(FilterControls, { columns: columns, activeFilters: activeFilters, onAddFilter: addFilter, onRemoveFilter: removeFilter, onClearFilters: clearFilters }) }), showRefreshButton && (_jsx("div", { className: "flex-shrink-0", children: _jsx("button", { onClick: handleRefresh, disabled: loading, className: "px-4 py-2 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-blue-500", children: loading ? 'Loading...' : 'Refresh' }) }))] }) })), _jsx("div", { className: "px-4 pb-4", children: _jsxs("div", { className: "flex justify-between items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("span", { className: "text-sm text-gray-700", children: "Show" }), _jsx("select", { value: currentPageSize, onChange: (e) => setCurrentPageSize(parseInt(e.target.value)), className: "px-2 py-1 border border-gray-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", children: pageSizeOptions.map((size) => (_jsx("option", { value: size, children: size }, size))) }), _jsx("span", { className: "text-sm text-gray-700", children: "entries" })] }), enableSearch && (_jsx("div", { className: "w-48 flex-shrink-0", children: _jsx(SearchInput, { value: searchTerm, onChange: setSearchTerm, placeholder: "Search...", disabled: loading }) }))] }) }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: theme.table, children: [_jsx(TableHeader, { columns: columns, sortConfig: sortConfig, onSort: enableSorting ? setSort : undefined, enableSelection: enableSelection, selectedCount: selectedRows.size, totalCount: paginatedData.length, onSelectAll: enableSelection ? selectAll : undefined }), _jsx(TableBody, { columns: columns, data: paginatedData, selectedRows: selectedRows, onSelectRow: enableSelection ? handleRowSelect : undefined, onRowClick: onTableRowClick, onRowDoubleClick: onTableRowDoubleClick, onRowHover: onTableRowHover, onCellClick: onCellClick, enableSelection: enableSelection, loading: loading })] }) }), _jsxs("div", { className: "flex justify-between items-center px-4 py-3 bg-white border-t border-gray-200", children: [_jsxs("div", { className: "text-sm text-gray-700 flex-shrink-0", children: ["Showing ", paginationInfo.start, "-", paginationInfo.end, " of", ' ', paginationInfo.totalRecords.toLocaleString(), " records"] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: navigatePrevious, disabled: !paginationInfo.hasPrevious, className: "px-3 py-1 text-sm border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed", children: "Previous" }), _jsxs("span", { className: "text-sm text-gray-700 px-2", children: ["Page ", currentPage, " ", paginationInfo.totalPages > 0 && `of ${paginationInfo.totalPages}`] }), _jsx("button", { onClick: navigateNext, disabled: !paginationInfo.hasNext, className: "px-3 py-1 text-sm border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed", children: "Next" })] })] })] }));
68
+ return (_jsxs("div", { className: `${theme.container} ${className}`, ...rest, children: [enableFilters && (_jsx("div", { className: "p-4 pb-2", children: _jsxs("div", { className: "flex justify-between items-start gap-4", children: [_jsx("div", { className: "flex-1", children: _jsx(FilterControls, { columns: columns, activeFilters: activeFilters, onAddFilter: addFilter, onRemoveFilter: removeFilter, onClearFilters: clearFilters }) }), showRefreshButton && (_jsx("div", { className: "flex-shrink-0", children: _jsx("button", { onClick: handleRefresh, disabled: loading, className: "px-4 py-2 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 transition-colors duration-150", children: loading ? 'Loading...' : 'Refresh' }) }))] }) })), _jsx("div", { className: "px-4 pb-4", children: _jsxs("div", { className: "flex justify-between items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: "Show" }), _jsx("select", { value: currentPageSize, onChange: (e) => setCurrentPageSize(parseInt(e.target.value)), className: "px-2 py-1 border border-gray-300 dark:border-gray-600 rounded text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400", children: pageSizeOptions.map((size) => (_jsx("option", { value: size, children: size }, size))) }), _jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: "entries" })] }), enableSearch && (_jsx("div", { className: "w-48 flex-shrink-0", children: _jsx(SearchInput, { value: searchTerm, onChange: setSearchTerm, placeholder: "Search...", disabled: loading, className: theme.searchInput }) }))] }) }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: theme.table, children: [_jsx(TableHeader, { columns: columns, sortConfig: sortConfig, onSort: enableSorting ? setSort : undefined, enableSelection: enableSelection, selectedCount: selectedRows.size, totalCount: paginatedData.length, onSelectAll: enableSelection ? selectAll : undefined, theme: theme }), _jsx(TableBody, { columns: columns, data: paginatedData, selectedRows: selectedRows, onSelectRow: enableSelection ? handleRowSelect : undefined, onRowClick: onTableRowClick, onRowDoubleClick: onTableRowDoubleClick, onRowHover: onTableRowHover, onCellClick: onCellClick, enableSelection: enableSelection, loading: loading, theme: theme })] }) }), _jsxs("div", { className: theme.pagination, children: [_jsxs("div", { className: "text-sm text-gray-700 dark:text-gray-300 flex-shrink-0", children: ["Showing ", paginationInfo.start, "-", paginationInfo.end, " of", ' ', paginationInfo.totalRecords.toLocaleString(), " records"] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: navigatePrevious, disabled: !paginationInfo.hasPrevious, className: "px-3 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150", children: "Previous" }), _jsxs("span", { className: "text-sm text-gray-700 dark:text-gray-300 px-2", children: ["Page ", currentPage, " ", paginationInfo.totalPages > 0 && `of ${paginationInfo.totalPages}`] }), _jsx("button", { onClick: navigateNext, disabled: !paginationInfo.hasNext, className: "px-3 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150", children: "Next" })] })] })] }));
69
69
  };
70
70
  // Helper function to infer data type
71
71
  function inferDataType(value) {
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Column } from '../../types';
3
+ import { Theme } from '../../themes';
3
4
  interface TableBodyProps<T> {
4
5
  columns: Column<T>[];
5
6
  data: T[];
@@ -12,9 +13,10 @@ interface TableBodyProps<T> {
12
13
  enableSelection: boolean;
13
14
  loading: boolean;
14
15
  emptyMessage?: string;
16
+ theme: Theme;
15
17
  }
16
18
  export declare const TableBody: <T extends {
17
19
  id?: string | number;
18
- }>({ columns, data, selectedRows, onSelectRow, onRowClick, onRowDoubleClick, onRowHover, onCellClick, enableSelection, loading, emptyMessage, }: TableBodyProps<T>) => import("react/jsx-runtime").JSX.Element;
20
+ }>({ columns, data, selectedRows, onSelectRow, onRowClick, onRowDoubleClick, onRowHover, onCellClick, enableSelection, loading, emptyMessage, theme, }: TableBodyProps<T>) => import("react/jsx-runtime").JSX.Element;
19
21
  export {};
20
22
  //# sourceMappingURL=TableBody.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableBody.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,UAAU,cAAc,CAAC,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvD,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC7D,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC9D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvF,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS;IAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAAE,8IAY3D,cAAc,CAAC,CAAC,CAAC,4CAmInB,CAAC"}
1
+ {"version":3,"file":"TableBody.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,cAAc,CAAC,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvD,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC7D,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC9D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvF,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS;IAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAAE,qJAa3D,cAAc,CAAC,CAAC,CAAC,4CAiInB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- export const TableBody = ({ columns, data, selectedRows, onSelectRow, onRowClick, onRowDoubleClick, onRowHover, onCellClick, enableSelection, loading, emptyMessage = 'No data available', }) => {
2
+ export const TableBody = ({ columns, data, selectedRows, onSelectRow, onRowClick, onRowDoubleClick, onRowHover, onCellClick, enableSelection, loading, emptyMessage = 'No data available', theme, }) => {
3
3
  const renderCell = (row, column) => {
4
4
  const value = row[column.key];
5
5
  if (column.render) {
@@ -32,18 +32,18 @@ export const TableBody = ({ columns, data, selectedRows, onSelectRow, onRowClick
32
32
  }
33
33
  };
34
34
  if (loading && data.length === 0) {
35
- return (_jsx("tbody", { children: Array.from({ length: 5 }).map((_, index) => (_jsxs("tr", { className: "animate-pulse", children: [enableSelection && (_jsx("td", { className: "px-4 py-3", children: _jsx("div", { className: "w-4 h-4 bg-gray-200 rounded" }) })), columns.map((column) => (_jsx("td", { className: "px-4 py-3", children: _jsx("div", { className: "h-4 bg-gray-200 rounded" }) }, String(column.key))))] }, index))) }));
35
+ return (_jsx("tbody", { className: "bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-600", children: Array.from({ length: 5 }).map((_, index) => (_jsxs("tr", { className: "animate-pulse", children: [enableSelection && (_jsx("td", { className: theme.cell, children: _jsx("div", { className: "w-4 h-4 bg-gray-200 dark:bg-gray-600 rounded" }) })), columns.map((column) => (_jsx("td", { className: theme.cell, children: _jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-600 rounded" }) }, String(column.key))))] }, index))) }));
36
36
  }
37
37
  if (data.length === 0 && !loading) {
38
- return (_jsx("tbody", { children: _jsx("tr", { children: _jsx("td", { colSpan: columns.length + (enableSelection ? 1 : 0), className: "px-4 py-8 text-center text-gray-500", children: emptyMessage }) }) }));
38
+ return (_jsx("tbody", { className: "bg-white dark:bg-gray-800", children: _jsx("tr", { children: _jsx("td", { colSpan: columns.length + (enableSelection ? 1 : 0), className: "px-4 py-8 text-center text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800", children: emptyMessage }) }) }));
39
39
  }
40
- return (_jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: data.map((row) => {
40
+ return (_jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: data.map((row, index) => {
41
41
  const rowId = getRowId(row);
42
42
  const isSelected = selectedRows.has(rowId);
43
- return (_jsxs("tr", { className: `transition-colors duration-150 cursor-pointer ${isSelected ? 'bg-blue-50 hover:bg-blue-100' : 'hover:bg-gray-50'}`, onClick: (e) => handleRowClick(row, e), onDoubleClick: (e) => onRowDoubleClick?.(row, e), onMouseEnter: (e) => onRowHover?.(row, e), onMouseLeave: (e) => onRowHover?.(null, e), children: [enableSelection && (_jsx("td", { className: "px-4 py-3", children: _jsx("input", { type: "checkbox", checked: isSelected, onChange: (e) => {
43
+ return (_jsxs("tr", { className: `cursor-pointer ${isSelected ? theme.selectedRow : theme.row}`, onClick: (e) => handleRowClick(row, e), onDoubleClick: (e) => onRowDoubleClick?.(row, e), onMouseEnter: (e) => onRowHover?.(row, e), onMouseLeave: (e) => onRowHover?.(null, e), children: [enableSelection && (_jsx("td", { className: theme.cell, children: _jsx("input", { type: "checkbox", checked: isSelected, onChange: (e) => {
44
44
  e.stopPropagation();
45
45
  onSelectRow?.(rowId, e.target.checked);
46
- }, className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" }) })), columns.map((column) => (_jsx("td", { className: "px-4 py-3 text-sm text-gray-900", style: {
46
+ }, className: "w-4 h-4 text-blue-600 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 dark:focus:ring-blue-400" }) })), columns.map((column) => (_jsx("td", { className: theme.cell, style: {
47
47
  width: column.width,
48
48
  minWidth: column.minWidth,
49
49
  maxWidth: column.maxWidth,
@@ -1,4 +1,5 @@
1
1
  import { Column, SortConfig } from '../../types';
2
+ import { Theme } from '../../themes';
2
3
  interface TableHeaderProps<T> {
3
4
  columns: Column<T>[];
4
5
  sortConfig: SortConfig;
@@ -7,7 +8,8 @@ interface TableHeaderProps<T> {
7
8
  selectedCount: number;
8
9
  totalCount: number;
9
10
  onSelectAll?: (selected: boolean) => void;
11
+ theme: Theme;
10
12
  }
11
- export declare const TableHeader: <T>({ columns, sortConfig, onSort, enableSelection, selectedCount, totalCount, onSelectAll, }: TableHeaderProps<T>) => import("react/jsx-runtime").JSX.Element;
13
+ export declare const TableHeader: <T>({ columns, sortConfig, onSort, enableSelection, selectedCount, totalCount, onSelectAll, theme, }: TableHeaderProps<T>) => import("react/jsx-runtime").JSX.Element;
12
14
  export {};
13
15
  //# sourceMappingURL=TableHeader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableHeader.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjD,UAAU,gBAAgB,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3C;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,EAAG,2FAQ7B,gBAAgB,CAAC,CAAC,CAAC,4CA8ErB,CAAC"}
1
+ {"version":3,"file":"TableHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableHeader.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,gBAAgB,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,KAAK,CAAC;CACd;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,EAAG,kGAS7B,gBAAgB,CAAC,CAAC,CAAC,4CAsGrB,CAAC"}
@@ -1,24 +1,28 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- export const TableHeader = ({ columns, sortConfig, onSort, enableSelection, selectedCount, totalCount, onSelectAll, }) => {
2
+ export const TableHeader = ({ columns, sortConfig, onSort, enableSelection, selectedCount, totalCount, onSelectAll, theme, }) => {
3
3
  const getSortIcon = (columnKey) => {
4
4
  if (sortConfig.column !== columnKey) {
5
- return (_jsx("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) }));
5
+ return (_jsx("svg", { className: "w-4 h-4 text-gray-400 dark:text-gray-500", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) }));
6
6
  }
7
7
  if (sortConfig.direction === 'asc') {
8
- return (_jsx("svg", { className: "w-4 h-4 text-blue-500", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) }));
8
+ return (_jsx("svg", { className: "w-4 h-4 text-blue-500 dark:text-blue-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) }));
9
9
  }
10
- return (_jsx("svg", { className: "w-4 h-4 text-blue-500", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) }));
10
+ return (_jsx("svg", { className: "w-4 h-4 text-blue-500 dark:text-blue-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) }));
11
11
  };
12
- return (_jsx("thead", { className: "bg-gray-50 border-b border-gray-200", children: _jsxs("tr", { children: [enableSelection && (_jsx("th", { className: "w-12 px-4 py-3 text-left", role: "columnheader", "aria-label": "Select all rows", children: _jsx("input", { type: "checkbox", checked: selectedCount > 0 && selectedCount === totalCount, ref: (el) => {
12
+ return (_jsx("thead", { className: theme.header, children: _jsxs("tr", { children: [enableSelection && (_jsx("th", { className: `w-12 ${theme.headerCell}`, role: "columnheader", "aria-label": "Select all rows", children: _jsx("input", { type: "checkbox", checked: selectedCount > 0 && selectedCount === totalCount, ref: (el) => {
13
13
  if (el) {
14
14
  el.indeterminate = selectedCount > 0 && selectedCount < totalCount;
15
15
  }
16
- }, onChange: (e) => onSelectAll?.(e.target.checked), className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500", "aria-label": "Select all rows" }) })), columns.map((column) => (_jsx("th", { role: "columnheader", className: `px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${column.sortable && onSort ? 'cursor-pointer hover:bg-gray-100 select-none' : ''}`, onClick: () => column.sortable && onSort && onSort(String(column.key)), style: {
16
+ }, onChange: (e) => onSelectAll?.(e.target.checked), className: "w-4 h-4 text-blue-600 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 dark:focus:ring-blue-400", "aria-label": "Select all rows" }) })), columns.map((column) => (_jsx("th", { role: "columnheader", className: `${theme.headerCell} ${column.sortable && onSort
17
+ ? 'cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 select-none'
18
+ : ''}`, onClick: () => column.sortable && onSort && onSort(String(column.key)), style: {
17
19
  width: column.width,
18
20
  minWidth: column.minWidth,
19
21
  maxWidth: column.maxWidth,
20
22
  textAlign: column.align || 'left',
21
23
  }, "aria-sort": sortConfig.column === String(column.key)
22
- ? sortConfig.direction === 'asc' ? 'ascending' : 'descending'
24
+ ? sortConfig.direction === 'asc'
25
+ ? 'ascending'
26
+ : 'descending'
23
27
  : 'none', "aria-label": `Sort by ${column.label}`, children: _jsxs("div", { className: "flex items-center gap-2", children: [column.label, column.sortable && onSort && getSortIcon(String(column.key))] }) }, String(column.key))))] }) }));
24
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,KAa1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAO3B,CAAC;AAEF,eAAO,MAAM,MAAM;;;;CAIlB,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,UAAS,MAAM,OAAO,MAAkB,KAAG,KAEnE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,KAgB1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAS3B,CAAC;AAEF,eAAO,MAAM,MAAM;;;;CAIlB,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,UAAS,MAAM,OAAO,MAAkB,KAAG,KAEnE,CAAC"}
@@ -1,25 +1,25 @@
1
1
  export const defaultTheme = {
2
- container: 'bg-white rounded-lg shadow-sm border border-gray-200',
3
- table: 'w-full',
4
- header: 'bg-gray-50 border-b border-gray-200',
5
- headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider',
6
- row: 'hover:bg-gray-50 transition-colors duration-150',
7
- cell: 'px-4 py-3 text-sm text-gray-900',
8
- selectedRow: 'bg-blue-50 hover:bg-blue-100',
9
- searchInput: 'px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500',
10
- button: 'px-3 py-2 bg-blue-600 text-white text-sm rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500',
11
- pagination: 'flex items-center justify-between px-4 py-3 bg-white border-t border-gray-200',
2
+ container: 'bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700',
3
+ table: 'w-full bg-white dark:bg-gray-800',
4
+ header: 'bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600',
5
+ headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider bg-gray-50 dark:bg-gray-700',
6
+ row: 'bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-150',
7
+ cell: 'px-4 py-3 text-sm text-gray-900 dark:text-gray-100 border-b border-gray-200 dark:border-gray-600',
8
+ selectedRow: 'bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/30',
9
+ searchInput: 'px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400',
10
+ button: 'px-3 py-2 bg-blue-600 dark:bg-blue-700 text-white text-sm rounded-md hover:bg-blue-700 dark:hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 disabled:opacity-50 disabled:cursor-not-allowed',
11
+ pagination: 'flex items-center justify-between px-4 py-3 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-600',
12
12
  };
13
13
  export const stripedTheme = {
14
14
  ...defaultTheme,
15
- row: 'odd:bg-gray-50 even:bg-white hover:bg-gray-100 transition-colors duration-150',
15
+ row: 'odd:bg-white dark:odd:bg-gray-800 even:bg-gray-50 dark:even:bg-gray-700/50 hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors duration-150',
16
16
  };
17
17
  export const borderedTheme = {
18
18
  ...defaultTheme,
19
- container: 'bg-white rounded-lg shadow-sm border border-gray-200',
20
- table: 'w-full border-collapse',
21
- cell: 'px-4 py-3 text-sm text-gray-900 border-r border-gray-200 last:border-r-0',
22
- headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider border-r border-gray-200 last:border-r-0',
19
+ container: 'bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700',
20
+ table: 'w-full border-collapse bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600',
21
+ cell: 'px-4 py-3 text-sm text-gray-900 dark:text-gray-100 border-r border-gray-200 dark:border-gray-600 last:border-r-0 border-b border-gray-200 dark:border-gray-600',
22
+ headerCell: 'px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-r border-gray-200 dark:border-gray-600 last:border-r-0 bg-gray-50 dark:bg-gray-700',
23
23
  };
24
24
  export const themes = {
25
25
  default: defaultTheme,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactorui/datagrid",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "High-performance React data grid with TypeScript support, server-side integration, and continuation token pagination",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",