From 16c2ecd81462384c09ee351580d2601a2503f6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D1=80=D0=BE=D0=BB=D0=B5=D0=B2=20=D0=94=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=BB?= <105650840+pan1caisreal@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:15:58 +0300 Subject: [PATCH] =?UTF-8?q?feat(UIKIT-1163,PageHeader):=20=D0=94=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7?= =?UTF-8?q?=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B0=D1=82=D1=8C=20=D1=82=D1=83?= =?UTF-8?q?=D0=BB=D1=82=D0=B8=D0=BF=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD?= =?UTF-8?q?=D1=8B=D0=BC=20actions=20(#1086)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ButtonGroupMainActions.tsx | 58 ++++-- .../src/PageHeader/PageHeader.stories.tsx | 46 ++++- .../src/PageHeader/PageHeader.test.tsx | 168 ++++++++++++++++++ 3 files changed, 260 insertions(+), 12 deletions(-) create mode 100644 packages/components/src/PageHeader/PageHeader.test.tsx diff --git a/packages/components/src/PageHeader/ButtonGroup/ButtonGroupMainActions/ButtonGroupMainActions.tsx b/packages/components/src/PageHeader/ButtonGroup/ButtonGroupMainActions/ButtonGroupMainActions.tsx index 72d21f6ed..2803feecb 100644 --- a/packages/components/src/PageHeader/ButtonGroup/ButtonGroupMainActions/ButtonGroupMainActions.tsx +++ b/packages/components/src/PageHeader/ButtonGroup/ButtonGroupMainActions/ButtonGroupMainActions.tsx @@ -3,6 +3,7 @@ import { type ComponentProps, type ElementType } from 'react'; import { type ButtonProps } from '../../../Button'; import { type DropdownButtonProps } from '../../../DropdownButton'; import { MenuItem, type MenuItemProps } from '../../../MenuItem'; +import { Tooltip } from '../../../Tooltip'; import { StyledButton, StyledDropdownButton } from './styles'; @@ -24,6 +25,14 @@ type SingleAction = Omit< * Название действия */ text: string; + /** + * Текст тултипа при заблокированном состоянии кнопки + */ + disabledReason?: string; + /** + * Текст тултипа при наведении на кнопку + */ + note?: string; /** * Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонент @@ -57,6 +66,14 @@ type MultipleAction = Omit< */ text: string; + /** + * Текст тултипа при заблокированном состоянии кнопки + */ + disabledReason?: string; + /** + * Текст тултипа при наведении на кнопку + */ + note?: string; /** * Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонент */ @@ -92,26 +109,45 @@ export const ButtonGroupMainActions = < text, isNested, actions: nestedActions, + disabled, + disabledReason, + note, ...buttonProps } = action as MultipleAction; return ( - - {nestedActions.map(({ text: nestedActionText, ...nestedProps }) => ( - - {nestedActionText} - - ))} - + + + {nestedActions.map(({ text: nestedActionText, ...nestedProps }) => ( + + {nestedActionText} + + ))} + + ); } - const { text, ...mainProps } = action as SingleAction; + const { text, disabled, disabledReason, note, ...mainProps } = + action as SingleAction; return ( - - {text} - + + + {text} + + ); }); }; diff --git a/packages/components/src/PageHeader/PageHeader.stories.tsx b/packages/components/src/PageHeader/PageHeader.stories.tsx index 1cc2713d1..a1dbff64b 100644 --- a/packages/components/src/PageHeader/PageHeader.stories.tsx +++ b/packages/components/src/PageHeader/PageHeader.stories.tsx @@ -820,7 +820,10 @@ export const Actions = () => ( title="Черновик" actions={{ main: [ - { text: 'действие 1', startIcon: }, + { + text: 'действие 1', + startIcon: , + }, { text: 'действие 2', isNested: true, @@ -984,3 +987,44 @@ export const TooltipSecondaryAction = () => ( /> ); + +export const TooltipMainAction = () => ( + + + +); diff --git a/packages/components/src/PageHeader/PageHeader.test.tsx b/packages/components/src/PageHeader/PageHeader.test.tsx new file mode 100644 index 000000000..857e032de --- /dev/null +++ b/packages/components/src/PageHeader/PageHeader.test.tsx @@ -0,0 +1,168 @@ +import { describe, expect, it } from 'vitest'; +import { renderWithTheme, screen, userEvents } from '@astral/tests'; + +import { PageHeader } from './PageHeader'; + +describe('PageHeader', () => { + it('Note для основных действий отображается в tooltip', async () => { + renderWithTheme( + , + ); + + const button = screen.getByRole('button'); + + await userEvents.hover(button); + + const tooltip = await screen.findByRole('tooltip'); + + expect(tooltip).toBeVisible(); + expect(tooltip).toHaveTextContent('Кнопка'); + }); + + it('DisabledReason для основных действий отображается в tooltip при disabled=true', async () => { + renderWithTheme( + , + ); + + const item = screen.getByLabelText('Заблокировано'); + + await userEvents.hover(item); + + const tooltip = await screen.findByRole('tooltip'); + + expect(tooltip).toBeVisible(); + expect(tooltip).toHaveTextContent('Заблокировано'); + }); + + it('DisabledReason для вторичных действий отображается в tooltip при disabled=true', async () => { + renderWithTheme( + , + ); + + const secondaryActionButton = screen.getByRole('button'); + + await userEvents.click(secondaryActionButton); + + const item = await screen.findByLabelText('Заблокировано'); + + await userEvents.hover(item); + + const tooltip = await screen.findByRole('tooltip'); + + expect(tooltip).toBeVisible(); + expect(tooltip).toHaveTextContent('Заблокировано'); + }); + + it('Note для вторичных действий отображается в tooltip', async () => { + renderWithTheme( + , + ); + + const secondaryActionButton = screen.getByRole('button'); + + await userEvents.click(secondaryActionButton); + + const item = await screen.findByLabelText('Кнопка'); + + await userEvents.hover(item); + + const tooltip = await screen.findByRole('tooltip'); + + expect(tooltip).toBeVisible(); + expect(tooltip).toHaveTextContent('Кнопка'); + }); + + it('DisabledReason для вторичных видимых действий отображается в tooltip при disabled=true', async () => { + renderWithTheme( + , + disabled: true, + disableReason: 'Заблокировано', + }, + ], + }} + />, + ); + + const item = await screen.findByLabelText('Заблокировано'); + + await userEvents.hover(item); + + const tooltip = await screen.findByRole('tooltip'); + + expect(tooltip).toBeVisible(); + expect(tooltip).toHaveTextContent('Заблокировано'); + }); + + it('Tooltip отображается для вторичных видимых действий', async () => { + renderWithTheme( + , + }, + ], + }} + />, + ); + + const button = screen.getByRole('button'); + + await userEvents.hover(button); + + const tooltip = await screen.findByRole('tooltip'); + + expect(tooltip).toBeVisible(); + expect(tooltip).toHaveTextContent('Отправка по маршруту'); + }); +});