@opencorestack/opengridx 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/llms.txt ADDED
@@ -0,0 +1,494 @@
1
+ # OpenGridX — AI Agent Context
2
+ # Package: @opencorestack/opengridx
3
+ # Version: 0.1.4
4
+ # Docs: https://opencorestack.github.io/OpenGridX/
5
+ # This file is machine-readable. AI developers: start here.
6
+
7
+ ---
8
+
9
+ ## OVERVIEW
10
+
11
+ OpenGridX is a zero-dependency, high-performance React DataGrid library.
12
+ It matches and extends the feature set of MUI X DataGrid Pro — offered completely free.
13
+
14
+ - **React**: 18+ required
15
+ - **TypeScript**: Full typings shipped in `dist/index.d.ts`
16
+ - **Bundle**: 52 KB gzip (ES module). ExcelJS is optional peer dep (lazy-loaded).
17
+ - **CSS**: Auto-imported via barrel. If unstyled, add: `import '@opencorestack/opengridx/styles'`
18
+
19
+ ---
20
+
21
+ ## INSTALLATION
22
+
23
+ ```bash
24
+ npm install @opencorestack/opengridx
25
+ # Optional — for advanced Excel export only:
26
+ npm install exceljs
27
+ ```
28
+
29
+ ```tsx
30
+ import { DataGrid } from '@opencorestack/opengridx';
31
+ // If grid appears unstyled in your bundler:
32
+ import '@opencorestack/opengridx/styles';
33
+ ```
34
+
35
+ ---
36
+
37
+ ## MINIMAL EXAMPLE
38
+
39
+ ```tsx
40
+ import { DataGrid, GridColDef } from '@opencorestack/opengridx';
41
+
42
+ const columns: GridColDef[] = [
43
+ { field: 'id', headerName: 'ID', width: 70 },
44
+ { field: 'name', headerName: 'Name', width: 180 },
45
+ { field: 'age', headerName: 'Age', width: 100, type: 'number', editable: true },
46
+ ];
47
+ const rows = [
48
+ { id: 1, name: 'Jon Snow', age: 25 },
49
+ { id: 2, name: 'Arya Stark', age: 18 },
50
+ ];
51
+
52
+ export default function App() {
53
+ return <DataGrid rows={rows} columns={columns} height={400} />;
54
+ }
55
+ ```
56
+
57
+ ---
58
+
59
+ ## DataGrid PROPS (DataGridProps<R extends GridRowModel>)
60
+
61
+ ### Required
62
+ | Prop | Type | Description |
63
+ |-----------|------------------|----------------------------------|
64
+ | rows | GridRowModel[] | Data array. Each row needs an id |
65
+ | columns | GridColDef<R>[] | Column definitions |
66
+
67
+ ### Display
68
+ | Prop | Type | Default | Description |
69
+ |-------------------|-----------|---------|----------------------------------------|
70
+ | height | number | 500 | Grid height in pixels |
71
+ | autoHeight | boolean | false | Fit height to rows |
72
+ | rowHeight | number | 52 | Row height in pixels |
73
+ | headerHeight | number | 56 | Header height in pixels |
74
+ | loading | boolean | false | Show skeleton loading overlay |
75
+ | noRowsLabel | string | — | Empty state message |
76
+ | density | 'compact'/'standard'/'comfortable' | 'standard' | Row density |
77
+
78
+ ### Selection
79
+ | Prop | Type | Description |
80
+ |----------------------------|-------------------------------|-------------------------------------|
81
+ | checkboxSelection | boolean | Enable checkbox column |
82
+ | rowSelectionModel | GridRowId[] | Controlled selection |
83
+ | onRowSelectionModelChange | (model: GridRowId[]) => void | Selection change callback |
84
+ | disableRowSelectionOnClick | boolean | Prevent click toggling selection |
85
+
86
+ ### Sorting
87
+ | Prop | Type | Description |
88
+ |-------------------|-----------------------------|----------------------------------|
89
+ | sortModel | GridSortItem[] | Controlled sort state |
90
+ | onSortModelChange | (model: GridSortItem[]) => void | Sort change callback |
91
+ | sortingMode | 'client' / 'server' | Where sorting is applied |
92
+ | disableColumnSorting | boolean | Disable sorting for all columns |
93
+
94
+ ### Filtering
95
+ | Prop | Type | Description |
96
+ |---------------------|--------------------------------|-----------------------------------|
97
+ | filterModel | GridFilterModel | Controlled filter state |
98
+ | onFilterModelChange | (model: GridFilterModel) => void | Filter change callback |
99
+ | filterMode | 'client' / 'server' | Where filtering is applied |
100
+ | disableColumnFilter | boolean | Disable filter for all columns |
101
+
102
+ ### Pagination
103
+ | Prop | Type | Description |
104
+ |-------------------------|-----------------------------------------|----------------------------------|
105
+ | pagination | boolean | Enable client-side pagination |
106
+ | paginationModel | GridPaginationModel | {page, pageSize} controlled |
107
+ | onPaginationModelChange | (model: GridPaginationModel) => void | Pagination change callback |
108
+ | pageSizeOptions | number[] | Available page sizes |
109
+ | paginationMode | 'client' / 'server' / 'infinite' | Pagination mode |
110
+ | rowCount | number | Total rows for server pagination |
111
+
112
+ ### Column Features
113
+ | Prop | Type | Description |
114
+ |---------------------------|---------------------------|-------------------------------------------|
115
+ | pinnedColumns | GridColumnPinning | {left: string[], right: string[]} |
116
+ | onPinnedColumnsChange | (model) => void | Pin change callback |
117
+ | columnVisibilityModel | Record<string, boolean> | {field: false} to hide |
118
+ | onColumnVisibilityModelChange | (model) => void | Visibility change callback |
119
+ | columnOrder | string[] | Controlled column order |
120
+ | onColumnOrderChange | (params) => void | Column reorder callback |
121
+ | disableColumnReorder | boolean | Disable drag-to-reorder |
122
+ | disableColumnResize | boolean | Disable resize handles |
123
+ | columnGroupingModel | GridColumnGroupingModel | Multi-level column header groups |
124
+
125
+ ### Row Features
126
+ | Prop | Type | Description |
127
+ |-------------------|---------------------------|-------------------------------------------|
128
+ | pinnedRows | GridRowPinning | {top: id[], bottom: id[]} |
129
+ | rowReordering | boolean | Enable drag-and-drop row reordering |
130
+ | onRowOrderChange | (params) => void | Row reorder callback |
131
+ | getRowId | (row: R) => GridRowId | Custom row ID accessor (default: row.id) |
132
+ | getRowClassName | (params) => string | Dynamic CSS class per row |
133
+ | getRowHeight | (params) => number | Dynamic row height |
134
+
135
+ ### Cell Editing
136
+ | Prop | Type | Description |
137
+ |-------------------------|----------------------------|-----------------------------------------|
138
+ | processRowUpdate | (newRow, oldRow) => R | Commit edits. Must return updated row |
139
+ | onProcessRowUpdateError | (error) => void | Handle commit errors |
140
+ | isCellEditable | (params) => boolean | Fine-grained editability control |
141
+
142
+ ### Detail Panels (Master-Detail)
143
+ | Prop | Type | Description |
144
+ |-------------------------|----------------------------|-----------------------------------------|
145
+ | getDetailPanelContent | (params) => ReactNode | Render expanded detail row |
146
+ | getDetailPanelHeight | (params) => number / 'auto'| Height of detail panel |
147
+ | expandedRowIds | Set<GridRowId> | Controlled expanded rows |
148
+ | onDetailPanelExpandedRowIdsChange | (ids) => void | Expand/collapse callback |
149
+
150
+ ### Grouping & Aggregation
151
+ | Prop | Type | Description |
152
+ |------------------------|---------------------------|------------------------------------------|
153
+ | rowGroupingModel | string[] | Fields to group by |
154
+ | aggregationModel | GridAggregationModel | {field: 'sum'/'avg'/'min'/'max'/'count'} |
155
+ | getAggregationPosition | (group) => 'footer'/'inline' | Where to render aggregation row |
156
+ | defaultGroupingExpansionDepth | number | Auto-expand depth (default -1 = all) |
157
+
158
+ ### Tree Data
159
+ | Prop | Type | Description |
160
+ |---------------------------|----------------------------|--------------------------------------|
161
+ | treeData | boolean | Enable tree data mode |
162
+ | getTreeDataPath | (row) => string[] | Return path array for each row |
163
+ | defaultGroupingExpansionDepth | number | Same as grouping depth |
164
+
165
+ ### Pivot
166
+ | Prop | Type | Description |
167
+ |----------------|----------------|-----------------------------------------------|
168
+ | pivotMode | boolean | Enable pivot view |
169
+ | pivotModel | GridPivotModel | {rowFields, columnFields, valueFields} |
170
+ | onPivotModelChange | (model) => void | Pivot change callback |
171
+
172
+ ### Server-Side
173
+ | Prop | Type | Description |
174
+ |------------|-----------------|----------------------------------------------------|
175
+ | dataSource | GridDataSource | Adapter for server-side fetching (see below) |
176
+
177
+ ### Styling & Customization
178
+ | Prop | Type | Description |
179
+ |--------------|-----------------------|------------------------------------------|
180
+ | slots | GridSlots | Replace toolbar, pagination, overlays |
181
+ | slotProps | GridSlotProps | Props for slot components |
182
+ | theme | GridTheme | Override theme tokens |
183
+ | sx | React.CSSProperties | Inline styles on the root element |
184
+
185
+ ### Callbacks
186
+ | Prop | Type | Description |
187
+ |-------------------|-----------------------|-------------------------------|
188
+ | onRowClick | (params) => void | Row click |
189
+ | onCellClick | (params) => void | Cell click |
190
+ | onRowDoubleClick | (params) => void | Row double-click |
191
+ | onRowsScrollEnd | (params) => void | Fired near bottom of scroll |
192
+ | onStateChange | (state) => void | Fires on any state change |
193
+
194
+ ### State Persistence
195
+ | Prop | Type | Description |
196
+ |--------------|------------------|----------------------------------------------|
197
+ | initialState | GridInitialState | Restore column widths, sort, filter on mount |
198
+ | apiRef | RefObject<GridApi> | Attach imperative API handle |
199
+
200
+ ### List View
201
+ | Prop | Type | Description |
202
+ |----------------|--------------------|---------------------------------------------|
203
+ | listView | boolean | Render as card/list instead of table |
204
+ | listViewColumn | GridListViewColDef | Defines the card renderer |
205
+
206
+ ---
207
+
208
+ ## GridColDef<R> PROPERTIES
209
+
210
+ | Property | Type | Description |
211
+ |-------------------|--------------------------------------------------------|--------------------------------------------|
212
+ | field | string | **Required.** Key in row data |
213
+ | headerName | string | Column label |
214
+ | width | number / string (px or %) | Column width |
215
+ | flex | number | Flex grow factor |
216
+ | minWidth | number | Minimum width constraint |
217
+ | maxWidth | number | Maximum width constraint |
218
+ | type | 'string'/'number'/'boolean'/'date'/'singleSelect'/'image' | Data type |
219
+ | editable | boolean | Enable double-click editing |
220
+ | valueOptions | string[] / {value, label}[] | Options for singleSelect type |
221
+ | renderCell | (params: GridRenderCellParams) => ReactNode | Custom cell renderer |
222
+ | renderHeader | (params: GridRenderHeaderParams) => ReactNode | Custom header renderer |
223
+ | renderEditCell | (params: GridRenderCellParams) => ReactNode | Custom editor component |
224
+ | valueGetter | ({row, field, value}) => any | Computed cell value |
225
+ | valueFormatter | ({value, row, field}) => string | Format display value |
226
+ | cellClassName | string / (params) => string | CSS class on cells |
227
+ | headerClassName | string | CSS class on header cell |
228
+ | colSpan | number / (params) => number | Cell column span |
229
+ | rowSpan | number / (params) => number | Cell row span |
230
+ | align | 'left'/'center'/'right' | Cell content alignment |
231
+ | headerAlign | 'left'/'center'/'right' | Header content alignment |
232
+ | sortable | boolean (default true) | Enable sorting |
233
+ | filterable | boolean (default true) | Enable filtering |
234
+ | resizable | boolean (default true) | Enable resize handle |
235
+ | hideable | boolean (default true) | Allow hiding via toolbar |
236
+ | pinnable | boolean (default true) | Allow pinning via column menu |
237
+ | disableColumnMenu | boolean | Hide the ⋮ column menu button |
238
+
239
+ ---
240
+
241
+ ## GridApi METHODS (via useGridApiRef)
242
+
243
+ ```tsx
244
+ import { useGridApiRef } from '@opencorestack/opengridx';
245
+ const apiRef = useGridApiRef();
246
+ <DataGrid apiRef={apiRef} ... />
247
+
248
+ // Row access
249
+ apiRef.current.getRow(id) // → GridRowModel | null
250
+ apiRef.current.getAllRows() // → GridRowModel[]
251
+ apiRef.current.getVisibleRows() // → GridRowModel[]
252
+
253
+ // Column access
254
+ apiRef.current.getColumn(field) // → GridColDef | null
255
+ apiRef.current.getAllColumns() // → GridColDef[]
256
+ apiRef.current.getVisibleColumns() // → GridColDef[]
257
+
258
+ // Selection
259
+ apiRef.current.selectRow(id, isSelected?) // select/deselect a row
260
+ apiRef.current.selectRows(ids, isSelected?) // bulk select
261
+ apiRef.current.getSelectedRows() // → GridRowId[]
262
+
263
+ // Sort / Filter
264
+ apiRef.current.sortColumn(field, 'asc' | 'desc' | null)
265
+ apiRef.current.getSortModel() // → GridSortItem[]
266
+ apiRef.current.setFilterModel(model)
267
+
268
+ // Pagination
269
+ apiRef.current.setPage(page)
270
+ apiRef.current.setPageSize(size)
271
+
272
+ // Clipboard
273
+ apiRef.current.copySelectedRows() // → Promise<void> (TSV to clipboard)
274
+
275
+ // Aggregation (when aggregationModel is set)
276
+ apiRef.current.getAggregationResult() // → GridAggregationResult | null
277
+ ```
278
+
279
+ ---
280
+
281
+ ## CELL EDITING — FULL EXAMPLE
282
+
283
+ ```tsx
284
+ const [rows, setRows] = useState(initialRows);
285
+
286
+ const processRowUpdate = (newRow, oldRow) => {
287
+ setRows(prev => prev.map(r => r.id === newRow.id ? newRow : r));
288
+ return newRow; // Must return the committed row
289
+ };
290
+
291
+ <DataGrid
292
+ rows={rows}
293
+ columns={[
294
+ { field: 'name', headerName: 'Name', editable: true },
295
+ { field: 'age', headerName: 'Age', editable: true, type: 'number' },
296
+ { field: 'role', headerName: 'Role', editable: true, type: 'singleSelect',
297
+ valueOptions: ['Engineer', 'Manager', 'Analyst'] },
298
+ ]}
299
+ processRowUpdate={processRowUpdate}
300
+ onProcessRowUpdateError={console.error}
301
+ />
302
+ ```
303
+
304
+ ---
305
+
306
+ ## SERVER-SIDE DATA SOURCE
307
+
308
+ ```tsx
309
+ import { useGridDataSource } from '@opencorestack/opengridx';
310
+
311
+ const dataSource: GridDataSource = {
312
+ getRows: async ({ page, pageSize, sortModel, filterModel }) => {
313
+ const data = await fetch(`/api/rows?page=${page}&size=${pageSize}`).then(r => r.json());
314
+ return { rows: data.items, rowCount: data.total };
315
+ },
316
+ // Optional: lazy-load children for server-side tree data
317
+ getChildren: async ({ row }) => {
318
+ return fetch(`/api/rows/${row.id}/children`).then(r => r.json());
319
+ }
320
+ };
321
+
322
+ <DataGrid
323
+ columns={columns}
324
+ rows={[]} // empty — data comes from dataSource
325
+ dataSource={dataSource}
326
+ paginationMode="server"
327
+ sortingMode="server"
328
+ filterMode="server"
329
+ rowCount={1000}
330
+ />
331
+ ```
332
+
333
+ ---
334
+
335
+ ## THEMING
336
+
337
+ ```tsx
338
+ import { DataGridThemeProvider, darkTheme } from '@opencorestack/opengridx';
339
+
340
+ // Built-in themes: darkTheme, roseTheme, emeraldTheme, amberTheme, compactTheme
341
+ <DataGridThemeProvider theme={darkTheme}>
342
+ <DataGrid rows={rows} columns={columns} />
343
+ </DataGridThemeProvider>
344
+
345
+ // Custom theme override:
346
+ const myTheme = {
347
+ colors: {
348
+ primary: '#6366f1',
349
+ headerBackground: '#1e1e2e',
350
+ rowHover: '#2a2a3e',
351
+ }
352
+ };
353
+ <DataGridThemeProvider theme={myTheme}>
354
+ <DataGrid ... />
355
+ </DataGridThemeProvider>
356
+ ```
357
+
358
+ ---
359
+
360
+ ## SLOTS CUSTOMIZATION
361
+
362
+ ```tsx
363
+ import { GridToolbar } from '@opencorestack/opengridx';
364
+
365
+ // Replace built-in components:
366
+ <DataGrid
367
+ slots={{
368
+ toolbar: MyCustomToolbar,
369
+ pagination: MyPagination,
370
+ noRowsOverlay: EmptyState,
371
+ loadingOverlay: Spinner,
372
+ footer: CustomFooter,
373
+ }}
374
+ slotProps={{
375
+ toolbar: { onExport: () => apiRef.current.copySelectedRows() },
376
+ }}
377
+ />
378
+ ```
379
+
380
+ ---
381
+
382
+ ## STATE PERSISTENCE
383
+
384
+ ```tsx
385
+ import { useGridStateStorage } from '@opencorestack/opengridx';
386
+
387
+ function MyGrid() {
388
+ const { initialState, handleStateChange } = useGridStateStorage('my-grid-v1');
389
+ return (
390
+ <DataGrid
391
+ initialState={initialState}
392
+ onStateChange={handleStateChange}
393
+ rows={rows}
394
+ columns={columns}
395
+ />
396
+ );
397
+ }
398
+ ```
399
+
400
+ ---
401
+
402
+ ## EXPORT UTILITIES
403
+
404
+ ```tsx
405
+ import {
406
+ exportToCsv,
407
+ exportToExcel, // HTML-based .xlsx — zero deps
408
+ exportToExcelAdvanced, // Rich .xlsx binary — requires: npm install exceljs
409
+ exportToJson,
410
+ printGrid,
411
+ } from '@opencorestack/opengridx';
412
+
413
+ exportToCsv(rows, columns, { fileName: 'export.csv' });
414
+ exportToExcel(rows, columns, { fileName: 'export.xlsx' });
415
+ exportToExcelAdvanced(rows, columns, {
416
+ fileName: 'export.xlsx',
417
+ sheetName: 'Data',
418
+ columnStyles: {
419
+ avatar: { embedImage: true, imageWidth: 32, imageHeight: 32 }
420
+ }
421
+ });
422
+ exportToJson(rows, columns, { fileName: 'export.json' });
423
+ printGrid(rows, columns, 'My Report Title');
424
+ ```
425
+
426
+ ---
427
+
428
+ ## CSS CUSTOMIZATION
429
+
430
+ All CSS variables use the `--ogx-` prefix. Set them on the grid wrapper:
431
+
432
+ ```css
433
+ .my-grid-wrapper {
434
+ --ogx-color-primary: #6366f1;
435
+ --ogx-color-header-bg: #1e1e2e;
436
+ --ogx-color-row-hover: rgba(99, 102, 241, 0.08);
437
+ --ogx-color-border: #2a2a3e;
438
+ --ogx-font-size-cell: 13px;
439
+ --ogx-border-radius: 8px;
440
+ }
441
+ ```
442
+
443
+ All class names use the `ogx__` BEM prefix, e.g.:
444
+ - `ogx__row`, `ogx__row--selected`, `ogx__row--even`
445
+ - `ogx__cell`, `ogx__cell--focused`, `ogx__cell--editing`
446
+ - `ogx__header-cell`, `ogx__header-cell--sorted`
447
+
448
+ ---
449
+
450
+ ## TYPE REFERENCE
451
+
452
+ ```ts
453
+ type GridRowModel = Record<string, any> & { id: GridRowId };
454
+ type GridRowId = string | number;
455
+ type GridSortDirection = 'asc' | 'desc' | null;
456
+ type GridPinnedPosition = 'left' | 'right' | null;
457
+
458
+ interface GridSortItem { field: string; sort: 'asc' | 'desc'; }
459
+ interface GridFilterItem { field: string; operator: string; value: any; }
460
+ interface GridFilterModel { items: GridFilterItem[]; logicOperator?: 'and' | 'or'; }
461
+ interface GridPaginationModel { page: number; pageSize: number; }
462
+ interface GridColumnPinning { left?: string[]; right?: string[]; }
463
+ interface GridRowPinning { top?: GridRowId[]; bottom?: GridRowId[]; }
464
+
465
+ interface GridRenderCellParams<R = GridRowModel> {
466
+ value: any; row: R; field: string;
467
+ colDef: GridColDef<R>; rowIndex: number; colIndex: number;
468
+ }
469
+
470
+ interface GridDataSource {
471
+ getRows: (params: GridGetRowsParams) => Promise<GridGetRowsResponse>;
472
+ getChildren?: (params: { row: GridRowModel }) => Promise<GridRowModel[]>;
473
+ }
474
+ interface GridGetRowsParams {
475
+ page: number; pageSize: number;
476
+ sortModel: GridSortItem[]; filterModel: GridFilterModel;
477
+ }
478
+ interface GridGetRowsResponse { rows: GridRowModel[]; rowCount: number; }
479
+ ```
480
+
481
+ ---
482
+
483
+ ## KEY NOTES FOR AI AGENTS
484
+
485
+ 1. **Always `return newRow`** from `processRowUpdate` — failing to do so breaks the internal state update.
486
+ 2. **`getRowId` default is `row.id`** — if your data uses a different key, always pass `getRowId`.
487
+ 3. **CSS must be imported**: if grid is unstyled, add `import '@opencorestack/opengridx/styles'` to app root.
488
+ 4. **ExcelJS is optional**: `exportToExcelAdvanced` requires `npm install exceljs` separately (peer dep).
489
+ 5. **`dataSource` + `rows={[]}`**: when using server-side mode, pass empty `rows` array — the grid fills via `dataSource.getRows`.
490
+ 6. **`flex` columns**: columns with `flex` expand to fill available space. Setting `width` on a flex column sets its base size but it will still flex.
491
+ 7. **`singleSelect` editing**: for dropdown editors in cells, set `type: 'singleSelect'` and provide `valueOptions`.
492
+ 8. **`initialState.columns.columnWidths`**: accepts `Record<string, number>` to restore saved column widths.
493
+ 9. **`pinnedColumns`** and **`columnWidths`** are independent state — pinning does not reset widths.
494
+ 10. **Aggregation** requires `rowGroupingModel` OR a global footer via `getAggregationPosition={() => 'footer'}`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencorestack/opengridx",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "OpenGridX: High-performance React data infrastructure. Unlock advanced Row Grouping, Excel Export, and Column Pinning without the usual \"Pro\" gatekeeping. Built for speed, scale, and complete architectural freedom. Fully open, virtualization-ready, and feature-complete.",
5
5
  "type": "module",
