Skip to content

Commit

Permalink
feat(plasma-*, sdds-*): fix keyboard interaction bug in Combobox
Browse files Browse the repository at this point in the history
  • Loading branch information
shuga2704 committed Dec 4, 2024
1 parent 8daa805 commit eee4bf2
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1401,7 +1401,43 @@ describe('plasma-b2c: Combobox', () => {
cy.matchImageSnapshot();
});

it('keyboard interactions', () => {
it('keyboard interactions: single', () => {
cy.viewport(1000, 500);

const Component = () => {
return (
<div style={{ width: '300px' }}>
<Combobox id="single" label="Label" placeholder="Placeholder" items={items} />
</div>
);
};

mount(<Component />);

cy.get('body').realClick();
cy.realPress('Tab');
cy.get('#single').should('be.focused');

// Escape
cy.realPress('ArrowDown').realPress('ArrowDown').realPress('ArrowRight').realPress('ArrowRight');
cy.realPress('Escape');
cy.get('[id$="tree_level_1"]').should('not.exist');
cy.get('[id$="tree_level_2"]').should('not.exist');
cy.get('[id$="tree_level_3"]').should('not.exist');
cy.get('#single').should('be.focused');
cy.realPress('ArrowDown').realPress('Enter').realPress('Escape');
cy.get('#single').should('be.focused');
cy.get('#single').should('have.value', 'Северная Америка');
cy.get('[id$="tree_level_1"]').should('not.exist');

// Tab
cy.realPress('Tab');
cy.get('#single').should('not.be.focused');
cy.get('#single').should('have.value', 'Северная Америка');
cy.get('[id$="tree_level_1"]').should('not.exist');
});

it('keyboard interactions: multiple', () => {
cy.viewport(1000, 500);

const Component = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ export const comboboxRoot = (Root: RootProps<HTMLInputElement, Omit<ComboboxProp
handleListToggle,
handlePressDown,
setTextValue,
multiple,
value,
textValue,
valueToItemMap,
});

// В данном эффекте мы следим за изменениями value снаружи и вносим коррективы в дерево чекбоксов.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import React from 'react';

import { PathAction, PathState, FocusedPathAction, FocusedPathState } from '../reducers';
import type { ItemOptionTransformed } from '../ui/Inner/ui/Item/Item.types';
import { isEmpty } from '../../../../utils';

import { PathMapType, FocusedToValueMapType } from './getPathMaps';
import { PathMapType, FocusedToValueMapType, ValueToItemMapType } from './getPathMaps';

const JUMP_SIZE = 10;

Expand Down Expand Up @@ -40,6 +41,10 @@ type Props = {
handleListToggle: (opened: boolean) => void;
handlePressDown: (item: ItemOptionTransformed, e?: React.MouseEvent<HTMLElement>) => void;
setTextValue: React.Dispatch<React.SetStateAction<string>>;
multiple: boolean | undefined;
value: string | string[];
textValue: string;
valueToItemMap: ValueToItemMapType;
};

type ReturnedProps = {
Expand All @@ -56,6 +61,10 @@ export const useKeyNavigation = ({
handleListToggle,
handlePressDown,
setTextValue,
multiple,
value,
textValue,
valueToItemMap,
}: Props): ReturnedProps => {
const currentIndex: number = focusedPath?.[focusedPath.length - 1] || 0;
const currentLength: number = pathMap.get(path?.[focusedPath.length - 1]) || 0;
Expand Down Expand Up @@ -179,7 +188,19 @@ export const useKeyNavigation = ({
dispatchPath({ type: 'reset' });
dispatchFocusedPath({ type: 'reset' });
handleListToggle(false);
setTextValue('');

if (multiple) {
setTextValue('');
} else if (textValue !== value) {
// Проверяем, отличается ли значение в инпуте от выбранного value после нажатия Tab/Enter.
// Если изменилось, то возвращаем label выбранного айтема.
// Если нет выбранного элемента, то стираем значение инпута.
if (isEmpty(value)) {
setTextValue('');
} else {
setTextValue(valueToItemMap.get(value as string)?.label || '');
}
}

break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1401,7 +1401,43 @@ describe('plasma-web: Combobox', () => {
cy.matchImageSnapshot();
});

it('keyboard interactions', () => {
it('keyboard interactions: single', () => {
cy.viewport(1000, 500);

const Component = () => {
return (
<div style={{ width: '300px' }}>
<Combobox id="single" label="Label" placeholder="Placeholder" items={items} />
</div>
);
};

mount(<Component />);

cy.get('body').realClick();
cy.realPress('Tab');
cy.get('#single').should('be.focused');

// Escape
cy.realPress('ArrowDown').realPress('ArrowDown').realPress('ArrowRight').realPress('ArrowRight');
cy.realPress('Escape');
cy.get('[id$="tree_level_1"]').should('not.exist');
cy.get('[id$="tree_level_2"]').should('not.exist');
cy.get('[id$="tree_level_3"]').should('not.exist');
cy.get('#single').should('be.focused');
cy.realPress('ArrowDown').realPress('Enter').realPress('Escape');
cy.get('#single').should('be.focused');
cy.get('#single').should('have.value', 'Северная Америка');
cy.get('[id$="tree_level_1"]').should('not.exist');

// Tab
cy.realPress('Tab');
cy.get('#single').should('not.be.focused');
cy.get('#single').should('have.value', 'Северная Америка');
cy.get('[id$="tree_level_1"]').should('not.exist');
});

it('keyboard interactions: multiple', () => {
cy.viewport(1000, 500);

const Component = () => {
Expand Down

0 comments on commit eee4bf2

Please sign in to comment.