flexi-datagrid 1.2.7 → 1.2.9

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.
Files changed (40) hide show
  1. package/dist/DataTable/DataTable.d.ts +2 -0
  2. package/dist/DataTable/components/FilterDropdown.d.ts +4 -0
  3. package/dist/DataTable/components/GroupZone.d.ts +1 -0
  4. package/dist/DataTable/components/HeaderCell.d.ts +8 -0
  5. package/dist/DataTable/components/Pagination.d.ts +1 -0
  6. package/dist/DataTable/components/PinnedBottomBody.d.ts +1 -0
  7. package/dist/DataTable/components/SettingsMenu.d.ts +4 -0
  8. package/dist/DataTable/components/TableBody.d.ts +1 -0
  9. package/dist/DataTable/components/TableColGroup.d.ts +1 -0
  10. package/dist/DataTable/components/TableHeader.d.ts +1 -0
  11. package/dist/DataTable/components/rows.d.ts +18 -0
  12. package/dist/DataTable/constants.d.ts +11 -0
  13. package/dist/DataTable/context/DataTableContext.d.ts +8 -0
  14. package/dist/DataTable/hooks/index.d.ts +12 -0
  15. package/dist/DataTable/hooks/useAnchoredPosition.d.ts +13 -0
  16. package/dist/DataTable/hooks/useClickOutside.d.ts +5 -0
  17. package/dist/DataTable/hooks/useColumnFilters.d.ts +25 -0
  18. package/dist/DataTable/hooks/useColumnReorder.d.ts +15 -0
  19. package/dist/DataTable/hooks/useColumnResize.d.ts +7 -0
  20. package/dist/DataTable/hooks/useColumnVisibility.d.ts +13 -0
  21. package/dist/DataTable/hooks/useDataTableState.d.ts +87 -0
  22. package/dist/DataTable/hooks/usePagination.d.ts +18 -0
  23. package/dist/DataTable/hooks/usePinnedColumns.d.ts +5 -0
  24. package/dist/DataTable/hooks/useRowGrouping.d.ts +7 -0
  25. package/dist/DataTable/hooks/useSettingsMenu.d.ts +11 -0
  26. package/dist/DataTable/hooks/useSorting.d.ts +6 -0
  27. package/dist/DataTable/hooks/useVirtualRows.d.ts +15 -0
  28. package/dist/DataTable/index.d.ts +2 -0
  29. package/dist/{Datatable.d.ts → DataTable/types.d.ts} +36 -7
  30. package/dist/DataTable/utils/classNames.d.ts +1 -0
  31. package/dist/DataTable/utils/columns.d.ts +12 -0
  32. package/dist/DataTable/utils/grouping.d.ts +5 -0
  33. package/dist/DataTable/utils/pinning.d.ts +12 -0
  34. package/dist/DataTable/utils/records.d.ts +10 -0
  35. package/dist/DataTable/utils/rowSpan.d.ts +7 -0
  36. package/dist/flexi-datagrid.css +1 -1
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.es.js +1165 -868
  39. package/dist/index.umd.js +1 -1
  40. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ import type { DataTableProps } from './types';
