Skip to content

Commit

Permalink
[EuiComboBox] Replace autosizing input dependency with more performan…
Browse files Browse the repository at this point in the history
…t utility (#7215)
  • Loading branch information
cee-chen authored Sep 26, 2023
1 parent 501e186 commit fedc004
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 117 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
"@hello-pangea/dnd": "^16.3.0",
"@types/lodash": "^4.14.198",
"@types/numeral": "^2.0.2",
"@types/react-input-autosize": "^2.2.1",
"@types/react-window": "^1.8.5",
"@types/refractor": "^3.0.2",
"@types/resize-observer-browser": "^0.1.7",
Expand All @@ -80,7 +79,6 @@
"react-dropzone": "^11.7.1",
"react-element-to-jsx-string": "^14.3.4",
"react-focus-on": "^3.9.1",
"react-input-autosize": "^3.0.0",
"react-is": "^17.0.2",
"react-remove-scroll-bar": "^2.3.4",
"react-virtualized-auto-sizer": "^1.0.20",
Expand Down
6 changes: 6 additions & 0 deletions scripts/jest/setup/mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ jest.mock('./../../../src/components/icon', () => {
return { EuiIcon };
});

jest.mock('./../../../src/components/text_truncate', () => {
const rest = jest.requireActual('./../../../src/components/text_truncate');
const utils = require('./../../../src/components/text_truncate/utils.testenv');
return { ...rest, ...utils };
});

jest.mock('./../../../src/services/accessibility', () => {
const a11y = jest.requireActual('./../../../src/services/accessibility');
const {
Expand Down
73 changes: 23 additions & 50 deletions src/components/combo_box/__snapshots__/combo_box.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,19 @@ exports[`EuiComboBox is rendered 1`] = `
data-test-subj="comboBoxInput"
tabindex="-1"
>
<div
<input
aria-autocomplete="list"
aria-controls=""
aria-expanded="false"
aria-invalid="false"
aria-label="aria-label"
class="euiComboBox__input"
style="font-size: 14px; display: inline-block;"
>
<input
aria-autocomplete="list"
aria-controls=""
aria-expanded="false"
aria-invalid="false"
aria-label="aria-label"
data-test-subj="comboBoxSearchInput"
id="generated-id__eui-combobox-id"
role="combobox"
style="box-sizing: content-box; width: 2px;"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-size: 14px; font-family: 'Inter',BlinkMacSystemFont,Helvetica,Arial,sans-serif; font-weight: 400; letter-spacing: normal; text-transform: none;"
/>
</div>
data-test-subj="comboBoxSearchInput"
id="generated-id__eui-combobox-id"
role="combobox"
style="inline-size: 2px;"
value=""
/>
</div>
<div
class="euiFormControlLayoutIcons euiFormControlLayoutIcons--right euiFormControlLayoutIcons--absolute"
Expand Down Expand Up @@ -67,7 +60,6 @@ exports[`props aria-label attribute is rendered 1`] = `
>
<EuiComboBoxInput
aria-label="Test label"
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={false}
Expand Down Expand Up @@ -102,7 +94,6 @@ exports[`props aria-labelledby attribute is rendered 1`] = `
>
<EuiComboBoxInput
aria-labelledby="test-heading-id"
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={false}
Expand Down Expand Up @@ -136,7 +127,6 @@ exports[`props autoFocus is rendered 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down Expand Up @@ -179,7 +169,6 @@ exports[`props custom ID is rendered 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down Expand Up @@ -222,7 +211,6 @@ exports[`props delimiter is rendered 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down Expand Up @@ -265,7 +253,6 @@ exports[`props full width is rendered 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={true}
hasSelectedOptions={true}
Expand Down Expand Up @@ -305,7 +292,6 @@ exports[`props isClearable=false disallows user from clearing input when no opti
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={false}
Expand Down Expand Up @@ -338,7 +324,6 @@ exports[`props isClearable=false disallows user from clearing input when options
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down Expand Up @@ -380,7 +365,6 @@ exports[`props isDisabled is rendered 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down Expand Up @@ -635,25 +619,18 @@ exports[`props options list is rendered 1`] = `
data-test-subj="comboBoxInput"
tabindex="-1"
>
<div
<input
aria-autocomplete="list"
aria-controls="generated-id_listbox"
aria-expanded="true"
aria-invalid="false"
class="euiComboBox__input"
style="font-size: 14px; display: inline-block;"
>
<input
aria-autocomplete="list"
aria-controls="generated-id_listbox"
aria-expanded="true"
aria-invalid="false"
data-test-subj="comboBoxSearchInput"
id="generated-id__eui-combobox-id"
role="combobox"
style="box-sizing: content-box; width: 2px;"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
data-test-subj="comboBoxSearchInput"
id="generated-id__eui-combobox-id"
role="combobox"
style="inline-size: 2px;"
value=""
/>
</div>
<div
class="euiFormControlLayoutIcons euiFormControlLayoutIcons--right euiFormControlLayoutIcons--absolute"
Expand Down Expand Up @@ -952,7 +929,6 @@ exports[`props selectedOptions are rendered 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down Expand Up @@ -995,7 +971,6 @@ exports[`props singleSelection is rendered 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down Expand Up @@ -1036,7 +1011,6 @@ exports[`props singleSelection prepend and append is rendered 1`] = `
>
<EuiComboBoxInput
append="String"
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={false}
Expand Down Expand Up @@ -1079,7 +1053,6 @@ exports[`props singleSelection selects existing option when opened 1`] = `
onKeyDown={[Function]}
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
Expand Down
31 changes: 12 additions & 19 deletions src/components/combo_box/_combo_box.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,20 @@
/**
* 1. Force field height to match other field heights.
* 2. Force input height to expand to fill this element.
* 3. Reset appearance on Safari.
* 4. Fix react-input-autosize appearance.
* 5. Prevent a lot of input from causing the react-input-autosize to overflow the container.
* 3. Reset input appearance to mimic text
*/
.euiComboBox__input {
// stylelint-disable-next-line declaration-no-important
display: inline-flex !important; /* 1 */
height: $euiSizeXL; /* 2 */
overflow: hidden; /* 5 */

> input {
@include euiFont;
appearance: none; /* 3 */
padding: 0;
border: none;
background: transparent;
font-size: $euiFontSizeS;
color: $euiTextColor;
margin: $euiSizeXS;
line-height: $euiLineHeight; /* 4 */
}
block-size: $euiSizeL; /* 2 */
min-inline-size: 2px;
max-inline-size: 100%;
margin: $euiSizeXS;

/* 3 */
appearance: none;
outline: none;
border: none;
background: transparent;
color: $euiTextColor;
}

&.euiComboBox-isOpen {
Expand Down
36 changes: 36 additions & 0 deletions src/components/combo_box/combo_box.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,42 @@ describe('EuiComboBox', () => {
});
});

describe('input auto sizing', () => {
it('resizes the width of the input based to fit the search text', () => {
cy.realMount(<EuiComboBox options={[]} />);
cy.get('[data-test-subj="comboBoxSearchInput"]').should(
'have.attr',
'style',
'inline-size: 2px;'
);

cy.get('[data-test-subj="comboBoxSearchInput"]').realClick();
cy.realType('lorem ipsum dolor');
cy.get('[data-test-subj="comboBoxSearchInput"]').should(
'have.attr',
'style',
'inline-size: 121px;'
);
});

it('does not exceed the maximum possible width of the input wrapper', () => {
cy.realMount(<EuiComboBox options={[]} />);
cy.get('[data-test-subj="comboBoxSearchInput"]').realClick();
cy.realType(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit......'
);

cy.get('[data-test-subj="comboBoxSearchInput"]').should(
'have.attr',
'style',
'inline-size: 387px;'
);
cy.get('[data-test-subj="comboBoxSearchInput"]')
.invoke('width')
.should('be.eq', 354);
});
});

describe('truncation', () => {
const sharedProps = {
style: { width: 200 },
Expand Down
15 changes: 0 additions & 15 deletions src/components/combo_box/combo_box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import React, {
RefCallback,
} from 'react';
import classNames from 'classnames';
import AutosizeInput from 'react-input-autosize';

import { findPopoverPosition, htmlIdGenerator, keys } from '../../services';
import { getElementZIndex } from '../../services/popover';
Expand Down Expand Up @@ -256,12 +255,6 @@ export class EuiComboBox<T> extends Component<
});
}
};
autoSizeInputRefInstance: RefInstance<AutosizeInput & HTMLDivElement> = null;
autoSizeInputRefCallback: RefCallback<AutosizeInput & HTMLDivElement> = (
ref
) => {
this.autoSizeInputRefInstance = ref;
};

searchInputRefInstance: RefInstance<HTMLInputElement> = null;
searchInputRefCallback: RefCallback<HTMLInputElement> = (ref) => {
Expand Down Expand Up @@ -787,13 +780,6 @@ export class EuiComboBox<T> extends Component<

componentDidMount() {
this._isMounted = true;

// TODO: This will need to be called once the actual stylesheet loads.
setTimeout(() => {
if (this.autoSizeInputRefInstance) {
this.autoSizeInputRefInstance.copyInputStyles();
}
}, 100);
}

static getDerivedStateFromProps<T>(
Expand Down Expand Up @@ -1044,7 +1030,6 @@ export class EuiComboBox<T> extends Component<
ref={this.comboBoxRefCallback}
>
<EuiComboBoxInput
autoSizeInputRef={this.autoSizeInputRefCallback}
compressed={compressed}
focusedOptionId={
this.hasActiveOption()
Expand Down
Loading

0 comments on commit fedc004

Please sign in to comment.