/* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ import {AriaLabelingProps, AsyncLoadable, DOMProps, Key, LinkDOMProps, LoadingState, MultipleSelection, Sortable, SpectrumSelectionProps, StyleProps} from '@react-types/shared'; import {GridCollection, GridNode} from '@react-types/grid'; import {JSX, ReactElement, ReactNode} from 'react'; /** Widths that result in a constant pixel value for the same Table width. */ export type ColumnStaticSize = number | `${number}` | `${number}%`; // match regex: /^(\d+)(?=%$)/ /** * Widths that change size in relation to the remaining space and in ratio to other dynamic columns. * All numbers must be integers and greater than 0. * FR units take up remaining, if any, space in the table. */ export type ColumnDynamicSize = `${number}fr`; // match regex: /^(\d+)(?=fr$)/ /** All possible sizes a column can be assigned. */ export type ColumnSize = ColumnStaticSize | ColumnDynamicSize; export interface TableProps extends MultipleSelection, Sortable { /** The elements that make up the table. Includes the TableHeader, TableBody, Columns, and Rows. */ children: [ReactElement>, ReactElement>], /** A list of row keys to disable. */ disabledKeys?: Iterable, /** * Whether pressing the escape key should clear selection in the table or not. * * Most experiences should not modify this option as it eliminates a keyboard user's ability to * easily clear selection. Only use if the escape key is being handled externally or should not * trigger selection clearing contextually. * @default 'clearSelection' */ escapeKeyBehavior?: 'clearSelection' | 'none', /** Whether selection should occur on press up instead of press down. */ shouldSelectOnPressUp?: boolean } /** * @deprecated - use SpectrumTableProps from '@adobe/react-spectrum' instead. */ export interface SpectrumTableProps extends TableProps, SpectrumSelectionProps, DOMProps, AriaLabelingProps, StyleProps { /** * Sets the amount of vertical padding within each cell. * @default 'regular' */ density?: 'compact' | 'regular' | 'spacious', /** * Sets the overflow behavior for the cell contents. * @default 'truncate' */ overflowMode?: 'wrap' | 'truncate', /** Whether the TableView should be displayed with a quiet style. */ isQuiet?: boolean, /** Sets what the TableView should render when there is no content to display. */ renderEmptyState?: () => JSX.Element, /** Handler that is called when a user performs an action on a row. */ onAction?: (key: Key) => void, /** * Handler that is called when a user starts a column resize. */ onResizeStart?: (widths: Map) => void, /** * Handler that is called when a user performs a column resize. * Can be used with the width property on columns to put the column widths into * a controlled state. */ onResize?: (widths: Map) => void, /** * Handler that is called after a user performs a column resize. * Can be used to store the widths of columns for another future session. */ onResizeEnd?: (widths: Map) => void } export interface TableHeaderProps { /** A list of table columns. */ columns?: T[], /** A list of `Column(s)` or a function. If the latter, a list of columns must be provided using the `columns` prop. */ children: ColumnElement | ColumnElement[] | ColumnRenderer } type ColumnElement = ReactElement>; type ColumnRenderer = (item: T) => ColumnElement; export interface ColumnProps { /** Rendered contents of the column if `children` contains child columns. */ title?: ReactNode, /** Static child columns or content to render as the column header. */ children: ReactNode | ColumnElement | ColumnElement[], /** A list of child columns used when dynamically rendering nested child columns. */ childColumns?: T[], /** The width of the column. */ width?: ColumnSize | null, /** The minimum width of the column. */ minWidth?: ColumnStaticSize | null, /** The maximum width of the column. */ maxWidth?: ColumnStaticSize | null, /** The default width of the column. */ defaultWidth?: ColumnSize | null, /** Whether the column allows resizing. */ allowsResizing?: boolean, /** Whether the column allows sorting. */ allowsSorting?: boolean, /** Whether a column is a [row header](https://www.w3.org/TR/wai-aria-1.1/#rowheader) and should be announced by assistive technology during row navigation. */ isRowHeader?: boolean, /** A string representation of the column's contents, used for accessibility announcements. */ textValue?: string } // TODO: how to support these in CollectionBuilder... export interface SpectrumColumnProps extends ColumnProps { /** * The alignment of the column's contents relative to its allotted width. * @default 'start' */ align?: 'start' | 'center' | 'end', // /** Whether the column should stick to the viewport when scrolling. */ // isSticky?: boolean, // shouldStick?? Not implemented yet? /** Whether the column should render a divider between it and the next column. */ showDivider?: boolean, /** * Whether the column should hide its header text. A tooltip with the column's header text * will be displayed when the column header is focused instead. Note that this prop is specifically for columns * that contain ActionButtons in place of text content. */ hideHeader?: boolean } export type RowElement = ReactElement>; export interface TableBodyProps extends Omit { /** The contents of the table body. Supports static items or a function for dynamic rendering. */ children: RowElement | RowElement[] | ((item: T) => RowElement), /** A list of row objects in the table body used when dynamically rendering rows. */ items?: Iterable, /** The current loading state of the table. */ loadingState?: LoadingState } export interface RowProps extends LinkDOMProps { /** * A list of child item objects used when dynamically rendering row children. Requires the feature flag to be * enabled along with UNSTABLE_allowsExpandableRows, see https://react-spectrum.adobe.com/react-spectrum/TableView.html#expandable-rows. * @version alpha * @private */ UNSTABLE_childItems?: Iterable, // TODO: update when async loading is supported for expandable rows // /** Whether this row has children, even if not loaded yet. */ // hasChildItems?: boolean, /** Rendered contents of the row or row child items. */ children: CellElement | CellElement[] | CellRenderer, /** A string representation of the row's contents, used for features like typeahead. */ textValue?: string // ??? } export interface CellProps { /** The contents of the cell. */ children: ReactNode, /** A string representation of the cell's contents, used for features like typeahead. */ textValue?: string, /** Indicates how many columns the data cell spans. */ colSpan?: number } export type CellElement = ReactElement; export type CellRenderer = (columnKey: Key) => CellElement; export interface TableCollection extends GridCollection { // TODO perhaps elaborate on this? maybe not clear enough, essentially returns the table header rows (e.g. in a tiered headers table, will return the nodes containing the top tier column, next tier, etc) /** A list of header row nodes in the table. */ headerRows: GridNode[], /** A list of column nodes in the table. */ columns: GridNode[], /** A set of column keys that serve as the [row header](https://www.w3.org/TR/wai-aria-1.1/#rowheader). */ rowHeaderColumnKeys: Set, /** The node that makes up the header of the table. */ head?: GridNode, /** The node that makes up the body of the table. */ body: GridNode }