@dynostack/react-grid 0.3.1 → 0.4.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 -6
- package/dist/index.cjs +69 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -11
- package/dist/index.d.ts +24 -11
- package/dist/index.js +70 -28
- package/dist/index.js.map +1 -1
- package/dist/styles.css +8 -0
- package/dist/tailwind-content.js +3 -0
- package/package.json +9 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { Column, RowData, ColumnDef, SortingState, ColumnFiltersState, ColumnPinningState, VisibilityState, Table, CellContext, FilterFn } from '@tanstack/react-table';
|
|
3
1
|
import * as React$1 from 'react';
|
|
4
2
|
import { CSSProperties } from 'react';
|
|
3
|
+
import { Column, RowData, ColumnDef, SortingState, ColumnFiltersState, ColumnPinningState, VisibilityState, Table, CellContext, FilterFn } from '@tanstack/react-table';
|
|
5
4
|
|
|
6
5
|
type RowActionId = "view" | "edit" | "duplicate" | "delete" | string;
|
|
7
6
|
type CustomRowAction<TData> = {
|
|
@@ -20,7 +19,7 @@ type DataTableRowActionsProps<TData> = {
|
|
|
20
19
|
onSaveEdit?: () => void;
|
|
21
20
|
onCancelEdit?: () => void;
|
|
22
21
|
};
|
|
23
|
-
declare function DataTableRowActions<TData>({ row, actions, customActions, onAction, isEditing, onSaveEdit, onCancelEdit, }: DataTableRowActionsProps<TData>):
|
|
22
|
+
declare function DataTableRowActions<TData>({ row, actions, customActions, onAction, isEditing, onSaveEdit, onCancelEdit, }: DataTableRowActionsProps<TData>): React$1.JSX.Element;
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
25
|
* CSS variable overrides for a single DataTable instance.
|
|
@@ -157,7 +156,7 @@ type ViewSheetLabels = {
|
|
|
157
156
|
type ViewSheetConfig<TData> = {
|
|
158
157
|
/** Side of the screen to slide in from. Defaults to "right". */
|
|
159
158
|
side?: SheetSide;
|
|
160
|
-
/** Initial
|
|
159
|
+
/** Initial layout density. Defaults to "compact" (more fields per row). */
|
|
161
160
|
defaultDensity?: ViewSheetDensity;
|
|
162
161
|
/** Hide the density tabs entirely if you want a fixed layout. */
|
|
163
162
|
hideDensityTabs?: boolean;
|
|
@@ -357,6 +356,18 @@ type DataTableProps<TData extends {
|
|
|
357
356
|
pageSizeOptions?: number[];
|
|
358
357
|
initialColumnPinning?: ColumnPinningState;
|
|
359
358
|
initialColumnVisibility?: VisibilityState;
|
|
359
|
+
/** Initial sort order. */
|
|
360
|
+
initialSorting?: SortingState;
|
|
361
|
+
/** Observe selected row objects (loaded rows only in server mode). */
|
|
362
|
+
onSelectionChange?: (rows: TData[]) => void;
|
|
363
|
+
/** Accessible table name. */
|
|
364
|
+
ariaLabel?: string;
|
|
365
|
+
/** Alternating row backgrounds. */
|
|
366
|
+
striped?: boolean;
|
|
367
|
+
/** Keep headers visible inside a vertically constrained table. */
|
|
368
|
+
stickyHeader?: boolean;
|
|
369
|
+
/** Scroll viewport height, e.g. "480px". */
|
|
370
|
+
maxHeight?: React.CSSProperties["maxHeight"];
|
|
360
371
|
/** Optional controlled global filter (for cross-tab persistence). */
|
|
361
372
|
globalFilter?: string;
|
|
362
373
|
onGlobalFilterChange?: (value: string) => void;
|
|
@@ -396,7 +407,7 @@ type DataTableProps<TData extends {
|
|
|
396
407
|
};
|
|
397
408
|
declare function DataTable<TData extends {
|
|
398
409
|
id: string | number;
|
|
399
|
-
}>({ data, columns, dataSource, isLoading, isFetching, onRefresh, totalRecords, exportFileName, enableSelection, renderSubRow, getSubRows, rowActions, customRowActions, onRowAction, onCellEdit, onRowSave, onAddRow, onBulkDelete, initialPageSize, pageSizeOptions, initialColumnPinning, initialColumnVisibility, globalFilter: globalFilterProp, onGlobalFilterChange, className, toolbarSlot, features, labels: labelsProp, density, theme, isolate, onView, onDelete, viewSheet, confirmDelete, }: DataTableProps<TData>):
|
|
410
|
+
}>({ data, columns, dataSource, isLoading, isFetching, onRefresh, totalRecords, exportFileName, enableSelection, renderSubRow, getSubRows, rowActions, customRowActions, onRowAction, onCellEdit, onRowSave, onAddRow, onBulkDelete, initialPageSize, pageSizeOptions, initialColumnPinning, initialColumnVisibility, initialSorting, onSelectionChange, ariaLabel, striped, stickyHeader, maxHeight, globalFilter: globalFilterProp, onGlobalFilterChange, className, toolbarSlot, features, labels: labelsProp, density, theme, isolate, onView, onDelete, viewSheet, confirmDelete, }: DataTableProps<TData>): React$1.JSX.Element;
|
|
400
411
|
|
|
401
412
|
/**
|
|
402
413
|
* Shared portal container for every overlay inside a DataTable (popover,
|
|
@@ -426,13 +437,13 @@ type Props$2<TData, TValue> = {
|
|
|
426
437
|
column: Column<TData, TValue>;
|
|
427
438
|
title: string;
|
|
428
439
|
};
|
|
429
|
-
declare function DataTableColumnHeader<TData, TValue>({ column, title, }: Props$2<TData, TValue>):
|
|
440
|
+
declare function DataTableColumnHeader<TData, TValue>({ column, title, }: Props$2<TData, TValue>): React$1.JSX.Element;
|
|
430
441
|
|
|
431
442
|
type Props$1<TData> = {
|
|
432
443
|
table: Table<TData>;
|
|
433
444
|
pageSizeOptions?: number[];
|
|
434
445
|
};
|
|
435
|
-
declare function DataTablePagination<TData>({ table, pageSizeOptions, }: Props$1<TData>):
|
|
446
|
+
declare function DataTablePagination<TData>({ table, pageSizeOptions, }: Props$1<TData>): React$1.JSX.Element;
|
|
436
447
|
|
|
437
448
|
type ToolbarFeatureFlags = {
|
|
438
449
|
search?: boolean;
|
|
@@ -468,7 +479,7 @@ type Props<TData> = {
|
|
|
468
479
|
features?: ToolbarFeatureFlags;
|
|
469
480
|
labels?: ToolbarLabels;
|
|
470
481
|
};
|
|
471
|
-
declare function DataTableToolbar<TData>({ table, totalRecords, isFetching, onRefresh, onAddRow, onBulkDelete, exportFileName, globalFilter, onGlobalFilterChange, toolbarSlot, features, labels: labelsProp, }: Props<TData>):
|
|
482
|
+
declare function DataTableToolbar<TData>({ table, totalRecords, isFetching, onRefresh, onAddRow, onBulkDelete, exportFileName, globalFilter, onGlobalFilterChange, toolbarSlot, features, labels: labelsProp, }: Props<TData>): React$1.JSX.Element;
|
|
472
483
|
|
|
473
484
|
type EditableCellProps<TData, TValue> = CellContext<TData, TValue> & {
|
|
474
485
|
isEditing: boolean;
|
|
@@ -478,7 +489,7 @@ type EditableCellProps<TData, TValue> = CellContext<TData, TValue> & {
|
|
|
478
489
|
onCancel: () => void;
|
|
479
490
|
onStartEdit: () => void;
|
|
480
491
|
};
|
|
481
|
-
declare function EditableCell<TData, TValue>({ getValue, column, row, isEditing, autoOpen, onCommit, onCancel, onStartEdit, }: EditableCellProps<TData, TValue>):
|
|
492
|
+
declare function EditableCell<TData, TValue>({ getValue, column, row, isEditing, autoOpen, onCommit, onCancel, onStartEdit, }: EditableCellProps<TData, TValue>): React$1.JSX.Element;
|
|
482
493
|
|
|
483
494
|
type TextOp = "contains" | "notContains" | "equals" | "notEqual" | "startsWith" | "endsWith" | "blank" | "notBlank";
|
|
484
495
|
type NumberOp = "equals" | "notEqual" | "lessThan" | "lessThanOrEqual" | "greaterThan" | "greaterThanOrEqual" | "inRange" | "blank" | "notBlank";
|
|
@@ -507,9 +518,11 @@ type CommonProps<TData, TValue> = {
|
|
|
507
518
|
column: Column<TData, TValue>;
|
|
508
519
|
onClose: () => void;
|
|
509
520
|
};
|
|
510
|
-
declare function ColumnFilterPanel<TData, TValue>(props: CommonProps<TData, TValue>):
|
|
521
|
+
declare function ColumnFilterPanel<TData, TValue>(props: CommonProps<TData, TValue>): React$1.JSX.Element | null;
|
|
511
522
|
|
|
523
|
+
/** Neutralize spreadsheet formulas in untrusted text; preserve real numbers. */
|
|
524
|
+
declare function sanitizeSpreadsheetValue(value: unknown): string;
|
|
512
525
|
declare function exportToCsv<TData>(table: Table<TData>, fileName?: string): void;
|
|
513
526
|
declare function exportToExcel<TData>(table: Table<TData>, fileName?: string): void;
|
|
514
527
|
|
|
515
|
-
export { type AdvFilter, type CellEditorType, ColumnFilterPanel, type Combine, type Condition, type ConfirmDeleteConfig, type ConfirmDeleteContext, type CustomRowAction, DataTable, type DataTableColumn, DataTableColumnHeader, type DataTableDataSource, type DataTableDataSourceResult, type DataTableDensity, type DataTableErrorContext, type DataTableFeatures, type DataTableFetchParams, type DataTableLabels, type DataTableModedTheme, DataTablePagination, type DataTableProps, DataTableRowActions, type DataTableRowActionsProps, type DataTableTheme, type DataTableThemeName, type DataTableTokens, DataTableToolbar, type DateOp, EditableCell, type FilterType, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, type NumberOp, PortalContainerContext, type RowAction, type RowActionId, type SelectOption, type SetFilter, type TextOp, type ViewSheetConfig, type ViewSheetDensity, type ViewSheetLabels, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle, usePortalContainer };
|
|
528
|
+
export { type AdvFilter, type CellEditorType, ColumnFilterPanel, type Combine, type Condition, type ConfirmDeleteConfig, type ConfirmDeleteContext, type CustomRowAction, DataTable, type DataTableColumn, DataTableColumnHeader, type DataTableDataSource, type DataTableDataSourceResult, type DataTableDensity, type DataTableErrorContext, type DataTableFeatures, type DataTableFetchParams, type DataTableLabels, type DataTableModedTheme, DataTablePagination, type DataTableProps, DataTableRowActions, type DataTableRowActionsProps, type DataTableTheme, type DataTableThemeName, type DataTableTokens, DataTableToolbar, type DateOp, EditableCell, type FilterType, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, type NumberOp, PortalContainerContext, type RowAction, type RowActionId, type SelectOption, type SetFilter, type TextOp, type ViewSheetConfig, type ViewSheetDensity, type ViewSheetLabels, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, sanitizeSpreadsheetValue, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle, usePortalContainer };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { Column, RowData, ColumnDef, SortingState, ColumnFiltersState, ColumnPinningState, VisibilityState, Table, CellContext, FilterFn } from '@tanstack/react-table';
|
|
3
1
|
import * as React$1 from 'react';
|
|
4
2
|
import { CSSProperties } from 'react';
|
|
3
|
+
import { Column, RowData, ColumnDef, SortingState, ColumnFiltersState, ColumnPinningState, VisibilityState, Table, CellContext, FilterFn } from '@tanstack/react-table';
|
|
5
4
|
|
|
6
5
|
type RowActionId = "view" | "edit" | "duplicate" | "delete" | string;
|
|
7
6
|
type CustomRowAction<TData> = {
|
|
@@ -20,7 +19,7 @@ type DataTableRowActionsProps<TData> = {
|
|
|
20
19
|
onSaveEdit?: () => void;
|
|
21
20
|
onCancelEdit?: () => void;
|
|
22
21
|
};
|
|
23
|
-
declare function DataTableRowActions<TData>({ row, actions, customActions, onAction, isEditing, onSaveEdit, onCancelEdit, }: DataTableRowActionsProps<TData>):
|
|
22
|
+
declare function DataTableRowActions<TData>({ row, actions, customActions, onAction, isEditing, onSaveEdit, onCancelEdit, }: DataTableRowActionsProps<TData>): React$1.JSX.Element;
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
25
|
* CSS variable overrides for a single DataTable instance.
|
|
@@ -157,7 +156,7 @@ type ViewSheetLabels = {
|
|
|
157
156
|
type ViewSheetConfig<TData> = {
|
|
158
157
|
/** Side of the screen to slide in from. Defaults to "right". */
|
|
159
158
|
side?: SheetSide;
|
|
160
|
-
/** Initial
|
|
159
|
+
/** Initial layout density. Defaults to "compact" (more fields per row). */
|
|
161
160
|
defaultDensity?: ViewSheetDensity;
|
|
162
161
|
/** Hide the density tabs entirely if you want a fixed layout. */
|
|
163
162
|
hideDensityTabs?: boolean;
|
|
@@ -357,6 +356,18 @@ type DataTableProps<TData extends {
|
|
|
357
356
|
pageSizeOptions?: number[];
|
|
358
357
|
initialColumnPinning?: ColumnPinningState;
|
|
359
358
|
initialColumnVisibility?: VisibilityState;
|
|
359
|
+
/** Initial sort order. */
|
|
360
|
+
initialSorting?: SortingState;
|
|
361
|
+
/** Observe selected row objects (loaded rows only in server mode). */
|
|
362
|
+
onSelectionChange?: (rows: TData[]) => void;
|
|
363
|
+
/** Accessible table name. */
|
|
364
|
+
ariaLabel?: string;
|
|
365
|
+
/** Alternating row backgrounds. */
|
|
366
|
+
striped?: boolean;
|
|
367
|
+
/** Keep headers visible inside a vertically constrained table. */
|
|
368
|
+
stickyHeader?: boolean;
|
|
369
|
+
/** Scroll viewport height, e.g. "480px". */
|
|
370
|
+
maxHeight?: React.CSSProperties["maxHeight"];
|
|
360
371
|
/** Optional controlled global filter (for cross-tab persistence). */
|
|
361
372
|
globalFilter?: string;
|
|
362
373
|
onGlobalFilterChange?: (value: string) => void;
|
|
@@ -396,7 +407,7 @@ type DataTableProps<TData extends {
|
|
|
396
407
|
};
|
|
397
408
|
declare function DataTable<TData extends {
|
|
398
409
|
id: string | number;
|
|
399
|
-
}>({ data, columns, dataSource, isLoading, isFetching, onRefresh, totalRecords, exportFileName, enableSelection, renderSubRow, getSubRows, rowActions, customRowActions, onRowAction, onCellEdit, onRowSave, onAddRow, onBulkDelete, initialPageSize, pageSizeOptions, initialColumnPinning, initialColumnVisibility, globalFilter: globalFilterProp, onGlobalFilterChange, className, toolbarSlot, features, labels: labelsProp, density, theme, isolate, onView, onDelete, viewSheet, confirmDelete, }: DataTableProps<TData>):
|
|
410
|
+
}>({ data, columns, dataSource, isLoading, isFetching, onRefresh, totalRecords, exportFileName, enableSelection, renderSubRow, getSubRows, rowActions, customRowActions, onRowAction, onCellEdit, onRowSave, onAddRow, onBulkDelete, initialPageSize, pageSizeOptions, initialColumnPinning, initialColumnVisibility, initialSorting, onSelectionChange, ariaLabel, striped, stickyHeader, maxHeight, globalFilter: globalFilterProp, onGlobalFilterChange, className, toolbarSlot, features, labels: labelsProp, density, theme, isolate, onView, onDelete, viewSheet, confirmDelete, }: DataTableProps<TData>): React$1.JSX.Element;
|
|
400
411
|
|
|
401
412
|
/**
|
|
402
413
|
* Shared portal container for every overlay inside a DataTable (popover,
|
|
@@ -426,13 +437,13 @@ type Props$2<TData, TValue> = {
|
|
|
426
437
|
column: Column<TData, TValue>;
|
|
427
438
|
title: string;
|
|
428
439
|
};
|
|
429
|
-
declare function DataTableColumnHeader<TData, TValue>({ column, title, }: Props$2<TData, TValue>):
|
|
440
|
+
declare function DataTableColumnHeader<TData, TValue>({ column, title, }: Props$2<TData, TValue>): React$1.JSX.Element;
|
|
430
441
|
|
|
431
442
|
type Props$1<TData> = {
|
|
432
443
|
table: Table<TData>;
|
|
433
444
|
pageSizeOptions?: number[];
|
|
434
445
|
};
|
|
435
|
-
declare function DataTablePagination<TData>({ table, pageSizeOptions, }: Props$1<TData>):
|
|
446
|
+
declare function DataTablePagination<TData>({ table, pageSizeOptions, }: Props$1<TData>): React$1.JSX.Element;
|
|
436
447
|
|
|
437
448
|
type ToolbarFeatureFlags = {
|
|
438
449
|
search?: boolean;
|
|
@@ -468,7 +479,7 @@ type Props<TData> = {
|
|
|
468
479
|
features?: ToolbarFeatureFlags;
|
|
469
480
|
labels?: ToolbarLabels;
|
|
470
481
|
};
|
|
471
|
-
declare function DataTableToolbar<TData>({ table, totalRecords, isFetching, onRefresh, onAddRow, onBulkDelete, exportFileName, globalFilter, onGlobalFilterChange, toolbarSlot, features, labels: labelsProp, }: Props<TData>):
|
|
482
|
+
declare function DataTableToolbar<TData>({ table, totalRecords, isFetching, onRefresh, onAddRow, onBulkDelete, exportFileName, globalFilter, onGlobalFilterChange, toolbarSlot, features, labels: labelsProp, }: Props<TData>): React$1.JSX.Element;
|
|
472
483
|
|
|
473
484
|
type EditableCellProps<TData, TValue> = CellContext<TData, TValue> & {
|
|
474
485
|
isEditing: boolean;
|
|
@@ -478,7 +489,7 @@ type EditableCellProps<TData, TValue> = CellContext<TData, TValue> & {
|
|
|
478
489
|
onCancel: () => void;
|
|
479
490
|
onStartEdit: () => void;
|
|
480
491
|
};
|
|
481
|
-
declare function EditableCell<TData, TValue>({ getValue, column, row, isEditing, autoOpen, onCommit, onCancel, onStartEdit, }: EditableCellProps<TData, TValue>):
|
|
492
|
+
declare function EditableCell<TData, TValue>({ getValue, column, row, isEditing, autoOpen, onCommit, onCancel, onStartEdit, }: EditableCellProps<TData, TValue>): React$1.JSX.Element;
|
|
482
493
|
|
|
483
494
|
type TextOp = "contains" | "notContains" | "equals" | "notEqual" | "startsWith" | "endsWith" | "blank" | "notBlank";
|
|
484
495
|
type NumberOp = "equals" | "notEqual" | "lessThan" | "lessThanOrEqual" | "greaterThan" | "greaterThanOrEqual" | "inRange" | "blank" | "notBlank";
|
|
@@ -507,9 +518,11 @@ type CommonProps<TData, TValue> = {
|
|
|
507
518
|
column: Column<TData, TValue>;
|
|
508
519
|
onClose: () => void;
|
|
509
520
|
};
|
|
510
|
-
declare function ColumnFilterPanel<TData, TValue>(props: CommonProps<TData, TValue>):
|
|
521
|
+
declare function ColumnFilterPanel<TData, TValue>(props: CommonProps<TData, TValue>): React$1.JSX.Element | null;
|
|
511
522
|
|
|
523
|
+
/** Neutralize spreadsheet formulas in untrusted text; preserve real numbers. */
|
|
524
|
+
declare function sanitizeSpreadsheetValue(value: unknown): string;
|
|
512
525
|
declare function exportToCsv<TData>(table: Table<TData>, fileName?: string): void;
|
|
513
526
|
declare function exportToExcel<TData>(table: Table<TData>, fileName?: string): void;
|
|
514
527
|
|
|
515
|
-
export { type AdvFilter, type CellEditorType, ColumnFilterPanel, type Combine, type Condition, type ConfirmDeleteConfig, type ConfirmDeleteContext, type CustomRowAction, DataTable, type DataTableColumn, DataTableColumnHeader, type DataTableDataSource, type DataTableDataSourceResult, type DataTableDensity, type DataTableErrorContext, type DataTableFeatures, type DataTableFetchParams, type DataTableLabels, type DataTableModedTheme, DataTablePagination, type DataTableProps, DataTableRowActions, type DataTableRowActionsProps, type DataTableTheme, type DataTableThemeName, type DataTableTokens, DataTableToolbar, type DateOp, EditableCell, type FilterType, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, type NumberOp, PortalContainerContext, type RowAction, type RowActionId, type SelectOption, type SetFilter, type TextOp, type ViewSheetConfig, type ViewSheetDensity, type ViewSheetLabels, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle, usePortalContainer };
|
|
528
|
+
export { type AdvFilter, type CellEditorType, ColumnFilterPanel, type Combine, type Condition, type ConfirmDeleteConfig, type ConfirmDeleteContext, type CustomRowAction, DataTable, type DataTableColumn, DataTableColumnHeader, type DataTableDataSource, type DataTableDataSourceResult, type DataTableDensity, type DataTableErrorContext, type DataTableFeatures, type DataTableFetchParams, type DataTableLabels, type DataTableModedTheme, DataTablePagination, type DataTableProps, DataTableRowActions, type DataTableRowActionsProps, type DataTableTheme, type DataTableThemeName, type DataTableTokens, DataTableToolbar, type DateOp, EditableCell, type FilterType, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, type NumberOp, PortalContainerContext, type RowAction, type RowActionId, type SelectOption, type SetFilter, type TextOp, type ViewSheetConfig, type ViewSheetDensity, type ViewSheetLabels, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, sanitizeSpreadsheetValue, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle, usePortalContainer };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext, useState, useRef, useEffect, useMemo, useLayoutEffect, useId } from 'react';
|
|
2
2
|
import { useReactTable, getPaginationRowModel, getExpandedRowModel, getSortedRowModel, getFilteredRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
|
|
3
|
-
import { Trash2Icon, XIcon, SearchIcon, RefreshCwIcon, ColumnsIcon, DownloadIcon, FileTextIcon, FileSpreadsheetIcon, PlusIcon, ChevronsLeftIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsRightIcon, ArrowDownIcon, ArrowUpIcon, ChevronsUpDownIcon, PinOffIcon, PinIcon, EyeOffIcon, FilterIcon, CheckIcon, MoreHorizontalIcon, ChevronDownIcon, GripVerticalIcon, Loader2Icon, MinusIcon, CopyIcon, PencilIcon, EyeIcon, ChevronUpIcon,
|
|
3
|
+
import { Trash2Icon, XIcon, SearchIcon, RefreshCwIcon, ColumnsIcon, DownloadIcon, FileTextIcon, FileSpreadsheetIcon, PlusIcon, ChevronsLeftIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsRightIcon, ArrowDownIcon, ArrowUpIcon, ChevronsUpDownIcon, PinOffIcon, PinIcon, EyeOffIcon, FilterIcon, CheckIcon, MoreHorizontalIcon, ChevronDownIcon, GripVerticalIcon, Loader2Icon, MinusIcon, CopyIcon, PencilIcon, EyeIcon, ChevronUpIcon, ListIcon, Rows3Icon, LayoutGridIcon } from 'lucide-react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { Slot, Separator as Separator$1, Popover as Popover$1, Checkbox as Checkbox$1, DropdownMenu as DropdownMenu$1, Select as Select$1, Dialog, AlertDialog as AlertDialog$1 } from 'radix-ui';
|
|
@@ -281,15 +281,21 @@ function PopoverContent({
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
// src/export.ts
|
|
284
|
+
function sanitizeSpreadsheetValue(value) {
|
|
285
|
+
if (value == null) return "";
|
|
286
|
+
const text = String(value);
|
|
287
|
+
if (typeof value === "string" && (/^[\s\u0000-\u001f]*[=+\-@=+-@]/u.test(text) || /^[\t\r\n]/.test(text))) return `'${text}`;
|
|
288
|
+
return text;
|
|
289
|
+
}
|
|
284
290
|
function escapeCsv(value) {
|
|
285
291
|
if (value === null || value === void 0) return "";
|
|
286
|
-
const s =
|
|
292
|
+
const s = sanitizeSpreadsheetValue(value);
|
|
287
293
|
if (/[",\n\r]/.test(s)) return `"${s.replace(/"/g, '""')}"`;
|
|
288
294
|
return s;
|
|
289
295
|
}
|
|
290
296
|
function escapeHtml(value) {
|
|
291
297
|
if (value === null || value === void 0) return "";
|
|
292
|
-
return
|
|
298
|
+
return sanitizeSpreadsheetValue(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
293
299
|
}
|
|
294
300
|
function getExportRows(table) {
|
|
295
301
|
const visible = table.getVisibleLeafColumns().filter((c) => {
|
|
@@ -1899,7 +1905,7 @@ function EditableCell({
|
|
|
1899
1905
|
if (typeof flag === "function") return flag(row.original);
|
|
1900
1906
|
return flag;
|
|
1901
1907
|
})();
|
|
1902
|
-
if (!isEditing) {
|
|
1908
|
+
if (!isEditing || !isEditable) {
|
|
1903
1909
|
const display = renderDisplay(initial, editor, meta);
|
|
1904
1910
|
return /* @__PURE__ */ jsx(
|
|
1905
1911
|
"div",
|
|
@@ -1916,7 +1922,9 @@ function EditableCell({
|
|
|
1916
1922
|
}
|
|
1917
1923
|
);
|
|
1918
1924
|
}
|
|
1919
|
-
const commit = (value) =>
|
|
1925
|
+
const commit = (value) => {
|
|
1926
|
+
if (isEditable) onCommit(value);
|
|
1927
|
+
};
|
|
1920
1928
|
const handleKey = (e) => {
|
|
1921
1929
|
if (e.key === "Enter") commit(local);
|
|
1922
1930
|
else if (e.key === "Escape") onCancel();
|
|
@@ -2046,6 +2054,9 @@ var TOKEN_TO_VAR = {
|
|
|
2046
2054
|
radius: "--radius",
|
|
2047
2055
|
fontFamily: "--font-family"
|
|
2048
2056
|
};
|
|
2057
|
+
function isSafeToken(value) {
|
|
2058
|
+
return typeof value === "string" && !/[;{}<>@\\\u0000-\u001f]/.test(value) && !/\/\*|\*\/|url\s*\(|expression\s*\(/i.test(value);
|
|
2059
|
+
}
|
|
2049
2060
|
function isModed(theme) {
|
|
2050
2061
|
if (!theme) return false;
|
|
2051
2062
|
return "light" in theme || "dark" in theme;
|
|
@@ -2054,8 +2065,8 @@ function tokensToStyle(tokens) {
|
|
|
2054
2065
|
if (!tokens) return {};
|
|
2055
2066
|
const out = {};
|
|
2056
2067
|
for (const [k, v] of Object.entries(tokens)) {
|
|
2057
|
-
if (v
|
|
2058
|
-
const cssVar = TOKEN_TO_VAR[k];
|
|
2068
|
+
if (!isSafeToken(v)) continue;
|
|
2069
|
+
const cssVar = Object.prototype.hasOwnProperty.call(TOKEN_TO_VAR, k) ? TOKEN_TO_VAR[k] : void 0;
|
|
2059
2070
|
if (cssVar) out[cssVar] = v;
|
|
2060
2071
|
}
|
|
2061
2072
|
return out;
|
|
@@ -2129,8 +2140,8 @@ function tokensToCssBlock(tokens) {
|
|
|
2129
2140
|
if (!tokens) return "";
|
|
2130
2141
|
const parts = [];
|
|
2131
2142
|
for (const [k, v] of Object.entries(tokens)) {
|
|
2132
|
-
if (v
|
|
2133
|
-
const cssVar = TOKEN_TO_VAR[k];
|
|
2143
|
+
if (!isSafeToken(v)) continue;
|
|
2144
|
+
const cssVar = Object.prototype.hasOwnProperty.call(TOKEN_TO_VAR, k) ? TOKEN_TO_VAR[k] : void 0;
|
|
2134
2145
|
if (cssVar) parts.push(`${cssVar}:${v}`);
|
|
2135
2146
|
}
|
|
2136
2147
|
return parts.join(";");
|
|
@@ -2214,8 +2225,8 @@ function SheetOverlay({
|
|
|
2214
2225
|
);
|
|
2215
2226
|
}
|
|
2216
2227
|
var SIDE_CLASS = {
|
|
2217
|
-
right: "right-0 top-0 h-full w-
|
|
2218
|
-
left: "left-0 top-0 h-full w-
|
|
2228
|
+
right: "right-0 top-0 h-full w-full border-l sm:w-[min(48rem,calc(100vw-2rem))] data-closed:slide-out-to-right data-open:slide-in-from-right",
|
|
2229
|
+
left: "left-0 top-0 h-full w-full border-r sm:w-[min(48rem,calc(100vw-2rem))] data-closed:slide-out-to-left data-open:slide-in-from-left",
|
|
2219
2230
|
top: "left-0 top-0 w-full max-h-[80vh] border-b data-closed:slide-out-to-top data-open:slide-in-from-top",
|
|
2220
2231
|
bottom: "left-0 bottom-0 w-full max-h-[80vh] border-t data-closed:slide-out-to-bottom data-open:slide-in-from-bottom"
|
|
2221
2232
|
};
|
|
@@ -2290,14 +2301,19 @@ function SheetDescription({
|
|
|
2290
2301
|
);
|
|
2291
2302
|
}
|
|
2292
2303
|
var COLS_CLASS = {
|
|
2293
|
-
compact: "grid-cols-1",
|
|
2304
|
+
compact: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
|
2294
2305
|
relaxed: "grid-cols-1 sm:grid-cols-2",
|
|
2295
|
-
comfy: "grid-cols-1
|
|
2306
|
+
comfy: "grid-cols-1"
|
|
2307
|
+
};
|
|
2308
|
+
var CARD_CLASS = {
|
|
2309
|
+
compact: "gap-0.5 p-2.5",
|
|
2310
|
+
relaxed: "gap-1 p-3",
|
|
2311
|
+
comfy: "gap-1.5 p-4"
|
|
2296
2312
|
};
|
|
2297
2313
|
var DENSITY_ICON = {
|
|
2298
|
-
compact: /* @__PURE__ */ jsx(
|
|
2314
|
+
compact: /* @__PURE__ */ jsx(LayoutGridIcon, { className: "size-3.5" }),
|
|
2299
2315
|
relaxed: /* @__PURE__ */ jsx(Rows3Icon, { className: "size-3.5" }),
|
|
2300
|
-
comfy: /* @__PURE__ */ jsx(
|
|
2316
|
+
comfy: /* @__PURE__ */ jsx(ListIcon, { className: "size-3.5" })
|
|
2301
2317
|
};
|
|
2302
2318
|
function DataTableViewSheet({
|
|
2303
2319
|
table,
|
|
@@ -2370,10 +2386,13 @@ function DataTableViewSheet({
|
|
|
2370
2386
|
return /* @__PURE__ */ jsxs(
|
|
2371
2387
|
"div",
|
|
2372
2388
|
{
|
|
2373
|
-
className:
|
|
2389
|
+
className: cn(
|
|
2390
|
+
"flex min-w-0 flex-col rounded-md border bg-card",
|
|
2391
|
+
CARD_CLASS[density]
|
|
2392
|
+
),
|
|
2374
2393
|
children: [
|
|
2375
2394
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] uppercase tracking-wide text-muted-foreground", children: headerLabel }),
|
|
2376
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground
|
|
2395
|
+
/* @__PURE__ */ jsx("span", { className: "break-words text-sm text-foreground", children: rendered })
|
|
2377
2396
|
]
|
|
2378
2397
|
},
|
|
2379
2398
|
colId
|
|
@@ -2398,11 +2417,15 @@ function AlertDialogContent({
|
|
|
2398
2417
|
...props
|
|
2399
2418
|
}) {
|
|
2400
2419
|
const container = usePortalContainer();
|
|
2420
|
+
const positionClass = container ? "absolute" : "fixed";
|
|
2401
2421
|
return /* @__PURE__ */ jsxs(AlertDialog$1.Portal, { container: container ?? void 0, children: [
|
|
2402
2422
|
/* @__PURE__ */ jsx(
|
|
2403
2423
|
AlertDialog$1.Overlay,
|
|
2404
2424
|
{
|
|
2405
|
-
className:
|
|
2425
|
+
className: cn(
|
|
2426
|
+
"inset-0 z-50 bg-foreground/30 backdrop-blur-sm data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
|
|
2427
|
+
positionClass
|
|
2428
|
+
)
|
|
2406
2429
|
}
|
|
2407
2430
|
),
|
|
2408
2431
|
/* @__PURE__ */ jsx(
|
|
@@ -2410,7 +2433,8 @@ function AlertDialogContent({
|
|
|
2410
2433
|
{
|
|
2411
2434
|
"data-slot": "alert-dialog-content",
|
|
2412
2435
|
className: cn(
|
|
2413
|
-
"
|
|
2436
|
+
"top-1/2 left-1/2 z-50 grid w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border bg-background p-6 shadow-lg outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
2437
|
+
positionClass,
|
|
2414
2438
|
className
|
|
2415
2439
|
),
|
|
2416
2440
|
...props,
|
|
@@ -2541,6 +2565,10 @@ function useEditingContext() {
|
|
|
2541
2565
|
if (!ctx) throw new Error("DataTable editing context missing");
|
|
2542
2566
|
return ctx;
|
|
2543
2567
|
}
|
|
2568
|
+
function DefaultCellHost(ctx) {
|
|
2569
|
+
const value = ctx.getValue();
|
|
2570
|
+
return value == null ? null : String(value);
|
|
2571
|
+
}
|
|
2544
2572
|
function EditableCellHost(ctx) {
|
|
2545
2573
|
const {
|
|
2546
2574
|
editingCell,
|
|
@@ -2629,6 +2657,7 @@ function ActionsCellHost({ row }) {
|
|
|
2629
2657
|
onView?.(row.original);
|
|
2630
2658
|
} else if (a === "delete") {
|
|
2631
2659
|
onRequestDelete?.(row.original);
|
|
2660
|
+
return;
|
|
2632
2661
|
}
|
|
2633
2662
|
onRowAction?.(a, row.original);
|
|
2634
2663
|
}
|
|
@@ -2661,6 +2690,7 @@ var DENSITY_CLASS = {
|
|
|
2661
2690
|
default: "",
|
|
2662
2691
|
comfortable: "[&_tbody_td]:py-2"
|
|
2663
2692
|
};
|
|
2693
|
+
var EMPTY_DATA = [];
|
|
2664
2694
|
function DataTable({
|
|
2665
2695
|
data,
|
|
2666
2696
|
columns,
|
|
@@ -2684,6 +2714,12 @@ function DataTable({
|
|
|
2684
2714
|
pageSizeOptions,
|
|
2685
2715
|
initialColumnPinning,
|
|
2686
2716
|
initialColumnVisibility,
|
|
2717
|
+
initialSorting,
|
|
2718
|
+
onSelectionChange,
|
|
2719
|
+
ariaLabel = "Data table",
|
|
2720
|
+
striped = false,
|
|
2721
|
+
stickyHeader = false,
|
|
2722
|
+
maxHeight,
|
|
2687
2723
|
globalFilter: globalFilterProp,
|
|
2688
2724
|
onGlobalFilterChange,
|
|
2689
2725
|
className,
|
|
@@ -2760,7 +2796,7 @@ function DataTable({
|
|
|
2760
2796
|
}
|
|
2761
2797
|
setConfirmCtx(null);
|
|
2762
2798
|
};
|
|
2763
|
-
const [sorting, setSorting] = useState([]);
|
|
2799
|
+
const [sorting, setSorting] = useState(initialSorting ?? []);
|
|
2764
2800
|
const [columnFilters, setColumnFilters] = useState([]);
|
|
2765
2801
|
const [internalGlobalFilter, setInternalGlobalFilter] = useState("");
|
|
2766
2802
|
const isControlledFilter = globalFilterProp !== void 0;
|
|
@@ -2856,7 +2892,7 @@ function DataTable({
|
|
|
2856
2892
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2857
2893
|
...dataSourceDeps
|
|
2858
2894
|
]);
|
|
2859
|
-
const baseData = dataSourceEnabled ? sourceRows : data ??
|
|
2895
|
+
const baseData = dataSourceEnabled ? sourceRows : data ?? EMPTY_DATA;
|
|
2860
2896
|
const effectiveIsLoading = dataSourceEnabled ? sourceLoading : isLoading;
|
|
2861
2897
|
const effectiveIsFetching = dataSourceEnabled ? sourceFetching : isFetching;
|
|
2862
2898
|
const effectiveOnRefresh = dataSourceEnabled ? () => setSourceRefreshKey((key) => key + 1) : onRefresh;
|
|
@@ -2900,7 +2936,7 @@ function DataTable({
|
|
|
2900
2936
|
title: headerLabel
|
|
2901
2937
|
}
|
|
2902
2938
|
),
|
|
2903
|
-
cell: hasEditor ? EditableCellHost : original
|
|
2939
|
+
cell: hasEditor ? EditableCellHost : original ?? DefaultCellHost
|
|
2904
2940
|
};
|
|
2905
2941
|
};
|
|
2906
2942
|
const built = columns.map(wrap);
|
|
@@ -3012,10 +3048,10 @@ function DataTable({
|
|
|
3012
3048
|
enableColumnFilters: f.filtering,
|
|
3013
3049
|
enableColumnResizing: f.resizing,
|
|
3014
3050
|
columnResizeMode: "onChange",
|
|
3015
|
-
enableRowSelection:
|
|
3051
|
+
enableRowSelection: enableSelection,
|
|
3016
3052
|
enableExpanding: !!(renderSubRow || getSubRows),
|
|
3017
3053
|
enablePinning: f.pinning,
|
|
3018
|
-
manualPagination: isServerSideDataSource,
|
|
3054
|
+
manualPagination: isServerSideDataSource || !f.pagination,
|
|
3019
3055
|
manualSorting: isServerSideDataSource,
|
|
3020
3056
|
manualFiltering: isServerSideDataSource,
|
|
3021
3057
|
pageCount: isServerSideDataSource ? Math.max(1, Math.ceil(effectiveTotalRecords / pagination.pageSize)) : void 0,
|
|
@@ -3105,6 +3141,11 @@ function DataTable({
|
|
|
3105
3141
|
setEditingRowId(tempId);
|
|
3106
3142
|
} : void 0;
|
|
3107
3143
|
const rows = table.getRowModel().rows;
|
|
3144
|
+
const selectionCallback = useRef(onSelectionChange);
|
|
3145
|
+
selectionCallback.current = onSelectionChange;
|
|
3146
|
+
useEffect(() => {
|
|
3147
|
+
selectionCallback.current?.(table.getSelectedRowModel().flatRows.map((row) => row.original));
|
|
3148
|
+
}, [rowSelection, mergedData, table]);
|
|
3108
3149
|
const visibleLeafCount = table.getVisibleLeafColumns().length;
|
|
3109
3150
|
const editingContextValue = useMemo(
|
|
3110
3151
|
() => ({
|
|
@@ -3182,17 +3223,18 @@ function DataTable({
|
|
|
3182
3223
|
labels
|
|
3183
3224
|
}
|
|
3184
3225
|
),
|
|
3185
|
-
/* @__PURE__ */ jsxs("div", { className: "relative w-full overflow-auto", children: [
|
|
3226
|
+
/* @__PURE__ */ jsxs("div", { className: "relative w-full overflow-auto", style: { maxHeight }, children: [
|
|
3186
3227
|
/* @__PURE__ */ jsxs(
|
|
3187
3228
|
"table",
|
|
3188
3229
|
{
|
|
3189
|
-
|
|
3230
|
+
"aria-label": ariaLabel,
|
|
3231
|
+
className: cn("w-full caption-bottom text-sm", striped && "[&_tbody>tr:nth-child(even)]:bg-muted/25"),
|
|
3190
3232
|
style: {
|
|
3191
3233
|
width: table.getCenterTotalSize() ? void 0 : "100%",
|
|
3192
3234
|
minWidth: "100%"
|
|
3193
3235
|
},
|
|
3194
3236
|
children: [
|
|
3195
|
-
/* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-10
|
|
3237
|
+
/* @__PURE__ */ jsx("thead", { className: cn("bg-card", stickyHeader && "sticky top-0 z-10"), children: table.getHeaderGroups().map((hg) => /* @__PURE__ */ jsx("tr", { className: "border-b", children: hg.headers.map((header) => {
|
|
3196
3238
|
const meta = header.column.columnDef.meta;
|
|
3197
3239
|
const isUtility = header.column.id === "__select" || header.column.id === "__expand" || header.column.id === "__actions";
|
|
3198
3240
|
const isPinned = !!header.column.getIsPinned();
|
|
@@ -3368,6 +3410,6 @@ function renderSkeleton(cols, rows) {
|
|
|
3368
3410
|
return Array.from({ length: rows }).map((_, r) => /* @__PURE__ */ jsx("tr", { className: "border-b", children: Array.from({ length: cols }).map((__, c) => /* @__PURE__ */ jsx("td", { className: "px-2 py-2", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }) }, c)) }, r));
|
|
3369
3411
|
}
|
|
3370
3412
|
|
|
3371
|
-
export { ColumnFilterPanel, DataTable, DataTableColumnHeader, DataTablePagination, DataTableRowActions, DataTableToolbar, EditableCell, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, PortalContainerContext, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle, usePortalContainer };
|
|
3413
|
+
export { ColumnFilterPanel, DataTable, DataTableColumnHeader, DataTablePagination, DataTableRowActions, DataTableToolbar, EditableCell, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, PortalContainerContext, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, sanitizeSpreadsheetValue, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle, usePortalContainer };
|
|
3372
3414
|
//# sourceMappingURL=index.js.map
|
|
3373
3415
|
//# sourceMappingURL=index.js.map
|