import { ReactNode } from 'react'; import { ColumnDef, ColumnTypeConfig, TextEditConfig, NumberEditConfig, SelectEditConfig, SelectAsyncEditConfig, MultiselectEditConfig, MultiselectAsyncEditConfig, BooleanEditConfig, TableRow, ColumnHeaderConfig } from './types'; import { MultiSelectMenuOption } from '../MultiSelectMenu'; /** * Base column configuration shared by all column types */ type BaseColumnConfig = ColumnHeaderConfig & { /** * The cleaned-up header configuration. */ header?: ColumnDef["header"]; /** * The label of the header. * @deprecated Use `header.label` instead. */ headerLabel?: string; /** * The alignment of the header. * When using `type`, this is set automatically but can be overridden. */ align?: "start" | "center" | "end"; /** * Columns of a group column (for grouped columns) */ columns?: ColumnDef[]; /** * Custom content to display when a cell value is empty (null, undefined, or empty string). * Overrides the default em dash. When set on both the column and the DataTable, * the column-level value takes precedence. */ emptyCellContent?: ReactNode; /** * The content of the footer cell. An array will display multiple footer rows */ footerContent?: ReactNode | ReactNode[]; /** * The maximum width of the column, in pixels */ maxWidth?: number; /** * The minimum width of the column, in pixels */ minWidth?: number; /** * The pinning location of the column */ pinned?: "left" | "right"; /** * Whether the column is resizable */ resizable?: boolean; /** * The function to customize how the cell content is rendered. * When using `type`, a default renderer is provided but can be overridden. */ renderCell?: (value: T[K], { row, depth }: { row?: TableRow; depth?: number; }) => ReactNode; /** * Whether the column is sortable, or a function to customize the sorting logic */ sortable?: boolean | ((valueA: T[K], valueB: T[K]) => number); /** * The column type for automatic display configuration. * Sets default `renderCell` (formatter) and `align` based on the data type. */ type?: ColumnTypeConfig; }; /** * Configuration for read-only columns (no editing) */ type ReadOnlyColumnConfig = BaseColumnConfig & { editConfig?: undefined; }; /** * Configuration for text editable columns using editConfig. * Valid when T[K] is a string. */ type TextEditConfigColumnConfig = NonNullable extends string ? BaseColumnConfig & { editConfig: TextEditConfig; } : never; /** * Configuration for number editable columns using editConfig. * Valid when T[K] is a number type. */ type NumberEditConfigColumnConfig = NonNullable extends number ? BaseColumnConfig & { editConfig: NumberEditConfig; } : never; /** * Configuration for select editable columns using editConfig */ type SelectEditConfigColumnConfig = BaseColumnConfig & { editConfig: SelectEditConfig; }; /** * Configuration for async select editable columns using editConfig */ type SelectAsyncEditConfigColumnConfig = BaseColumnConfig & { editConfig: SelectAsyncEditConfig; }; type CellArrayItem = object | string | number | boolean | bigint | symbol | null | undefined; type CellArrayValue = readonly CellArrayItem[]; /** * Configuration for multiselect editable columns using editConfig * Only valid when T[K] is an array type */ type MultiselectEditConfigColumnConfig = NonNullable extends CellArrayValue ? BaseColumnConfig & { editConfig: MultiselectEditConfig; } : never; /** * Configuration for async multiselect editable columns using editConfig. * Only valid when T[K] is MultiSelectMenuOption[] — full option objects, * not a plain primitive array like string[]. */ type MultiselectAsyncEditConfigColumnConfig = NonNullable extends MultiSelectMenuOption[] ? BaseColumnConfig & { editConfig: MultiselectAsyncEditConfig; } : never; /** * Configuration for boolean editable columns using editConfig. * Valid when T[K] is a boolean type. */ type BooleanEditConfigColumnConfig = NonNullable extends boolean ? BaseColumnConfig & { editConfig: BooleanEditConfig; } : never; /** * Full column configuration type - union of all possible configurations. * TypeScript will enforce that the editConfig matches the value type constraints. */ type ColumnConfig = ReadOnlyColumnConfig | TextEditConfigColumnConfig | NumberEditConfigColumnConfig | SelectEditConfigColumnConfig | SelectAsyncEditConfigColumnConfig | MultiselectEditConfigColumnConfig | MultiselectAsyncEditConfigColumnConfig | BooleanEditConfigColumnConfig; /** * Factory function to create column helper function for defining Table columns. * * This helper provides type safety by enforcing that: * - `type` sets display defaults (formatter and alignment) for the column * - `editConfig` enables cell editing with proper type constraints * - `editConfig.mode: "text"` can only be used with string columns * - `editConfig.mode: "boolean"` can only be used with boolean columns * - `editConfig.mode: "number"` can only be used with number columns * - `editConfig.mode: "multiselect"` can only be used with array columns * - `editConfig.mode: "select"` options values must match the column's value type * - `editConfig.onChange` callback receives the correct value type for the column * * @template T - The type of the row data * @returns A function that creates type-safe column definitions * * @example * ```ts * type Data = { name: string; amount: number; tags: string[] }; * const createColumn = createColumnHelper(); * * // Display-only column with type defaults * createColumn("amount", { header: { label: "Amount" }, type: "currency" }); * * // Editable column with editConfig * createColumn("name", { * header: { label: "Name" }, * type: "text", * editConfig: { mode: "text", onChange: (value, rowId) => save(value, rowId) } * }); * * // Number editing * createColumn("amount", { * header: { label: "Amount" }, * editConfig: { * mode: "number", * minValue: 0, * maxValue: 10000, * step: 0.01, * onChange: (value, rowId) => save(value, rowId) * } * }); * * // Select editing * createColumn("status", { * header: { label: "Status" }, * editConfig: { * mode: "select", * options: [{ id: "active", label: "Active" }], * onChange: (option, rowId) => save(option?.id, rowId) * } * }); * * // Multiselect editing with array column * createColumn("tags", { * header: { label: "Tags" }, * editConfig: { * mode: "multiselect", * options: [{ id: "urgent", label: "Urgent" }], * onChange: (options, rowId) => save(options.map(o => o.id), rowId) * } * }); * ``` */ export declare function createColumnHelper(): (id: K | { group: string; }, column: ColumnConfig) => ColumnDef; export {};