From 62216f52c5b0194f9dda44c5569164a6c74af9fa Mon Sep 17 00:00:00 2001 From: Chandler Prall Date: Wed, 29 Jul 2020 13:54:47 -0600 Subject: [PATCH 1/3] Update EuiValidatableControl to update a RefObject ref in addition to supporting callback refs --- .../validatable_control.test.tsx | 32 ++++++++++++++++++- .../validatable_control.tsx | 19 +++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/components/form/validatable_control/validatable_control.test.tsx b/src/components/form/validatable_control/validatable_control.test.tsx index a3d7da8191a..31f5f1097d5 100644 --- a/src/components/form/validatable_control/validatable_control.test.tsx +++ b/src/components/form/validatable_control/validatable_control.test.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { render } from 'enzyme'; +import { render, mount } from 'enzyme'; import { EuiValidatableControl } from './validatable_control'; @@ -32,4 +32,34 @@ describe('EuiValidatableControl', () => { expect(component).toMatchSnapshot(); }); + + describe('ref management', () => { + it('calls a ref function', () => { + const ref = jest.fn(); + + mount( + + + + ); + + expect(ref).toHaveBeenCalledTimes(1); + + const input = ref.mock.calls[0][0]; + expect(input.getAttribute('id')).toBe('testInput'); + }); + + it('sets a ref object\'s "current" property', () => { + const ref: React.RefObject = { current: null }; + + mount( + + + + ); + + expect(ref.current).not.toBeNull(); + expect(ref.current!.getAttribute('id')).toBe('testInput'); + }); + }); }); diff --git a/src/components/form/validatable_control/validatable_control.tsx b/src/components/form/validatable_control/validatable_control.tsx index 3fe3db8cfec..c5e451cd189 100644 --- a/src/components/form/validatable_control/validatable_control.tsx +++ b/src/components/form/validatable_control/validatable_control.tsx @@ -17,7 +17,14 @@ * under the License. */ -import { Children, cloneElement, Component, ReactElement } from 'react'; +import { + Children, + cloneElement, + Component, + MutableRefObject, + ReactElement, + Ref, +} from 'react'; import { CommonProps } from '../../common'; export interface HTMLConstraintValidityElement extends Element { @@ -25,7 +32,13 @@ export interface HTMLConstraintValidityElement extends Element { } export interface ReactElementWithRef extends ReactElement { - ref?: (element: HTMLConstraintValidityElement) => void; + ref?: Ref; +} + +function isMutableRef( + ref?: Ref +): ref is MutableRefObject { + return ref != null && ref.hasOwnProperty('current'); } export interface EuiValidatableControlProps { @@ -68,6 +81,8 @@ export class EuiValidatableControl extends Component< const { ref } = this.props.children; if (typeof ref === 'function') { ref(element); + } else if (isMutableRef(ref)) { + ref.current = element; } }; From e8fa6b29d80d0478d88f63e1b97d8e23643bc07a Mon Sep 17 00:00:00 2001 From: Chandler Prall Date: Wed, 29 Jul 2020 14:01:06 -0600 Subject: [PATCH 2/3] changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fa886a2d13..16213d61d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `27.3.0`. +**Bug fixes** + +- Fixed bug in EUI's input field components where their `inputRef` couldn't be a `RefObject` ([#3822](https://github.com/elastic/eui/pull/3822)) ## [`27.3.0`](https://github.com/elastic/eui/tree/v27.3.0) From bba0bcafcc47ec1a9d2f155b4908af9ffa0c7193 Mon Sep 17 00:00:00 2001 From: Chandler Prall Date: Thu, 30 Jul 2020 08:07:27 -0600 Subject: [PATCH 3/3] Use React.createRef to create a reference object instead of a custom one --- .../form/validatable_control/validatable_control.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/form/validatable_control/validatable_control.test.tsx b/src/components/form/validatable_control/validatable_control.test.tsx index 31f5f1097d5..8ea3d87ca23 100644 --- a/src/components/form/validatable_control/validatable_control.test.tsx +++ b/src/components/form/validatable_control/validatable_control.test.tsx @@ -50,7 +50,7 @@ describe('EuiValidatableControl', () => { }); it('sets a ref object\'s "current" property', () => { - const ref: React.RefObject = { current: null }; + const ref = React.createRef(); mount(