2
+ export declare function DataTable<T>(props: DataTableProps<T>): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ /** The open filter popup for one column. Renders nothing until its position has been measured. */
2
+ export declare function FilterDropdown({ columnKey }: {
3
+ columnKey: string;
4
+ }): import("react").ReactPortal | null;
@@ -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 = 48;
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,87 @@
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
+ controlPanel: boolean;
14
+ rowHeight: number;
15
+ rowSpanColumns: string[] | undefined;
16
+ rowClassRules: Record<string, (record: T, index: number) => boolean> | undefined;
17
+ onRowClick: ((record: T, index: number, event: import("react").MouseEvent<HTMLTableRowElement>) => void) | undefined;
18
+ pinnedBottomRowData: T[];
19
+ pinnedRowClassName: string | ((record: T, index: number) => string) | undefined;
20
+ pageSizeOptions: number[];
21
+ paginationEnabled: boolean;
22
+ initialLeafColumns: ColumnConfig<T>[];
23
+ columnsByKey: Map<string, ColumnConfig<T>>;
24
+ visibleLeafColumns: ColumnConfig<T>[];
25
+ headerRows: import("../types").HeaderCellSpec<T>[][];
26
+ pinnedColumns: Record<string, import("..").PinSide>;
27
+ pinOffsets: import("../types").PinOffsets;
28
+ columnWidths: Record<string, number>;
29
+ togglePin: (columnKey: string) => void;
30
+ startResize: (e: import("react").MouseEvent, col: ColumnConfig<T>) => void;
31
+ handleDragStart: (e: import("react").DragEvent, columnKey: string, isLeaf: boolean) => void;
32
+ handleDragEnd: () => void;
33
+ handleDrop: (e: import("react").DragEvent, targetKey: string) => void;
34
+ hiddenColumns: string[];
35
+ displayPinnedIcon: boolean;
36
+ toggleColumnVisibility: (columnKey: string) => void;
37
+ toggleDisplayPinnedIcon: () => void;
38
+ resetControlPanelDefaults: () => void;
39
+ settingsMenu: {
40
+ isOpen: boolean;
41
+ position: {
42
+ top: number;
43
+ right: number;
44
+ } | null;
45
+ menuRef: import("react").RefObject<HTMLDivElement | null>;
46
+ buttonRef: import("react").RefObject<HTMLButtonElement | null>;
47
+ toggle: () => void;
48
+ };
49
+ groupedColumns: string[];
50
+ expandedGroups: Record<string, boolean>;
51
+ addGroup: (columnKey: string) => void;
52
+ removeGroup: (columnKey: string) => void;
53
+ toggleGroupExpansion: (path: string) => void;
54
+ hasGroups: boolean;
55
+ hasActions: boolean;
56
+ sortState: import("../types").SortState;
57
+ handleSort: (columnKey: string) => void;
58
+ filters: {
59
+ activeFilterKey: string | null;
60
+ selectedFilters: Record<string, unknown[]>;
61
+ filterSearchQuery: string;
62
+ setFilterSearchQuery: import("react").Dispatch<import("react").SetStateAction<string>>;
63
+ filterPosition: {
64
+ top: number;
65
+ left: number;
66
+ } | null;
67
+ dropdownRef: import("react").RefObject<HTMLDivElement | null>;
68
+ filteredUniqueValues: unknown[];
69
+ registerFilterButton: (key: string, el: HTMLButtonElement | null) => void;
70
+ toggleFilterDropdown: (columnKey: string) => void;
71
+ handleFilterChange: (columnKey: string, value: unknown) => void;
72
+ clearFilter: (columnKey: string) => void;
73
+ };
74
+ currentPage: number;
75
+ pageSize: number;
76
+ totalPages: number;
77
+ totalCount: number;
78
+ goToPage: (page: number) => void;
79
+ changePageSize: (size: number) => void;
80
+ visibleRows: import("../types").RowNode<T>[];
81
+ startIndex: number;
82
+ totalRowCount: number;
83
+ topSpacerHeight: number;
84
+ bottomSpacerHeight: number;
85
+ rowSpanInfo: import("../types").RowSpanInfo;
86
+ totalColumnsCount: number;
87
+ };
@@ -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,6 @@
1
+ import type { SortState } from '../types';
2
+ /** Click cycle on a sortable header: asc -> desc -> off. */
3
+ export declare function useSorting(): {
4
+ sortState: SortState;
5
+ handleSort: (columnKey: string) => void;
6
+ };
@@ -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 {};
@@ -0,0 +1,2 @@
1
+ export { DataTable } from './DataTable';
2
+ export type { ColumnConfig, DataTableProps, PinSide, SortDirection } from './types';
@@ -1,5 +1,4 @@
1
- import { type ReactNode, type CSSProperties } from 'react';
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
- interface DataTableProps<T> {
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: React.MouseEvent<HTMLTableRowElement>) => void;
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
- export declare function DataTable<T>({ columns, data, rowKey, actions, isLoading, groupBy, defaultGroupBy, onPinChange, onGroupChange, containerStyle, tableStyle, bordered, pinnedBottomRowData, pinnedRowClassName, rowHeight, overscan, onColumnResize, onColumnReorder, rowClassRules, onRowClick, rowSpanColumns, controlPanel, defaultDisplayPinnedIcon, defaultHiddenColumns, onColumnVisibilityChange, pagination, defaultPageSize, pageSizeOptions, onPageChange, }: DataTableProps<T>): React.JSX.Element;
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;
@@ -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%;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-actions-th{vertical-align:middle;text-align:right;height:48px;padding:0 1rem;font-size:12px;font-weight:700;box-shadow:-1px 0 #e2e8f0}.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;line-height:normal}.flexi-root input{font:inherit}.flexi-root table{border-collapse:collapse;border-spacing:0}
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-actions-th{vertical-align:middle;text-align:right;height:48px;padding:0 1rem;font-size:12px;font-weight:700;box-shadow:-1px 0 #e2e8f0}.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 './Datatable';
3
- export type { ColumnConfig } from './Datatable';
2
+ export { DataTable } from './DataTable/index';
3
+ export type { ColumnConfig, DataTableProps, PinSide, SortDirection } from './DataTable/index';