From 4e05ca71f87e77c33ded119c525b42b4f3945d0e Mon Sep 17 00:00:00 2001 From: Ferdinand Salis Date: Tue, 12 Sep 2017 22:35:22 +0200 Subject: [PATCH] feat(actions): add clear items action (#187) * feat(actions): add clear items action * Update docs --- README.md | 1 + src/__tests__/downshift.misc.js | 7 ++ src/downshift.js | 8 +- typings/index.d.ts | 145 ++++++++++++++++++-------------- 4 files changed, 99 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 60994f475..222fe13f6 100644 --- a/README.md +++ b/README.md @@ -452,6 +452,7 @@ These are functions you can call to change the state of the downshift component. | property | type | description | |-------------------------|------------------------------------------------------------------|------------------------------------------------------------------------------| | `clearSelection` | `function(cb: Function)` | clears the selection | +| `clearItems` | `function()` | Clears downshift's record of all the items. Only really useful if you render your items asynchronously within downshift. See [#186](https://github.com/paypal/downshift/issues/186) | | `closeMenu` | `function(cb: Function)` | closes the menu | | `openMenu` | `function(cb: Function)` | opens the menu | | `selectHighlightedItem` | `function(otherStateToSet: object, cb: Function)` | selects the item that is currently highlighted | diff --git a/src/__tests__/downshift.misc.js b/src/__tests__/downshift.misc.js index 52ddf12a9..a7adfeab0 100644 --- a/src/__tests__/downshift.misc.js +++ b/src/__tests__/downshift.misc.js @@ -56,6 +56,13 @@ test('toggleMenu can take no arguments at all', () => { ) }) +test('clearItems clears the all items', () => { + const items = ['Chess'] + const {wrapper, clearItems} = setup({items}) + clearItems() + expect(wrapper.node.items).toEqual([]) +}) + test('reset can take no arguments at all', () => { const {reset, childSpy} = setup() reset() diff --git a/src/downshift.js b/src/downshift.js index 55b8e952e..615e13f03 100644 --- a/src/downshift.js +++ b/src/downshift.js @@ -334,6 +334,7 @@ class Downshift extends Component { selectHighlightedItem, setHighlightedIndex, clearSelection, + clearItems, reset, } = this return { @@ -354,6 +355,7 @@ class Downshift extends Component { selectHighlightedItem, setHighlightedIndex, clearSelection, + clearItems, itemToString, // state @@ -598,6 +600,10 @@ class Downshift extends Component { } //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ITEM + clearItems = () => { + this.items = [] + } + reset = (otherStateToSet = {}, cb) => { otherStateToSet = pickState(otherStateToSet) this.internalSetState( @@ -706,7 +712,7 @@ class Downshift extends Component { const children = unwrapArray(this.props.children, noop) // because the items are rerendered every time we call the children // we clear this out each render and - this.items = [] + this.clearItems() // we reset this so we know whether the user calls getRootProps during // this render. If they do then we don't need to do anything, // if they don't then we need to clone the element they return and diff --git a/typings/index.d.ts b/typings/index.d.ts index 181845ef8..41c4ba50a 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,89 +1,112 @@ -import * as React from 'react'; +import * as React from 'react' export interface DownshiftProps { - children: ChildrenFunction; - defaultHighlightedIndex?: number | null; - defaultSelectedItem?: any; - defaultInputValue?: string; - defaultIsOpen?: boolean; - getA11yStatusMessage?: (options: A11yStatusMessageOptions) => any; - itemToString?: (item: any) => string; - onChange?: (selectedItem: any, stateAndHelpers: ControllerStateAndHelpers) => void; - onStateChange?: (options: StateChangeOptions, stateAndHelpers: ControllerStateAndHelpers) => void; - onUserAction?: (options: StateChangeOptions, stateAndHelpers: ControllerStateAndHelpers) => void; - itemCount?: number; - selectedItem?: any; - isOpen?: boolean; - inputValue?: string; - highlightedIndex?: number; + children: ChildrenFunction + defaultHighlightedIndex?: number | null + defaultSelectedItem?: any + defaultInputValue?: string + defaultIsOpen?: boolean + getA11yStatusMessage?: (options: A11yStatusMessageOptions) => any + itemToString?: (item: any) => string + onChange?: ( + selectedItem: any, + stateAndHelpers: ControllerStateAndHelpers, + ) => void + onStateChange?: ( + options: StateChangeOptions, + stateAndHelpers: ControllerStateAndHelpers, + ) => void + onUserAction?: ( + options: StateChangeOptions, + stateAndHelpers: ControllerStateAndHelpers, + ) => void + itemCount?: number + selectedItem?: any + isOpen?: boolean + inputValue?: string + highlightedIndex?: number } export interface A11yStatusMessageOptions { - highlightedIndex: number | null; - highlightedValue: any; - inputValue: string; - isOpen: boolean; - itemToString: (item: any) => string; - previousResultCount: number; - resultCount: number; - selectedItem: any; + highlightedIndex: number | null + highlightedValue: any + inputValue: string + isOpen: boolean + itemToString: (item: any) => string + previousResultCount: number + resultCount: number + selectedItem: any } export interface StateChangeOptions { - highlightedIndex: number; - inputValue: string; - isOpen: boolean; - selectedItem: any; + highlightedIndex: number + inputValue: string + isOpen: boolean + selectedItem: any } export interface GetRootPropsOptions { - refKey: string; + refKey: string } -export interface GetInputPropsOptions extends React.HTMLProps { } +export interface GetInputPropsOptions + extends React.HTMLProps {} -export interface GetLabelPropsOptions extends React.HTMLProps { } +export interface GetLabelPropsOptions + extends React.HTMLProps {} -export interface GetButtonPropsOptions extends React.HTMLProps { } +export interface GetButtonPropsOptions + extends React.HTMLProps {} interface OptionalExtraGetItemPropsOptions { - [key: string]: any; + [key: string]: any } export interface GetItemPropsOptions extends OptionalExtraGetItemPropsOptions { - index?: number; - item: any; + index?: number + item: any } export interface ControllerStateAndHelpers { - // prop getters - getRootProps: (options: GetRootPropsOptions) => any; - getButtonProps: (options?: GetButtonPropsOptions) => any; - getLabelProps: (options?: GetLabelPropsOptions) => any; - getInputProps: (options?: GetInputPropsOptions) => any; - getItemProps: (options: GetItemPropsOptions) => any; + // prop getters + getRootProps: (options: GetRootPropsOptions) => any + getButtonProps: (options?: GetButtonPropsOptions) => any + getLabelProps: (options?: GetLabelPropsOptions) => any + getInputProps: (options?: GetInputPropsOptions) => any + getItemProps: (options: GetItemPropsOptions) => any - // actions - openMenu: (cb?: Function) => void; - closeMenu: (cb?: Function) => void; - toggleMenu: (cb?: Function) => void; - selectItem: (item: any, otherStateToSet?: object, cb?: Function) => void; - selectItemAtIndex: (index: number, otherStateToSet?: object, cb?: Function) => void; - selectHighlightedItem: (otherStateToSet?: object, cb?: Function) => void; - setHighlightedIndex: (index: number, otherStateToSet?: object, cb?: Function) => void; - clearSelection: (cb?: Function) => void; - reset: (otherStateToSet?: object, cb?: Function) => void; - itemToString: (item: any) => void; + // actions + openMenu: (cb?: Function) => void + closeMenu: (cb?: Function) => void + toggleMenu: (cb?: Function) => void + selectItem: (item: any, otherStateToSet?: object, cb?: Function) => void + selectItemAtIndex: ( + index: number, + otherStateToSet?: object, + cb?: Function, + ) => void + selectHighlightedItem: (otherStateToSet?: object, cb?: Function) => void + setHighlightedIndex: ( + index: number, + otherStateToSet?: object, + cb?: Function, + ) => void + clearSelection: (cb?: Function) => void + clearItems: () => void + reset: (otherStateToSet?: object, cb?: Function) => void + itemToString: (item: any) => void - // state - highlightedIndex: number | null; - inputValue: string | null; - isOpen: boolean; - selectedItem: any; + // state + highlightedIndex: number | null + inputValue: string | null + isOpen: boolean + selectedItem: any } -export type ChildrenFunction = (options: ControllerStateAndHelpers) => React.ReactNode; -export type DownshiftInterface = React.ComponentClass; +export type ChildrenFunction = ( + options: ControllerStateAndHelpers, +) => React.ReactNode +export type DownshiftInterface = React.ComponentClass -declare const Downshift: DownshiftInterface; -export default Downshift; +declare const Downshift: DownshiftInterface +export default Downshift