UNPKG

@react-types/shared

Version:
242 lines (205 loc) • 8.63 kB
/* * 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 {Key} from '@react-types/shared'; import {LinkDOMProps} from './dom'; import {ReactElement, ReactNode} from 'react'; export interface ItemProps<T> extends LinkDOMProps { /** Rendered contents of the item or child items. */ children: ReactNode; /** Rendered contents of the item if `children` contains child items. */ title?: ReactNode; // label?? contents? /** A string representation of the item's contents, used for features like typeahead. */ textValue?: string; /** An accessibility label for this item. */ 'aria-label'?: string; /** A list of child item objects. Used for dynamic collections. */ childItems?: Iterable<T>; /** Whether this item has children, even if not loaded yet. */ hasChildItems?: boolean; } export type ItemElement<T> = ReactElement<ItemProps<T>> | null; export type ItemRenderer<T> = (item: T) => ItemElement<T>; export type LoadingState = 'loading' | 'sorting' | 'loadingMore' | 'error' | 'idle' | 'filtering'; export interface AsyncLoadable { /** Whether the items are currently loading. */ isLoading?: boolean; // possibly isLoadingMore /** Handler that is called when more items should be loaded, e.g. while scrolling near the bottom. */ onLoadMore?: () => any; } export interface SectionProps<T> { /** Rendered contents of the section, e.g. a header. */ title?: ReactNode; /** An accessibility label for the section. */ 'aria-label'?: string; /** Static child items or a function to render children. */ children: ItemElement<T> | ItemElement<T>[] | ItemRenderer<T>; /** Item objects in the section. */ items?: Iterable<T>; } export type SectionElement<T> = ReactElement<SectionProps<T>> | null; export type CollectionElement<T> = SectionElement<T> | ItemElement<T>; export type CollectionChildren<T> = | CollectionElement<T> | CollectionElement<T>[] | ((item: T) => CollectionElement<T>); export interface CollectionBase<T> { /** The contents of the collection. */ children: CollectionChildren<T>; /** Item objects in the collection. */ items?: Iterable<T>; /** * The item keys that are disabled. These items cannot be selected, focused, or otherwise * interacted with. */ disabledKeys?: Iterable<Key>; } export interface CollectionStateBase< T, C extends Collection<Node<T>> = Collection<Node<T>> > extends Partial<CollectionBase<T>> { /** A pre-constructed collection to use instead of building one from items and children. */ collection?: C; } export interface Expandable { /** The currently expanded keys in the collection (controlled). */ expandedKeys?: Iterable<Key>; /** The initial expanded keys in the collection (uncontrolled). */ defaultExpandedKeys?: Iterable<Key>; /** Handler that is called when items are expanded or collapsed. */ onExpandedChange?: (keys: Set<Key>) => any; } export interface Sortable { /** The current sorted column and direction. */ sortDescriptor?: SortDescriptor; /** Handler that is called when the sorted column or direction changes. */ onSortChange?: (descriptor: SortDescriptor) => any; } export interface SortDescriptor { /** The key of the column to sort by. */ column: Key; /** The direction to sort by. */ direction: SortDirection; } export type SortDirection = 'ascending' | 'descending'; export interface KeyboardDelegate { /** Returns the key visually below the given one, or `null` for none. */ getKeyBelow?(key: Key, options?: {includeDisabled?: boolean}): Key | null; /** Returns the key visually above the given one, or `null` for none. */ getKeyAbove?(key: Key, options?: {includeDisabled?: boolean}): Key | null; /** Returns the key visually to the left of the given one, or `null` for none. */ getKeyLeftOf?(key: Key, options?: {includeDisabled?: boolean}): Key | null; /** Returns the key visually to the right of the given one, or `null` for none. */ getKeyRightOf?(key: Key, options?: {includeDisabled?: boolean}): Key | null; /** Returns the key visually one page below the given one, or `null` for none. */ getKeyPageBelow?(key: Key): Key | null; /** Returns the key visually one page above the given one, or `null` for none. */ getKeyPageAbove?(key: Key): Key | null; /** Returns the first key, or `null` for none. */ getFirstKey?(key?: Key | null, global?: boolean): Key | null; /** Returns the last key, or `null` for none. */ getLastKey?(key?: Key | null, global?: boolean): Key | null; /** Returns the next key after `fromKey` that matches the given search string, or `null` for none. */ getKeyForSearch?(search: string, fromKey?: Key | null): Key | null; } export interface Rect { x: number; y: number; width: number; height: number; } export interface Size { width: number; height: number; } /** A LayoutDelegate provides layout information for collection items. */ export interface LayoutDelegate { /** Returns a rectangle for the item with the given key. */ getItemRect(key: Key): Rect | null; /** Returns the visible rectangle of the collection. */ getVisibleRect(): Rect; /** Returns the size of the scrollable content in the collection. */ getContentSize(): Size; /** Returns a list of keys between `from` and `to`. */ getKeyRange?(from: Key, to: Key): Key[]; } /** * A generic interface to access a readonly sequential * collection of unique keyed items. */ export interface Collection<T> extends Iterable<T> { /** The number of items in the collection. */ readonly size: number; /** Iterate over all keys in the collection. */ getKeys(): Iterable<Key>; /** Get an item by its key. */ getItem(key: Key): T | null; /** Get an item by the index of its key. */ at(idx: number): T | null; /** Get the key that comes before the given key in the collection. */ getKeyBefore(key: Key): Key | null; /** Get the key that comes after the given key in the collection. */ getKeyAfter(key: Key): Key | null; /** Get the first key in the collection. */ getFirstKey(): Key | null; /** Get the last key in the collection. */ getLastKey(): Key | null; /** Iterate over the child items of the given key. */ getChildren?(key: Key): Iterable<T>; /** Returns a string representation of the item's contents. */ getTextValue?(key: Key): string; /** Filters the collection using the given function. */ filter?(filterFn: (nodeValue: string, node: T) => boolean): Collection<T>; } export interface Node<T> { /** The type of item this node represents. */ type: string; /** A unique key for the node. */ key: Key; /** The object value the node was created from. */ value: T | null; /** The level of depth this node is at in the hierarchy. */ level: number; /** Whether this item has children, even if not loaded yet. */ hasChildNodes: boolean; /** * The loaded children of this node. * * @deprecated Use `collection.getChildren(node.key)` instead. */ childNodes: Iterable<Node<T>>; /** The rendered contents of this node (e.g. JSX). */ rendered: ReactNode; /** A string value for this node, used for features like typeahead. */ textValue: string; /** An accessibility label for this node. */ 'aria-label'?: string; /** The index of this node within its parent. */ index: number; /** A function that should be called to wrap the rendered node. */ wrapper?: (element: ReactElement) => ReactElement; /** The key of the parent node. */ parentKey?: Key | null; /** The key of the node before this node. */ prevKey?: Key | null; /** The key of the node after this node. */ nextKey?: Key | null; /** The first child key of this node. */ firstChildKey?: Key | null; /** The last child key of this node. */ lastChildKey?: Key | null; /** Additional properties specific to a particular node type. */ props?: any; /** @private */ shouldInvalidate?: (context: any) => boolean; /** A function that renders this node to a React Element in the DOM. */ render?: (node: Node<any>) => ReactElement; }