Skip to content

Commit

Permalink
cherry-pick: fix(ImageBaseOverlay): fix nested Tappable (#7006) | (#7152
Browse files Browse the repository at this point in the history
)

* fix(ImageBaseOverlay): fix nested Tappable (#7006)

* fix(ImageBaseOverlay): fix nested Tappable

* fix(ImageBaseOverlay): add non interactive wrapper

* chore: clean up

Co-authored-by: Andrey Medvedev <[email protected]>

* chore: fix prettier

* fix: review notes

* fix merge

* fix: remove tests

* fix: revert DisableClickableLockStateContext  adding

---------

Co-authored-by: Andrey Medvedev <[email protected]>

* fix: run prettier

* CHORE: Update screenshots

* fix: delete e2e test

---------

Co-authored-by: Andrey Medvedev <[email protected]>
Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
3 people authored Jul 8, 2024
1 parent b073303 commit 5019c30
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,3 @@ export const CustomSelectNoMaxHeightPlayground = (props: ComponentPlaygroundProp
</ComponentPlayground>
);
};

export const CustomSelectOptionScrollPlayground = (props: ComponentPlaygroundProps) => {
return (
<ComponentPlayground {...props} propSets={[{ value: [7] }]}>
{(props: SelectProps) => (
<div style={{ height: 200 }}>
<CustomSelect
data-testid="target-select"
{...props}
options={[
{ value: 1, label: 'Гарри Поттер и философский камень' },
{ value: 2, label: 'Гарри Поттер и Тайная комната' },
{
value: 3,
label: 'Гарри Поттер и узник Азкабана',
},
{ value: 4, label: 'Гарри Поттер и Кубок Огня' },
{ value: 5, label: 'Гарри Поттер и Орден Феникса' },
{ value: 6, label: 'Гарри Поттер и Принц-полукровка' },
{ value: 7, label: 'Гарри Поттер и Дары Смерти' },
]}
/>
</div>
)}
</ComponentPlayground>
);
};
21 changes: 0 additions & 21 deletions packages/vkui/src/components/CustomSelect/CustomSelect.e2e.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { test } from '@vkui-e2e/test';
import { Appearance } from '../../lib/appearance';
import {
CustomSelectNoMaxHeightPlayground,
CustomSelectOptionScrollPlayground,
CustomSelectPlayground,
} from './CustomSelect.e2e-playground';

Expand Down Expand Up @@ -38,23 +37,3 @@ test.describe('CustomSelect', () => {
await expectScreenshotClippedToContent();
});
});

test.describe('CustomSelect', () => {
test.use({
onlyForAppearances: [Appearance.LIGHT],
platform: 'android',
onlyForBrowsers: ['chromium'],
});
test('scroll to option', async ({
mount,
page,
expectScreenshotClippedToContent,
componentPlaygroundProps,
}) => {
await mount(<CustomSelectOptionScrollPlayground {...componentPlaygroundProps} />);

await page.getByTestId('target-select').click();

await expectScreenshotClippedToContent();
});
});

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@
opacity: 1;
}

@media (--hover-has) {
.ImageBaseOverlay:hover {
opacity: 1;
}
}

.ImageBaseOverlay--clickable {
cursor: pointer;
}

