rx-datatable API
    Preparing search index...

    Type Alias DefaultRowProps

    DefaultRowProps: React.ComponentProps<"td"> & React.ComponentProps<"tr"> & {
        highlightChildrenOfSelectedParents?: boolean;
        noPadding?: boolean | nully;
    }

    DataTable and DataTableCore are based on TreeListCore, so please have a look at the simpler TreeList/TreeListCore components first. The difference is that while TreeList is a tree of "items", DataTable is a tree of "rows" and therefore adds a set of columns and column headers. If you want a plain table rather than a tree, simply don't provide properties that would make it a tree.

    • The only required props are columns and list (or tree). list is an array of any type T, while columns is typically an array of DataTableColumn<T>.
    • DataTable is the usual choice. DataTableCore is the same, but omits the outer <div> and <table> elements (which is useful if you want to change the rendering method, e.g. to avoid table in favor of flexbox).
    • The table uses table-layout: fixed, so the widths of the columns are determined by the header row alone. If you provide a numeric/Holder width for a column, the user can resize it by dragging the right edge of the column header.
    • To make a tree, provide a getChildren or getParents prop and set isTreeCol: true on exactly one of the columns.
    • If you want to mix different kinds of rows on a single table (often parents and children are different things, for example), the getRowConfig prop lets you configure behavior for each row type individually (see example below).
    • DataTableProps: props of DataTable. Inherits DataTableCoreProps, TreeListMainProps TreeListAuxProps and most of ListCoreProps.
    • DataTableColumn<T,...>: settings for a single column. Inherits from DataTableCellConfig<T,T,...>.

    A table has a single set of columns, but the way values are chosen for a column can be specified separately for each row type. Here is a simple example of a "file browser" to explain the principle:

     class FileInfo {
         constructor(public name: string, public folderPath: string, public size: number, public modified: Date) {}
     }
     
     const files = [
         new FileInfo('README.md', '', 1345, new Date(2024,0,2)),
         new FileInfo('index.html', 'Documents', 1345, new Date(2024,0,2)),
         new FileInfo('Life 3.0.pdf', 'Documents/Books/Nonfiction', 5235091, new Date(2022,2,3)),
         new FileInfo('Rules for Radicals.pdf', 'Documents/Books/Nonfiction', 583020, new Date(2022,0,1)),
         new FileInfo('IMG_20240106_101958_861.jpg', 'Documents/Photos', 5830220, new Date(2024,0,6)),
         new FileInfo('IMG_20240107_141614_680.jpg', 'Documents/Photos', 5731990, new Date(2024,0,7)),
         new FileInfo('test.pdf', 'Books/Nonfiction', 5235091, new Date(2022,2,3)),
     ];
     
     export function FileTree() {
         // You don't have to memoize the column configuration, but hey, why not?
         const { columns, folderConfig } = useMemo(getColumnsAndRowConfigs, []);
     
         return (
             // TypeScript can infer the type argument(s), but in case of a type error, the 
             // error message tends to be easier to understand if the type argument is explicit.
             <DataTable<FileInfo|string>
                 columns={columns}
                 list={files}
                 // `getParents` is only called for items in `list`, all of which are `FileInfo`.
                 getParents={item => getParentPathsOf((item as FileInfo).folderPath, '/', true)}
                 getRowConfig={item => {
                     if (typeof item.item === 'string') {
                         return folderConfig;
                     }
                 }}
                 // Note: if your folders close, or the selection is lost, whenever the outer 
                 //       component is re-rendered, it means you need to add a `getSelKey` prop. 
                 //       But in this example the folders are just strings, which serve as 
                 //       their own keys.
             />);
     
         function getColumnsAndRowConfigs() {
             // Basic column configuration
             let columns: DataTableColumn<string|FileInfo>[] = [
                 {
                     name: 'name',
                     heading: 'Name',
                     width: 300,
                     isTreeCol: true,
                 },
                 {
                     name: 'size',
                     heading: 'Size',
                     width: 100,
                     renderCell(node, props) {
                         let size = props.value as number;
                         if (size > 1024 * 1024) {
                             return `${(size / (1 << 20)).toFixed(1)} MiB`;
                         } else {
                             return size > 1024 ? `${(size / 1024).toFixed(1)} KiB` : `${size} bytes`;
                         }
                     }
                 },
                 {
                     name: 'modified',
                     heading: 'Modified',
                     width: 220,
                     renderCell(node, props) {
                         return (props.value as unknown as Date).toLocaleString();
                     }
                 },
             ];
     
             // Configures "folder" (parent) rows
             let folder = new Map<string, DataTableCellConfig<string|FileInfo, string>>([
                 ['name', {
                     getValue: path => path.substring(path.lastIndexOf('/') + 1),
                     getColSpan: _ => 3,
                 }],
             ]);
                 
             return { columns, folderConfig: { columns: folder } };
         }
     }
    

    In this example, files are FileInfo while folders are simply strings. The main columns list contains default settings, and configuration for a specific row type is specified with an object of type ItemAndColumns ({ columns: Map<string, DataTableCellConfig<...>>, ... }). In this example we only need a single Map<string, DataTableCellConfig> for folders, but often it's more convenient to define one for every row type.

    Note that the folders are derived on-the-fly from the files using getParentPathsOf (e.g. 'Books/Nonfiction' => ['Books', 'Books/Nonfiction']). You cannot simply use folderPath.split('/') because if a folder such as 'Nonfiction' appears as part of multiple paths, as it does in this example, DataTable will treat it like the "same" item, which can cause problems, e.g. if you click one of the 'Nonfiction' folders, the other one will be selected too. getParentPathsOf ensures that the two 'Nonfiction' folders are different strings, and a getValue method is also required so that 'Books/Nonfiction' shows up as 'Nonfiction'.