Skip to content

Commit

Permalink
Improve focus UX of MultiInputRows (#97695) (#97861)
Browse files Browse the repository at this point in the history
Co-authored-by: Constance <[email protected]>
  • Loading branch information
kibanamachine and Constance authored Apr 21, 2021
1 parent 4b42523 commit 654548f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('InputRow', () => {
const props = {
value: 'some value',
placeholder: 'Enter a value',
autoFocus: false,
onChange: jest.fn(),
onDelete: jest.fn(),
disableDelete: false,
Expand All @@ -33,6 +34,7 @@ describe('InputRow', () => {
expect(wrapper.find(EuiFieldText)).toHaveLength(1);
expect(wrapper.find(EuiFieldText).prop('value')).toEqual('some value');
expect(wrapper.find(EuiFieldText).prop('placeholder')).toEqual('Enter a value');
expect(wrapper.find(EuiFieldText).prop('autoFocus')).toEqual(false);
expect(wrapper.find('[data-test-subj="deleteInputRowButton"]').prop('title')).toEqual(
'Delete value'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic
interface Props {
value: string;
placeholder: string;
autoFocus: boolean;
onChange(newValue: string): void;
onDelete(): void;
disableDelete: boolean;
Expand All @@ -23,6 +24,7 @@ import './input_row.scss';
export const InputRow: React.FC<Props> = ({
value,
placeholder,
autoFocus,
onChange,
onDelete,
disableDelete,
Expand All @@ -35,7 +37,7 @@ export const InputRow: React.FC<Props> = ({
placeholder={placeholder}
value={value}
onChange={(e) => onChange(e.target.value)}
autoFocus
autoFocus={autoFocus}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('MultiInputRows', () => {
};
const values = {
values: ['a', 'b', 'c'],
addedNewRow: false,
hasEmptyValues: false,
hasOnlyOneValue: false,
};
Expand Down Expand Up @@ -56,6 +57,20 @@ describe('MultiInputRows', () => {
expect(wrapper.find(InputRow).at(2).prop('value')).toEqual('c');
});

it('focuses the first input row on load, but focuses new input rows on add', () => {
setMockValues({ ...values, addedNewRow: false });
const wrapper = shallow(<MultiInputRows {...props} />);

expect(wrapper.find(InputRow).first().prop('autoFocus')).toEqual(true);
expect(wrapper.find(InputRow).last().prop('autoFocus')).toEqual(false);

setMockValues({ ...values, addedNewRow: true });
rerender(wrapper);

expect(wrapper.find(InputRow).first().prop('autoFocus')).toEqual(false);
expect(wrapper.find(InputRow).last().prop('autoFocus')).toEqual(true);
});

it('calls editValue when the InputRow value changes', () => {
const wrapper = shallow(<MultiInputRows {...props} />);
wrapper.find(InputRow).at(0).simulate('change', 'new value');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const MultiInputRows: React.FC<Props> = ({
inputPlaceholder = INPUT_ROW_PLACEHOLDER,
}) => {
const logic = MultiInputRowsLogic({ id, values: initialValues });
const { values, hasEmptyValues, hasOnlyOneValue } = useValues(logic);
const { values, addedNewRow, hasEmptyValues, hasOnlyOneValue } = useValues(logic);
const { addValue, editValue, deleteValue } = useActions(logic);

useEffect(() => {
Expand All @@ -55,17 +55,22 @@ export const MultiInputRows: React.FC<Props> = ({

return (
<>
{values.map((value: string, index: number) => (
<InputRow
key={`inputRow${index}`}
value={value}
placeholder={inputPlaceholder}
onChange={(newValue) => editValue(index, newValue)}
onDelete={() => deleteValue(index)}
disableDelete={hasOnlyOneValue}
deleteLabel={deleteRowLabel}
/>
))}
{values.map((value: string, index: number) => {
const firstRow = index === 0;
const lastRow = index === values.length - 1;
return (
<InputRow
key={`inputRow-${id}-${index}`}
value={value}
placeholder={inputPlaceholder}
autoFocus={addedNewRow ? lastRow : firstRow}
onChange={(newValue) => editValue(index, newValue)}
onDelete={() => deleteValue(index)}
disableDelete={hasOnlyOneValue}
deleteLabel={deleteRowLabel}
/>
);
})}
<EuiButtonEmpty
size="s"
iconType="plusInCircle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('MultiInputRowsLogic', () => {
};
const DEFAULT_VALUES = {
values: MOCK_VALUES,
addedNewRow: false,
hasEmptyValues: false,
hasOnlyOneValue: false,
};
Expand All @@ -48,11 +49,12 @@ describe('MultiInputRowsLogic', () => {
});

describe('addValue', () => {
it('appends an empty string to the values array', () => {
it('appends an empty string to the values array & sets addedNewRow to true', () => {
logic.actions.addValue();

expect(logic.values).toEqual({
...DEFAULT_VALUES,
addedNewRow: true,
hasEmptyValues: true,
values: ['a', 'b', 'c', ''],
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { kea, MakeLogicType } from 'kea';

interface MultiInputRowsValues {
values: string[];
addedNewRow: boolean;
hasEmptyValues: boolean;
hasOnlyOneValue: boolean;
}
Expand Down Expand Up @@ -51,6 +52,12 @@ export const MultiInputRowsLogic = kea<
},
},
],
addedNewRow: [
false,
{
addValue: () => true,
},
],
}),
selectors: {
hasEmptyValues: [(selectors) => [selectors.values], (values) => values.indexOf('') >= 0],
Expand Down

0 comments on commit 654548f

Please sign in to comment.