.ImageBaseOverlay--theme-light {
color: var(--vkui--color_icon_accent);
background-color: var(--vkui--color_avatar_overlay_inverse_alpha);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ import { Meta, StoryObj } from '@storybook/react';
import { CanvasFullLayout, DisableCartesianParam } from '../../../storybook/constants';
import { getAvatarUrl } from '../../../testing/mock';
import { ImageBase } from '../ImageBase';
import { ImageBaseOverlay, ImageBaseOverlayProps } from './ImageBaseOverlay';
import { ImageBaseOverlay, type ImageBaseOverlayProps } from './ImageBaseOverlay';

const story: Meta<ImageBaseOverlayProps> = {
title: 'Blocks/ImageBaseOverlay',
component: ImageBaseOverlay,
parameters: { ...CanvasFullLayout, ...DisableCartesianParam },
decorators: [
(Component) => (
<ImageBase size={48} src={getAvatarUrl('app_shorm_online')} alt="Приложение шторм онлайн">
<Component />
</ImageBase>
),
],
};

export default story;
Expand All @@ -18,11 +25,4 @@ export const Playground: Story = {
args: {
'aria-label': 'Кнопка для изображения',
},
decorators: [
(Component) => (
<ImageBase size={48} src={getAvatarUrl('app_shorm_online')} alt="Приложение шторм онлайн">
<Component />
</ImageBase>
),
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { act } from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { Icon12Add } from '@vkontakte/icons';
import { Button } from '../../../components/Button/Button';
import { baselineComponent, userEvent } from '../../../testing/utils';
import { ImageBaseOverlay, ImageBaseOverlayProps } from './ImageBaseOverlay';
import styles from './ImageBaseOverlay.module.css';

const ImageBaseOverlayClickableTest = (props: Omit<ImageBaseOverlayProps, 'children'>) => (
<ImageBaseOverlay
data-testid="overlay"
aria-label="Интерактивная Кнопка"
{...props}
disableInteractive={false}
>
<Icon12Add />
</ImageBaseOverlay>
);

const ImageBaseOverlayNonClickableTest = (
props: Omit<ImageBaseOverlayProps, 'children' | 'onClick'>,
) => (
<ImageBaseOverlay data-testid="overlay" {...props} disableInteractive>
<Button data-testid="button1">Button</Button>
<Button data-testid="button2">Button</Button>
</ImageBaseOverlay>
);

describe(ImageBaseOverlay, () => {
baselineComponent(ImageBaseOverlayClickableTest);

it('focus event works as expected without noInteractive', async () => {
render(<ImageBaseOverlayClickableTest />);
const element = screen.getByTestId('overlay');

await userEvent.tab();
expect(element).toHaveFocus();
act(jest.runAllTimers);
await userEvent.tab();
expect(document.querySelector(`.${styles['ImageBaseOverlay--visible']}`)).toBeNull();
});

it('focus event works as expected with noInteractive', async () => {
render(<ImageBaseOverlayNonClickableTest />);
const button1 = screen.getByTestId('button1');
const button2 = screen.getByTestId('button2');

await userEvent.tab();
expect(button1).toHaveFocus();
act(jest.runAllTimers);
expect(document.querySelector(`.${styles['ImageBaseOverlay--visible']}`)).not.toBeNull();
await userEvent.tab();
expect(button2).toHaveFocus();
act(jest.runAllTimers);
expect(document.querySelector(`.${styles['ImageBaseOverlay--visible']}`)).not.toBeNull();
await userEvent.tab();
act(jest.runAllTimers);
expect(document.querySelector(`.${styles['ImageBaseOverlay--visible']}`)).toBeNull();
});

describe('works as clickable element', () => {
it('appears as clickable element', () => {
render(<ImageBaseOverlayClickableTest />);

const element = screen.getByTestId('overlay');

expect(element.tagName.toLowerCase()).toMatch('div');
expect(element).toHaveAttribute('role', 'button');
expect(element).toHaveAttribute('tabindex', '0');
expect(document.querySelector(`.${styles['ImageBaseOverlay--clickable']}`)).not.toBeNull();
});

it('handles onClick prop', () => {
const handleClick = jest.fn();
render(
<ImageBaseOverlayClickableTest onClick={handleClick} disableInteractive={undefined} />,
);

fireEvent.click(screen.getByTestId('overlay'));
expect(handleClick).toHaveBeenCalledTimes(1);
});

it('handles onClick prop by keyboard Enter & Space event', () => {
const handleClick = jest.fn();
render(<ImageBaseOverlayClickableTest onClick={handleClick} />);

const element = screen.getByTestId('overlay');

act(() => element.focus());

// onClick gets called on Enter and Space
fireEvent.keyDown(element, { key: 'Enter', code: 'Enter' });
expect(handleClick).toHaveBeenCalledTimes(1);

fireEvent.keyDown(element, { key: ' ', code: 'Space' });
expect(handleClick).toHaveBeenCalledTimes(2);
});
});

describe('works as wrapper for clickable elements', () => {
it('appears as non clickable element', () => {
render(<ImageBaseOverlayNonClickableTest />);
const element = screen.getByTestId('overlay');

expect(element.tagName.toLowerCase()).toMatch('div');
expect(element).not.toHaveAttribute('role', 'button');
expect(element).not.toHaveAttribute('tabindex', '0');
expect(document.querySelector(`.${styles['ImageBaseOverlay--clickable']}`)).toBeNull();
});
});
});
Loading

0 comments on commit 5019c30

Please sign in to comment.