Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions website/content/components/_meta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,21 @@ const meta: MetaRecord = {
'use-modal-manager': 'useModalManager',
'use-today-date': 'useTodayDate',
'visually-hidden': 'VisuallyHidden',

// Эти страницы нужны только для MCP, поэтому скрыты из навигации
'_partials': { display: 'hidden' },
'action-sheet-item': { display: 'hidden' },
'footer': { display: 'hidden' },
'header': { display: 'hidden' },
'list': { display: 'hidden' },
'panel-header-button': { display: 'hidden' },
'panel-header-content': { display: 'hidden' },
'panel-spinner': { display: 'hidden' },
'split-col': { display: 'hidden' },
'subnavigation-button': { display: 'hidden' },
'tabbar': { display: 'hidden' },
'tabbar-item': { display: 'hidden' },
'tabs-item': { display: 'hidden' },
};

export default meta;
222 changes: 222 additions & 0 deletions website/content/components/_partials/action-sheet-item-content.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
Подкомпонент для отображения элемента всплывающего меню [`ActionSheet`](/components/action-sheet). Каждому компоненту можно задать различные режимы отображения,
добавлять иконки и метаданные.

<Playground>
```jsx
<ActionSheetItem>Сохранить</ActionSheetItem>
```
</Playground>

### Цвет

Задаётся свойством `mode`.

#### `"default"`

Стандартный цвет отображения текста, используется в действиях, где нет необходимости в привлечении дополнительного внимания.

<Playground>
```jsx
<ActionSheetItem>Сохранить</ActionSheetItem>
```
</Playground>

#### `"destructive"`

Цвет критических действий (чаще всего красный), старайтесь располагать такие действия сверху списка,
где они наиболее заметны.

<Playground>
```jsx
<ActionSheetItem mode="destructive">Удалить</ActionSheetItem>
```
</Playground>

#### ~`"cancel"`~

