diff --git a/CHANGELOG.md b/CHANGELOG.md index f8dd7ddc21a..0d0395a40b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Added a `size` prop to `EuiContextMenu` and added a smaller size ([#4409](https://github.com/elastic/eui/pull/4409)) - Added a `textSize` prop to `EuiHealth` ([#4420](https://github.com/elastic/eui/pull/4420)) +- Removed selected item of `EuiSelect` when `hasNoInitialSelection=true` and value reset to `undefined` ([#4428](https://github.com/elastic/eui/pull/4428)) ## [`31.2.0`](https://github.com/elastic/eui/tree/v31.2.0) diff --git a/src/components/form/select/select.test.tsx b/src/components/form/select/select.test.tsx index e7e33eaea36..0b0409fea09 100644 --- a/src/components/form/select/select.test.tsx +++ b/src/components/form/select/select.test.tsx @@ -16,9 +16,10 @@ * specific language governing permissions and limitations * under the License. */ +/* eslint-disable no-irregular-whitespace */ import React from 'react'; -import { render } from 'enzyme'; +import { render, mount } from 'enzyme'; import { requiredProps } from '../../../test/required_props'; import { EuiSelect } from './select'; @@ -31,7 +32,7 @@ jest.mock('../validatable_control', () => ({ })); describe('EuiSelect', () => { - test('is rendered', () => { + it('is rendered', () => { const component = render( ); @@ -40,7 +41,7 @@ describe('EuiSelect', () => { }); describe('props', () => { - test('options are rendered', () => { + it('options are rendered', () => { const component = render( { expect(component).toMatchSnapshot(); }); - test('isInvalid is rendered', () => { + it('isInvalid is rendered', () => { const component = render(); expect(component).toMatchSnapshot(); }); - test('fullWidth is rendered', () => { + it('fullWidth is rendered', () => { const component = render(); expect(component).toMatchSnapshot(); }); - test('isLoading is rendered', () => { + it('isLoading is rendered', () => { const component = render(); expect(component).toMatchSnapshot(); }); - test('disabled options are rendered', () => { + it('disabled options are rendered', () => { const component = render( { expect(component).toMatchSnapshot(); }); - test('value option is rendered', () => { + it('value option is rendered', () => { const component = render( { expect(component).toMatchSnapshot(); }); }); + + describe('hasNoInitialSelection', () => { + it('renders with an extra option at the top', () => { + const component = mount( + {}} + /> + ); + + expect(component.find('option').length).toBe(3); + expect(component.find('option').at(0)).toMatchInlineSnapshot(` + +`); + }); + + it('can be reset to an empty initial selection', () => { + const component = mount( + {}} + /> + ); + + expect( + component.find('select').getDOMNode().value + ).toBe('1'); + + component.setProps({ value: '' }); + expect( + component.find('select').getDOMNode().value + ).toBe(''); + + component.setProps({ value: '1' }); + expect( + component.find('select').getDOMNode().value + ).toBe('1'); + + component.setProps({ value: undefined }); + expect( + component.find('select').getDOMNode().value + ).toBe(''); + }); + }); }); diff --git a/src/components/form/select/select.tsx b/src/components/form/select/select.tsx index 653c4fb8317..89324c6f0af 100644 --- a/src/components/form/select/select.tsx +++ b/src/components/form/select/select.tsx @@ -83,12 +83,16 @@ export const EuiSelect: FunctionComponent = ({ hasNoInitialSelection = false, defaultValue, compressed = false, - value, + value: _value, prepend, append, onMouseUp, ...rest }) => { + // if this is injecting an empty option for `hasNoInitialSelection` then + // value needs to fallback to an empty string to interact properly with `defaultValue` + const value = hasNoInitialSelection ? _value ?? '' : _value; + const handleMouseUp = (e: React.MouseEvent) => { // Normalizes cross-browser mouse eventing by preventing propagation, // notably for use in conjunction with EuiOutsideClickDetector.