import { Column, ColumnDef, ColumnDef as ColumnDef$1, ColumnFiltersState, ColumnFiltersState as ColumnFiltersState$1, FilterFn, OnChangeFn, SortingState, SortingState as SortingState$1, Table as Table$1, VisibilityState, VisibilityState as VisibilityState$1 } from "@tanstack/react-table"; import { MotionValue } from "framer-motion"; import * as React from "react"; import { Dispatch, MouseEvent, ReactNode, SetStateAction } from "react"; import { ClassValue } from "clsx"; //#region src/types.d.ts /** Base constraint for all row types. */ type TableRowData = Record; /** Stable, unique per-row id accessor. Drives selection, editing, virtualization keys. */ type GetRowId = (row: TRow) => string | number; /** Editor kind for editable cells. */ type EditInputType = 'text' | 'number' | 'boolean' | 'select'; /** Injectable text measurer: returns the pixel width of `text` rendered in `font`. */ type MeasureTextFn = (text: string, font: string) => number; /** Declarative action button rendered inside a cell (see spec §20). */ type CellActionButton = { id: string; /** Label and/or icon. At least one is required; icon-only buttons must set ariaLabel. */ label?: string; icon?: ReactNode; ariaLabel?: string; variant?: 'default' | 'secondary' | 'ghost' | 'destructive' | 'outline'; /** Click handler. The implementation stops propagation before invoking. May be async. */ onClick: (row: TRow, event: MouseEvent) => void | Promise; isHidden?: (row: TRow) => boolean; isDisabled?: (row: TRow) => boolean; /** Optional confirm step before firing onClick (e.g. destructive actions). */ confirm?: { title: string; description?: string; confirmLabel?: string; }; tooltip?: string; }; /** * Arbitrary custom action control rendered inside a cell's action slot. Use for * anything the declarative button variant can't express — popover triggers, * dropdown menus, etc. The slot click-isolates the rendered control (selection, * expand, and edit are never triggered) without consumer cooperation. */ type CellActionCustom = { id: string; /** Render any interactive control for this row. */ render: (row: TRow) => ReactNode; isHidden?: (row: TRow) => boolean; }; /** A cell action: either a declarative button or a custom-rendered control. Discriminated by the `render` field. */ type CellAction = CellActionButton | CellActionCustom; type FooterAggregate = 'sum' | 'avg' | 'min' | 'max' | 'count'; /** * Typed context handed to a column's custom cell renderer (`meta.renderCell`) * and cell click handler (`meta.onCellClick`). Lets a consumer fully control a * cell's content and click behavior with full type information. */ type CellRenderContext = { /** The full row record. */row: TRow; /** The cell's accessor value. */ value: unknown; /** The column id. */ columnId: string; /** The underlying TanStack column instance. */ column: Column; /** The owning TanStack table instance. */ table: Table$1; /** True only when this exact cell is currently in edit mode (EditableTable). */ isEditing: boolean; }; /** The single custom per-column metadata contract (spec §5.1). */ type TableColumnMeta = { editable?: boolean; inputType?: EditInputType; selectOptions?: { label: string; value: string; }[]; /** Returns the underlying string that should be measured for non-text cells. */ measureText?: (row: TableRowData) => string; /** Fixed content width (px, excluding cell chrome/padding) used instead of measuring. */ fixedMeasureWidth?: number; /** * Returns the exact content width (px, excluding cell chrome/padding) for this * column's cell on a given row. Use when a custom cell's width is not a * function of any text — a sparkline, a variable set of chips, an image grid — * so neither `measureText` nor `fixedMeasureWidth` fits. Takes precedence over * both: auto-sizing evaluates it across the same sampled rows and takes the * widest. The returned number is treated as the exact content width — cell * padding is still added, but no text safety margin is applied, so the * consumer owns the value. */ measureWidth?: (row: TableRowData) => number; /** Per-column max-width clamp (px) for auto-sizing. Defaults to the system max. */ maxColumnWidth?: number; footerAggregate?: FooterAggregate; footerFormat?: (value: number) => string; footerLabel?: string; actions?: CellAction[]; /** * Opt this column out of the built-in global search bar. Defaults to true * (searched). Ignored when the table is given an explicit `searchableColumns` * list, which takes precedence over per-column flags. */ searchable?: boolean; /** * Opt this column's value area out of single-line truncation, giving the * column's `cell` renderer full layout control (e.g. multiple badges, wrapping * content, interactive controls). Defaults to false (truncated single line). * When using custom content, set `measureText`, `fixedMeasureWidth`, or * `measureWidth` so auto-sizing can size the column — the raw value is not * meaningful here. */ disableTruncate?: boolean; /** * Fully controls a cell's content, taking precedence over the column's * TanStack `cell`. The output is rendered in a non-truncating, * horizontally-flexible container so multiple inline elements sit side by * side instead of being clipped. Because custom content has no inferable * text, pair this with `measureText` / `fixedMeasureWidth` / `measureWidth` / * `maxColumnWidth` for correct auto-sizing. */ renderCell?: (ctx: CellRenderContext) => ReactNode; /** * Makes the whole cell clickable (e.g. to open a portaled popover). The * implementation isolates the event from row selection / expansion / edit * before invoking. On an editable column, opting into this means the cell * does NOT also auto-enter inline edit; an actively-editing cell still shows * its editor. Use the exported `isolateCellEvent` / `cellInteractionProps` * to stop interactive children inside a custom cell from leaking events. */ onCellClick?: (ctx: CellRenderContext, event: MouseEvent) => void; }; declare module '@tanstack/react-table' { interface ColumnMeta extends TableColumnMeta {} } /** At most one cell is in edit mode at a time (spec §7.5). */ type EditingState = { rowId: string | number; columnId: string; initialValue: string; } | null; /** Per-column filter value: combined text search + faceted checklist (spec §10.1). */ type ColumnFilterValue = { text: string; checkedValues: Set | null; }; /** Column group definition for grouped headers (editable tables). */ type ColumnGroupDef = { id: string; label: string; /** Leaf column ids covered by this group, in display order. */ columnIds: string[]; }; /** * Custom loading skeleton: either static markup, or a render function that * receives the computed visible column widths (the same `widths` the built-in * skeleton uses) so a custom skeleton can mirror the grid layout if desired. */ type LoadingSkeleton = ReactNode | ((widths: number[]) => ReactNode); /** Where an opt-in record count renders relative to the table body. */ type RecordCountPosition = 'top' | 'bottom'; /** Leaf-row counts handed to a record-count label override. */ type RecordCountInfo = { /** Leaf rows after the active filters are applied. */filtered: number; /** Total leaf rows ignoring filters. */ total: number; /** True only when the active filters narrow the set (`filtered < total`). */ isFiltered: boolean; }; /** Override for the record-count display text/markup. */ type RecordCountLabel = (info: RecordCountInfo) => ReactNode; /** Class overrides for every visual region; merged with the defaults via cn(). */ type TableClassNames = { root?: string; toolbar?: string; filterBadges?: string; headerRow?: string; headerCell?: string; groupHeaderCell?: string; bodyRow?: string; bodyCell?: string; footerRow?: string; footerCell?: string; empty?: string; skeleton?: string; /** The opt-in record-count region (top toolbar/tab-strip count or bottom floated corner annotation). */ recordCount?: string; }; /** Class overrides for the TabbedTable chrome. */ type TabbedTableClassNames = TableClassNames & { container?: string; tabStrip?: string; tab?: string; activeTab?: string; inactiveTab?: string; tabIndicator?: string; /** The Excel-style step arrows shown when the tab strip overflows. */ tabScrollButton?: string; panel?: string; }; /** * Body row height. * * - unset (default): fixed 56px rows — identical behavior and performance to * prior versions. * - `number`: a uniform fixed pixel height for every row. * - `(row) => number`: an explicit per-row pixel height. * - `'auto'`: content-driven height — cells wrap instead of clipping to a single * line, with the fixed 56px height acting as a minimum floor. */ type RowHeight = number | 'auto' | ((row: TRow) => number); /** Shared advanced features — everything defaults off (spec §23). */ type AdvancedFeatureProps = { enableMultiSort?: boolean; enableRowSelection?: boolean; selectedRowIds?: string[]; onSelectedRowIdsChange?: (ids: string[]) => void; enableColumnVisibility?: boolean; columnVisibilityStorageKey?: string; /** * Row virtualization. On by default. Set false to render every row in normal * document flow instead of a sliding virtual window — useful for small tables * where you want browser find-in-page (Ctrl+F), printing, screen-reader access * to all rows, or simpler DOM snapshots. This is a "small table" escape hatch * and may be slow on large datasets. */ enableRowVirtualization?: boolean; /** * Column virtualization of the scrollable pane. On by default. Set false to * render every scrollable column at once instead of a sliding horizontal * window. Frozen/pinned columns are never virtualized either way. Same * "small table" escape hatch caveat as {@link enableRowVirtualization}. */ enableColumnVirtualization?: boolean; /** * Body row height. Default (unset) keeps fixed 56px rows — identical behavior * and performance to prior versions. * * - `number` / `(row) => number`: explicit fixed/per-row pixel heights. These * feed the row virtualizer directly (no DOM measurement), so virtualization * stays fully performant in both the virtualized and non-virtualized paths. * - `'auto'`: rows grow to fit their content (cells wrap instead of clipping * to a single line) with a 56px minimum floor. Auto rows render every * scrollable column (column virtualization does not apply); row * virtualization is supported via dynamic measurement. */ rowHeight?: RowHeight; enableFooter?: boolean; /** * Show a built-in global search bar — a single text input that filters rows * by a case-insensitive "includes" match across all searched columns at once * (distinct from the per-column filter popovers). Off by default. Combines * with active per-column filters and sorting. In single-table mode the input * renders in the toolbar before the sort/columns/record-count cluster; in * tabbed modes it renders in the tab strip between the tabs and the end * controls and applies to the active tab's rows. */ enableGlobalSearch?: boolean; /** Controlled global-search query. When set, pair with {@link onGlobalSearchChange}. */ globalSearch?: string; /** Notified when the global-search query changes (controlled or uncontrolled). */ onGlobalSearchChange?: (value: string) => void; /** * Restrict global search to these column ids. When provided it takes * precedence over per-column `meta.searchable` flags; otherwise every visible * non-selection column is searched unless it sets `meta.searchable: false`. */ searchableColumns?: string[]; /** Placeholder for the global-search input. Defaults to "Search…". */ searchPlaceholder?: string; /** * Show an opt-in count of the table's rows. Off by default. When a filter * narrows the set it reads "Showing X of Y" (filtered leaf rows vs. total * leaf rows); otherwise a single total (e.g. "1,234 rows"). */ enableRecordCount?: boolean; /** Where the record count renders: `'top'` (right of the toolbar, after the Columns button) or `'bottom'` (annotation floated at the table's bottom-right corner). Default `'top'`. */ recordCountPosition?: RecordCountPosition; /** Override the record-count text/markup; receives the filtered/total leaf counts. */ recordCountLabel?: RecordCountLabel; enableExpanding?: boolean; getSubRows?: (row: TRow) => TRow[] | undefined; expanded?: Record; onExpandedChange?: (next: Record) => void; defaultExpanded?: boolean | Record; }; type ReadOnlyTableProps = { data: TRow[]; columns: ColumnDef$1[]; getRowId: GetRowId; toolbar?: ReactNode; maxHeight?: string; emptyMessage?: string; isLoading?: boolean; /** * Custom skeleton rendered in the scroll area while `isLoading` is true, * replacing the built-in `TableSkeleton`. Accepts static markup, or a render * function receiving the computed visible column widths so it can mirror the * grid layout. When omitted, the default skeleton is used. */ loadingSkeleton?: LoadingSkeleton; bordered?: boolean; frozenColumns?: number; columnFilters?: ColumnFiltersState$1; onColumnFiltersChange?: Dispatch>; initialSorting?: SortingState$1; measure?: MeasureTextFn; /** * When true (default), the header label plus its sort/filter affordances act * as a floor on each column's auto-sized width. Set false to drive width * purely from data-cell content (the header may then clip and its icons fall * back to an overlay). Not a user-facing toggle — a build-time prop. */ includeHeaderInAutosize?: boolean; /** Human label for a column id (used by filter badges and the visibility picker). */ columnLabel?: (columnId: string) => string; classNames?: TableClassNames; } & AdvancedFeatureProps; type SaveEditFn = (row: TRow, columnId: string, value: string | number | boolean) => Promise; type EditableTableExtraProps = { /** Whitelist of columns that may enter edit mode (column must also set meta.editable). */editableColumnIds: string[]; /** Resolve true to commit and close; false keeps the editor open. */ onSaveEdit: SaveEditFn; isSubmitting?: boolean; singleClickEdit?: boolean; columnGroups?: ColumnGroupDef[]; getCellClassName?: (row: TRow, columnId: string) => string | undefined; }; type EditableTableProps = ReadOnlyTableProps & EditableTableExtraProps; /** * Props for `TableGX`'s single-table variant. Unifies read-only and editable * into one surface: a state-controlled `editable` boolean flips the table * between display-only and inline-editing live (no remount). Because the * discriminated union can't enforce the editable-only props against a runtime * boolean, they are optional here and `TableGX` warns in development when * `editable` is true but a required one (`onSaveEdit`, `editableColumnIds`) is * missing. */ type TableGXTableProps = ReadOnlyTableProps & { /** Toggle inline editing on/off live. Defaults to read-only (`false`). */editable?: boolean; } & Partial>; type CommonTab = { /** Stable tab key. */id: string; /** Button text + filter-badge source label. */ label: string; /** Column set shown on this tab. */ columns: ColumnDef$1[]; frozenColumns?: number; initialSorting?: SortingState$1; columnVisibilityStorageKey?: string; columnLabel?: (columnId: string) => string; }; type ReadOnlyTab = CommonTab & { editable?: false; }; type EditableTab = CommonTab & { editable: true; editableColumnIds: string[]; onSaveEdit: SaveEditFn; columnGroups?: ColumnGroupDef[]; singleClickEdit?: boolean; getCellClassName?: (row: TRow, columnId: string) => string | undefined; isSubmitting?: boolean; }; type TabbedTableTab = ReadOnlyTab | EditableTab; /** * Shared config for one independent tab. Unlike `TabbedTableTab`, each tab owns * its **entire** dataset and identity — there is no shared row identity across * tabs, so the row shape may differ from tab to tab. Build these through the * typed `independentTable()` factory so each tab stays fully type-checked at the * point of definition even when row shapes differ across tabs. */ type IndependentTabBase = { /** Stable tab key. */id: string; /** Button text. */ label: ReactNode; /** This tab's own rows. */ data: TRow[]; /** This tab's own row identity. */ getRowId: GetRowId; /** This tab's column set. */ columns: ColumnDef$1[]; frozenColumns?: number; initialSorting?: SortingState$1; emptyMessage?: string; isLoading?: boolean; loadingSkeleton?: LoadingSkeleton; measure?: MeasureTextFn; /** Floor auto-width on the header label + icons (default true); false sizes from data only. */ includeHeaderInAutosize?: boolean; columnLabel?: (columnId: string) => string; enableMultiSort?: boolean; enableRowSelection?: boolean; enableColumnVisibility?: boolean; /** Full localStorage key for this tab's column visibility (not a base). */ columnVisibilityStorageKey?: string; /** Row virtualization for this tab (default true). See {@link AdvancedFeatureProps.enableRowVirtualization}. */ enableRowVirtualization?: boolean; /** Column virtualization for this tab (default true). See {@link AdvancedFeatureProps.enableColumnVirtualization}. */ enableColumnVirtualization?: boolean; /** Body row height for this tab (default fixed 56px). See {@link AdvancedFeatureProps.rowHeight}. */ rowHeight?: RowHeight; enableFooter?: boolean; /** Show a built-in global search bar for this tab (see {@link AdvancedFeatureProps.enableGlobalSearch}). */ enableGlobalSearch?: boolean; /** Restrict this tab's global search to these column ids (see {@link AdvancedFeatureProps.searchableColumns}). */ searchableColumns?: string[]; /** Placeholder for this tab's global-search input. Defaults to "Search…". */ searchPlaceholder?: string; /** Show an opt-in row count for this tab (see {@link AdvancedFeatureProps.enableRecordCount}). */ enableRecordCount?: boolean; /** Where this tab's record count renders: `'top'` or `'bottom'`. Default `'top'`. */ recordCountPosition?: RecordCountPosition; /** Override this tab's record-count text/markup. */ recordCountLabel?: RecordCountLabel; enableExpanding?: boolean; getSubRows?: (row: TRow) => TRow[] | undefined; defaultExpanded?: boolean | Record; }; type ReadOnlyIndependentTab = IndependentTabBase & { editable?: false; }; type EditableIndependentTab = IndependentTabBase & { editable: true; editableColumnIds: string[]; onSaveEdit: SaveEditFn; columnGroups?: ColumnGroupDef[]; singleClickEdit?: boolean; getCellClassName?: (row: TRow, columnId: string) => string | undefined; isSubmitting?: boolean; }; /** A single independent tab's typed config (read-only or editable). */ type IndependentTabConfig = ReadOnlyIndependentTab | EditableIndependentTab; type TabbedTableProps = { data: TRow[]; getRowId: GetRowId; /** * Stable column shared by all tabs; drives cross-tab filter intersection. * Must be the column getRowId reads. */ idColumn: string; tabs: TabbedTableTab[]; /** Controlled active tab. */ activeTabId?: string; /** Initial active tab when uncontrolled. */ defaultTabId?: string; onActiveTabChange?: (id: string) => void; /** Right-aligned tab-strip controls (refresh/export, etc.). */ actions?: ReactNode; emptyMessage?: string; isLoading?: boolean; /** * Custom skeleton rendered while `isLoading` is true, replacing the built-in * `TableSkeleton`. Accepts static markup, or a render function receiving the * computed visible column widths. When omitted, the default skeleton is used. */ loadingSkeleton?: LoadingSkeleton; /** Each tab persists column visibility under `${base}:${tab.id}`. */ columnVisibilityStorageKeyBase?: string; /** Distinct per mounted TabbedTable so sliding indicators don't cross instances. */ tabIndicatorLayoutId?: string; /** * Show a toolbar button that opens a popover for managing the shared * multi-column sort hierarchy (flip direction, remove, reorder priority), * including sorts on columns not shown on the active tab. Default off. */ enableSortHierarchy?: boolean; measure?: MeasureTextFn; /** * Forwarded to every tab's table. When true (default) the header label and * its icons floor each column's auto-sized width; false sizes purely from * data-cell content. Build-time prop, not a user-facing toggle. */ includeHeaderInAutosize?: boolean; classNames?: TabbedTableClassNames; } & Pick, 'enableMultiSort' | 'enableRowSelection' | 'selectedRowIds' | 'onSelectedRowIdsChange' | 'enableColumnVisibility' | 'enableRowVirtualization' | 'enableColumnVirtualization' | 'rowHeight' | 'enableFooter' | 'enableGlobalSearch' | 'globalSearch' | 'onGlobalSearchChange' | 'searchableColumns' | 'searchPlaceholder' | 'enableRecordCount' | 'recordCountPosition' | 'recordCountLabel'> & Pick, 'enableExpanding' | 'getSubRows' | 'defaultExpanded'>; //#endregion //#region src/components/ReadOnlyTable.d.ts /** Display-only grid: TableCore with `editable={false}` (spec §4). */ declare function ReadOnlyTable(props: ReadOnlyTableProps): import("react").JSX.Element; //#endregion //#region src/components/EditableTable.d.ts /** Inline-editing grid: TableCore with `editable={true}` (spec §4, §7). */ declare function EditableTable(props: EditableTableProps): import("react").JSX.Element; //#endregion //#region src/components/TabbedTable.d.ts /** * Multiple table views (tabs) over the same rows, with cross-tab filter * intersection, shared selection, and shared multi-column sorting (spec §18). * A thin composition over the shared headless store + compound primitives: the * store is the single source of truth for all cross-cutting state. */ declare function TabbedTable(props: TabbedTableProps): import("react").JSX.Element; //#endregion //#region src/core/FilterBadges.d.ts type FilterBadgeItem = { key: string; label: string; onClear: () => void; }; //#endregion //#region src/core/ColumnVisibilityPicker.d.ts type ColumnVisibilityItem = { id: string; label: string; visible: boolean; }; //#endregion //#region src/primitives/types.d.ts /** * Selects how the shared store combines cross-cutting state: * - `shared` — one dataset, many views: sorting + selection are shared across * tabs and filters intersect (the `TabbedTable` semantics). * - `independent` — every tab is its own table: sorting, selection, and filters * are isolated per tab (the `IndependentTabbedTable` semantics). */ type TableMode = 'shared' | 'independent'; /** * Generic-erased state + handlers the store computes for the active tab and * hands to a tab model's `render`. Mirrors the props a tab's `TableCore` needs, * kept type-erased so a heterogeneous tab set can share one store. */ type TableBodyRenderArgs = { sorting: SortingState$1; onSortingChange: OnChangeFn; columnFilters: ColumnFiltersState$1; onColumnFiltersChange: Dispatch>; visibility: VisibilityState$1; onVisibilityChange: OnChangeFn; /** Active tab's global-search query (applies to the active tab's rows). */ globalSearch: string; onGlobalSearchChange: (value: string) => void; selectedRowIds: string[] | undefined; onSelectedRowIdsChange: (ids: string[]) => void; /** Shared-dataset rows after cross-tab filter intersection (shared mode only). */ sharedData?: unknown[]; /** Every tab's current filters, so shared-mode adapters can resolve sort-only columns. */ allFilters: Record; measure?: MeasureTextFn; classNames?: TabbedTableClassNames; /** When false, the panel suppresses its own top count so the strip shows it. */ recordCountInToolbar?: boolean; /** Lifts the panel's computed leaf counts up to the tab strip. */ onRecordCountChange?: (info: RecordCountInfo | null) => void; /** Negated tab-slide x, supplied by the sliding panel host (kept static pane). */ pinnedPaneX?: MotionValue; }; /** * A type-erased descriptor for one tab in the store. Both `TabbedTable` * (shared) and `IndependentTabbedTable` (independent) produce these; the * concrete row type lives inside the closures so tabs may differ in shape. */ type TableTabModel = { id: string; label: ReactNode; /** Full localStorage key for this tab's column visibility, if any. */ columnVisibilityStorageKey?: string; initialSorting?: SortingState$1; enableRowSelection: boolean; /** True when this tab opts into the built-in global search bar. */ enableGlobalSearch: boolean; /** Placeholder for this tab's global-search input. */ searchPlaceholder?: string; /** True when this tab's record count is enabled and placed at the top (tab strip). */ showsTopRecordCount: boolean; recordCountLabel?: RecordCountLabel; /** Column-picker rows for the current visibility (empty when not applicable). */ getPickerItems: (visibility: VisibilityState$1) => ColumnVisibilityItem[]; /** Render this tab's table panel from the store-computed args. */ render: (args: TableBodyRenderArgs) => ReactNode; }; /** Read-only handle on filter state, passed to the badge-building adapter. */ type FilterChromeApi = { activeId: string; filtersByTab: Record; /** All non-empty filters across every tab (shared-mode badge source). */ activeFilters: { tabId: string; columnId: string; value: unknown; }[]; clearFilter: (tabId: string, columnId: string) => void; }; /** The shared-dataset inputs the store needs to intersect cross-tab filters. */ type SharedFilterSource = { data: unknown[]; getRowId: (row: unknown) => unknown; getSubRows?: (row: unknown) => unknown[] | undefined; /** Shared tabs (with columns) used to build per-tab filter accessors. */ tabs: unknown[]; }; /** Configuration handed to {@link TableProvider}. */ type TableProviderConfig = { mode: TableMode; tabs: TableTabModel[]; activeTabId?: string; defaultTabId?: string; onActiveTabChange?: (id: string) => void; /** Distinct per mounted instance so sliding indicators don't cross instances. */ indicatorLayoutId?: string; classNames?: TabbedTableClassNames; measure?: MeasureTextFn; enableRowSelection?: boolean; selectedRowIds?: string[]; onSelectedRowIdsChange?: (ids: string[]) => void; sharedFilterSource?: SharedFilterSource; buildFilterBadges?: (api: FilterChromeApi) => FilterBadgeItem[]; enableSortHierarchy?: boolean; resolveSortLabel?: (columnId: string) => string; }; /** The headless store exposed through context to every primitive. */ type TableStore = { mode: TableMode; tabs: TableTabModel[]; /** Resolved active id (falls back to the first tab when stale/missing). */ activeId: string; activeTab: TableTabModel | undefined; selectTab: (id: string) => void; indicatorLayoutId: string; classNames?: TabbedTableClassNames; /** Body args for the active tab; the panel host injects `pinnedPaneX`. */ getBodyArgs: (pinnedPaneX?: MotionValue) => TableBodyRenderArgs; filterBadges: FilterBadgeItem[]; clearAllFilters: () => void; pickerItems: ColumnVisibilityItem[]; togglePickerItem: (id: string, visible: boolean) => void; /** Set every column currently in the picker to a single visibility. */ setAllPickerItems: (visible: boolean) => void; sortControl: { sorting: SortingState$1; resolveLabel: (columnId: string) => string; onChange: (next: SortingState$1) => void; } | null; /** Global-search control for the active tab; null when that tab disables it. */ search: { value: string; onChange: (value: string) => void; placeholder?: string; } | null; recordCount: { info: RecordCountInfo | null; label?: RecordCountLabel; } | null; }; //#endregion //#region src/primitives/store.d.ts /** Read the headless table store. Throws when used outside a `TableProvider`. */ declare function useTableStore(): TableStore; type TableProviderProps = TableProviderConfig & { children: ReactNode; }; /** * The headless root: owns all cross-cutting tabbed-table state (active tab, * sorting, filters, selection, per-tab column visibility) with no UI of its * own, and exposes it to the compound primitives via context. A `mode` selects * shared-dataset vs fully-independent semantics. */ declare function TableProvider({ children, ...config }: TableProviderProps): import("react").JSX.Element; //#endregion //#region src/primitives/TableContainer.d.ts type TableContainerProps = { children: ReactNode; className?: string; }; /** * The outer folder-table frame (border, rounded corners, card background). * Holds the tab strip + panels; matches the chrome previously emitted by the * shared tab shell so styling and `data-tgx-tabbed-table` hooks are unchanged. */ declare function TableContainer({ children, className }: TableContainerProps): import("react").JSX.Element; //#endregion //#region src/primitives/TableTabStrip.d.ts type TableTabStripProps = { /** Stretchy middle region of the strip (e.g. filter badges). */centerContent?: ReactNode; /** Right-aligned region of the strip (e.g. actions + column picker). */ endContent?: ReactNode; }; /** * The folder-tab strip: the tab buttons, the sliding active-tab indicator * (`layoutId`-driven), and the Excel-style overflow step arrows. Reads the tab * set + active id from the store; chrome slots are supplied by the caller so * they can be reordered or omitted. */ declare function TableTabStrip({ centerContent, endContent }: TableTabStripProps): import("react").JSX.Element; //#endregion //#region src/primitives/TablePanels.d.ts /** * The sliding tab-panel host: renders the active tab's body inside a * framer-motion slide, suppressing native scrollbars mid-slide and feeding the * negated pane translate down so the frozen pane appears static. Pair with * `TableTabStrip`; for a plain (no-tab) table use `TableBody` instead so this * animation code is never pulled in. */ declare function TablePanels(): import("react").JSX.Element; //#endregion //#region src/primitives/TableBody.d.ts /** * Renders the active tab's table body with no slide animation. Use this for a * plain (no-tab) composition — leaving out `TableTabStrip`/`TablePanels` keeps * the framer-motion tab animation code out of the bundle entirely. */ declare function TableBody(): import("react").JSX.Element | null; //#endregion //#region src/primitives/TableToolbar.d.ts type TableToolbarProps = { children: ReactNode; className?: string; }; /** * A plain right-aligned chrome row for composing controls (actions, sort, the * column picker, record count) outside the tab strip — e.g. above a plain * `TableBody`. Inside a tab strip, pass these controls to its `endContent`. */ declare function TableToolbar({ children, className }: TableToolbarProps): import("react").JSX.Element; //#endregion //#region src/primitives/TableFilterBadges.d.ts type TableFilterBadgesProps = { className?: string; }; /** * The removable active-filter badge strip, wired to the store. In shared mode it * shows every tab's filters; in independent mode only the active tab's. */ declare function TableFilterBadges({ className }: TableFilterBadgesProps): import("react").JSX.Element; //#endregion //#region src/primitives/TableSortControl.d.ts type TableSortControlProps = { className?: string; }; /** * The shared multi-column sort-hierarchy popover, wired to the store. Renders * only when the store exposes a sort control (shared mode with the hierarchy * enabled); otherwise nothing. */ declare function TableSortControl({ className }: TableSortControlProps): import("react").JSX.Element | null; //#endregion //#region src/primitives/TableSearch.d.ts type TableSearchProps = { className?: string; }; /** * The global-search text field, wired to the store. Renders only when the active * tab opts into the built-in search (`enableGlobalSearch`); otherwise nothing. * In shared-tabbed mode the query is shared across tabs; in independent-tabbed * mode each tab keeps its own. */ declare function TableSearch({ className }: TableSearchProps): import("react").JSX.Element | null; //#endregion //#region src/primitives/TableColumnVisibility.d.ts type TableColumnVisibilityProps = { className?: string; }; /** * The column-visibility picker for the active tab, wired to the store. Renders * nothing when the active tab exposes no hideable columns. */ declare function TableColumnVisibility({ className }: TableColumnVisibilityProps): import("react").JSX.Element | null; //#endregion //#region src/primitives/TableRecordCount.d.ts type TableRecordCountProps = { className?: string; }; /** * The top-placed record count for the active tab, lifted from its panel into * the chrome. Renders nothing unless the active tab enables a top record count * and has a computed value. */ declare function TableRecordCount({ className }: TableRecordCountProps): import("react").JSX.Element | null; //#endregion //#region src/primitives/index.d.ts /** * Namespaced access to the compound table primitives. The high-level `TableGX` * facade attaches to this same family, so consumers can drop down to the slots * (`Table.Provider`, `Table.TabStrip`, `Table.Panels`, …) for full control over * chrome layout without leaving the library's conventions. */ declare const Table: { readonly Provider: typeof TableProvider; readonly Container: typeof TableContainer; readonly TabStrip: typeof TableTabStrip; readonly Panels: typeof TablePanels; readonly Body: typeof TableBody; readonly Toolbar: typeof TableToolbar; readonly FilterBadges: typeof TableFilterBadges; readonly SortControl: typeof TableSortControl; readonly Search: typeof TableSearch; readonly ColumnVisibility: typeof TableColumnVisibility; readonly RecordCount: typeof TableRecordCount; }; //#endregion //#region src/components/IndependentTabbedTable.d.ts /** * A type-erased independent tab descriptor produced by {@link independentTable}. * The concrete row type is captured inside the closures, so tabs with different * row shapes can be held together in a single `IndependentTab[]`. Compatible * with the headless store's {@link TableTabModel} (extends it with a per-tab * filter-badge builder, since independent tabs surface their own filters). */ type IndependentTab = TableTabModel & { enableColumnVisibility: boolean; /** Active-filter badge descriptors for the current filters. */ getFilterBadges: (filters: { id: string; value: unknown; }[], clearColumn: (columnId: string) => void) => FilterBadgeItem[]; }; /** * Build a fully type-checked, type-erased independent tab. Each call captures * its own row type `TRow`, so a `IndependentTab[]` may mix tabs with completely * different row shapes while each config stays type-safe at its definition site. */ declare function independentTable(config: IndependentTabConfig): IndependentTab; type IndependentTabbedTableProps = { /** Built via the {@link independentTable} factory; each tab is its own table. */tabs: IndependentTab[]; /** Controlled active tab. */ activeTabId?: string; /** Initial active tab when uncontrolled. */ defaultTabId?: string; onActiveTabChange?: (id: string) => void; /** Right-aligned tab-strip controls (refresh/export, etc.). */ actions?: ReactNode; /** Distinct per mounted instance so sliding indicators don't cross instances. */ tabIndicatorLayoutId?: string; /** Default text measurer; a tab's own `measure` takes precedence. */ measure?: MeasureTextFn; classNames?: TabbedTableClassNames; }; /** * A tabbed container where each tab is a **completely independent table** — its * own data, row shape, identity, sorting, filtering, selection, and column * visibility. Tabs share only the folder-tab strip and slide animation; nothing * crosses between them. For multiple views over one shared dataset (shared * selection + cross-tab filter intersection), use `TabbedTable` instead. * * A thin composition over the shared headless store (in `independent` mode) + * compound primitives. */ declare function IndependentTabbedTable({ tabs, activeTabId, defaultTabId, onActiveTabChange, actions, tabIndicatorLayoutId, measure, classNames }: IndependentTabbedTableProps): import("react").JSX.Element; //#endregion //#region src/components/TableGX.d.ts /** Single-table mode: read-only or editable, flipped live via `editable`. */ type TableGXTableVariantProps = { variant: 'table'; } & TableGXTableProps; /** Shared-dataset tabs (cross-tab filter intersection, shared selection/sort). */ type TableGXTabbedVariantProps = { variant: 'tabbed'; } & TabbedTableProps; /** Fully independent per-tab tables (nothing shared but the tab strip). */ type TableGXIndependentVariantProps = { variant: 'independent'; } & IndependentTabbedTableProps; /** * The discriminated prop union for {@link TableGX}. The `variant` discriminator * selects the mode and narrows the surface to exactly that mode's props, so * autocomplete never offers nonsensical cross-variant combinations. */ type TableGXProps = TableGXTableVariantProps | TableGXTabbedVariantProps | TableGXIndependentVariantProps; /** * `TableGX` is the single, recommended entry point to the library. It is a thin * **preset facade** over the compound primitives + shared headless store: one * import reaches every table mode through a discriminated `variant` prop, with * no parallel state logic of its own. * * - `variant="table"` — one table, read-only or editable. Pass a controllable * `editable` boolean to flip inline editing on/off live (no remount). * - `variant="tabbed"` — many views over one shared dataset (shared selection + * cross-tab filter intersection + shared sorting). * - `variant="independent"` — fully independent per-tab tables. * * Need to rearrange the chrome (move the toolbar, split the tab strip, etc.)? * Drop down to the primitives — `TableGX.Provider`, `TableGX.TabStrip`, * `TableGX.Panels`, … (the same family as the standalone `Table` namespace). */ declare function TableGX(props: TableGXProps): import("react").JSX.Element; declare namespace TableGX { var Provider: typeof TableProvider; var Container: typeof TableContainer; var TabStrip: typeof TableTabStrip; var Panels: typeof TablePanels; var Body: typeof TableBody; var Toolbar: typeof TableToolbar; var FilterBadges: typeof TableFilterBadges; var SortControl: typeof TableSortControl; var ColumnVisibility: typeof TableColumnVisibility; var RecordCount: typeof TableRecordCount; } //#endregion //#region src/constants.d.ts /** Fixed body row height (enables row virtualization). */ declare const ROW_HEIGHT_PX = 56; /** Header row height. */ declare const HEADER_HEIGHT_PX = 48; /** Pre-measurement fallback width, used only until auto-sizing resolves. */ declare const MIN_COLUMN_WIDTH_PX = 160; /** Hard floor so an empty-header column still shows its icons. */ declare const ABSOLUTE_MIN_COLUMN_WIDTH_PX = 48; /** * Auto-sized frozen (pinned) columns are scaled so their combined width does not * exceed this fraction of the viewport until the user resizes a pinned data column; * after that, pinned columns use their effective widths and the pane may grow wider. */ declare const FROZEN_PANE_MAX_FRACTION = 0.5; /** Horizontal indent applied per nesting depth for the disclosure column. */ declare const INDENT_STEP_PX = 20; /** System-wide max width for auto-sized columns (per-column override via meta.maxColumnWidth). */ declare const MAX_COLUMN_WIDTH_PX = 480; //#endregion //#region src/lib/columns.d.ts /** Text column: stringifies the value, filterable with the default filter. */ declare function textColumn(id: string, header: string, meta?: TableColumnMeta): ColumnDef$1; /** Number column: locale-formatted display. */ declare function numberColumn(id: string, header: string, meta?: TableColumnMeta): ColumnDef$1; /** Boolean column: BodyCell renders the Yes/No checkbox affordance via meta.inputType. */ declare function booleanColumn(id: string, header: string, meta?: TableColumnMeta): ColumnDef$1; /** Select column: displays the option label matching the value. */ declare function selectColumn(id: string, header: string, options: { label: string; value: string; }[], meta?: TableColumnMeta): ColumnDef$1; /** Date column: timezone-safe MM/dd/yyyy display. */ declare function dateColumn(id: string, header: string, meta?: TableColumnMeta): ColumnDef$1; /** Badge column: renders the value inside a Badge. */ declare function badgeColumn(id: string, header: string, meta?: TableColumnMeta): ColumnDef$1; /** * Custom column: full control over cell content via a render function that * receives a {@link CellRenderContext}. Rendered through `meta.renderCell`, so * the value area opts out of truncation and is horizontally flexible — multi- * element layouts (e.g. several badges) and interactive controls (e.g. a * popover trigger) render unclipped, side by side. Mirrors the other factories * (spreads `meta` last). * * Because the rendered content is arbitrary, auto-sizing can't infer a width * from the raw value — pass `meta.measureText` or `meta.fixedMeasureWidth` to * size the column. The `id` is used as the accessor key for sorting/filtering; * if it isn't a real row field, supply `meta` accordingly. */ declare function customColumn(id: string, header: string, render: (ctx: CellRenderContext) => ReactNode, meta?: TableColumnMeta): ColumnDef$1; //#endregion //#region src/core/CellOverflowList.d.ts type CellOverflowListProps = { /** Arbitrary inline items. Each child is treated as one indivisible unit. */children: React.ReactNode; /** * Customizes the collapsed indicator. Receives the number of hidden items. * Defaults to a small "+N" pill. */ renderOverflow?: (hiddenCount: number) => React.ReactNode; /** Horizontal gap (px) between items. Default 8 (matches Tailwind gap-2). */ gap?: number; className?: string; }; /** * Content-agnostic, opt-in overflow affordance for custom cells. Lays out an * arbitrary set of inline items within the fixed row height and the available * column width, showing as many as fit and collapsing the remainder into a * customizable "+N" indicator. Re-measures whenever the container resizes * (e.g. on column resize). * * Measurement is DOM-based (each child's natural width) rather than text-based, * because children are arbitrary React content with no inferable text — the * text-only `measure.ts` utility cannot size them. */ declare function CellOverflowList({ children, renderOverflow, gap, className }: CellOverflowListProps): React.JSX.Element; //#endregion //#region src/lib/isolate.d.ts /** * Swallows an event so it cannot leak into row selection, row expansion, or * inline-edit behaviors. Shared by `CellActions` and custom interactive cells. */ declare function isolateCellEvent(event: React.SyntheticEvent): void; /** * Spread onto an interactive child rendered inside a custom cell so its * pointer events don't trigger the cell's click handler, row selection, * expansion, or inline edit. */ declare const cellInteractionProps: { readonly onClick: typeof isolateCellEvent; readonly onDoubleClick: typeof isolateCellEvent; readonly onMouseDown: typeof isolateCellEvent; readonly onPointerDown: typeof isolateCellEvent; }; //#endregion //#region src/lib/cell.d.ts /** * Extracts a cell's editable string value: `String(value)`, or `''` for * null/undefined (spec §7.5). */ declare function getCellEditValue(row: TRow, columnId: string): string; //#endregion //#region src/lib/date.d.ts /** * Parses a date-only value without timezone off-by-one errors. * `"YYYY-MM-DD"` strings are interpreted at midnight UTC. Date instances pass * through; anything else returns null. */ declare function parseDateSafe(value: unknown): Date | null; /** * Formats a date-only value as `MM/dd/yyyy` using UTC fields so the displayed * day never shifts with the local timezone. */ declare function formatDateSafe(value: unknown): string; //#endregion //#region src/lib/aggregates.d.ts /** * Computes a footer aggregate over raw cell values. Numeric aggregates ignore * non-numeric values; `count` tallies non-empty values. Returns null when no * value participates (so the caller can render nothing). */ declare function computeAggregate(kind: FooterAggregate, values: unknown[]): number | null; //#endregion //#region src/lib/filtering.d.ts /** Core predicate shared by the table filterFn and cross-tab intersection. */ declare function matchesFilterValue(cellValue: unknown, filterValue: ColumnFilterValue): boolean; /** * Default column filter: case-insensitive "includes" text search combined with * a faceted checklist of exact values (spec §10.1). */ declare const tgxFilterFn: FilterFn; /** * Case-insensitive "includes" match used by the built-in global search bar — * the same text semantics as {@link matchesFilterValue}, applied to a single * cell value against the global query. An empty query matches everything. */ declare function matchesGlobalSearch(cellValue: unknown, query: string): boolean; /** * Global-filter function for the table engine. TanStack applies it per * globally-filterable column and keeps a row when ANY column matches, giving * single-box "search across all columns" semantics. Which columns participate * is controlled by the engine's `getColumnCanGlobalFilter` resolver. */ declare const tgxGlobalFilterFn: FilterFn; //#endregion //#region src/lib/measure.d.ts /** * DOM-free text measurement backed by @chenglou/pretext. `prepare` work is * cached per (font, text) pair, so repeated measurements are arithmetic-only. */ declare const measureTextWidth: MeasureTextFn; /** True when canvas-based measurement can run (i.e. not during SSR). */ declare function canMeasureText(): boolean; //#endregion //#region src/lib/cn.d.ts declare function cn(...inputs: ClassValue[]): string; //#endregion export { ABSOLUTE_MIN_COLUMN_WIDTH_PX, type AdvancedFeatureProps, type CellAction, type CellActionButton, type CellActionCustom, CellOverflowList, type CellOverflowListProps, type CellRenderContext, type ColumnDef, type ColumnFilterValue, type ColumnFiltersState, type ColumnGroupDef, type CommonTab, type EditInputType, type EditableIndependentTab, type EditableTab, EditableTable, type EditableTableExtraProps, type EditableTableProps, type EditingState, FROZEN_PANE_MAX_FRACTION, type FilterChromeApi, type FooterAggregate, type GetRowId, HEADER_HEIGHT_PX, INDENT_STEP_PX, type IndependentTab, type IndependentTabBase, type IndependentTabConfig, IndependentTabbedTable, type IndependentTabbedTableProps, type LoadingSkeleton, MAX_COLUMN_WIDTH_PX, MIN_COLUMN_WIDTH_PX, type MeasureTextFn, ROW_HEIGHT_PX, type ReadOnlyIndependentTab, type ReadOnlyTab, ReadOnlyTable, type ReadOnlyTableProps, type RecordCountInfo, type RecordCountLabel, type RecordCountPosition, type SaveEditFn, type SharedFilterSource, type SortingState, TabbedTable, type TabbedTableClassNames, type TabbedTableProps, type TabbedTableTab, Table, TableBody, type TableBodyRenderArgs, type TableClassNames, type TableColumnMeta, TableColumnVisibility, type TableColumnVisibilityProps, TableContainer, type TableContainerProps, TableFilterBadges, type TableFilterBadgesProps, TableGX, type TableGXIndependentVariantProps, type TableGXProps, type TableGXTabbedVariantProps, type TableGXTableProps, type TableGXTableVariantProps, type TableMode, TablePanels, TableProvider, type TableProviderConfig, type TableProviderProps, TableRecordCount, type TableRecordCountProps, type TableRowData, TableSearch, type TableSearchProps, TableSortControl, type TableSortControlProps, type TableStore, type TableTabModel, TableTabStrip, type TableTabStripProps, TableToolbar, type TableToolbarProps, type VisibilityState, badgeColumn, booleanColumn, canMeasureText, cellInteractionProps, cn, computeAggregate, customColumn, dateColumn, formatDateSafe, getCellEditValue, independentTable, isolateCellEvent, matchesFilterValue, matchesGlobalSearch, measureTextWidth, numberColumn, parseDateSafe, selectColumn, textColumn, tgxFilterFn, tgxGlobalFilterFn, useTableStore }; //# sourceMappingURL=index.d.ts.map