diff --git a/__tests__/__snapshots__/index.spec.js.snap b/__tests__/__snapshots__/index.spec.js.snap index c252d780..17932a7f 100644 --- a/__tests__/__snapshots__/index.spec.js.snap +++ b/__tests__/__snapshots__/index.spec.js.snap @@ -453,6 +453,149 @@ exports[` renders with clearable 1`] = ` `; +exports[` renders with custom search function 1`] = ` +.emotion-6 { + box-sizing: border-box; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + border: 1px solid #ccc; + width: 100%; + border-radius: 2px; + padding: 2px 5px; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + direction: ltr; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + cursor: pointer; + min-height: 36px; + pointer-events: all; +} + +.emotion-6:hover, +.emotion-6:focus-within { + border-color: #0074D9; +} + +.emotion-6:focus, +.emotion-6:focus-within { + outline: 0; + box-shadow: 0 0 0 3px rgba(0,116,217,0.2); +} + +.emotion-6 * { + box-sizing: border-box; +} + +.emotion-2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.emotion-0 { + line-height: inherit; + border: none; + margin-left: 5px; + background: transparent; + font-size: smaller; +} + +.emotion-0:focus { + outline: none; +} + +.emotion-4 { + text-align: center; + pointer-events: none; + margin: 0 0 0 5px; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); + cursor: pointer; +} + +.emotion-4 svg { + width: 16px; + height: 16px; +} + +.emotion-4:hover path { + stroke: #0074D9; +} + +.emotion-4:focus { + outline: none; +} + +.emotion-4:focus path { + stroke: #0074D9; +} + +
+
+
+ +
+
+ + + +
+
+
+`; + exports[` renders with loading 1`] = ` .emotion-8 { box-sizing: border-box; diff --git a/__tests__/components/Dropdown.spec.js b/__tests__/components/Dropdown.spec.js index 5e43dace..19ad3452 100644 --- a/__tests__/components/Dropdown.spec.js +++ b/__tests__/components/Dropdown.spec.js @@ -10,7 +10,8 @@ const props = { dropdownHeight: '300px' }, state: { - selectBounds: {} + selectBounds: {}, + searchResults: [], }, methods: { searchResults: () => [], diff --git a/__tests__/index.spec.js b/__tests__/index.spec.js index 235cefb7..b64c2a21 100644 --- a/__tests__/index.spec.js +++ b/__tests__/index.spec.js @@ -1,5 +1,6 @@ import React from 'react'; import TestRenderer from 'react-test-renderer'; +import { LIB_NAME } from '../src/constants'; import Select from '../src/index'; @@ -59,9 +60,31 @@ describe(' renders with custom search function', () => { + const options = [ + { id: 0, name: 'Zero' }, + { id: 1, name: 'One' }, + { id: 2, name: 'Two' }, + ]; + + const searchFn = ({ props, state }) => { + return props.options.filter(({ name }) => new RegExp(state.search).test(name) ); + }; + + const component = selectWithProps( is disabled', () => { const tree = selectWithProps( + + ); +}; + +WithSearchFn.propTypes = {}; + +export default WithSearchFn; diff --git a/docs/src/pages/examples.js b/docs/src/pages/examples.js index 9dcb34d2..48d2399b 100644 --- a/docs/src/pages/examples.js +++ b/docs/src/pages/examples.js @@ -28,6 +28,7 @@ import ExternalClear from '../examples/ExternalClear'; import AccessDataByPath from '../examples/AccessDataByPath'; import CustomDropdownHandle from '../examples/CustomDropdownHandle'; import WithAnimation from '../examples/WithAnimation'; +import WithSearchFn from '../examples/WithSearchFn'; const demoOptions = options.map((option) => ({ ...option, @@ -116,6 +117,10 @@ const Examples = () => ( + + + +


diff --git a/docs/src/pages/state.md b/docs/src/pages/state.md index 680ae084..b03f0c84 100644 --- a/docs/src/pages/state.md +++ b/docs/src/pages/state.md @@ -11,4 +11,6 @@ Access to current state of <Select/> component | dropdown | boolean | check if dropdown is open | | values | array | selected value(s) | | search | string | current search string | +| searchResults| string | Filtered search results +| | selectBounds | object | current `getBoundingClientRect()` of <Select/> | diff --git a/package-lock.json b/package-lock.json index aef639f1..88aefe33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4139,7 +4139,8 @@ }, "minimist": { "version": "1.2.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "schema-utils": { @@ -12782,7 +12783,8 @@ }, "minimist": { "version": "1.2.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "tapable": { @@ -12851,7 +12853,8 @@ }, "minimist": { "version": "1.2.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "string-width": { diff --git a/src/components/Dropdown.js b/src/components/Dropdown.js index 10a23829..407d0618 100644 --- a/src/components/Dropdown.js +++ b/src/components/Dropdown.js @@ -49,7 +49,7 @@ const Dropdown = ({ props, state, methods }) => ( {props.createNewLabel.replace('{search}', `"${state.search}"`)} )} - {methods.searchResults().length === 0 ? ( + {state.searchResults.length === 0 ? ( ( methods={methods} /> ) : ( - methods - .searchResults() - .map((item, itemIndex) => ( - - )) - )} + state.searchResults + .map((item, itemIndex) => ( + + )) + )} )} diff --git a/src/index.js b/src/index.js index 5c1d88ba..1b5dbba8 100644 --- a/src/index.js +++ b/src/index.js @@ -74,7 +74,8 @@ export class Select extends Component { values: props.values, search: '', selectBounds: {}, - cursor: null + cursor: null, + searchResults: props.options, }; this.methods = { @@ -289,7 +290,9 @@ export class Select extends Component { }); this.setState({ - search: event.target.value + search: event.target.value, + }, () => { + this.setState({ searchResults: this.searchResults() }) }); }; @@ -391,7 +394,7 @@ export class Select extends Component { }; handleKeyDownFn = ({ event, state, props, methods, setState }) => { - const { cursor } = state; + const { cursor, searchResults } = state; const escape = event.key === 'Escape'; const enter = event.key === 'Enter'; const arrowUp = event.key === 'ArrowUp'; @@ -423,7 +426,7 @@ export class Select extends Component { } if (enter) { - const currentItem = methods.searchResults()[cursor]; + const currentItem = searchResults[cursor]; if (currentItem && !currentItem.disabled) { if (props.create && valueExistInSelected(state.search, state.values, props)) { return null; @@ -433,7 +436,7 @@ export class Select extends Component { } } - if ((arrowDown || (tab && state.dropdown)) && methods.searchResults().length === cursor) { + if ((arrowDown || (tab && state.dropdown)) && searchResults.length === cursor) { return setState({ cursor: 0 }); @@ -453,7 +456,7 @@ export class Select extends Component { if ((arrowUp || (shiftTab && state.dropdown)) && cursor === 0) { setState({ - cursor: methods.searchResults().length + cursor: searchResults.length }); }