gridular 2.1.0 → 3.0.0
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/README.md +88 -107
- package/dist/DataGrid.d.ts +3 -0
- package/dist/Pagination.d.ts +12 -0
- package/dist/__tests__/DataGrid.test.d.ts +1 -0
- package/dist/__tests__/setup.d.ts +0 -0
- package/dist/__tests__/utils.d.ts +17 -0
- package/dist/components/ColumnManager.d.ts +13 -0
- package/dist/components/GroupManager.d.ts +11 -0
- package/dist/components/Skeleton.d.ts +7 -0
- package/dist/gridular.css +1 -0
- package/dist/hooks/useDataGrouping.d.ts +14 -0
- package/dist/hooks/useGridPersistence.d.ts +12 -0
- package/dist/hooks/useSelectCell.d.ts +10 -0
- package/dist/index.d.ts +11 -797
- package/dist/lib/utils.d.ts +21 -0
- package/dist/logo.svg +26 -0
- package/dist/stories/customization/CustomRendering.stories.d.ts +8 -0
- package/dist/stories/customization/Themes.stories.d.ts +8 -0
- package/dist/stories/examples/BasicExample.stories.d.ts +9 -0
- package/dist/stories/examples/ComprehensiveDemo.stories.d.ts +6 -0
- package/dist/stories/examples/Pagination.stories.d.ts +6 -0
- package/dist/stories/examples/ServerPagination.stories.d.ts +8 -0
- package/dist/stories/examples/Sorting.stories.d.ts +7 -0
- package/dist/stories/features/CellSelection.stories.d.ts +6 -0
- package/dist/stories/features/ColumnFiltering.stories.d.ts +25 -0
- package/dist/stories/features/ColumnManagement.stories.d.ts +9 -0
- package/dist/stories/features/ColumnMenu.stories.d.ts +33 -0
- package/dist/stories/features/ContextMenu.stories.d.ts +15 -0
- package/dist/stories/features/ExpandableRows.stories.d.ts +7 -0
- package/dist/stories/features/Grouping.stories.d.ts +8 -0
- package/dist/stories/features/RowSelection.stories.d.ts +9 -0
- package/dist/types.d.ts +278 -0
- package/dist/virtualized-grid.js +8915 -0
- package/package.json +71 -80
- package/LICENSE +0 -21
- package/dist/index.d.mts +0 -797
- package/dist/index.js +0 -2866
- package/dist/index.mjs +0 -2766
package/README.md
CHANGED
|
@@ -1,131 +1,112 @@
|
|
|
1
|
-
# Gridular
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
# Gridular v3
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
<img src="./public/logo.svg" alt="Gridular Logo" width="200" height="200" />
|
|
5
|
+
|
|
6
|
+
<p><strong>A high-performance virtualized React data grid with comprehensive features</strong></p>
|
|
7
|
+
|
|
8
|
+
[](https://www.npmjs.com/package/gridular)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
[](https://www.typescriptlang.org/)
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
## ✨ Features
|
|
14
|
+
|
|
15
|
+
- ⚡ **True Virtualization** - Handles 100,000+ rows smoothly using `@tanstack/react-virtual`
|
|
16
|
+
- 📊 **Data Grouping** - Multi-level hierarchical grouping with expand/collapse
|
|
17
|
+
- 🔍 **Sorting & Filtering** - Column-level sorting and filtering with custom functions
|
|
18
|
+
- 📄 **Pagination** - Client-side and server-side pagination support
|
|
19
|
+
- ✏️ **Column Resizing** - Drag to resize columns with persistence
|
|
20
|
+
- 🔄 **Column Reordering** - Drag-and-drop column reordering
|
|
21
|
+
- 👁️ **Column Management** - Show/hide columns with reset to defaults
|
|
22
|
+
- 📱 **Expandable Rows** - Custom expandable row content
|
|
23
|
+
- 🎯 **Cell Selection** - Individual cell selection with visual indicators
|
|
24
|
+
- 💾 **State Persistence** - localStorage persistence for grid preferences
|
|
25
|
+
- 🎨 **Dual Styling** - Support for both Tailwind CSS and TSS-React (CSS-in-JS)
|
|
26
|
+
- 🧪 **Fully Tested** - 43 comprehensive test cases
|
|
27
|
+
- 📘 **TypeScript First** - Complete type safety and IntelliSense support
|
|
28
|
+
|
|
29
|
+
## 📦 Installation
|
|
30
|
+
|
|
31
|
+
\`\`\`bash
|
|
32
|
+
# npm
|
|
20
33
|
npm install gridular
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
yarn add gridular
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Usage
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
# pnpm
|
|
36
|
+
pnpm add gridular
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const MyComponent = () => {
|
|
35
|
-
const columns = [
|
|
36
|
-
{ id: "name", header: "Name" },
|
|
37
|
-
{ id: "age", header: "Age" },
|
|
38
|
-
// Add more columns as needed
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
const data = [
|
|
42
|
-
{ id: 1, name: "John Doe", age: 28 },
|
|
43
|
-
{ id: 2, name: "Jane Smith", age: 34 },
|
|
44
|
-
// Add more data as needed
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
return <DataGrid columns={columns} data={data} />;
|
|
48
|
-
};
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Components
|
|
52
|
-
|
|
53
|
-
- **DataGrid**: The main component that renders the grid.
|
|
54
|
-
- **FilterMenu**: A component for filtering data in the grid.
|
|
55
|
-
- **Pagination**: A component for managing pagination controls.
|
|
56
|
-
- **TableBody**: Renders the rows of the data grid.
|
|
57
|
-
- **TableCell**: Represents individual cells in the data grid.
|
|
58
|
-
- **TableHeader**: Renders the header of the data grid.
|
|
59
|
-
- **TableRow**: Represents individual rows in the data grid.
|
|
60
|
-
- **ColumnManager**: Manages column visibility and order.
|
|
61
|
-
|
|
62
|
-
## Custom Hooks
|
|
63
|
-
|
|
64
|
-
Gridular provides custom hooks for managing various functionalities:
|
|
38
|
+
# yarn
|
|
39
|
+
yarn add gridular
|
|
40
|
+
\`\`\`
|
|
65
41
|
|
|
66
|
-
|
|
67
|
-
- **useGridPersistence**: For persisting grid preferences like - \*\*column widths and order.
|
|
42
|
+
## 🚀 Quick Start
|
|
68
43
|
|
|
69
|
-
|
|
44
|
+
\`\`\`tsx
|
|
45
|
+
import { DataGrid } from 'gridular';
|
|
46
|
+
import type { ColumnDef } from 'gridular';
|
|
70
47
|
|
|
71
|
-
|
|
48
|
+
const columns: ColumnDef[] = [
|
|
49
|
+
{ id: 'name', key: 'name', header: 'Name', enableSorting: true },
|
|
50
|
+
{ id: 'email', key: 'email', header: 'Email', enableSorting: true },
|
|
51
|
+
{ id: 'age', key: 'age', header: 'Age', enableSorting: true },
|
|
52
|
+
];
|
|
72
53
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
54
|
+
const data = [
|
|
55
|
+
{ id: '1', name: 'John Doe', email: 'john@example.com', age: 28 },
|
|
56
|
+
{ id: '2', name: 'Jane Smith', email: 'jane@example.com', age: 34 },
|
|
57
|
+
];
|
|
76
58
|
|
|
77
|
-
|
|
59
|
+
function App() {
|
|
60
|
+
return <DataGrid columns={columns} data={data} enableSorting enableColumnResize />;
|
|
61
|
+
}
|
|
62
|
+
\`\`\`
|
|
78
63
|
|
|
79
|
-
|
|
80
|
-
import { cn } from "gridular";
|
|
64
|
+
## 📖 Documentation
|
|
81
65
|
|
|
82
|
-
|
|
83
|
-
<div
|
|
84
|
-
className={cn(
|
|
85
|
-
"base-class",
|
|
86
|
-
isActive && "active-class",
|
|
87
|
-
isFocused ? "focused-class" : "unfocused-class"
|
|
88
|
-
)}
|
|
89
|
-
>
|
|
90
|
-
Content
|
|
91
|
-
</div>;
|
|
92
|
-
```
|
|
66
|
+
See [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) for upgrading from v2.
|
|
93
67
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
68
|
+
For complete examples, run Storybook:
|
|
69
|
+
\`\`\`bash
|
|
70
|
+
npm run storybook
|
|
71
|
+
\`\`\`
|
|
97
72
|
|
|
98
|
-
|
|
73
|
+
## 🔄 Migration from v2
|
|
99
74
|
|
|
100
|
-
|
|
101
|
-
|
|
75
|
+
**Quick changes:**
|
|
76
|
+
- ✅ Add \`key\` property to all columns
|
|
77
|
+
- ✅ Rename \`cell\` to \`renderCell\`
|
|
78
|
+
- ✅ Remove \`ThemeProvider\` wrapper
|
|
79
|
+
- ✅ Consolidate pagination props
|
|
80
|
+
- ✅ Remove group icon props
|
|
102
81
|
|
|
103
|
-
|
|
104
|
-
const styles = mergeStyles(
|
|
105
|
-
{ color: "#000", backgroundColor: "#fff" },
|
|
106
|
-
"p-4 rounded-md hover:bg-gray-100"
|
|
107
|
-
);
|
|
82
|
+
See [PRODUCT_STATUS_GRID_MIGRATION.md](./PRODUCT_STATUS_GRID_MIGRATION.md) for specific ProductStatusGrid migration example.
|
|
108
83
|
|
|
109
|
-
|
|
110
|
-
```
|
|
84
|
+
## 📚 More Examples
|
|
111
85
|
|
|
112
|
-
|
|
86
|
+
- [Storybook](https://gridular.vercel.app)
|
|
87
|
+
- Run locally: \`npm run storybook\`
|
|
113
88
|
|
|
114
|
-
|
|
115
|
-
-- tailwindClasses: A string or array of strings containing -- Tailwind class names Returns an object with merged styles that can be spread into React components.
|
|
89
|
+
## 🧪 Testing
|
|
116
90
|
|
|
117
|
-
|
|
91
|
+
\`\`\`bash
|
|
92
|
+
npm test # Run tests
|
|
93
|
+
npm run test:ui # Tests with UI
|
|
94
|
+
npm run test:coverage # With coverage
|
|
95
|
+
\`\`\`
|
|
118
96
|
|
|
119
|
-
|
|
97
|
+
## 📝 License
|
|
120
98
|
|
|
121
|
-
|
|
122
|
-
-- ThemeSwitcher: Component for toggling between light and dark themes.
|
|
123
|
-
-- ThemeWrapper: Utility component for wrapping your components with theme context.
|
|
99
|
+
MIT © [Michael Teagle](https://github.com/mkteagle)
|
|
124
100
|
|
|
125
|
-
##
|
|
101
|
+
## 🌟 Built With
|
|
126
102
|
|
|
127
|
-
|
|
103
|
+
- [@tanstack/react-virtual](https://tanstack.com/virtual) - Virtualization
|
|
104
|
+
- [Radix UI](https://www.radix-ui.com/) - Accessible components
|
|
105
|
+
- [Tailwind CSS](https://tailwindcss.com/) - Styling
|
|
106
|
+
- [TSS-React](https://www.tss-react.dev/) - CSS-in-JS
|
|
128
107
|
|
|
129
|
-
|
|
108
|
+
---
|
|
130
109
|
|
|
131
|
-
|
|
110
|
+
<div align="center">
|
|
111
|
+
Made with ❤️ by <a href="https://github.com/mkteagle">Michael Teagle</a>
|
|
112
|
+
</div>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { VirtualizedGridProps } from './types';
|
|
2
|
+
export declare function DataGrid<T extends Record<string, any> = Record<string, any>>({ columns: propColumns, data, pagination, virtualizationThreshold, rowHeight, overscan, sortState: controlledSortState, onSortChange, enableSorting, sortIconVariant, filterState: controlledFilterState, onFilterChange: _onFilterChange, enableFiltering, selectedRows: controlledSelectedRows, onRowSelectionChange: _onRowSelectionChange, enableRowSelection: _enableRowSelection, enableCellSelection, selectedCell: controlledSelectedCell, onCellSelect, enableColumnResize, columnWidths: controlledColumnWidths, onColumnWidthsChange, enableColumnReorder, columnOrder: controlledColumnOrder, onColumnOrderChange, enableColumnMenu, defaultColumnMenuItems, onColumnAction, renderFilterMenu, renderColumnMenu, renderColumnMenuTrigger, enableGrouping, groupingState: controlledGroupingState, onGroupingChange, renderGroupRow, enableExpandableRows, expandedRows: controlledExpandedRows, onExpandedRowsChange, renderExpandedRow, isLoading: _isLoading, emptyMessage: _emptyMessage, loadingMessage: _loadingMessage, className, classes, renderCell, renderHeader: _renderHeader, renderSortIcon: _renderSortIcon, renderFilterIcon: _renderFilterIcon, onRowClick, onRowMouseDown, onRowMouseEnter, getRowId, onScroll, gridId, hideColumnManager, hideGroupControls, }: VirtualizedGridProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export default DataGrid;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GridClasses } from './types';
|
|
2
|
+
export interface PaginationProps {
|
|
3
|
+
pageIndex: number;
|
|
4
|
+
pageSize: number;
|
|
5
|
+
totalRows: number;
|
|
6
|
+
onPageChange: (page: number) => void;
|
|
7
|
+
onPageSizeChange?: (size: number) => void;
|
|
8
|
+
pageSizeOptions?: number[];
|
|
9
|
+
classes?: GridClasses;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function Pagination({ pageIndex, pageSize, totalRows, onPageChange, onPageSizeChange, pageSizeOptions, classes, className, }: PaginationProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { RenderOptions, RenderResult } from '@testing-library/react';
|
|
3
|
+
import { default as userEvent } from '@testing-library/user-event';
|
|
4
|
+
export * from '@testing-library/react';
|
|
5
|
+
interface CustomRenderResult extends RenderResult {
|
|
6
|
+
user: ReturnType<typeof userEvent.setup>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Custom render function that wraps the component
|
|
10
|
+
* and sets up userEvent.
|
|
11
|
+
*
|
|
12
|
+
* @param ui - The React component to render
|
|
13
|
+
* @param options - Additional render options
|
|
14
|
+
* @returns The render result with added user property for userEvent
|
|
15
|
+
*/
|
|
16
|
+
declare function render(ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>): CustomRenderResult;
|
|
17
|
+
export { render };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ColumnDef, GridClasses } from '../types';
|
|
2
|
+
interface ColumnManagerProps<T> {
|
|
3
|
+
columns: ColumnDef<T>[];
|
|
4
|
+
visibleColumns: string[];
|
|
5
|
+
toggleColumnVisibility: (columnId: string, visible: boolean) => void;
|
|
6
|
+
resetGridPreferences: () => void;
|
|
7
|
+
align?: 'start' | 'center' | 'end';
|
|
8
|
+
showResetButton?: boolean;
|
|
9
|
+
className?: string;
|
|
10
|
+
classes?: GridClasses;
|
|
11
|
+
}
|
|
12
|
+
export declare function ColumnManager<T>({ columns, visibleColumns, toggleColumnVisibility, resetGridPreferences, align, showResetButton, className, classes, }: ColumnManagerProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ColumnDef, GridClasses } from '../types';
|
|
2
|
+
interface GroupManagerProps<T> {
|
|
3
|
+
columns: ColumnDef<T>[];
|
|
4
|
+
groupByColumns: string[];
|
|
5
|
+
updateGroupByColumns: (groupByColumns: string[]) => void;
|
|
6
|
+
align?: 'start' | 'center' | 'end';
|
|
7
|
+
className?: string;
|
|
8
|
+
classes?: GridClasses;
|
|
9
|
+
}
|
|
10
|
+
export declare function GroupManager<T>({ columns, groupByColumns, updateGroupByColumns, align, className, classes, }: GroupManagerProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Syne:wght@400;500;600;700;800&family=Manrope:wght@300;400;500;600;700&display=swap";:root{--vg-charcoal: #1a1a1a;--vg-charcoal-light: #2a2a2a;--vg-ivory: #faf8f6;--vg-ivory-dark: #f0ede9;--vg-copper: #b87333;--vg-copper-light: #d4935a;--vg-copper-dark: #9a5e28;--vg-border: rgba(184, 115, 51, .15);--vg-shadow: rgba(26, 26, 26, .08);--vg-font-display: "Manrope", sans-serif;--vg-font-ui: "Syne", sans-serif;--vg-spacing-xs: .5rem;--vg-spacing-sm: .75rem;--vg-spacing-md: 1.25rem;--vg-spacing-lg: 2rem}.virtualized-grid-container{position:relative;width:100%;height:100%;background:var(--vg-ivory);border:1px solid var(--vg-border);border-radius:2px;overflow:hidden;font-family:var(--vg-font-ui);isolation:isolate;display:flex;flex-direction:column}.grain-overlay{position:absolute;inset:0;pointer-events:none;opacity:.03;mix-blend-mode:overlay;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='2.5' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");z-index:10}.virtualized-grid-header{display:flex;background:linear-gradient(180deg,var(--vg-charcoal) 0%,var(--vg-charcoal-light) 100%);border-bottom:2px solid var(--vg-copper);position:sticky;top:0;z-index:5;box-shadow:0 4px 12px var(--vg-shadow)}.virtualized-grid-header-cell{position:relative;padding:var(--vg-spacing-md) var(--vg-spacing-md);display:flex;flex-direction:column;justify-content:center;border-right:1px solid rgba(184,115,51,.2);animation:fadeInDown .6s cubic-bezier(.16,1,.3,1) both;overflow:hidden}.virtualized-grid-header-cell:last-child{border-right:none}.header-text{font-family:var(--vg-font-ui);font-size:.75rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--vg-ivory);position:relative;z-index:1}.header-accent{position:absolute;bottom:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent 0%,var(--vg-copper) 50%,transparent 100%);opacity:0;transition:opacity .4s cubic-bezier(.16,1,.3,1)}.virtualized-grid-header-cell:hover .header-accent{opacity:1}.virtualized-grid-body{overflow:auto;flex:1;position:relative;scrollbar-width:thin;scrollbar-color:var(--vg-copper) var(--vg-ivory-dark);user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.virtualized-grid-body::-webkit-scrollbar{width:12px;height:12px}.virtualized-grid-body::-webkit-scrollbar-track{background:var(--vg-ivory-dark)}.virtualized-grid-body::-webkit-scrollbar-thumb{background:var(--vg-copper);border-radius:6px;border:2px solid var(--vg-ivory-dark);transition:background .3s ease}.virtualized-grid-body::-webkit-scrollbar-thumb:hover{background:var(--vg-copper-dark)}.virtualized-grid-row{display:flex;border-bottom:1px solid var(--vg-border);background-color:var(--vg-ivory);transition:all .3s cubic-bezier(.16,1,.3,1);position:relative;isolation:isolate}.virtualized-grid-row.clickable{cursor:pointer}.virtualized-grid-row:hover:not([class*=bg-]):not([style*=background]){background-color:var(--vg-ivory-dark)}.virtualized-grid-row:hover{border-bottom-color:var(--vg-copper-light);box-shadow:0 2px 8px var(--vg-shadow);z-index:1}.virtualized-grid-row.selected{background-color:#b873331f;border-bottom-color:var(--vg-copper);box-shadow:inset 3px 0 0 var(--vg-copper),0 2px 8px var(--vg-shadow);z-index:2}.virtualized-grid-row.selected:hover{background-color:#b873332e;box-shadow:inset 3px 0 0 var(--vg-copper-dark),0 2px 12px var(--vg-shadow)}.virtualized-grid-row.selected .cell-content{color:var(--vg-copper-dark);font-weight:600}.virtualized-grid-row:hover .row-shimmer{opacity:1;transform:translate(100%)}.row-shimmer{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(90deg,transparent 0%,rgba(184,115,51,.1) 50%,transparent 100%);opacity:0;transform:translate(-100%);transition:transform .8s cubic-bezier(.16,1,.3,1),opacity .3s ease;pointer-events:none;z-index:-1}.virtualized-grid-cell{padding:var(--vg-spacing-md);display:flex;align-items:center;border-right:1px solid rgba(184,115,51,.08);position:relative}.virtualized-grid-cell:last-child{border-right:none}.cell-content{font-family:var(--vg-font-display);font-size:.9375rem;font-weight:500;color:var(--vg-charcoal);line-height:1.5;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .3s cubic-bezier(.16,1,.3,1)}.virtualized-grid-row:hover:not([class*=text-]) .cell-content:not([class*=text-]){color:var(--vg-copper-dark)}.virtualized-grid-row:hover .cell-content{transform:translate(2px)}.skeleton-shimmer{background:linear-gradient(90deg,var(--vg-ivory-dark) 0%,var(--vg-ivory) 50%,var(--vg-ivory-dark) 100%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:4px}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.virtualized-grid-container.loading{pointer-events:none}.virtualized-grid-container.loading:after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent 0%,rgba(250,248,246,.8) 50%,transparent 100%);animation:shimmer 2s infinite;z-index:20}@media(max-width:768px){.virtualized-grid-header-cell,.virtualized-grid-cell{padding:var(--vg-spacing-sm)}.header-text{font-size:.625rem}.cell-content{font-size:1rem}}.virtualized-grid-context-menu{position:fixed;z-index:50;background:var(--vg-ivory);border:2px solid var(--vg-copper);border-radius:2px;box-shadow:0 8px 24px #1a1a1a26,0 2px 8px #b873331a;padding:4px 0;min-width:180px;animation:contextMenuFadeIn .15s cubic-bezier(.16,1,.3,1);font-family:var(--vg-font-ui)}.virtualized-grid-context-menu button{width:100%;padding:10px 16px;text-align:left;border:none;background:none;cursor:pointer;font-family:var(--vg-font-display);font-size:.875rem;font-weight:500;color:var(--vg-charcoal);transition:all .2s cubic-bezier(.16,1,.3,1);position:relative;overflow:hidden}.virtualized-grid-context-menu button:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--vg-copper);transform:translate(-3px);transition:transform .2s cubic-bezier(.16,1,.3,1)}.virtualized-grid-context-menu button:hover{background:linear-gradient(90deg,rgba(184,115,51,.08) 0%,transparent 100%);color:var(--vg-copper-dark);padding-left:20px}.virtualized-grid-context-menu button:hover:before{transform:translate(0)}.virtualized-grid-context-menu button:active{background:#b873331f}.virtualized-grid-context-menu-divider{height:1px;background:linear-gradient(90deg,transparent 0%,var(--vg-copper) 50%,transparent 100%);opacity:.3;margin:4px 8px}.virtualized-grid-context-menu-header{padding:8px 16px 4px;font-family:var(--vg-font-ui);font-size:.6875rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--vg-copper)}.virtualized-grid-context-menu button.danger{color:#b91c1c}.virtualized-grid-context-menu button.danger:hover{background:linear-gradient(90deg,rgba(185,28,28,.08) 0%,transparent 100%);color:#991b1b}.virtualized-grid-context-menu button.danger:before{background:#b91c1c}@keyframes contextMenuFadeIn{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@media(prefers-contrast:high){.virtualized-grid-container{border-width:2px}.virtualized-grid-row{border-bottom-width:2px}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GroupingState } from '../types';
|
|
2
|
+
export interface GroupRow {
|
|
3
|
+
isGroupRow: true;
|
|
4
|
+
groupKey: string;
|
|
5
|
+
groupValue: any;
|
|
6
|
+
columnId: string;
|
|
7
|
+
depth: number;
|
|
8
|
+
count: number;
|
|
9
|
+
children: any[];
|
|
10
|
+
}
|
|
11
|
+
export declare function useDataGrouping<T>(data: T[], groupingState: GroupingState, _idAccessor: (row: T) => string): {
|
|
12
|
+
rows: (GroupRow | T)[];
|
|
13
|
+
flattenedRows: any[];
|
|
14
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GridPreferences } from '../types';
|
|
2
|
+
export declare function useGridPersistence(gridId: string, columns: {
|
|
3
|
+
id: string;
|
|
4
|
+
}[], defaultColumnWidth?: number): {
|
|
5
|
+
preferences: GridPreferences;
|
|
6
|
+
updateColumnWidth: (columnId: string, width: number) => void;
|
|
7
|
+
updateColumnOrder: (newOrder: string[]) => void;
|
|
8
|
+
toggleColumnVisibility: (columnId: string, visible: boolean) => void;
|
|
9
|
+
updateGroupByColumns: (groupByColumns: string[]) => void;
|
|
10
|
+
toggleGroupExpanded: (groupKey: string, expanded: boolean) => void;
|
|
11
|
+
resetPreferences: () => void;
|
|
12
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CellPosition {
|
|
2
|
+
rowId: string;
|
|
3
|
+
columnId: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function useSelectCell(): {
|
|
6
|
+
selectedCell: CellPosition | null;
|
|
7
|
+
selectCell: (rowId: string, columnId: string) => void;
|
|
8
|
+
clearSelection: () => void;
|
|
9
|
+
isCellSelected: (rowId: string, columnId: string) => boolean;
|
|
10
|
+
};
|