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.