6
6
  "main": "./dist/opengridx.umd.js",
@@ -12,13 +12,17 @@
12
12
  "import": "./dist/opengridx.es.js",
13
13
  "require": "./dist/opengridx.umd.js"
14
14
  },
15
- "./styles": "./dist/opengridx.css"
15
+ "./styles": {
16
+ "types": "./dist/opengridx.css.d.ts",
17
+ "default": "./dist/opengridx.css"
18
+ }
16
19
  },
17
20
  "files": [
18
21
  "dist",
19
22
  "README.md",
20
23
  "LICENSE",
21
- "CHANGELOG.md"
24
+ "CHANGELOG.md",
25
+ "llms.txt"
22
26
  ],
23
27
  "sideEffects": [
24
28
  "**/*.css",
@@ -27,7 +31,7 @@
27
31
  "scripts": {
28
32
  "dev": "vite",
29
33
  "build": "tsc --project tsconfig.build.json && vite build",
30
- "build:lib": "tsc --project tsconfig.build.json && vite build --config vite.config.lib.js",
34
+ "build:lib": "tsc --project tsconfig.build.json && vite build --config vite.config.lib.js && cp lib/styles/opengridx.css.d.ts dist/opengridx.css.d.ts",
31
35
  "lint": "eslint .",
32
36
  "preview": "vite preview",
33
37
  "prepublishOnly": "npm run build:lib"