Skip to content

Commit

Permalink
fix(Alert): Move dismiss button before actions to focus on it first (#…
Browse files Browse the repository at this point in the history
…8266) (#8290)

Кнопка закрытия, при наличии, первой получает фокус при открытии алерта
В документацию по доступности компонента добавлен пункт по поводу имен кнопок с одинаковыми действиями
  • Loading branch information
andrey-medvedev-vk authored Feb 18, 2025
1 parent 5ec41e7 commit d56bb04
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 30 deletions.
11 changes: 3 additions & 8 deletions packages/vkui/src/components/Alert/Alert.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,11 @@ export const Playground: StoryObj<AlertProps> = {
},
args: {
actions: [
{
title: 'Отмена',
mode: 'cancel',
},
{
title: 'Удалить',
mode: 'destructive',
},
{ title: 'Отмена', mode: 'cancel' },
{ title: 'Удалить', mode: 'destructive' },
],
actionsLayout: 'horizontal',
dismissLabel: 'Отмена',
title: 'Удаление документа',
description: 'Вы уверены, что хотите удалить этот документ?',
},
Expand Down
10 changes: 5 additions & 5 deletions packages/vkui/src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,18 @@ export const Alert = ({
</IconButton>
)}
</div>
{isDismissButtonVisible && dismissButtonMode === 'outside' && (
<ModalDismissButton onClick={close} data-testid={dismissButtonTestId}>
{dismissLabel}
</ModalDismissButton>
)}
<AlertActions
actions={actions}
actionsAlign={actionsAlign}
actionsLayout={actionsLayout}
renderAction={renderAction}
onItemClick={onItemClick}
/>
{isDismissButtonVisible && dismissButtonMode === 'outside' && (
<ModalDismissButton onClick={close} data-testid={dismissButtonTestId}>
{dismissLabel}
</ModalDismissButton>
)}
</FocusTrap>
</PopoutWrapper>
</AppRootPortal>
Expand Down
54 changes: 38 additions & 16 deletions packages/vkui/src/components/Alert/Readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
Начиная с VKUI v7 этот компонент можно объявить в любом месте приложения в пределах [`AppRoot`](#/AppRoot). Больше нет необходимости явно передавать его в свойство `popout` компоненту [`SplitLayout`](#/SplitLayout).

## Цифровая доступность (a11y)

`Alert` является модальным окном (`aria-role="dialog"`), а значит у него обязательно должно быть имя — его краткое название. Благодаря этому пользователи вспомогательных технологий знают, что это за элемент и какое у него содержимое.

Задать имя можно с помощью следующих способов:

- используя свойство `title`;
- используя свойство `aria-label`;
- используя свойство `aria-labelledby`;

### Доступные имена кнопок

Если две кнопки находятся в разных местах, но выполняют одну функцию, то лучше дать им одинаковые имена.
Это относится, например, к кнопке закрытия (крестик на декстопах), имя которой можно задать через свойство `dismissLabel`.
Если у вас среди кнопок действия есть кнопка `Отмена`, которая без дополнительного действия просто закрывает `Alert`, ровно
как и кнопка закрытия, то кнопке закрытия следует дать то же имя `Отмена` через свойство `dismissLabel`.

```jsx static
<Alert
dismissLabel="Отмена"
actions={[
{ title: 'Отмена', mode: 'cancel' },
{ title: 'Удалить', mode: 'destructive', action: () => addActionLogItem('Документ удален.') },
]}
title="Удаление документа"
description="Вы уверены, что хотите удалить этот документ?"
/>
```

## Типы кнопок

В Алертах особое внимание нужно уделить кнопкам. Всего есть три типа кнопок:
`cancel`, `destructive` и `default`.

Expand Down Expand Up @@ -44,11 +75,9 @@ const Example = () => {
mode: 'destructive',
action: () => addActionLogItem('Право на модерацию контента убрано.'),
},
{
title: 'Отмена',
mode: 'cancel',
},
{ title: 'Отмена', mode: 'cancel' },
]}
dismissLabel="Отмена"
actionsLayout="vertical"
onClose={closePopout}
title="Подтвердите действие"
Expand All @@ -61,17 +90,15 @@ const Example = () => {
setPopout(
<Alert
actions={[
{
title: 'Отмена',
mode: 'cancel',
},
{ title: 'Отмена', mode: 'cancel' },
{
title: 'Удалить',
mode: 'destructive',
action: () => addActionLogItem('Документ удален.'),
},
]}
actionsLayout="horizontal"
dismissLabel="Отмена"
dismissButtonMode="inside"
onClose={closePopout}
title="Удаление документа"
Expand Down Expand Up @@ -124,15 +151,10 @@ const Example = () => {
setPopout(
<Alert
actions={[
{
title: 'Лишить права',
mode: 'destructive',
},
{
title: 'Отмена',
mode: 'cancel',
},
{ title: 'Лишить права', mode: 'destructive' },
{ title: 'Отмена', mode: 'cancel' },
]}
dismissLabel="Отмена"
actionsAlign="left"
actionsLayout="horizontal"
renderAction={renderAction}
Expand Down
3 changes: 2 additions & 1 deletion packages/vkui/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export interface Version {
export type AnchorHTMLAttributesOnly = Omit<
React.AnchorHTMLAttributes<HTMLAnchorElement>,
keyof React.HTMLAttributes<HTMLAnchorElement>
>;
> &
React.AriaAttributes;

/**
* Проверяет, является ли тип подтипом другого.
Expand Down

0 comments on commit d56bb04

Please sign in to comment.