@verifiedinc-public/shared-ui-elements 11.0.3-beta.1 → 11.1.1
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/dist/components/DataTable/DataTable.context.d.ts +102 -0
- package/dist/components/DataTable/DataTable.context.mjs +1 -0
- package/dist/components/DataTable/DataTable.d.ts +8 -0
- package/dist/components/DataTable/DataTable.export.d.ts +37 -0
- package/dist/components/DataTable/DataTable.export.mjs +8 -0
- package/dist/components/DataTable/DataTable.filters.d.ts +51 -0
- package/dist/components/DataTable/DataTable.filters.mjs +1 -0
- package/dist/components/DataTable/DataTable.hooks.d.ts +43 -0
- package/dist/components/DataTable/DataTable.hooks.mjs +1 -0
- package/dist/components/DataTable/DataTable.mjs +1 -0
- package/dist/components/DataTable/DataTable.types.d.ts +525 -0
- package/dist/components/DataTable/DataTable.utils.d.ts +39 -0
- package/dist/components/DataTable/DataTable.utils.mjs +1 -0
- package/dist/components/DataTable/DataTableBody.d.ts +7 -0
- package/dist/components/DataTable/DataTableBody.mjs +1 -0
- package/dist/components/DataTable/DataTableColumnMenu.d.ts +22 -0
- package/dist/components/DataTable/DataTableColumnMenu.mjs +1 -0
- package/dist/components/DataTable/DataTableExportMenu.d.ts +16 -0
- package/dist/components/DataTable/DataTableExportMenu.mjs +1 -0
- package/dist/components/DataTable/DataTableFilterPanel.d.ts +36 -0
- package/dist/components/DataTable/DataTableFilterPanel.mjs +1 -0
- package/dist/components/DataTable/DataTableFooter.d.ts +6 -0
- package/dist/components/DataTable/DataTableFooter.mjs +1 -0
- package/dist/components/DataTable/DataTableHead.d.ts +8 -0
- package/dist/components/DataTable/DataTableHead.mjs +1 -0
- package/dist/components/DataTable/DataTableHeaderCell.d.ts +16 -0
- package/dist/components/DataTable/DataTableHeaderCell.mjs +1 -0
- package/dist/components/DataTable/DataTableManageColumnsPanel.d.ts +30 -0
- package/dist/components/DataTable/DataTableManageColumnsPanel.mjs +1 -0
- package/dist/components/DataTable/DataTablePanels.d.ts +6 -0
- package/dist/components/DataTable/DataTablePanels.mjs +1 -0
- package/dist/components/DataTable/DataTableToolbar.d.ts +7 -0
- package/dist/components/DataTable/DataTableToolbar.mjs +1 -0
- package/dist/components/DataTable/index.d.ts +5 -0
- package/dist/components/chart/BillableEventsTable/BillableEventsTable.mjs +1 -1
- package/dist/components/chart/BillableEventsTable/BillableEventsTable.types.d.ts +0 -23
- package/dist/components/chart/BillableEventsTable/BrandDetailsPanel.d.ts +1 -2
- package/dist/components/chart/BillableEventsTable/BrandDetailsPanel.mjs +1 -1
- package/dist/components/chart/BillableEventsTable/exportBillableEventsToCsv.d.ts +2 -4
- package/dist/components/chart/BillableEventsTable/exportBillableEventsToCsv.mjs +3 -3
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.mjs +1 -1
- package/dist/hooks/useBidirectionalScroll.d.ts +8 -1
- package/dist/hooks/useBidirectionalScroll.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { CSSProperties, MouseEvent, MutableRefObject, ReactNode, RefObject, TouchEvent } from 'react';
|
|
2
|
+
import { Cell, ColumnPinningPosition, Header, OnChangeFn, Row, Table } from '@tanstack/react-table';
|
|
3
|
+
import { Virtualizer } from '@tanstack/react-virtual';
|
|
4
|
+
import { DataTableActiveFilters, DataTableBidirectionalScroll, DataTableCellProps, DataTableData, DataTableIcons, DataTableRowContext } from './DataTable.types';
|
|
5
|
+
/** Where a floating panel opens and which of its top corners pins there. */
|
|
6
|
+
export type DataTablePanelAnchor = {
|
|
7
|
+
anchorPosition: {
|
|
8
|
+
top: number;
|
|
9
|
+
left: number;
|
|
10
|
+
};
|
|
11
|
+
transformHorizontal: 'left' | 'right';
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* One floating column panel is open at a time: a column's kebab menu
|
|
15
|
+
* (anchored to its button), or the filter / manage columns panels
|
|
16
|
+
* (anchored to a position snapshot, since they can outlive the element
|
|
17
|
+
* that opened them). With the toolbar shown, those two panels anchor to
|
|
18
|
+
* their toolbar button instead, wherever they were opened from.
|
|
19
|
+
*/
|
|
20
|
+
export type DataTableColumnPanelState = {
|
|
21
|
+
type: 'menu';
|
|
22
|
+
columnId: string;
|
|
23
|
+
anchorEl: HTMLElement;
|
|
24
|
+
} | ({
|
|
25
|
+
type: 'filter';
|
|
26
|
+
columnId: string;
|
|
27
|
+
} & DataTablePanelAnchor) | ({
|
|
28
|
+
type: 'manageColumns';
|
|
29
|
+
} & DataTablePanelAnchor) | null;
|
|
30
|
+
/**
|
|
31
|
+
* Everything the DataTable subcomponents (toolbar, head, body, footer,
|
|
32
|
+
* floating panels) read from the root component. The value is rebuilt on
|
|
33
|
+
* every DataTable render — the same cadence the single-component render
|
|
34
|
+
* had — so it is intentionally not memoized.
|
|
35
|
+
*/
|
|
36
|
+
export interface DataTableContextValue<TData extends DataTableData> {
|
|
37
|
+
/** TanStack table instance. */
|
|
38
|
+
table: Table<TData>;
|
|
39
|
+
/** Unfiltered rows — the filter panel derives value suggestions from them. */
|
|
40
|
+
data: TData[];
|
|
41
|
+
/** Rows of the current page (or all rows when pagination is disabled). */
|
|
42
|
+
rows: Array<Row<TData>>;
|
|
43
|
+
/** Total row count across every page — drives the pagination footer. */
|
|
44
|
+
totalRowCount: number;
|
|
45
|
+
/**
|
|
46
|
+
* Visible leaf column count — drives the colSpan of full-width rows
|
|
47
|
+
* (loading, empty, dividers, virtualizer padding).
|
|
48
|
+
*/
|
|
49
|
+
columnCount: number;
|
|
50
|
+
icons: DataTableIcons;
|
|
51
|
+
isLoading: boolean;
|
|
52
|
+
emptyMessage: string;
|
|
53
|
+
tableLayout: 'auto' | 'fixed';
|
|
54
|
+
enableColumnResizing: boolean;
|
|
55
|
+
enableColumnMenu: boolean;
|
|
56
|
+
enableExport: boolean;
|
|
57
|
+
exportFilename: string;
|
|
58
|
+
disablePagination: boolean;
|
|
59
|
+
pageSizeOptions: number[];
|
|
60
|
+
footerLeft?: ReactNode;
|
|
61
|
+
bidirectionalScroll?: DataTableBidirectionalScroll;
|
|
62
|
+
renderLoading?: (columnCount: number) => ReactNode;
|
|
63
|
+
renderRow?: (context: DataTableRowContext<TData>) => ReactNode;
|
|
64
|
+
filters: DataTableActiveFilters;
|
|
65
|
+
onFiltersChange: OnChangeFn<DataTableActiveFilters>;
|
|
66
|
+
search: string;
|
|
67
|
+
onSearchChange: OnChangeFn<string>;
|
|
68
|
+
columnPanel: DataTableColumnPanelState;
|
|
69
|
+
setColumnPanel: (panel: DataTableColumnPanelState) => void;
|
|
70
|
+
closeColumnPanel: () => void;
|
|
71
|
+
openFilterPanel: (columnId: string, opener: HTMLElement) => void;
|
|
72
|
+
openManageColumnsPanel: (opener: HTMLElement) => void;
|
|
73
|
+
toolbarFilterButtonRef: RefObject<HTMLButtonElement>;
|
|
74
|
+
toolbarManageColumnsButtonRef: RefObject<HTMLButtonElement>;
|
|
75
|
+
headerRowRefs: MutableRefObject<Array<HTMLTableRowElement | null>>;
|
|
76
|
+
headerCellRefs: MutableRefObject<Record<string, HTMLTableCellElement | null>>;
|
|
77
|
+
/** Sticky top offsets of the header rows below the first (grouped headers). */
|
|
78
|
+
headerRowTops: number[];
|
|
79
|
+
/**
|
|
80
|
+
* Measured total header height — the loading-newer indicator sticks
|
|
81
|
+
* right below it. 0 unless bidirectional scroll is active.
|
|
82
|
+
*/
|
|
83
|
+
headerHeight: number;
|
|
84
|
+
isPinnedEdge: (pinned: ColumnPinningPosition, columnId: string) => boolean;
|
|
85
|
+
getPinnedOffsetStyle: (pinned: ColumnPinningPosition, columnId: string) => CSSProperties | undefined;
|
|
86
|
+
getCellProps: (cell: Cell<TData, unknown>) => DataTableCellProps;
|
|
87
|
+
hasResizedColumns: boolean;
|
|
88
|
+
startColumnResize: (header: Header<TData, unknown>, event: MouseEvent<HTMLElement> | TouchEvent<HTMLElement>) => void;
|
|
89
|
+
virtualizer: Virtualizer<HTMLDivElement, Element>;
|
|
90
|
+
}
|
|
91
|
+
interface DataTableProviderProps<TData extends DataTableData> {
|
|
92
|
+
value: DataTableContextValue<TData>;
|
|
93
|
+
children: ReactNode;
|
|
94
|
+
}
|
|
95
|
+
export declare function DataTableProvider<TData extends DataTableData>({ value, children, }: Readonly<DataTableProviderProps<TData>>): import("react").JSX.Element;
|
|
96
|
+
/**
|
|
97
|
+
* Reads the enclosing DataTable's context. Subcomponents default to the
|
|
98
|
+
* base `DataTableData` row shape; pass the concrete `TData` when a typed
|
|
99
|
+
* view is needed.
|
|
100
|
+
*/
|
|
101
|
+
export declare function useDataTableContext<TData extends DataTableData = DataTableData>(): DataTableContextValue<TData>;
|
|
102
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{createContext as r,useContext as n}from"react";import{jsx as o}from"react/jsx-runtime";const t=r(null);function s({value:e,children:a}){return o(t.Provider,{value:e,children:a})}function u(){const e=n(t);if(!e)throw new Error("useDataTableContext must be used within a <DataTable/>");return e}export{s as DataTableProvider,u as useDataTableContext};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DataTableData, DataTableProps } from './DataTable.types';
|
|
2
|
+
/**
|
|
3
|
+
* Root of the DataTable: owns every piece of table state and the TanStack
|
|
4
|
+
* instance, shares them with the subcomponents (toolbar, head, body,
|
|
5
|
+
* footer, floating panels) through DataTableProvider, and renders the
|
|
6
|
+
* layout shell around them.
|
|
7
|
+
*/
|
|
8
|
+
export declare function DataTable<TData extends DataTableData>({ data, columns, getRowId, renderRow, initialSorting, sorting: controlledSorting, onSortingChange, manualSorting, initialPageSize, pageSizeOptions, pagination: controlledPagination, onPaginationChange, manualPagination, rowCount, disableSorting, disablePagination, bidirectionalScroll, enableColumnResizing, enableColumnMenu, enableColumnPinning, showToolbar, enableExport, exportFilename, initialFilters, filters: controlledFilters, onFiltersChange, manualFiltering, initialSearch, search: controlledSearch, onSearchChange, initialColumnVisibility, columnVisibility: controlledColumnVisibility, onColumnVisibilityChange, initialColumnPinning, columnPinning: controlledColumnPinning, onColumnPinningChange, footerLeft, estimateRowHeight, minWidth, maxHeight, tableLayout, icons, emptyMessage, isLoading, renderLoading, }: Readonly<DataTableProps<TData>>): import("react").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Table } from '@tanstack/react-table';
|
|
2
|
+
import { DataTableData } from './DataTable.types';
|
|
3
|
+
/** Cell value shape carried into the export formats. */
|
|
4
|
+
export type DataTableExportValue = string | number | boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Snapshot of the displayed table used by every export format: the
|
|
7
|
+
* filtered + sorted rows across every page and the visible accessor
|
|
8
|
+
* columns in display order.
|
|
9
|
+
*/
|
|
10
|
+
export interface DataTableExportModel {
|
|
11
|
+
/**
|
|
12
|
+
* Group header row mirroring the table's grouped header — each group
|
|
13
|
+
* label at the start of its span, blanks elsewhere. Omitted when no
|
|
14
|
+
* visible column is grouped.
|
|
15
|
+
*/
|
|
16
|
+
groupHeader?: string[];
|
|
17
|
+
header: string[];
|
|
18
|
+
rows: DataTableExportValue[][];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Builds the export snapshot from the table instance. Rows come from the
|
|
22
|
+
* pre-pagination row model, so they reflect the active filters, quick
|
|
23
|
+
* search and sort order across every page (with manual pagination only
|
|
24
|
+
* the loaded page is available). Display-only columns (no accessor, e.g.
|
|
25
|
+
* expand chevrons) are skipped.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getDataTableExportModel<TData extends DataTableData>(table: Table<TData>): DataTableExportModel;
|
|
28
|
+
/** Downloads the export snapshot as `<filename>.csv`. */
|
|
29
|
+
export declare function exportDataTableToCsv(model: DataTableExportModel, filename: string): void;
|
|
30
|
+
/** Downloads the export snapshot as `<filename>.xlsx`. */
|
|
31
|
+
export declare function exportDataTableToExcel(model: DataTableExportModel, filename: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Opens the browser print dialog with a print-friendly rendering of the
|
|
34
|
+
* export snapshot (via a hidden iframe, so the page itself never
|
|
35
|
+
* navigates). The title becomes the printed document name.
|
|
36
|
+
*/
|
|
37
|
+
export declare function printDataTable(model: DataTableExportModel, title: string): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";import{getColumnLabel as y}from"./DataTable.utils.mjs";function b(e){return e==null?"":typeof e=="number"||typeof e=="boolean"?e:e instanceof Date?e.toLocaleString():typeof e=="object"?JSON.stringify(e):String(e)}function U(e){const n=e.getVisibleLeafColumns().filter(o=>o.accessorFn!==void 0),t=n.map(o=>{var r;const l=(r=o.parent)==null?void 0:r.columnDef.header;return typeof l=="string"?l:""});return{groupHeader:t.some(o=>o!=="")?t.map((o,r)=>r>0&&t[r-1]===o?"":o):void 0,header:n.map(o=>y(o)),rows:e.getPrePaginationRowModel().rows.map(o=>n.map(r=>b(o.getValue(r.id))))}}function x(e,n){const t=URL.createObjectURL(e),o=document.createElement("a");o.href=t,o.download=n,o.click(),URL.revokeObjectURL(t)}function w(e){const n=String(e);return/[",\n]/.test(n)?`"${n.replace(/"/g,'""')}"`:n}function v(e,n){const t=[...e.groupHeader?[e.groupHeader]:[],e.header,...e.rows].map(r=>r.map(w).join(",")),o=new Blob(["\uFEFF",t.join(`
|
|
2
|
+
`)],{type:"text/csv;charset=utf-8;"});x(o,`${n}.csv`)}function f(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function k(e){let n="",t=e+1;for(;t>0;)n=String.fromCharCode(65+(t-1)%26)+n,t=Math.floor((t-1)/26);return n}function T(e){return`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>${[...e.groupHeader?[e.groupHeader]:[],e.header,...e.rows].map((n,t)=>{const o=n.map((r,l)=>{const s=`${k(l)}${t+1}`;return typeof r=="number"&&Number.isFinite(r)?`<c r="${s}"><v>${r}</v></c>`:typeof r=="boolean"?`<c r="${s}" t="b"><v>${r?1:0}</v></c>`:`<c r="${s}" t="inlineStr"><is><t xml:space="preserve">${f(String(r))}</t></is></c>`}).join("");return`<row r="${t+1}">${o}</row>`}).join("")}</sheetData></worksheet>`}const $=[{name:"[Content_Types].xml",content:'<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/></Types>'},{name:"_rels/.rels",content:'<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>'},{name:"xl/workbook.xml",content:'<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets><sheet name="Data" sheetId="1" r:id="rId1"/></sheets></workbook>'},{name:"xl/_rels/workbook.xml.rels",content:'<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/></Relationships>'}],D=(()=>{const e=new Uint32Array(256);for(let n=0;n<256;n++){let t=n;for(let o=0;o<8;o++)t=t&1?3988292384^t>>>1:t>>>1;e[n]=t>>>0}return e})();function R(e){let n=4294967295;for(let t=0;t<e.length;t++)n=D[(n^e[t])&255]^n>>>8;return(n^4294967295)>>>0}function C(e){const n=new TextEncoder,t=[],o=[];let r=0;for(const p of e){const m=n.encode(p.name),c=n.encode(p.content),g=R(c),i=new DataView(new ArrayBuffer(30));i.setUint32(0,67324752,!0),i.setUint16(4,20,!0),i.setUint16(6,2048,!0),i.setUint16(8,0,!0),i.setUint16(10,0,!0),i.setUint16(12,33,!0),i.setUint32(14,g,!0),i.setUint32(18,c.length,!0),i.setUint32(22,c.length,!0),i.setUint16(26,m.length,!0),i.setUint16(28,0,!0),t.push(new Uint8Array(i.buffer),m,c);const a=new DataView(new ArrayBuffer(46));a.setUint32(0,33639248,!0),a.setUint16(4,20,!0),a.setUint16(6,20,!0),a.setUint16(8,2048,!0),a.setUint16(10,0,!0),a.setUint16(12,0,!0),a.setUint16(14,33,!0),a.setUint32(16,g,!0),a.setUint32(20,c.length,!0),a.setUint32(24,c.length,!0),a.setUint16(28,m.length,!0),a.setUint32(42,r,!0),o.push(new Uint8Array(a.buffer),m),r+=30+m.length+c.length}const l=o.reduce((p,m)=>p+m.length,0),s=new DataView(new ArrayBuffer(22));s.setUint32(0,101010256,!0),s.setUint16(8,e.length,!0),s.setUint16(10,e.length,!0),s.setUint32(12,l,!0),s.setUint32(16,r,!0);const h=new Uint8Array(s.buffer),d=new Uint8Array(r+l+h.length);let u=0;for(const p of[...t,...o,h])d.set(p,u),u+=p.length;return d.buffer}function j(e,n){const t=C([...$,{name:"xl/worksheets/sheet1.xml",content:T(e)}]);x(new Blob([t],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}),`${n}.xlsx`)}function F(e,n){const t=(l,s)=>`<tr>${l.map(h=>`<${s}${typeof h=="number"?' class="num"':""}>${f(String(h))}</${s}>`).join("")}</tr>`,o=[...e.groupHeader?[t(e.groupHeader,"th")]:[],t(e.header,"th")].join(""),r=e.rows.map(l=>t(l,"td")).join("");return`<!doctype html><html><head><meta charset="utf-8"><title>${f(n)}</title><style>
|
|
3
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; margin: 16px; }
|
|
4
|
+
table { border-collapse: collapse; width: 100%; font-size: 12px; }
|
|
5
|
+
th, td { padding: 6px 8px; border-bottom: 1px solid #ddd; text-align: left; }
|
|
6
|
+
th { text-transform: uppercase; font-size: 10px; }
|
|
7
|
+
.num { text-align: right; }
|
|
8
|
+
</style></head><body><table><thead>${o}</thead><tbody>${r}</tbody></table></body></html>`}function S(e,n){const t=document.createElement("iframe");t.style.position="fixed",t.style.right="0",t.style.bottom="0",t.style.width="0",t.style.height="0",t.style.border="0",t.onload=()=>{const o=t.contentWindow;if(!o){t.remove();return}o.addEventListener("afterprint",()=>t.remove()),o.focus(),o.print()},t.srcdoc=F(e,n),document.body.appendChild(t)}export{v as exportDataTableToCsv,j as exportDataTableToExcel,U as getDataTableExportModel,S as printDataTable};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ColumnDef, Row } from '@tanstack/react-table';
|
|
2
|
+
import { DataTableActiveFilters, DataTableData, DataTableFilterOperator, DataTableFilterRow } from './DataTable.types';
|
|
3
|
+
/** Option entries for the filter panel operator select, in display order. */
|
|
4
|
+
export declare const dataTableFilterOperators: ReadonlyArray<{
|
|
5
|
+
value: DataTableFilterOperator;
|
|
6
|
+
label: string;
|
|
7
|
+
}>;
|
|
8
|
+
/** Whether the operator needs a value input to be meaningful. */
|
|
9
|
+
export declare function filterOperatorRequiresValue(operator: DataTableFilterOperator): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Whether the operator takes multiple values — rendered as a chips input
|
|
12
|
+
* in the filter panel instead of a single text field.
|
|
13
|
+
*/
|
|
14
|
+
export declare function filterOperatorIsMultiValue(operator: DataTableFilterOperator): boolean;
|
|
15
|
+
/** Empty filter state — no rows, AND logic. */
|
|
16
|
+
export declare const EMPTY_FILTERS: DataTableActiveFilters;
|
|
17
|
+
/**
|
|
18
|
+
* Whether a filter row has a usable value — rows without a value pass all
|
|
19
|
+
* rows through, so they are excluded from the active-filter indicator and
|
|
20
|
+
* from pre-filtering.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isFilterRowActive(row: DataTableFilterRow): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Client-side multi-filter: filters `data` rows using `filters.rows` with
|
|
25
|
+
* AND or OR logic. Rows with incomplete values are skipped. Returns `data`
|
|
26
|
+
* unchanged when there are no active rows (no re-allocation).
|
|
27
|
+
*
|
|
28
|
+
* With `columns`, each filter resolves its value through the targeted
|
|
29
|
+
* column's accessor (so columns reading nested values filter correctly);
|
|
30
|
+
* without them it falls back to the raw row key.
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyFilters<TData extends DataTableData>(data: TData[], filters: DataTableActiveFilters, columns?: Array<ColumnDef<TData, unknown>>): TData[];
|
|
33
|
+
/**
|
|
34
|
+
* Client-side quick search: keeps rows where any cell value contains the
|
|
35
|
+
* query (case-insensitive over the stringified value, mirroring
|
|
36
|
+
* `dataTableFilterFn`). Returns `data` unchanged when the query is blank
|
|
37
|
+
* (no re-allocation).
|
|
38
|
+
*
|
|
39
|
+
* With `columns`, the search covers the cell values the columns resolve —
|
|
40
|
+
* searching raw row values instead would also match fields that never
|
|
41
|
+
* render (ids, nested objects). Without them it falls back to every
|
|
42
|
+
* top-level row value.
|
|
43
|
+
*/
|
|
44
|
+
export declare function applySearch<TData extends DataTableData>(data: TData[], search: string, columns?: Array<ColumnDef<TData, unknown>>): TData[];
|
|
45
|
+
/**
|
|
46
|
+
* Operator-based filter function backing every filterable column.
|
|
47
|
+
* Comparisons are case-insensitive over the stringified cell value, so it
|
|
48
|
+
* works for the unknown-shape records the table is built around. Filters
|
|
49
|
+
* without a usable value match every row.
|
|
50
|
+
*/
|
|
51
|
+
export declare function dataTableFilterFn<TData>(row: Row<TData>, columnId: string, filterValue: unknown): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function d(e){return e.id?e.id:"accessorKey"in e&&e.accessorKey!==void 0?String(e.accessorKey).replace(/\./g,"_"):typeof e.header=="string"?e.header:void 0}function c(e){const n={};for(const s of e){if("columns"in s&&Array.isArray(s.columns)){Object.assign(n,c(s.columns));continue}const t=d(s);if(t!==void 0){if("accessorFn"in s&&s.accessorFn)n[t]=s.accessorFn;else if("accessorKey"in s&&s.accessorKey!==void 0){const i=String(s.accessorKey).split(".");n[t]=l=>i.reduce((r,a)=>r?.[a],l)}}}return n}const m=[{value:"contains",label:"contains"},{value:"doesNotContain",label:"does not contain"},{value:"equals",label:"equals"},{value:"doesNotEqual",label:"does not equal"},{value:"startsWith",label:"starts with"},{value:"endsWith",label:"ends with"},{value:"isEmpty",label:"is empty"},{value:"isNotEmpty",label:"is not empty"},{value:"isAnyOf",label:"is any of"}];function f(e){return e!=="isEmpty"&&e!=="isNotEmpty"}function y(e){return e==="contains"||e==="isAnyOf"}const g={rows:[],logicOperator:"and"};function p(e){return f(e.operator)?Array.isArray(e.value)?y(e.operator)&&e.value.some(n=>n.trim()!==""):e.operator==="isAnyOf"?!1:typeof e.value=="string"&&e.value.trim()!=="":!0}function h(e,n,s){const t=n.rows.filter(p);if(t.length===0)return e;const i=s?c(s):{};return e.filter((l,r)=>{const a={getValue:u=>i[u]?i[u](l,r):l[u]},o=u=>v(a,u.columnId,{operator:u.operator,value:u.value});return n.logicOperator==="and"?t.every(o):t.some(o)})}function b(e,n,s){const t=n.trim().toLowerCase();if(t==="")return e;const i=r=>r!=null&&r!==""&&String(r).toLowerCase().includes(t),l=s?Object.values(c(s)):[];return l.length>0?e.filter((r,a)=>l.some(o=>i(o(r,a)))):e.filter(r=>Object.values(r).some(i))}function v(e,n,s){const t=s;if(!t)return!0;const i=e.getValue(n),l=i==null||i==="",r=l?"":String(i).toLowerCase();switch(t.operator){case"isEmpty":return l;case"isNotEmpty":return!l;case"isAnyOf":{const a=Array.isArray(t.value)?t.value:[];return a.length===0||a.some(o=>r===o.trim().toLowerCase())}case"contains":{const a=(Array.isArray(t.value)?t.value:[t.value??""]).map(o=>o.trim().toLowerCase()).filter(o=>o!=="");return a.length===0||a.some(o=>r.includes(o))}default:{const a=typeof t.value=="string"?t.value.trim().toLowerCase():"";if(a==="")return!0;switch(t.operator){case"doesNotContain":return!r.includes(a);case"equals":return r===a;case"doesNotEqual":return r!==a;case"startsWith":return r.startsWith(a);case"endsWith":return r.endsWith(a);default:return!0}}}}export{g as EMPTY_FILTERS,h as applyFilters,b as applySearch,v as dataTableFilterFn,m as dataTableFilterOperators,y as filterOperatorIsMultiValue,f as filterOperatorRequiresValue,p as isFilterRowActive};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { MutableRefObject } from 'react';
|
|
2
|
+
import { OnChangeFn } from '@tanstack/react-table';
|
|
3
|
+
/**
|
|
4
|
+
* TanStack-style table state that is controlled when the consumer passes
|
|
5
|
+
* the state prop and internal otherwise; the change handler resolves
|
|
6
|
+
* updater functions and reports the next value either way.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useControllableState<T>(initialValue: T, controlledValue: T | undefined, onChange?: (next: T) => void): [T, OnChangeFn<T>];
|
|
9
|
+
/**
|
|
10
|
+
* Grouped columns produce multiple header rows. MUI's stickyHeader pins
|
|
11
|
+
* every header cell at top: 0, so rows below the first must be offset by
|
|
12
|
+
* the measured height of the rows above to stack instead of overlapping.
|
|
13
|
+
*
|
|
14
|
+
* `columnsKey` (the resolved column defs) remounts the header rows, so
|
|
15
|
+
* the observer must re-attach to the new nodes whenever it changes.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useHeaderRowTops(headerRowCount: number, columnsKey: unknown): {
|
|
18
|
+
headerRowRefs: MutableRefObject<Array<HTMLTableRowElement | null>>;
|
|
19
|
+
headerRowTops: number[];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Measured total height of the sticky header rows — the bidirectional
|
|
23
|
+
* loading-newer indicator sticks right below them, and their height
|
|
24
|
+
* varies with grouped headers and wrapping labels. Only measured while
|
|
25
|
+
* `enabled` (bidirectional scroll is active); 0 otherwise.
|
|
26
|
+
*/
|
|
27
|
+
export declare function useStickyHeaderHeight(enabled: boolean, headerRowRefs: MutableRefObject<Array<HTMLTableRowElement | null>>, headerRowCount: number, columnsKey: unknown): number;
|
|
28
|
+
/** Sticky offset maps for pinned columns (column id -> px). */
|
|
29
|
+
export type DataTablePinnedOffsets = {
|
|
30
|
+
left: Record<string, number>;
|
|
31
|
+
right: Record<string, number>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Sticky offsets for pinned columns, measured from the rendered leaf
|
|
35
|
+
* header cells — TanStack's own sizes assume the defs' sizes, which the
|
|
36
|
+
* browser's table layout does not honor. Also returns the header cell
|
|
37
|
+
* refs: they double as the width source for freezing column widths when a
|
|
38
|
+
* resize drag starts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function usePinnedOffsets(leftPinnedIds: string[], rightPinnedIds: string[], columnsKey: unknown): {
|
|
41
|
+
headerCellRefs: MutableRefObject<Record<string, HTMLTableCellElement | null>>;
|
|
42
|
+
pinnedOffsets: DataTablePinnedOffsets;
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{useState as b,useRef as O,useLayoutEffect as y}from"react";function j(r,s,t){const[o,a]=b(r),i=s??o;return[i,n=>{const e=typeof n=="function"?n(i):n;s===void 0&&a(e),t?.(e)}]}function k(r,s){const t=O([]),[o,a]=b([]);return y(()=>{if(r<=1){a(e=>e.length===0?e:[]);return}const i=()=>{var e;const c=[];let f=0;for(let u=0;u<r;u+=1)c.push(f),f+=((e=t.current[u])==null?void 0:e.offsetHeight)??0;a(u=>u.length===c.length&&u.every((v,l)=>v===c[l])?u:c)};if(i(),typeof ResizeObserver>"u")return;const n=new ResizeObserver(i);return t.current.slice(0,r).forEach(e=>e&&n.observe(e)),()=>n.disconnect()},[r,s]),{headerRowRefs:t,headerRowTops:o}}function z(r,s,t,o){const[a,i]=b(0);return y(()=>{if(!r)return;const n=()=>{const c=s.current.slice(0,t).reduce((f,u)=>f+(u?.offsetHeight??0),0);i(f=>f===c?f:c)};if(n(),typeof ResizeObserver>"u")return;const e=new ResizeObserver(n);return s.current.slice(0,t).forEach(c=>c&&e.observe(c)),()=>e.disconnect()},[r,s,t,o]),a}function w(r,s){const t=Object.keys(r);return t.length===Object.keys(s).length&&t.every(o=>r[o]===s[o])}function H(r,s,t){const o=O({}),[a,i]=b({left:{},right:{}}),n=r.join(","),e=s.join(",");return y(()=>{if(n===""&&e===""){i(l=>Object.keys(l.left).length===0&&Object.keys(l.right).length===0?l:{left:{},right:{}});return}const c=n===""?[]:n.split(","),f=e===""?[]:e.split(","),u=()=>{var l,g;const R={};let d=0;for(const h of c)R[h]=d,d+=((l=o.current[h])==null?void 0:l.getBoundingClientRect().width)??0;const p={};d=0;for(const h of[...f].reverse())p[h]=d,d+=((g=o.current[h])==null?void 0:g.getBoundingClientRect().width)??0;i(h=>w(h.left,R)&&w(h.right,p)?h:{left:R,right:p})};if(u(),typeof ResizeObserver>"u")return;const v=new ResizeObserver(u);return[...c,...f].forEach(l=>{const g=o.current[l];g&&v.observe(g)}),()=>v.disconnect()},[n,e,t]),{headerCellRefs:o,pinnedOffsets:a}}export{j as useControllableState,k as useHeaderRowTops,H as usePinnedOffsets,z as useStickyHeaderHeight};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{useState as Y,useRef as x,useMemo as _,useEffect as Xe}from"react";import{useReactTable as en,getPaginationRowModel as nn,getSortedRowModel as on,getCoreRowModel as tn}from"@tanstack/react-table";import{useVirtualizer as an}from"@tanstack/react-virtual";import{Box as ln,TableContainer as rn,Table as sn}from"@mui/material";import{useBidirectionalScroll as dn}from"../../hooks/useBidirectionalScroll.mjs";import{DataTableProvider as un}from"./DataTable.context.mjs";import{useControllableState as u,useHeaderRowTops as gn,useStickyHeaderHeight as mn,usePinnedOffsets as fn}from"./DataTable.hooks.mjs";import{applySearch as hn,applyFilters as cn,EMPTY_FILTERS as pn}from"./DataTable.filters.mjs";import{inferColumns as bn,applyMetaWidthsToSizes as Cn,getColumnMeta as q,measureRowGroup as Rn}from"./DataTable.utils.mjs";import{DataTableBody as wn}from"./DataTableBody.mjs";import{DataTableFooter as Sn}from"./DataTableFooter.mjs";import{DataTableHead as Pn}from"./DataTableHead.mjs";import{DataTablePanels as vn}from"./DataTablePanels.mjs";import{DataTableToolbar as yn}from"./DataTableToolbar.mjs";import{jsx as r,jsxs as A}from"react/jsx-runtime";const xn=25,Ln=[10,25,50,100],zn=53,Mn={},Tn={left:[],right:[]},J=()=>{};function Hn({data:a,columns:L,getRowId:z,renderRow:U,initialSorting:Z=[],sorting:Q,onSortingChange:X,manualSorting:M=!1,initialPageSize:ee=xn,pageSizeOptions:ne=Ln,pagination:oe,onPaginationChange:te,manualPagination:g=!1,rowCount:c,disableSorting:p=!1,disablePagination:b=!1,bidirectionalScroll:o,enableColumnResizing:s=!1,enableColumnMenu:ie=!1,enableColumnPinning:m=!1,showToolbar:ae=!1,enableExport:le=!1,exportFilename:re="data",initialFilters:se=pn,filters:de,onFiltersChange:ue,manualFiltering:T=!1,initialSearch:ge="",search:me,onSearchChange:fe,initialColumnVisibility:H={},columnVisibility:he,onColumnVisibilityChange:ce,initialColumnPinning:pe=Tn,columnPinning:be,onColumnPinningChange:Ce,footerLeft:Re,estimateRowHeight:we=zn,minWidth:Se=650,maxHeight:Pe=800,tableLayout:C="auto",icons:ve=Mn,emptyMessage:ye="No data to display.",isLoading:xe=!1,renderLoading:Le}){const[ze,Me]=u(Z,Q,X),[Te,He]=u({pageIndex:0,pageSize:ee},oe,te),[R,Oe]=u(se,de,ue),[w,Ve]=u(ge,me,fe),[Fe,Ee]=u(H,he,ce),[Ie,Be]=u(pe,be,Ce),[S,De]=Y({}),O=s&&Object.keys(S).length>0,[Ne,f]=Y(null),ke=()=>{f(null)},V=x(null),F=x(null),E=(e,n)=>{if(n){const d=n.getBoundingClientRect();return{anchorPosition:{top:d.bottom,left:d.right},transformHorizontal:"right"}}const t=e.getBoundingClientRect();return{anchorPosition:{top:t.bottom,left:t.left},transformHorizontal:"left"}},$e=(e,n)=>{f({type:"filter",columnId:e,...E(n,V.current)})},We=e=>{f({type:"manageColumns",...E(e,F.current)})},P=x(null),l=_(()=>{const e=L??bn(a);return s?Cn(e):e},[L,a,s]),je=_(()=>T?a:hn(cn(a,R,l),w,l),[a,R,w,T,l]),i=en({data:je,columns:l,state:{...p?{}:{sorting:ze},...b?{}:{pagination:Te},...m?{columnPinning:Ie}:{},columnVisibility:Fe,columnSizing:S},initialState:{columnVisibility:H},onSortingChange:Me,onPaginationChange:He,onColumnVisibilityChange:Ee,onColumnPinningChange:Be,onColumnSizingChange:De,enableColumnPinning:m,columnResizeMode:"onChange",enableColumnResizing:s,getCoreRowModel:tn(),defaultColumn:{enableSorting:!1},enableSorting:!p,manualSorting:M,...p||M?{}:{getSortedRowModel:on()},manualPagination:g,...g&&c!==void 0?{rowCount:c}:{},getRowCanExpand:()=>!0,...b||g?{}:{getPaginationRowModel:nn()},...z?{getRowId:z}:{}}),v=i.getRowModel().rows,Ge=g?c??a.length:i.getPrePaginationRowModel().rows.length,Ke=i.getVisibleLeafColumns().length||1,Ye=s&&i.getVisibleLeafColumns().some(e=>{var n;return typeof((n=q(e.columnDef.meta))==null?void 0:n.width)=="number"}),_e=O||Ye,y=m?i.getLeftVisibleLeafColumns().map(e=>e.id):[],I=m?i.getRightVisibleLeafColumns().map(e=>e.id):[],B=i.getHeaderGroups().length,{headerRowRefs:D,headerRowTops:qe}=gn(B,l),N=o!==void 0,Ae=mn(N,D,B,l),{headerCellRefs:k,pinnedOffsets:$}=fn(y,I,l),Je=(e,n)=>{var t;for(const d of i.getVisibleLeafColumns())if(S[d.id]===void 0){const K=(t=k.current[d.id])==null?void 0:t.getBoundingClientRect().width;K&&(d.columnDef.size=Math.round(K))}e.getResizeHandler()(n)},W=(e,n)=>e==="left"?y[y.length-1]===n:I[0]===n,j=(e,n)=>{if(e==="left")return{left:$.left[n]??0};if(e==="right")return{right:$.right[n]??0}},G=C==="fixed"?{overflow:"hidden",textOverflow:"ellipsis"}:void 0,Ue=(e,n)=>e?t=>({...G,position:"sticky",zIndex:1,bgcolor:"background.paper",".MuiTableRow-hover:hover > &":{backgroundImage:`linear-gradient(${t.palette.action.hover}, ${t.palette.action.hover})`},...W(e,n)?{boxShadow:`inset ${e==="left"?-1:1}px 0 0 ${t.palette.divider}`}:{}}):G,Ze=e=>{var n;const t=e.column.getIsPinned();return{align:(n=q(e.column.columnDef.meta))==null?void 0:n.align,style:j(t,e.column.id),sx:Ue(t,e.column.id)}},h=an({count:v.length,getScrollElement:()=>P.current,estimateSize:()=>we,overscan:5,measureElement:Rn});dn({enabled:N,scrollContainerRef:P,virtualizer:h,rowCount:v.length,hasNewer:o?.hasNewer,hasOlder:o?.hasOlder,isLoadingNewer:o?.isLoadingNewer,isLoadingOlder:o?.isLoadingOlder,onLoadNewer:o?.onLoadNewer??J,onLoadOlder:o?.onLoadOlder??J,resetKey:o?.resetKey});const{pageIndex:Qe}=i.getState().pagination;return Xe(()=>{h.scrollToOffset(0)},[Qe,h]),r(un,{value:{table:i,data:a,rows:v,totalRowCount:Ge,columnCount:Ke,icons:ve,isLoading:xe,emptyMessage:ye,tableLayout:C,enableColumnResizing:s,enableColumnMenu:ie,enableExport:le,exportFilename:re,disablePagination:b,pageSizeOptions:ne,footerLeft:Re,bidirectionalScroll:o,renderLoading:Le,renderRow:U,filters:R,onFiltersChange:Oe,search:w,onSearchChange:Ve,columnPanel:Ne,setColumnPanel:f,closeColumnPanel:ke,openFilterPanel:$e,openManageColumnsPanel:We,toolbarFilterButtonRef:V,toolbarManageColumnsButtonRef:F,headerRowRefs:D,headerCellRefs:k,headerRowTops:qe,headerHeight:Ae,isPinnedEdge:W,getPinnedOffsetStyle:j,getCellProps:Ze,hasResizedColumns:O,startColumnResize:Je,virtualizer:h},children:A(ln,{sx:{width:"100%"},children:[ae&&r(yn,{}),r(rn,{ref:P,sx:{maxHeight:Pe,width:0,minWidth:"100%"},children:A(sn,{stickyHeader:!0,sx:{minWidth:Se,tableLayout:C},style:_e?{width:`max(${i.getTotalSize()}px, 100%)`}:void 0,"aria-label":"data table",children:[r(Pn,{}),r(wn,{})]})}),r(vn,{}),r(Sn,{})]})})}export{Hn as DataTable};
|