> **@deprecated** Since 8.0.0. Значение `"cancel"` устарело и будет удалено в **VKUI v10**.
> Используйте компонент [`ActionSheetDefaultIosCloseItem`](/components/action-sheet#action-sheet-default-ios-close-item) или передайте пропсы через `slotProps.iosCloseItem` в `ActionSheet`.

Цвет действия отмены.

<Playground>
```jsx
<ActionSheetItem mode="cancel">Отмена</ActionSheetItem>
```
</Playground>

### ~Кнопка "Отмена"~

> **@deprecated** Since 8.0.0. Свойство `isCancelItem` устарело и будет удалено в **VKUI v10**.
> Используйте компонент [`ActionSheetDefaultIosCloseItem`](/components/action-sheet#action-sheet-default-ios-close-item) или передайте пропсы через `slotProps.iosCloseItem` в `ActionSheet`.

Свойство `isCancelItem` позволяет пометить пункт действия как "Отмена".

Согласно рекомендациям **Apple** в `ActionSheet` должен быть вариант действия "Отмена", который
бы позволял закрывать всплывающее окно без выполнения дополнительных действий.

> Обратите внимание, что такой компонент необходимо передавать в свойство `iosCloseItem` у `ActionSheet`,
> потому что данный компонент должен визуально отделяться от остальных пунктов.

Подробнее с использованием можно ознакомиться на странице [`ActionSheet`](/components/action-sheet#cancel-item).

### Текстовые элементы

Основной контент компонента (заголовок) можно задать, передав в свойство `children` необходимый текст:

<Playground>
```jsx
<ActionSheetItem>Скорость воспроизведения</ActionSheetItem>
```
</Playground>

Свойство `subtitle` позволяет отобразить дополнительный текст под заголовком:

<Playground>
```jsx
<ActionSheetItem subtitle="Обычная">Скорость воспроизведения</ActionSheetItem>
```
</Playground>

Свойство `meta` даёт возможность отобразить небольшой пояснительный текст или индикатор рядом с заголовком:

<Playground>
```jsx
<ActionSheetItem meta={<Icon12Circle fill="var(--vkui--color_icon_negative)" />}>
Закрепить запись
</ActionSheetItem>
```
</Playground>

#### Многострочный режим

По умолчанию большое количество текста обрезается и заменяется на многоточие, поддерживая однострочный режим отображения.
Это поведение можно отключить (_для всех текстовых элементов_) с помощью свойства `multiline`:

<Playground style={{ maxWidth: 270 }}>
```jsx
<ActionSheetItem multiline>
Очень длинный заголовок просто для примера, старайтесь избегать такого
</ActionSheetItem>
```
</Playground>

### Контент в начале/в конце

В компоненте доступна возможность добавления дополнительного контента слева и/или справа от текста,
задаётся свойством `before` и `after` соответственно.
Наиболее частый вариант использования свойств `before`/`after` - иконки или аватары.

В соответствии с рекомендациями дизайн-системы, для десктопного представления (`compact`-режим) следует
использовать иконки размером `20px`, для мобильного представления (`regular`-режим) — `28px`.
Проще всего это сделать, используя компонент [`AdaptiveIconRenderer`](/components/adaptive-icon-renderer).

<Playground>
```jsx
<ActionSheetItem
before={
<AdaptiveIconRenderer IconCompact={Icon20WriteOutline} IconRegular={Icon28EditOutline} />
}
>
Редактировать профиль
</ActionSheetItem>
```
</Playground>

### Состояния

#### `disabled`

Свойство позволяет отключить возможность взаимодействия с пунктом меню.

<Playground>
```jsx
<ActionSheetItem subtitle="Отсутствуют" disabled>
Субтитры
</ActionSheetItem>
```
</Playground>

#### `selectable`

Свойство даёт возможность выбирать элемент (визуальная и нативная имитация элемента радиокнопки).
При использовании данного свойства вы также можете передавать стандартные свойства радиокнопок, для управления поведением:

- `name` — имя группы для радиокнопок;
- `value` — значение радиокнопки;
- `defaultChecked` — установить выбранным по умолчанию;
- `checked` и [`onChange`](#onchange) — для контролируемого извне использования выбранного значения;

<Playground direction="column">

```jsx
const [filter, setFilter] = useState('Нормальная');

const onChange = (e) => {
// e.target.value будет равно значению, переданному в `value` выбранного компонента `ActionSheetItem`
setFilter(e.target.value);
};

return ['0.25x', '0.5x', '0.75x', 'Нормальная', '1.25x', '1.5x', '2x', '3x'].map((speed) => (
<ActionSheetItem
key={speed}
onChange={onChange}
checked={filter === speed}
name="filter"
value={speed}
selectable
>
{speed}
</ActionSheetItem>
));
```

</Playground>

Дополнительно через свойство `iconChecked` есть возможность изменить иконки радиокнопки, которая рисуется по умолчанию.

<Playground>
```jsx
<ActionSheetItem
defaultChecked
selectable
iconChecked={
// квадратные иконки выбора
<AdaptiveIconRenderer IconCompact={Icon20CheckBoxOn} IconRegular={Icon24CheckBoxOn} />
}
>
0.75x
</ActionSheetItem>
```
</Playground>

### Обработчики событий

#### `onClick`/ `onImmediateClick`

Нажатие на пункт меню можно обработать с помощью свойств `onClick` и `onImmediateClick`.

По умолчанию `onClick` будет вызван после завершения анимации скрытия всплывающего меню и после вызова `onClosed`.
Из этого следует, что в объекте события значение поля `currentTarget` будет не определено.
Если вам нужен объект события именно на момент нажатия, воспользуйтесь `onImmediateClick`.

> По умолчанию клик на пункт меню автоматически вызывает закрытие всплывающего меню (функцию, переданную в `onClosed` у `ActionSheet`).
>
> Если такое поведение нежелательно, то используйте свойство `autoCloseDisabled`. В таком случае закрытие всплывающего окна
> следует вызывать самостоятельно.

#### `onChange`

Если задано свойство `selectable={true}`, то выбор пункта следует обрабатывать с помощью свойства `onChange`.
Пример можно увидеть [выше](#selectable).

### Ссылки

Если указать свойство `href`, компонент будет рендериться как ссылка `<a>`.
Также можно задать стандартное свойство `target`:

```jsx
<ActionSheetItem href="https://vk.com" target="_blank">
Перейти на vk.com
</ActionSheetItem>
```
82 changes: 82 additions & 0 deletions website/content/components/_partials/footer-content.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
Подвал группы. Передаётся в конце `children`.

{/* @example-description: Базовый подвал `Footer` для мета-информации группы. */}
<Playground>
```jsx
<Footer>Copyright © vk.com</Footer>
```
</Playground>

### Доступность (a11y) [#a11y]

#### Семантическая роль

По умолчанию использует HTML-тег `<footer>`, дополнительно задаётся роль `role="contentinfo"` ([для поддержки Safari\<=13](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer#accessibility)).

Предназначен для:

- контактной информации;
- ссылок на разделы сайта;
- копирайта и юридических данных;
- мета-информации о содержимом.

#### Ключевые правила

| Сценарий | Решение | Почему важно |
| -------------------------- | ----------------------------- | ---------------------------------- |
| Глобальный подвал страницы | Только один на страницу | Соответствие стандартам `WAI-ARIA` |
| Несколько подвалов | Добавить `aria-label` каждому | Различение разделов скринридерами |
| Декоративный элемент | `<Footer Component="div">` | Избежать ложной семантики |

#### Контекст использования

В данном примере первый `Footer` "локальный", потому что находится внутри секционного контента (компонент `Group`)
и содержит мета-информацию, а второй `Footer` - глобальный, потому что относится ко всей странице.

{/* @example-description: Локальный и глобальный `Footer` в одном макете для разных контекстов. */}
<Playground>
```jsx
<Panel mode="plain">
<Group header={<Header size="s">Статьи</Header>}>
<SimpleCell onClick={() => {}}>
Связь между употреблением шоколада и получением Нобелевской премии
</SimpleCell>
<SimpleCell onClick={() => {}}>Кошка как нелинейный элемент в квантовой системе</SimpleCell>
<SimpleCell onClick={() => {}}>Алгоритм оптимального поедания пиццы</SimpleCell>
<Footer>Теги: наука, исследования</Footer>
</Group>
<Footer>
<Link href="#about">О нас</Link> | <Link href="#contact">Контакты</Link>
</Footer>
</Panel>
```
</Playground>

#### Множество

Несколько подвалов без контекста скринридеры воспринимают как дубли, чтобы этого избежать,
добавляйте `aria-label` каждому компоненту:

```jsx
<Footer aria-label="Навигация">
<Link href="#about">О нас</Link>
<Link href="#contacts">Контакты</Link>
</Footer>

<Footer aria-label="Юридическая информация">
<Text>© 2025 Компания</Text>
</Footer>
```

#### Пользовательский тэг

Используйте `Component="div"` если:

- контент не соответствует семантике подвала;
- элемент используется для визуального оформления;
- уже есть глобальный подвал на странице.

```jsx
// Декоративный раздел
<Footer Component="div">Информация на данной странице является конфиденциальной.</Footer>
```
69 changes: 69 additions & 0 deletions website/content/components/_partials/header-content.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { BlockWrapper } from '@/components/wrappers';

Заголовок группы. Передаётся либо в свойство `header`, либо в начале `children`, либо в `Group.Header`.

{/* @example-description: Отдельный `Header` с индикатором и правым управляющим элементом. */}
<Playground Wrapper={BlockWrapper}>
```jsx
<Header indicator={<Badge mode="prominent">12</Indicator>} after={<Switch label="Уведомления" />}>Уведомления</Header>
```
</Playground>

### Рекомендуемые размеры иконок

| Свойство | Расположение | Рекомендуемый размер |
| ---------------- | ----------------------- | -------------------- |
| `before` | Слева от всего контента | `28px` |
| `beforeTitle` | Слева от заголовка | `16px` |
| `afterTitle` | Справа от заголовка | `16px` |
| `beforeSubtitle` | Слева от подзаголовка | `12px` |
| `afterSubtitle` | Справа от подзаголовка | `12px` |

### Дополнительные элементы

- `indicator` — отображает счётчик/статус:

```jsx
<Header indicator={<Badge mode="prominent">12</Badge>}>Уведомления</Header>
```

- `after` — контент справа от всего заголовка:

```jsx
<Header after={<Switch label="Настройки" />}>Настройки</Header>
```

### Пример использования

{/* @example-description: Расширенный пример `Header` с иконками, подзаголовком, счетчиком и ссылкой. */}
<Playground Wrapper={BlockWrapper}>
```jsx
<Group
mode="card"
separator="hide"
header={
<Header
before={<Icon28UserCircleFillBlue />}
beforeTitle={<Icon16LockOutline />}
afterTitle={<Icon16UnlockOutline />}
beforeSubtitle={<Icon12Tag />}
afterSubtitle={<Icon12Fire />}
subtitle="SOHN — Conrad"
subtitleComponent="h3"
indicator={
<Counter size="s" mode="primary" appearance="accent-red">
3
</Counter>
}
after={<Link href="#">Показать все</Link>}
>
Плейлисты
</Header>
}
>
<Div>
<Text>Контент</Text>
</Div>
</Group>
```
</Playground>
Loading
Loading