UNPKG

gadgets

Version:

Reusable React UI widgets - This is my widget library. There are many like it, but this one is mine...

241 lines (240 loc) 9.27 kB
/** * The `DynamicList` control is a specialized List control that can be * manipulated by the user. They can add/remove/select items from it. The * control takes an initial list to seed the control, but then items can be * dynamically added/removed. * * Some of the features include: * * - Add new items with the "+" button * - Sort the list in ascending/descending order * - Incrementally search for items * - List is divided into pages for performance * - A right or left widget can be added to each list item * * ## Screen: * <img src="https://github.com/jmquigley/gadgets/blob/master/images/dynamicList.png" width="60%" /> * * ## Examples: * * #### Simple * ```javascript * import {DynamicList} from 'gadgets'; * * <DynamicList * errorMessage="Error message" * items={{ * title1: {left: widget1, right: widget1} * title2: {left: widget2, right: widget2} * title1: {left: widget3, right: widget3} * }} * onDelete={(title: string) => { * console.log(`Deleting item from list: ${title}`); * }} * onError({message: string} => { * console.log(message); * }) * onNew={(title: string) => { * console.log(`Adding new item to list: ${title}`); * }} * onSelection={(title: string) => { * console.log(`Selected item: ${title}`); * }} * onUpdate={(previous: string, title: string) => * console.log(`previous: ${previous}, title: ${title}`); * }} * pageSizes={[10, 20, 30]} * title="Dynamic List Test" * /> * ``` * * #### With Error Handling * This will display an error message at the top of the list and then automatically * fade away after 5 seconds. * * ```javascript * import {DynamicList} from 'gadgets'; * * <DynamicList * errorMessage="Show this error message" * errorMessageDuration={3} * items={{ * title1: {right: widget1} * title2: {right: widget2} * title1: {right: widget3} * }} * onError={(message: string) => console.log(message)} * pageSizes={[10, 20, 30]} * title="Dynamic List Test" * /> * ``` * * ## API * #### Events * - `onBlur` - Invoked when a list item control loses focus. * - `onClick` - Invoked when a list item is clicked. * - `onDelete(title: string)` - This event is executed when an item is removed * from the list. * - `onError(message: string)` - when an error message is written to the * component this callback is invoked. * - `onFocus` - Invoked when a list item is clicked. * - `onNew(title: string)` - This event is executed when an item is added to * the list. The title of the new item is a parameter to the callback * - `onSelection(title: string)` - Invoked when a list item is selected. The title * of the selected item is a parameter to the callback. * - `onSort(sortOrder: SortOrder)` - Invoked whne the list is sorted. It will * give the selected order to the callback. * - `onUpdate(previous: string, title: string)` - When an item is renamed this * callback is invoked. The previous value and the new title are passed to the * callback * * #### Styles * - `ui-dynamiclist` - applied to the `div` accordion control that holds the * list. * - `ui-dynamiclist-container` - applied to the top level container `div` that * surrounds the list and the *toast* for error message handling. * * #### Properties * - `errorMessage="" {string}` - A message the will be temporarily displayed * within the control. When this message is first set it will be shown and * then decay. It will then invoke the onError callback. * - `errorMessageDuration=5 {number}` - the time in seconds that the * error message string will be shown within the control before fading away. * Set to five seconds by default. * - `items={} {DynamicListItem}` - An object that holds unique title and * widgets in the format `{[title]: {left: widget, right: widget}`. Each item in * the object represents a list item. A widget, like a button or Option, can * be used as supporting widgets in the list. * - `layout=TitleLayout.dominant {TitleLayout}` - How the title/widget * will be displayed in the list item (seee the Title control). * - `nocollapse=false {boolean}` - Determines if the list can be * "rolled up" when the header is clicked. The default behavior is to * allow. IF this is set to false, then the list can't be collapsed. * - `noselect=false {boolean}` - when true the selection highlight is * disabled and removed. * - `pageSizes=[25, 50, 100] number[]` - A list of page number sizes that * can be used by the pager. It is used against the total items to * determine the total number of pages in the control display. * - `sortOrder=SortOrder.ascending {SortOrder}` - The list sort order. Can * be either ascending or descending. * - `title="" {string}` - This string value is in the header of the control. * * @module DynamicList */ import * as React from "react"; import { BaseComponent, BaseProps, BaseState, SortOrder } from "../shared"; import { TitleLayout } from "../title/Title"; export interface DynamicListItem { [key: string]: any; } export interface DynamicListProps extends BaseProps { collapsable?: boolean; errorMessageDuration?: number; items?: DynamicListItem; layout?: TitleLayout; nocollapse?: boolean; noselect?: boolean; onBlur?: (e: React.FocusEvent<HTMLLIElement>) => void; onClick?: (e: React.MouseEvent<HTMLLIElement>) => void; onDelete?: (title: string) => void; onError?: (message: string) => void; onFocus?: (e: React.FocusEvent<HTMLLIElement>) => void; onNew?: (title: string, widget: any) => void; onSelection?: (title: string) => void; onSort?: (sortOrder: SortOrder) => void; onUpdate?: (previousTitle: string, title: string) => void; pageSizes?: number[]; sortOrder?: SortOrder; title?: any; } export interface DynamicListState extends BaseState { errorMessage?: string; initialToggle?: boolean; page?: number; pageSize?: number; search?: string; showConfirm?: boolean; showError?: boolean; showNew?: boolean; sortOrder?: SortOrder; totalItems?: number; } export declare class DynamicList extends BaseComponent<DynamicListProps, DynamicListState> { static readonly defaultProps: DynamicListProps; private readonly _baseMessage; private _emptyListItem; private _fillerKeys; private _fillerIdx; private _footer; private _footerID; private _keyList; private _listItems; private _pager; private _pagerID; private _previousPage; private _qDelete; private _selection; private _startSearch; constructor(props: DynamicListProps); private buildListItems; private buildTitle; /** * Takes the given title and computes the page where this title would * be found. It takes the current position within the list items and * divides it by the page size to find its current page. * @param title {string} the title to find within the list items * @returns the page number where this item resides. If it is not * found it will return 1. */ private computePageByItem; private createListItem; /** * Sets the control into a new item mode. This will show the input control * and wait for user input. */ private createNewItem; private handleBlur; /** * Receives the name of an element to remove from the List. This will * remove it from the state and remove its ListItem control that was * generated for it. * @param title {string} the title to remove from the list * @param cb {Function} a callback function that is executed when the * delete state event update completes. */ private handleDelete; private handleDeleteConfirm; private handleErrorClose; private handleKeyDown; /** * When the data in the input control is changed/added, this event handler * is called to process it. This happens when the label within the * ListItem for new items is changed. * @param title {string} the title that will be added to the list * @param cb {Function} a callback function that is executed when the update * is complete */ private handleNewItem; private handleNewPageSize; private handlePageChange; private handleSearch; private handleSelect; private handleSort; private handleTitleClick; private handleUpdate; private hideEdit; private listItemDeletor; static getDerivedStateFromProps(props: DynamicListProps, state: DynamicListState): any; /** * An internal convenience method that updates internal components of the * the component. This could all be pasted into render, but I hate making * large single functions even if react wants to force me to do it. This * is a consequence of the updates to the react lifecycle. * * @param nextProps {DynamicListProps} the next set of props used to draw the component * @param nextState {DynamicListState} the current state of the component befoer render */ private _updateWidgets; render(): JSX.Element; } export default DynamicList;