diff --git a/docs/demo/external-search.md b/docs/demo/external-search.md new file mode 100644 index 00000000..cb30cfe9 --- /dev/null +++ b/docs/demo/external-search.md @@ -0,0 +1,8 @@ +--- +title: external search +nav: + title: Demo + path: /demo +--- + + diff --git a/examples/external-search.tsx b/examples/external-search.tsx new file mode 100644 index 00000000..e0bfbe9d --- /dev/null +++ b/examples/external-search.tsx @@ -0,0 +1,96 @@ +import React, { useState } from 'react'; +import '../assets/index.less'; +import Cascader from '../src'; + +const addressOptions = [ + { + label: '福建', + value: 'fj', + children: [ + { + label: '福州', + value: 'fuzhou', + children: [ + { + label: '马尾-mw', + value: 'mawei', + }, + ], + }, + { + label: '泉州-qz', + value: 'quanzhou', + }, + ], + }, + { + label: '浙江', + value: 'zj', + children: [ + { + label: '杭州', + value: 'hangzhou', + children: [ + { + label: '余杭', + value: 'yuhang', + }, + { + label: '福州', + value: 'fuzhou', + children: [ + { + label: '马尾', + value: 'mawei', + }, + ], + }, + ], + }, + ], + }, + { + label: '北京', + value: 'bj', + children: [ + { + label: '朝阳区', + value: 'chaoyang', + }, + { + label: '海淀区', + value: 'haidian', + }, + ], + }, +]; + +const Demo = () => { + const [searchValue, setSearchValue] = useState(''); + return ( + <> + { + return ( +
+ setSearchValue(e.target.value)} + placeholder="External Search" + /> + {menu} +
+ ); + }} + animation="slide-up" + notFoundContent="Empty Content!" + /> + + ); +}; + +export default Demo; diff --git a/src/Cascader.tsx b/src/Cascader.tsx index c746af10..502ddd65 100644 --- a/src/Cascader.tsx +++ b/src/Cascader.tsx @@ -57,6 +57,7 @@ export interface ShowSearchType< inputValue: string, fieldNames: FieldNames, ) => number; + displayInInput?: boolean; matchInputWidth?: boolean; limit?: number | false; } diff --git a/src/hooks/useSearchConfig.ts b/src/hooks/useSearchConfig.ts index b7b6da80..f2996711 100644 --- a/src/hooks/useSearchConfig.ts +++ b/src/hooks/useSearchConfig.ts @@ -12,6 +12,7 @@ export default function useSearchConfig(showSearch?: CascaderProps['showSearch'] let searchConfig: ShowSearchType = { matchInputWidth: true, limit: 50, + displayInInput: true, }; if (showSearch && typeof showSearch === 'object') { @@ -29,6 +30,6 @@ export default function useSearchConfig(showSearch?: CascaderProps['showSearch'] } } - return [true, searchConfig]; + return [!!searchConfig.displayInInput, searchConfig]; }, [showSearch]); } diff --git a/tests/search.spec.tsx b/tests/search.spec.tsx index 12c7b394..9054f1f4 100644 --- a/tests/search.spec.tsx +++ b/tests/search.spec.tsx @@ -1,7 +1,7 @@ import { fireEvent, render } from '@testing-library/react'; import KeyCode from 'rc-util/lib/KeyCode'; import { resetWarned } from 'rc-util/lib/warning'; -import React from 'react'; +import React, { useState } from 'react'; import Cascader from '../src'; import { optionsForActiveMenuItems } from './demoOptions'; import type { ReactWrapper } from './enzyme'; @@ -73,6 +73,49 @@ describe('Cascader.Search', () => { expect(onChange).toHaveBeenCalledWith(['bamboo', 'little', 'fish'], expect.anything()); }); + it('externally controlled search',() => { + const onSearch = jest.fn(); + const onChange = jest.fn(); + + function doExternalSearch(wrapper: ReactWrapper, search: string) { + wrapper.find('input[data-test="external-search"]').simulate('change', { + target: { + value: search, + }, + }); + } + + + const ExternallyControlledSearch = () => { + const [searchValue,setSearchValue] = useState('') + return ( + <> + setSearchValue(e.target.value)} /> + , + + ); + } + const wrapper = mount() + + // Leaf + doExternalSearch(wrapper, 'toy'); + let itemList = wrapper.find('div.rc-cascader-menu-item-content'); + expect(itemList).toHaveLength(2); + expect(itemList.at(0).text()).toEqual('Label Bamboo / Label Little / Toy Fish'); + expect(itemList.at(1).text()).toEqual('Label Bamboo / Label Little / Toy Cards'); + + // Parent + doExternalSearch(wrapper, 'Label Little'); + itemList = wrapper.find('div.rc-cascader-menu-item-content'); + expect(itemList).toHaveLength(2); + expect(itemList.at(0).text()).toEqual('Label Bamboo / Label Little / Toy Fish'); + expect(itemList.at(1).text()).toEqual('Label Bamboo / Label Little / Toy Cards'); + + // Change + wrapper.clickOption(0, 0); + expect(onChange).toHaveBeenCalledWith(['bamboo', 'little', 'fish'], expect.anything()); + }) + it('changeOnSelect', () => { const onChange = jest.fn(); const wrapper = mount(