Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

Commit

Permalink
feat(UIKIT-1163,PageHeader): Добавлена возможность отображать тултип …
Browse files Browse the repository at this point in the history
…основным actions (#1086)
  • Loading branch information
pan1caisreal authored Aug 9, 2024
1 parent 2075a4b commit 16c2ecd
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -24,6 +25,14 @@ type SingleAction<TMainActionComponent extends ElementType> = Omit<
* Название действия
*/
text: string;
/**
* Текст тултипа при заблокированном состоянии кнопки
*/
disabledReason?: string;
/**
* Текст тултипа при наведении на кнопку
*/
note?: string;

/**
* Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонент
Expand Down Expand Up @@ -57,6 +66,14 @@ type MultipleAction<TMainActionComponent extends ElementType> = Omit<
*/
text: string;

/**
* Текст тултипа при заблокированном состоянии кнопки
*/
disabledReason?: string;
/**
* Текст тултипа при наведении на кнопку
*/
note?: string;
/**
* Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонент
*/
Expand Down Expand Up @@ -92,26 +109,45 @@ export const ButtonGroupMainActions = <
text,
isNested,
actions: nestedActions,
disabled,
disabledReason,
note,
...buttonProps
} = action as MultipleAction<TMainActionComponent>;

return (
<StyledDropdownButton {...buttonProps} key={text} name={text}>
{nestedActions.map(({ text: nestedActionText, ...nestedProps }) => (
<MenuItem key={nestedActionText} {...nestedProps}>
{nestedActionText}
</MenuItem>
))}
</StyledDropdownButton>
<Tooltip
title={disabled ? disabledReason : note}
withoutContainer={!disabled}
>
<StyledDropdownButton
{...buttonProps}
key={text}
disabled={disabled}
name={text}
>
{nestedActions.map(({ text: nestedActionText, ...nestedProps }) => (
<MenuItem key={nestedActionText} {...nestedProps}>
{nestedActionText}
</MenuItem>
))}
</StyledDropdownButton>
</Tooltip>
);
}

const { text, ...mainProps } = action as SingleAction<TMainActionComponent>;
const { text, disabled, disabledReason, note, ...mainProps } =
action as SingleAction<TMainActionComponent>;

return (
<StyledButton {...mainProps} key={text}>
{text}
</StyledButton>
<Tooltip
title={disabled ? disabledReason : note}
withoutContainer={!disabled}
>
<StyledButton {...mainProps} disabled={disabled} key={text}>
{text}
</StyledButton>
</Tooltip>
);
});
};
46 changes: 45 additions & 1 deletion packages/components/src/PageHeader/PageHeader.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,10 @@ export const Actions = () => (
title="Черновик"
actions={{
main: [
{ text: 'действие 1', startIcon: <AddOutlineMd /> },
{
text: 'действие 1',
startIcon: <AddOutlineMd />,
},
{
text: 'действие 2',
isNested: true,
Expand Down Expand Up @@ -984,3 +987,44 @@ export const TooltipSecondaryAction = () => (
/>
</Wrapper>
);

export const TooltipMainAction = () => (
<Wrapper>
<PageHeader
title="Черновик"
actions={{
main: [
{
text: 'Отправка по маршруту',
disabled: true,
disabledReason: 'Заблокировано',
},
{
text: 'Выбор получателя',
note: 'Здесь можно выбрать несколько получателей',
},
{
text: 'Выберите документ',
isNested: true,
disabled: true,
disabledReason: 'На данный момент не доступно',
actions: [
{ text: 'действие в списке 1' },
{ text: 'действие в списке 2' },
],
},
],
secondary: [
{ text: 'Выбор получателя', disabled: true },
{
text: 'Сменить подразделение',
disabled: true,
},
{ text: 'Копировать' },
{ text: 'Удалить' },
],
}}
backButton={{}}
/>
</Wrapper>
);
168 changes: 168 additions & 0 deletions packages/components/src/PageHeader/PageHeader.test.tsx
Original file line number Diff line number Diff line change
@@ -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(
<PageHeader
title="Черновик"
actions={{
main: [
{
text: 'Отправка по маршруту',
note: 'Кнопка',
},
],
}}
/>,
);

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(
<PageHeader
title="Черновик"
actions={{
main: [
{
text: 'Отправка по маршруту',
disabled: true,
disabledReason: 'Заблокировано',
},
],
}}
/>,
);

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(
<PageHeader
title="Черновик"
actions={{
secondary: [
{
text: 'Отправка по маршруту',
disabled: true,
disabledReason: 'Заблокировано',
},
],
}}
/>,
);

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(
<PageHeader
title="Черновик"
actions={{
secondary: [
{
text: 'Отправка по маршруту',
note: 'Кнопка',
},
],
}}
/>,
);

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(
<PageHeader
title="Черновик"
actions={{
secondaryVisible: [
{
name: 'Отправка по маршруту',
icon: <svg />,
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(
<PageHeader
title="Черновик"
actions={{
secondaryVisible: [
{
name: 'Отправка по маршруту',
icon: <svg />,
},
],
}}
/>,
);

const button = screen.getByRole('button');

await userEvents.hover(button);

const tooltip = await screen.findByRole('tooltip');

expect(tooltip).toBeVisible();
expect(tooltip).toHaveTextContent('Отправка по маршруту');
});
});

0 comments on commit 16c2ecd

Please sign in to comment.