flexi-datagrid 1.2.8 → 1.2.11
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 +4 -3
- package/dist/DataTable/DataTable.d.ts +2 -0
- package/dist/DataTable/components/FilterDropdown.d.ts +4 -0
- package/dist/DataTable/components/GroupZone.d.ts +1 -0
- package/dist/DataTable/components/HeaderCell.d.ts +8 -0
- package/dist/DataTable/components/Pagination.d.ts +1 -0
- package/dist/DataTable/components/PinnedBottomBody.d.ts +1 -0
- package/dist/DataTable/components/SettingsMenu.d.ts +4 -0
- package/dist/DataTable/components/TableBody.d.ts +1 -0
- package/dist/DataTable/components/TableColGroup.d.ts +1 -0
- package/dist/DataTable/components/TableHeader.d.ts +1 -0
- package/dist/DataTable/components/rows.d.ts +18 -0
- package/dist/DataTable/constants.d.ts +11 -0
- package/dist/DataTable/context/DataTableContext.d.ts +8 -0
- package/dist/DataTable/hooks/index.d.ts +12 -0
- package/dist/DataTable/hooks/useAnchoredPosition.d.ts +13 -0
- package/dist/DataTable/hooks/useClickOutside.d.ts +5 -0
- package/dist/DataTable/hooks/useColumnFilters.d.ts +25 -0
- package/dist/DataTable/hooks/useColumnReorder.d.ts +15 -0
- package/dist/DataTable/hooks/useColumnResize.d.ts +7 -0
- package/dist/DataTable/hooks/useColumnVisibility.d.ts +13 -0
- package/dist/DataTable/hooks/useDataTableState.d.ts +89 -0
- package/dist/DataTable/hooks/usePagination.d.ts +18 -0
- package/dist/DataTable/hooks/usePinnedColumns.d.ts +5 -0
- package/dist/DataTable/hooks/useRowGrouping.d.ts +7 -0
- package/dist/DataTable/hooks/useSettingsMenu.d.ts +11 -0
- package/dist/DataTable/hooks/useSorting.d.ts +6 -0
- package/dist/DataTable/hooks/useVirtualRows.d.ts +15 -0
- package/dist/DataTable/index.d.ts +2 -0
- package/dist/{Datatable.d.ts → DataTable/types.d.ts} +36 -7
- package/dist/DataTable/utils/classNames.d.ts +1 -0
- package/dist/DataTable/utils/columns.d.ts +12 -0
- package/dist/DataTable/utils/grouping.d.ts +5 -0
- package/dist/DataTable/utils/pinning.d.ts +12 -0
- package/dist/DataTable/utils/records.d.ts +10 -0
- package/dist/DataTable/utils/rowSpan.d.ts +7 -0
- package/dist/flexi-datagrid.css +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.es.js +1194 -881
- package/dist/index.umd.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -148,7 +148,7 @@ Each entry in `columns` describes one column (or a group of columns, via `childr
|
|
|
148
148
|
| `rowKey` | `keyof T \| (record: T) => string` | Field name or function used to derive a unique React key per row. |
|
|
149
149
|
| `actions` | `(record: T) => ReactNode` | Renders a sticky, right-aligned actions cell per row (e.g. edit/delete buttons). |
|
|
150
150
|
| `isLoading` | `boolean` | Shows a loading state in place of rows. |
|
|
151
|
-
| `groupBy` | `boolean` | Enables drag-and-drop row grouping — drag a column header into the grouping zone above the grid. |
|
|
151
|
+
| `groupBy` | `boolean` | Enables drag-and-drop row grouping — drag a column header into the grouping zone above the grid. It also sets the initial state of the **Group By** checkbox in the settings menu (shown whenever `controlPanel` is on), which lets users turn grouping on or off at runtime. Defaults to `false`. |
|
|
152
152
|
| `defaultGroupBy` | `string[]` | Column keys the grid is grouped by on initial render (requires `groupBy`). |
|
|
153
153
|
| `onPinChange` | `(columnKey, isPinned, side?) => void` | Called whenever a column is pinned/unpinned, with the side (`'left'` \| `'right'`) it was pinned to. |
|
|
154
154
|
| `onGroupChange` | `(groupedKeys: string[]) => void` | Called whenever the set of grouped columns changes. |
|
|
@@ -253,8 +253,9 @@ Notes:
|
|
|
253
253
|
Pass `controlPanel` to render a small toolbar above the grid (and above the grouping drop zone, if `groupBy` is also on) with a single **Settings** menu button. Clicking it opens a dropdown with every display option in one place, instead of a row of separate buttons:
|
|
254
254
|
|
|
255
255
|
- **Show pin/filter icons on hover** — toggles `displayPinnedIcon`. When off, neither the pin button nor the filter button reveals on hovering a column header, regardless of whether the column is `filterable`; when on, hovering a leaf column header's action area reveals its filter icon (if `filterable`) and pin icon.
|
|
256
|
+
- **Group By** — always listed in the dropdown. Its checked state comes from the `groupBy` prop (`groupBy` → checked, otherwise unchecked), and it follows the prop if that value changes. Checking it shows the grouping drop zone and makes leaf column headers draggable into it; unchecking it hides the drop zone and renders the rows ungrouped. Columns the user had grouped by are remembered, so re-checking restores them.
|
|
256
257
|
- **Columns** — a checklist of every leaf column (by `header` label) to show or hide it. Hiding a column removes it from both the header and body, and adjusts any parent group header's `colSpan` automatically.
|
|
257
|
-
- **Reset to defaults** — restores pin/filter icon hover visibility
|
|
258
|
+
- **Reset to defaults** — restores pin/filter icon hover visibility, hidden columns and the Group By checkbox to the values passed via `defaultDisplayPinnedIcon` / `defaultHiddenColumns` / `groupBy` (not to "all columns visible" — it resets to *your configured defaults*, so a column you deliberately hid by default stays hidden after reset).
|
|
258
259
|
|
|
259
260
|
```tsx
|
|
260
261
|
<DataTable
|
|
@@ -289,7 +290,7 @@ Pagination is applied after filtering and sorting, and before row grouping — s
|
|
|
289
290
|
|
|
290
291
|
### Row Grouping
|
|
291
292
|
|
|
292
|
-
Set `groupBy` to enable a drop zone above the table. Dragging a sortable/leaf column header into it groups rows by that column's value, with collapsible group rows and per-group row counts. Multiple columns can be stacked to create nested groups; use `defaultGroupBy` to pre-group on mount.
|
|
293
|
+
Set `groupBy` to enable a drop zone above the table. With `controlPanel` on, the settings menu always shows a **Group By** checkbox whose initial state follows this prop; unchecking it hides the drop zone and ungroups the rows (the chosen group columns are kept for when it's re-checked). Dragging a sortable/leaf column header into it groups rows by that column's value, with collapsible group rows and per-group row counts. Multiple columns can be stacked to create nested groups; use `defaultGroupBy` to pre-group on mount.
|
|
293
294
|
|
|
294
295
|
### Column Reordering
|
|
295
296
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function GroupZone(): import("react").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ColumnConfig } from '../types';
|
|
2
|
+
interface HeaderCellProps<T> {
|
|
3
|
+
col: ColumnConfig<T>;
|
|
4
|
+
rowSpan: number;
|
|
5
|
+
colSpan: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function HeaderCell<T>({ col, rowSpan, colSpan }: HeaderCellProps<T>): import("react").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Pagination(): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function PinnedBottomBody(): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The gear button that lives in the header row when `controlPanel` is on. */
|
|
2
|
+
export declare function SettingsButton(): import("react").JSX.Element;
|
|
3
|
+
/** The popup opened by {@link SettingsButton}. Renders nothing while closed. */
|
|
4
|
+
export declare function SettingsMenu(): import("react").ReactPortal | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function TableBody<T>(): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function TableColGroup(): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function TableHeader(): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GroupNode } from '../types';
|
|
2
|
+
export declare function GroupRow<T>({ node }: {
|
|
3
|
+
node: GroupNode<T>;
|
|
4
|
+
}): import("react").JSX.Element;
|
|
5
|
+
interface DataRowProps<T> {
|
|
6
|
+
record: T;
|
|
7
|
+
/** Index within the full flattened row list (group rows included). */
|
|
8
|
+
rowIndex: number;
|
|
9
|
+
className: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function DataRow<T>({ record, rowIndex, className }: DataRowProps<T>): import("react").JSX.Element;
|
|
12
|
+
interface PinnedBottomRowProps<T> {
|
|
13
|
+
record: T;
|
|
14
|
+
index: number;
|
|
15
|
+
className: string | undefined;
|
|
16
|
+
}
|
|
17
|
+
export declare function PinnedBottomRow<T>({ record, index, className }: PinnedBottomRowProps<T>): import("react").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const DEFAULT_ROW_HEIGHT = 40;
|
|
2
|
+
export declare const DEFAULT_COL_WIDTH = 150;
|
|
3
|
+
export declare const MIN_COL_WIDTH = 60;
|
|
4
|
+
export declare const ACTIONS_WIDTH = 100;
|
|
5
|
+
export declare const GROUP_INDENT_WIDTH = 48;
|
|
6
|
+
export declare const PINNED_BOTTOM_ROW_HEIGHT = 48;
|
|
7
|
+
export declare const DEFAULT_OVERSCAN = 8;
|
|
8
|
+
export declare const DEFAULT_PAGE_SIZE = 10;
|
|
9
|
+
export declare const DEFAULT_PAGE_SIZE_OPTIONS: number[];
|
|
10
|
+
export declare const EMPTY_STRINGS: string[];
|
|
11
|
+
export declare const EMPTY_ARRAY: never[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { useDataTableState } from '../hooks/useDataTableState';
|
|
3
|
+
export type DataTableContextValue<T> = ReturnType<typeof useDataTableState<T>>;
|
|
4
|
+
export declare function DataTableProvider<T>({ value, children }: {
|
|
5
|
+
value: DataTableContextValue<T>;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
export declare function useDataTableContext<T = any>(): DataTableContextValue<T>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { useAnchoredPosition } from './useAnchoredPosition';
|
|
2
|
+
export { useClickOutside } from './useClickOutside';
|
|
3
|
+
export { useColumnFilters, type ColumnFilters } from './useColumnFilters';
|
|
4
|
+
export { useColumnReorder } from './useColumnReorder';
|
|
5
|
+
export { useColumnResize } from './useColumnResize';
|
|
6
|
+
export { useColumnVisibility } from './useColumnVisibility';
|
|
7
|
+
export { usePagination } from './usePagination';
|
|
8
|
+
export { usePinnedColumns } from './usePinnedColumns';
|
|
9
|
+
export { useRowGrouping } from './useRowGrouping';
|
|
10
|
+
export { useSettingsMenu } from './useSettingsMenu';
|
|
11
|
+
export { useSorting } from './useSorting';
|
|
12
|
+
export { useVirtualRows } from './useVirtualRows';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
interface AnchoredPositionOptions<P> {
|
|
3
|
+
/** Whether the popup is open. The position is only tracked (and kept up to date) while true. */
|
|
4
|
+
active: boolean;
|
|
5
|
+
/** Changing this while `active` re-anchors the popup (e.g. switching between filter columns). */
|
|
6
|
+
resetKey?: unknown;
|
|
7
|
+
rootRef: RefObject<HTMLElement | null>;
|
|
8
|
+
getAnchor: () => HTMLElement | null | undefined;
|
|
9
|
+
compute: (anchorRect: DOMRect, rootRect: DOMRect) => P;
|
|
10
|
+
}
|
|
11
|
+
/** Tracks a popup position relative to the grid root, updating on scroll and window resize. */
|
|
12
|
+
export declare function useAnchoredPosition<P>({ active, resetKey, rootRef, getAnchor, compute }: AnchoredPositionOptions<P>): P | null;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calls `onOutside` when a mousedown lands outside a popup.
|
|
3
|
+
* `getElements()` returns `[popup, ...extraInsideElements]`; if the popup isn't mounted yet nothing happens.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useClickOutside(enabled: boolean, getElements: () => Array<HTMLElement | null | undefined>, onOutside: () => void): void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
import type { ColumnConfig } from '../types';
|
|
3
|
+
interface ColumnFiltersOptions<T> {
|
|
4
|
+
data: T[];
|
|
5
|
+
columnsByKey: Map<string, ColumnConfig<T>>;
|
|
6
|
+
gridRootRef: RefObject<HTMLElement | null>;
|
|
7
|
+
}
|
|
8
|
+
export declare function useColumnFilters<T>({ data, columnsByKey, gridRootRef }: ColumnFiltersOptions<T>): {
|
|
9
|
+
activeFilterKey: string | null;
|
|
10
|
+
selectedFilters: Record<string, unknown[]>;
|
|
11
|
+
filterSearchQuery: string;
|
|
12
|
+
setFilterSearchQuery: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
13
|
+
filterPosition: {
|
|
14
|
+
top: number;
|
|
15
|
+
left: number;
|
|
16
|
+
} | null;
|
|
17
|
+
dropdownRef: RefObject<HTMLDivElement | null>;
|
|
18
|
+
filteredUniqueValues: unknown[];
|
|
19
|
+
registerFilterButton: (key: string, el: HTMLButtonElement | null) => void;
|
|
20
|
+
toggleFilterDropdown: (columnKey: string) => void;
|
|
21
|
+
handleFilterChange: (columnKey: string, value: unknown) => void;
|
|
22
|
+
clearFilter: (columnKey: string) => void;
|
|
23
|
+
};
|
|
24
|
+
export type ColumnFilters = ReturnType<typeof useColumnFilters>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type DragEvent, type RefObject } from 'react';
|
|
2
|
+
import type { ColumnConfig, PinSide } from '../types';
|
|
3
|
+
interface ColumnReorderOptions<T> {
|
|
4
|
+
columns: ColumnConfig<T>[];
|
|
5
|
+
pinnedColumns: Record<string, PinSide>;
|
|
6
|
+
isResizingRef: RefObject<boolean>;
|
|
7
|
+
onColumnReorder?: (orderedLeafKeys: string[]) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function useColumnReorder<T>({ columns, pinnedColumns, isResizingRef, onColumnReorder }: ColumnReorderOptions<T>): {
|
|
10
|
+
reorderedColumns: ColumnConfig<T>[];
|
|
11
|
+
handleDragStart: (e: DragEvent, columnKey: string, isLeaf: boolean) => void;
|
|
12
|
+
handleDragEnd: () => void;
|
|
13
|
+
handleDrop: (e: DragEvent, targetKey: string) => void;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type MouseEvent as ReactMouseEvent } from 'react';
|
|
2
|
+
import type { ColumnConfig } from '../types';
|
|
3
|
+
export declare function useColumnResize<T>(onColumnResize?: (columnKey: string, width: number) => void): {
|
|
4
|
+
columnWidths: Record<string, number>;
|
|
5
|
+
isResizingRef: import("react").RefObject<boolean>;
|
|
6
|
+
startResize: (e: ReactMouseEvent, col: ColumnConfig<T>) => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface ColumnVisibilityOptions {
|
|
2
|
+
defaultHiddenColumns: string[];
|
|
3
|
+
defaultDisplayPinnedIcon: boolean;
|
|
4
|
+
onColumnVisibilityChange?: (hiddenKeys: string[]) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function useColumnVisibility({ defaultHiddenColumns, defaultDisplayPinnedIcon, onColumnVisibilityChange }: ColumnVisibilityOptions): {
|
|
7
|
+
hiddenColumns: string[];
|
|
8
|
+
displayPinnedIcon: boolean;
|
|
9
|
+
toggleColumnVisibility: (columnKey: string) => void;
|
|
10
|
+
toggleDisplayPinnedIcon: () => void;
|
|
11
|
+
resetControlPanelDefaults: () => void;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { ColumnConfig, DataTableProps } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Owns all of the grid's state and derived data. `DataTable` publishes the result through
|
|
4
|
+
* `DataTableContext`, so child components read what they need instead of receiving it as props.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useDataTableState<T>({ columns, data, rowKey, actions, isLoading, groupBy, defaultGroupBy, onPinChange, onGroupChange, pinnedBottomRowData, pinnedRowClassName, rowHeight, overscan, onColumnResize, onColumnReorder, rowClassRules, onRowClick, rowSpanColumns, controlPanel, defaultDisplayPinnedIcon, defaultHiddenColumns, onColumnVisibilityChange, pagination, defaultPageSize, pageSizeOptions, onPageChange, }: DataTableProps<T>): {
|
|
7
|
+
gridRootRef: import("react").RefObject<HTMLDivElement | null>;
|
|
8
|
+
tableWrapRef: import("react").RefObject<HTMLDivElement | null>;
|
|
9
|
+
rowKey: keyof T | ((record: T) => string);
|
|
10
|
+
actions: ((record: T) => import("react").ReactNode) | undefined;
|
|
11
|
+
isLoading: boolean;
|
|
12
|
+
groupBy: boolean;
|
|
13
|
+
showGroupBy: boolean;
|
|
14
|
+
toggleShowGroupBy: () => void;
|
|
15
|
+
controlPanel: boolean;
|
|
16
|
+
rowHeight: number;
|
|
17
|
+
rowSpanColumns: string[] | undefined;
|
|
18
|
+
rowClassRules: Record<string, (record: T, index: number) => boolean> | undefined;
|
|
19
|
+
onRowClick: ((record: T, index: number, event: import("react").MouseEvent<HTMLTableRowElement>) => void) | undefined;
|
|
20
|
+
pinnedBottomRowData: T[];
|
|
21
|
+
pinnedRowClassName: string | ((record: T, index: number) => string) | undefined;
|
|
22
|
+
pageSizeOptions: number[];
|
|
23
|
+
paginationEnabled: boolean;
|
|
24
|
+
initialLeafColumns: ColumnConfig<T>[];
|
|
25
|
+
columnsByKey: Map<string, ColumnConfig<T>>;
|
|
26
|
+
visibleLeafColumns: ColumnConfig<T>[];
|
|
27
|
+
headerRows: import("../types").HeaderCellSpec<T>[][];
|
|
28
|
+
pinnedColumns: Record<string, import("..").PinSide>;
|
|
29
|
+
pinOffsets: import("../types").PinOffsets;
|
|
30
|
+
columnWidths: Record<string, number>;
|
|
31
|
+
togglePin: (columnKey: string) => void;
|
|
32
|
+
startResize: (e: import("react").MouseEvent, col: ColumnConfig<T>) => void;
|
|
33
|
+
handleDragStart: (e: import("react").DragEvent, columnKey: string, isLeaf: boolean) => void;
|
|
34
|
+
handleDragEnd: () => void;
|
|
35
|
+
handleDrop: (e: import("react").DragEvent, targetKey: string) => void;
|
|
36
|
+
hiddenColumns: string[];
|
|
37
|
+
displayPinnedIcon: boolean;
|
|
38
|
+
toggleColumnVisibility: (columnKey: string) => void;
|
|
39
|
+
toggleDisplayPinnedIcon: () => void;
|
|
40
|
+
resetControlPanelDefaults: () => void;
|
|
41
|
+
settingsMenu: {
|
|
42
|
+
isOpen: boolean;
|
|
43
|
+
position: {
|
|
44
|
+
top: number;
|
|
45
|
+
right: number;
|
|
46
|
+
} | null;
|
|
47
|
+
menuRef: import("react").RefObject<HTMLDivElement | null>;
|
|
48
|
+
buttonRef: import("react").RefObject<HTMLButtonElement | null>;
|
|
49
|
+
toggle: () => void;
|
|
50
|
+
};
|
|
51
|
+
groupedColumns: string[];
|
|
52
|
+
expandedGroups: Record<string, boolean>;
|
|
53
|
+
addGroup: (columnKey: string) => void;
|
|
54
|
+
removeGroup: (columnKey: string) => void;
|
|
55
|
+
toggleGroupExpansion: (path: string) => void;
|
|
56
|
+
hasGroups: boolean;
|
|
57
|
+
hasActions: boolean;
|
|
58
|
+
sortState: import("../types").SortState;
|
|
59
|
+
handleSort: (columnKey: string) => void;
|
|
60
|
+
filters: {
|
|
61
|
+
activeFilterKey: string | null;
|
|
62
|
+
selectedFilters: Record<string, unknown[]>;
|
|
63
|
+
filterSearchQuery: string;
|
|
64
|
+
setFilterSearchQuery: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
65
|
+
filterPosition: {
|
|
66
|
+
top: number;
|
|
67
|
+
left: number;
|
|
68
|
+
} | null;
|
|
69
|
+
dropdownRef: import("react").RefObject<HTMLDivElement | null>;
|
|
70
|
+
filteredUniqueValues: unknown[];
|
|
71
|
+
registerFilterButton: (key: string, el: HTMLButtonElement | null) => void;
|
|
72
|
+
toggleFilterDropdown: (columnKey: string) => void;
|
|
73
|
+
handleFilterChange: (columnKey: string, value: unknown) => void;
|
|
74
|
+
clearFilter: (columnKey: string) => void;
|
|
75
|
+
};
|
|
76
|
+
currentPage: number;
|
|
77
|
+
pageSize: number;
|
|
78
|
+
totalPages: number;
|
|
79
|
+
totalCount: number;
|
|
80
|
+
goToPage: (page: number) => void;
|
|
81
|
+
changePageSize: (size: number) => void;
|
|
82
|
+
visibleRows: import("../types").RowNode<T>[];
|
|
83
|
+
startIndex: number;
|
|
84
|
+
totalRowCount: number;
|
|
85
|
+
topSpacerHeight: number;
|
|
86
|
+
bottomSpacerHeight: number;
|
|
87
|
+
rowSpanInfo: import("../types").RowSpanInfo;
|
|
88
|
+
totalColumnsCount: number;
|
|
89
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface PaginationOptions<T> {
|
|
2
|
+
items: T[];
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
defaultPageSize: number;
|
|
5
|
+
onPageChange?: (page: number, pageSize: number) => void;
|
|
6
|
+
/** The page jumps back to 1 whenever any of these change. Keep the array length constant between renders. */
|
|
7
|
+
resetOn: readonly unknown[];
|
|
8
|
+
}
|
|
9
|
+
export declare function usePagination<T>({ items, enabled, defaultPageSize, onPageChange, resetOn }: PaginationOptions<T>): {
|
|
10
|
+
currentPage: number;
|
|
11
|
+
pageSize: number;
|
|
12
|
+
totalPages: number;
|
|
13
|
+
totalCount: number;
|
|
14
|
+
pagedItems: T[];
|
|
15
|
+
goToPage: (page: number) => void;
|
|
16
|
+
changePageSize: (size: number) => void;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ColumnConfig, PinSide } from '../types';
|
|
2
|
+
export declare function usePinnedColumns<T>(initialLeafColumns: ColumnConfig<T>[], onPinChange?: (columnKey: string, isPinned: boolean, side?: PinSide) => void): {
|
|
3
|
+
pinnedColumns: Record<string, PinSide>;
|
|
4
|
+
togglePin: (columnKey: string) => void;
|
|
5
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function useRowGrouping(defaultGroupBy: string[], onGroupChange?: (groupedKeys: string[]) => void): {
|
|
2
|
+
groupedColumns: string[];
|
|
3
|
+
expandedGroups: Record<string, boolean>;
|
|
4
|
+
addGroup: (columnKey: string) => void;
|
|
5
|
+
removeGroup: (columnKey: string) => void;
|
|
6
|
+
toggleGroupExpansion: (path: string) => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
export declare function useSettingsMenu(gridRootRef: RefObject<HTMLElement | null>): {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
position: {
|
|
5
|
+
top: number;
|
|
6
|
+
right: number;
|
|
7
|
+
} | null;
|
|
8
|
+
menuRef: RefObject<HTMLDivElement | null>;
|
|
9
|
+
buttonRef: RefObject<HTMLButtonElement | null>;
|
|
10
|
+
toggle: () => void;
|
|
11
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
interface VirtualRowsOptions {
|
|
3
|
+
containerRef: RefObject<HTMLElement | null>;
|
|
4
|
+
totalRowCount: number;
|
|
5
|
+
rowHeight: number;
|
|
6
|
+
overscan: number;
|
|
7
|
+
}
|
|
8
|
+
/** Fixed-height row windowing driven by the scroll container's scrollTop / clientHeight. */
|
|
9
|
+
export declare function useVirtualRows({ containerRef, totalRowCount, rowHeight, overscan }: VirtualRowsOptions): {
|
|
10
|
+
startIndex: number;
|
|
11
|
+
endIndex: number;
|
|
12
|
+
topSpacerHeight: number;
|
|
13
|
+
bottomSpacerHeight: number;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import React from 'react';
|
|
1
|
+
import type { CSSProperties, MouseEvent, ReactNode } from 'react';
|
|
3
2
|
export interface ColumnConfig<T> {
|
|
4
3
|
key: string;
|
|
5
4
|
header: string;
|
|
@@ -18,8 +17,13 @@ export interface ColumnConfig<T> {
|
|
|
18
17
|
minWidth?: number;
|
|
19
18
|
maxWidth?: number;
|
|
20
19
|
}
|
|
21
|
-
type PinSide = 'left' | 'right';
|
|
22
|
-
|
|
20
|
+
export type PinSide = 'left' | 'right';
|
|
21
|
+
export type SortDirection = 'asc' | 'desc' | null;
|
|
22
|
+
export interface SortState {
|
|
23
|
+
key: string | null;
|
|
24
|
+
direction: SortDirection;
|
|
25
|
+
}
|
|
26
|
+
export interface DataTableProps<T> {
|
|
23
27
|
columns: ColumnConfig<T>[];
|
|
24
28
|
data: T[];
|
|
25
29
|
rowKey: keyof T | ((record: T) => string);
|
|
@@ -39,7 +43,7 @@ interface DataTableProps<T> {
|
|
|
39
43
|
onColumnResize?: (columnKey: string, width: number) => void;
|
|
40
44
|
onColumnReorder?: (orderedLeafKeys: string[]) => void;
|
|
41
45
|
rowClassRules?: Record<string, (record: T, index: number) => boolean>;
|
|
42
|
-
onRowClick?: (record: T, index: number, event:
|
|
46
|
+
onRowClick?: (record: T, index: number, event: MouseEvent<HTMLTableRowElement>) => void;
|
|
43
47
|
rowSpanColumns?: string[];
|
|
44
48
|
controlPanel?: boolean;
|
|
45
49
|
defaultDisplayPinnedIcon?: boolean;
|
|
@@ -50,5 +54,30 @@ interface DataTableProps<T> {
|
|
|
50
54
|
pageSizeOptions?: number[];
|
|
51
55
|
onPageChange?: (page: number, pageSize: number) => void;
|
|
52
56
|
}
|
|
53
|
-
|
|
54
|
-
export {
|
|
57
|
+
/** A group header produced by `groupBy`. */
|
|
58
|
+
export interface GroupNode<T> {
|
|
59
|
+
kind: 'group';
|
|
60
|
+
groupKey: string;
|
|
61
|
+
groupValue: string;
|
|
62
|
+
path: string;
|
|
63
|
+
depth: number;
|
|
64
|
+
children: RowNode<T>[];
|
|
65
|
+
totalItemsCount: number;
|
|
66
|
+
}
|
|
67
|
+
/** A plain data record. Wrapping records keeps them distinguishable from group rows. */
|
|
68
|
+
export interface RecordNode<T> {
|
|
69
|
+
kind: 'record';
|
|
70
|
+
record: T;
|
|
71
|
+
}
|
|
72
|
+
export type RowNode<T> = GroupNode<T> | RecordNode<T>;
|
|
73
|
+
export interface HeaderCellSpec<T> {
|
|
74
|
+
col: ColumnConfig<T>;
|
|
75
|
+
rowSpan: number;
|
|
76
|
+
colSpan: number;
|
|
77
|
+
}
|
|
78
|
+
export type PinOffsets = Record<string, {
|
|
79
|
+
side: PinSide;
|
|
80
|
+
offset: number;
|
|
81
|
+
}>;
|
|
82
|
+
export type RowSpanEntry = number | 'skip';
|
|
83
|
+
export type RowSpanInfo = Map<number, Record<string, RowSpanEntry>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const cx: (...classes: Array<string | false | null | undefined>) => string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ColumnConfig, HeaderCellSpec, PinSide } from '../types';
|
|
2
|
+
export declare const getLeafColumns: <T>(cols: ColumnConfig<T>[]) => ColumnConfig<T>[];
|
|
3
|
+
export declare const normalizePinSide: (pinned: boolean | "left" | "right" | undefined) => PinSide | undefined;
|
|
4
|
+
export declare const getInitialPins: <T>(leafColumns: ColumnConfig<T>[]) => Record<string, PinSide>;
|
|
5
|
+
/** Orders every level of the column tree: left-pinned, then unpinned, then right-pinned; ties use the user's drag order. */
|
|
6
|
+
export declare const buildOrderedTree: <T>(cols: ColumnConfig<T>[], pinnedColumns: Record<string, PinSide>, columnOrderRanks: Record<string, number>) => ColumnConfig<T>[];
|
|
7
|
+
/** Finds the sibling list (at any depth) that contains both keys, so columns can only be reordered within their own level. */
|
|
8
|
+
export declare const findSiblingsContaining: <T>(cols: ColumnConfig<T>[], sourceKey: string, targetKey: string) => ColumnConfig<T>[] | null;
|
|
9
|
+
/** Resolves a column's pixel width: user-resized width > declared style width > default. */
|
|
10
|
+
export declare const resolveColumnWidth: <T>(col: ColumnConfig<T>, columnWidths: Record<string, number>) => number;
|
|
11
|
+
/** Builds the (possibly multi-level) header rows, skipping grouped/hidden columns and empty parents. */
|
|
12
|
+
export declare const buildHeaderRows: <T>(reorderedColumns: ColumnConfig<T>[], activeGroups: string[], hiddenColumns: string[]) => HeaderCellSpec<T>[][];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ColumnConfig, RowNode } from '../types';
|
|
2
|
+
/** Recursively groups records by `groupedColumns`; with no group columns it just wraps each record. */
|
|
3
|
+
export declare const groupRecords: <T>(records: T[], groupedColumns: string[], columnsByKey: Map<string, ColumnConfig<T>>, depth?: number, parentPath?: string) => RowNode<T>[];
|
|
4
|
+
/** Flattens the group tree into the visible row list, skipping the children of collapsed groups. */
|
|
5
|
+
export declare const flattenRows: <T>(nodes: RowNode<T>[], expandedGroups: Record<string, boolean>) => RowNode<T>[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
import type { ColumnConfig, PinOffsets, PinSide } from '../types';
|
|
3
|
+
interface PinOffsetOptions<T> {
|
|
4
|
+
visibleLeafColumns: ColumnConfig<T>[];
|
|
5
|
+
pinnedColumns: Record<string, PinSide>;
|
|
6
|
+
columnWidths: Record<string, number>;
|
|
7
|
+
hasGroups: boolean;
|
|
8
|
+
hasActions: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const computePinOffsets: <T>({ visibleLeafColumns, pinnedColumns, columnWidths, hasGroups, hasActions, }: PinOffsetOptions<T>) => PinOffsets;
|
|
11
|
+
export declare const getPinStyles: (pinOffsets: PinOffsets, colKey: string, isHeader?: boolean, baseColumnStyles?: CSSProperties) => CSSProperties;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ColumnConfig, SortDirection } from '../types';
|
|
2
|
+
/** Reads a record's value for a column, honouring the column's `getValue` override. */
|
|
3
|
+
export declare const getFieldValue: <T>(record: T, key: string, column?: ColumnConfig<T>) => unknown;
|
|
4
|
+
/** Returns the row's key as a string, or `undefined` when the key is missing (callers fall back to the index). */
|
|
5
|
+
export declare const getRowKeyValue: <T>(record: T, rowKey: keyof T | ((record: T) => string)) => string | undefined;
|
|
6
|
+
export declare const getRowRuleClassNames: <T>(record: T, index: number, rowClassRules?: Record<string, (record: T, index: number) => boolean>) => string | undefined;
|
|
7
|
+
export declare const getUniqueValues: <T>(data: T[], key: string, column?: ColumnConfig<T>) => unknown[];
|
|
8
|
+
export declare const filterRecords: <T>(data: T[], selectedFilters: Record<string, unknown[]>, columnsByKey: Map<string, ColumnConfig<T>>) => T[];
|
|
9
|
+
/** Sorts a copy of `records`. Empty values (null/undefined/NaN) always sort last regardless of direction. */
|
|
10
|
+
export declare const sortRecords: <T>(records: T[], key: string, direction: Exclude<SortDirection, null>, column?: ColumnConfig<T>) => T[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ColumnConfig, RowNode, RowSpanInfo } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Computes `rowSpan` / skip markers for the visible window of rows.
|
|
4
|
+
* Keys of the returned map are absolute indexes into the flattened row list (`startIndex + local index`).
|
|
5
|
+
* A column only merges while every column listed before it in `rowSpanColumns` also matches the previous row.
|
|
6
|
+
*/
|
|
7
|
+
export declare const computeRowSpanInfo: <T>(rows: RowNode<T>[], rowSpanColumns: string[] | undefined, columnsByKey: Map<string, ColumnConfig<T>>, startIndex: number) => RowSpanInfo;
|
package/dist/flexi-datagrid.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.flexi-root{width:100%;position:relative}.flexi-root>*+*{margin-top:.75rem}.flexi-settings-menu{z-index:50;background-color:#fff;border:1px solid #e2e8f0;border-radius:.5rem;flex-direction:column;width:13rem;max-height:20rem;padding:.5rem;font-weight:400;display:flex;position:absolute;top:calc(100% + 4px);overflow-y:auto;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.flexi-settings-section{flex-direction:column;gap:.125rem;display:flex}.flexi-settings-heading{text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:.25rem .5rem;font-size:11px;font-weight:700}.flexi-settings-divider{background-color:#f1f5f9;height:1px;margin:.375rem 0}.flexi-settings-reset{color:#ef4444;border-radius:.375rem;align-items:center;gap:.375rem;padding:.375rem .5rem;font-size:12px;font-weight:600;display:inline-flex}.flexi-settings-reset:hover{background-color:#fef2f2}.flexi-groupzone{box-sizing:border-box;background-color:#f8fafc80;border:1px dashed #e2e8f0;border-radius:.75rem;align-items:center;gap:.5rem;width:100%;min-height:52px;padding:.5rem 1rem;transition:all .2s;display:flex}.flexi-groupzone--dragover{background-color:#eff6ff80;border:1px solid #3b82f6;transform:scale(.99)}.flexi-groupzone-hint{color:#64748b;-webkit-user-select:none;user-select:none;font-size:12px;font-weight:500}.flexi-groupzone-chips{flex-wrap:wrap;align-items:center;gap:.375rem;display:flex}.flexi-groupzone-label{text-transform:uppercase;letter-spacing:.05em;color:#64748b;margin-right:.25rem;font-size:11px;font-weight:700}.flexi-chip{color:#64748b;background-color:#fff;border:1px solid #e2e8f0;border-radius:.5rem;align-items:center;gap:.375rem;padding:.25rem .25rem .25rem .5rem;font-size:12px;font-weight:600;display:flex;box-shadow:0 1px 2px #0000000d}.flexi-chip-remove{border-radius:5px;width:18px;height:18px}.flexi-table-wrap{box-sizing:border-box;background-color:#fff;border:1px solid #f1f5f9;border-radius:.75rem;width:100%;position:relative;overflow:auto;box-shadow:0 1px 2px #0000000d}.flexi-table{caption-side:bottom;border-collapse:collapse;border-spacing:0;table-layout:fixed;width:100%;font-size:.875rem;position:relative}.flexi-table--bordered th,.flexi-table--bordered td{border:1px solid #e2e8f0}.flexi-thead{-webkit-user-select:none;user-select:none;z-index:40;position:sticky}.flexi-header-row{border-bottom:1px solid #f1f5f9}.flexi-group-spacer-th{border-right:1px solid #f1f5f9;width:48px}.flexi-th{text-align:center;vertical-align:middle;z-index:25;background-color:#f8fafc;border-bottom:1px solid #f1f5f9;border-right:1px solid #f1f5f9;height:48px;padding:0 1rem;font-size:12px;font-weight:700;position:sticky;top:0}.flexi-th--draggable{cursor:grab}.flexi-th--draggable:active{cursor:grabbing}.flexi-th--pinned{background-color:#f8fafc}.flexi-th-inner{justify-content:space-between;align-items:center;gap:.25rem;width:100%;min-width:0;display:flex}.flexi-th-label{white-space:nowrap;text-overflow:ellipsis;flex:auto;align-items:center;gap:.375rem;min-width:0;display:flex;overflow:hidden}.flexi-th-label--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.flexi-th-label--sortable:hover{color:#2563eb}.flexi-th-text{white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.flexi-sort-icon,.flexi-filter-btn,.flexi-pin-btn{color:#94a3b8;opacity:0;transition:color .15s,opacity .15s}.flexi-sort-icon--active{color:#2563eb;opacity:1}.flexi-th-inner:hover .flexi-sort-icon,.flexi-th-inner:hover .flexi-filter-btn,.flexi-th-inner:hover .flexi-pin-btn{opacity:1}.flexi-th-actions{flex:none;align-items:center;gap:2px;display:flex}.flexi-th-resizer{cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none;z-index:5;width:6px;position:absolute;top:0;bottom:0;right:0}.flexi-th-resizer:hover,.flexi-th-resizer:active{background-color:#93c5fd}.flexi-icon-btn{color:#64748b;background-color:#0000;border-radius:6px;justify-content:center;align-items:center;width:22px;height:22px;margin:0;padding:0;transition:background-color .15s,color .15s,transform .1s;display:inline-flex}.flexi-icon-btn:hover{color:#334155;background-color:#e2e8f0}.flexi-icon-btn:active{background-color:#cbd5e1;transform:scale(.92)}.flexi-icon-btn:focus-visible{outline-offset:1px;outline:2px solid #93c5fd}.flexi-filter-btn--active{color:#2563eb;opacity:1}.flexi-filter-btn--active:hover{color:#2563eb;opacity:1;background-color:#dbeafe}.flexi-pin-btn--pinned{color:#3b82f6;opacity:1}.flexi-pin-btn--pinned:hover{color:#2563eb;opacity:1;background-color:#dbeafe}.flexi-
|
|
1
|
+
.flexi-root{width:100%;position:relative}.flexi-root>*+*{margin-top:.75rem}.flexi-settings-menu{z-index:50;background-color:#fff;border:1px solid #e2e8f0;border-radius:.5rem;flex-direction:column;width:13rem;max-height:20rem;padding:.5rem;font-weight:400;display:flex;position:absolute;top:calc(100% + 4px);overflow-y:auto;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.flexi-settings-section{flex-direction:column;gap:.125rem;display:flex}.flexi-settings-heading{text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:.25rem .5rem;font-size:11px;font-weight:700}.flexi-settings-divider{background-color:#f1f5f9;height:1px;margin:.375rem 0}.flexi-settings-reset{color:#ef4444;border-radius:.375rem;align-items:center;gap:.375rem;padding:.375rem .5rem;font-size:12px;font-weight:600;display:inline-flex}.flexi-settings-reset:hover{background-color:#fef2f2}.flexi-groupzone{box-sizing:border-box;background-color:#f8fafc80;border:1px dashed #e2e8f0;border-radius:.75rem;align-items:center;gap:.5rem;width:100%;min-height:52px;padding:.5rem 1rem;transition:all .2s;display:flex}.flexi-groupzone--dragover{background-color:#eff6ff80;border:1px solid #3b82f6;transform:scale(.99)}.flexi-groupzone-hint{color:#64748b;-webkit-user-select:none;user-select:none;font-size:12px;font-weight:500}.flexi-groupzone-chips{flex-wrap:wrap;align-items:center;gap:.375rem;display:flex}.flexi-groupzone-label{text-transform:uppercase;letter-spacing:.05em;color:#64748b;margin-right:.25rem;font-size:11px;font-weight:700}.flexi-chip{color:#64748b;background-color:#fff;border:1px solid #e2e8f0;border-radius:.5rem;align-items:center;gap:.375rem;padding:.25rem .25rem .25rem .5rem;font-size:12px;font-weight:600;display:flex;box-shadow:0 1px 2px #0000000d}.flexi-chip-remove{border-radius:5px;width:18px;height:18px}.flexi-table-wrap{box-sizing:border-box;background-color:#fff;border:1px solid #f1f5f9;border-radius:.75rem;width:100%;position:relative;overflow:auto;box-shadow:0 1px 2px #0000000d}.flexi-table{caption-side:bottom;border-collapse:collapse;border-spacing:0;table-layout:fixed;width:100%;font-size:.875rem;position:relative}.flexi-table--bordered th,.flexi-table--bordered td{border:1px solid #e2e8f0}.flexi-thead{-webkit-user-select:none;user-select:none;z-index:40;position:sticky}.flexi-header-row{border-bottom:1px solid #f1f5f9}.flexi-group-spacer-th{border-right:1px solid #f1f5f9;width:48px}.flexi-th{text-align:center;vertical-align:middle;z-index:25;background-color:#f8fafc;border-bottom:1px solid #f1f5f9;border-right:1px solid #f1f5f9;height:48px;padding:0 1rem;font-size:12px;font-weight:700;position:sticky;top:0}.flexi-th--draggable{cursor:grab}.flexi-th--draggable:active{cursor:grabbing}.flexi-th--pinned{background-color:#f8fafc}.flexi-th-inner{justify-content:space-between;align-items:center;gap:.25rem;width:100%;min-width:0;display:flex}.flexi-th-label{white-space:nowrap;text-overflow:ellipsis;flex:auto;align-items:center;gap:.375rem;min-width:0;display:flex;overflow:hidden}.flexi-th-label--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.flexi-th-label--sortable:hover{color:#2563eb}.flexi-th-text{white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.flexi-sort-icon,.flexi-filter-btn,.flexi-pin-btn{color:#94a3b8;opacity:0;transition:color .15s,opacity .15s}.flexi-sort-icon--active{color:#2563eb;opacity:1}.flexi-th-inner:hover .flexi-sort-icon,.flexi-th-inner:hover .flexi-filter-btn,.flexi-th-inner:hover .flexi-pin-btn{opacity:1}.flexi-th-actions{flex:none;align-items:center;gap:2px;display:flex}.flexi-th-resizer{cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none;z-index:5;width:6px;position:absolute;top:0;bottom:0;right:0}.flexi-th-resizer:hover,.flexi-th-resizer:active{background-color:#93c5fd}.flexi-icon-btn{color:#64748b;background-color:#0000;border-radius:6px;justify-content:center;align-items:center;width:22px;height:22px;margin:0;padding:0;transition:background-color .15s,color .15s,transform .1s;display:inline-flex}.flexi-icon-btn:hover{color:#334155;background-color:#e2e8f0}.flexi-icon-btn:active{background-color:#cbd5e1;transform:scale(.92)}.flexi-icon-btn:focus-visible{outline-offset:1px;outline:2px solid #93c5fd}.flexi-filter-btn--active{color:#2563eb;opacity:1}.flexi-filter-btn--active:hover{color:#2563eb;opacity:1;background-color:#dbeafe}.flexi-pin-btn--pinned{color:#3b82f6;opacity:1}.flexi-pin-btn--pinned:hover{color:#2563eb;opacity:1;background-color:#dbeafe}.flexi-settings-corner{z-index:60;width:100%;height:0;position:sticky;top:0;left:0}.flexi-settings-corner-inner{background:#f8fafc;border-bottom:1px solid #e3e4e3;border-left:1px solid #e3e4e3;align-items:center;height:48px;padding:0 .5rem 0 1rem;display:flex;position:absolute;top:0;right:0}.flexi-filter-dropdown{color:#334155;text-align:left;pointer-events:auto;background-color:#fff;border:1px solid #e2e8f0;border-radius:.5rem;flex-direction:column;width:13rem;padding:.5rem 0;font-weight:400;display:flex;position:absolute;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.flexi-filter-search{border-bottom:1px solid #f1f5f9;margin-bottom:.25rem;padding:0 .5rem .5rem}.flexi-input{color:#475569;box-sizing:border-box;border:1px solid #e2e8f0;border-radius:.25rem;width:100%;padding:.25rem .5rem;font-size:12px;font-weight:500}.flexi-input:focus{border-color:#3b82f6;outline:none}.flexi-filter-list{flex-direction:column;gap:.25rem;max-height:10rem;padding:0 .5rem;display:flex;overflow-y:auto}.flexi-filter-empty{color:#64748b;text-align:center;padding:.5rem;font-size:11px}.flexi-filter-option{cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:.25rem;align-items:center;gap:.5rem;padding:.375rem .5rem;font-size:12px;display:flex}.flexi-filter-option:hover{background-color:#f8fafc}.flexi-filter-option-text{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.flexi-checkbox{accent-color:#2563eb;border:1px solid #cbd5e1;border-radius:.25rem;width:.875rem;height:.875rem}.flexi-checkbox:focus{outline-offset:1px;outline:2px solid #3b82f6}.flexi-filter-footer{border-top:1px solid #f1f5f9;justify-content:flex-end;margin-top:.5rem;padding:.25rem .5rem 0;display:flex}.flexi-filter-clear{color:#ef4444;padding:.125rem .5rem;font-size:11px;font-weight:500}.flexi-filter-clear:hover{text-decoration:underline}.flexi-tbody{display:table-row-group}.flexi-tbody tr+tr{border-top:1px solid #f1f5f9}.flexi-empty-cell{text-align:center;color:#64748b;padding:2rem;font-size:12px;font-weight:500}.flexi-group-row{-webkit-user-select:none;user-select:none;background-color:#f8fafc99;height:48px;transition:background-color .15s}.flexi-group-row:hover{background-color:#f1f5f9cc}.flexi-group-cell{color:#334155;border-right:1px solid #f1f5f9;padding:.75rem 1rem;font-size:12px;font-weight:600}.flexi-group-toggle{text-align:left;border-radius:6px;align-items:center;gap:.375rem;margin:-4px -8px -4px -4px;padding:4px 8px 4px 4px;transition:background-color .15s;display:flex}.flexi-group-toggle:hover{background-color:#e2e8f099}.flexi-group-toggle:focus-visible{outline-offset:1px;outline:2px solid #93c5fd}.flexi-icon-muted{color:#64748b}.flexi-group-value{color:#1e293b;white-space:nowrap;text-overflow:ellipsis;width:10rem;font-weight:700;overflow:hidden}.flexi-group-count{color:#64748b;background-color:#e2e8f0b3;border-radius:9999px;margin-left:.25rem;padding:.05rem .375rem;font-size:10px;font-weight:500}.flexi-group-filler{background-color:#f8fafc4d}.flexi-row{border-bottom:1px solid #f1f5f9;height:48px;transition:background-color .15s}.flexi-row:hover{background-color:#f8fafccc}.flexi-row--clickable{cursor:pointer}.flexi-row-indent-cell{background-color:#fff;border-right:1px solid #f1f5f9;width:48px}.flexi-cell{vertical-align:middle;padding:.25rem 1rem;transition:background-color .15s}.flexi-row:hover .flexi-cell--pinned{background-color:#f1f5f9}.flexi-cell-text{color:#64748b;white-space:nowrap;text-overflow:ellipsis;font-size:12px;font-weight:500;display:block;overflow:hidden}.flexi-actions-cell{vertical-align:middle;text-align:right;background-color:#fff;padding:.25rem 1rem;box-shadow:-1px 0 #e2e8f0}.flexi-row:hover .flexi-actions-cell{background-color:#f8fafccc}.flexi-tbody--pinned-bottom{box-shadow:0 -2px 5px -2px #0000001a}.flexi-row--pinned-bottom{background-color:#f8fafc;font-weight:600}.flexi-row--pinned-bottom:hover,.flexi-row--pinned-bottom .flexi-cell,.flexi-row--pinned-bottom .flexi-actions-cell{background-color:#f8fafc}.flexi-row--pinned-bottom .flexi-cell-text{color:#334155}.flexi-actions-inner{opacity:0;justify-content:flex-end;gap:.25rem;transition:opacity .15s;display:flex}.flexi-row:hover .flexi-actions-inner{opacity:1}.flexi-icon-xs{width:.75rem;height:.75rem}.flexi-icon-sm{width:.875rem;height:.875rem}.flexi-icon-md{width:1rem;height:1rem}.flexi-pagination{color:#475569;box-sizing:border-box;background-color:#f8fafc80;border:1px solid #e2e8f0;border-radius:.75rem;justify-content:space-between;align-items:center;gap:1rem;width:100%;padding:.5rem .75rem;font-size:12px;font-weight:500;display:flex}.flexi-pagination-size{align-items:center;gap:.5rem;display:flex}.flexi-pagination-select{color:#334155;background-color:#fff;border:1px solid #e2e8f0;border-radius:.375rem;padding:.25rem .5rem;font-size:12px;font-weight:500}.flexi-pagination-info{text-align:center;flex:auto}.flexi-pagination-controls{align-items:center;gap:.25rem;display:flex}.flexi-pagination-controls .flexi-icon-btn:disabled{opacity:.4;cursor:not-allowed}.flexi-pagination-controls .flexi-icon-btn:disabled:hover{background-color:#0000}.flexi-pagination-page{white-space:nowrap;padding:0 .5rem}.flexi-root button{appearance:none;cursor:pointer;font:inherit;color:inherit;background:0 0;border:none;margin:0;padding:0 5px;line-height:normal}.flexi-root input{font:inherit}.flexi-root table{border-collapse:collapse;border-spacing:0}
|
|
2
2
|
/*$vite$:1*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import './index.css';
|
|
2
|
-
export { DataTable } from './
|
|
3
|
-
export type { ColumnConfig } from './
|
|
2
|
+
export { DataTable } from './DataTable/index';
|
|
3
|
+
export type { ColumnConfig, DataTableProps, PinSide, SortDirection } from './DataTable/index';
|