Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix EuiValidatableControl's ref handling #3822

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
**Bug fixes**

- Fixed bug in all input fields placeholders in Safari that weren't vertically centered ([#3809](https://github.com/elastic/eui/pull/3809))
- 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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import React from 'react';
import { render } from 'enzyme';
import { render, mount } from 'enzyme';

import { EuiValidatableControl } from './validatable_control';

Expand All @@ -32,4 +32,34 @@ describe('EuiValidatableControl', () => {

expect(component).toMatchSnapshot();
});

describe('ref management', () => {
it('calls a ref function', () => {
const ref = jest.fn();

mount(
<EuiValidatableControl>
<input id="testInput" ref={ref} />
</EuiValidatableControl>
);

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<HTMLInputElement> = { current: null };
chandlerprall marked this conversation as resolved.
Show resolved Hide resolved

mount(
<EuiValidatableControl>
<input id="testInput" ref={ref} />
</EuiValidatableControl>
);

expect(ref.current).not.toBeNull();
expect(ref.current!.getAttribute('id')).toBe('testInput');
});
});
});
19 changes: 17 additions & 2 deletions src/components/form/validatable_control/validatable_control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,28 @@
* 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 {
setCustomValidity: (error: string) => void;
}

export interface ReactElementWithRef extends ReactElement {
ref?: (element: HTMLConstraintValidityElement) => void;
ref?: Ref<HTMLConstraintValidityElement>;
}

function isMutableRef(
ref?: Ref<HTMLConstraintValidityElement>
): ref is MutableRefObject<HTMLConstraintValidityElement> {
return ref != null && ref.hasOwnProperty('current');
}

export interface EuiValidatableControlProps {
Expand Down Expand Up @@ -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;
}
};

Expand Down