Перейти к содержимому
v2.5.0
English
Русский
Документация

Slot

Slot — низкоуровневый примитив полиморфной композиции, на котором построены API asChild в VegaUI.

Обзор

У Slot нет визуального контракта. Он сливает пропсы с одним валидным дочерним элементом и оставляет весь рендер, токены и поведение CSS этому элементу и родительскому компоненту, который использует Slot.

Публичные CSS-переменные

В текущей реализации нет публичных CSS-переменных --slot-*.

Переменные частей

Корень

У Slot нет собственного DOM, если его не рендерит выбранный дочерний элемент.

Дочерний элемент

Стили полностью определяются дочерним элементом в слоте и родительским компонентом, который передаёт пропсы через asChild.

Взаимодействие состояний и вариантов

  • У Slot нет собственных визуальных вариантов.
  • Классы состояний, data-атрибуты и инлайн-стили передаются дочернему элементу.
  • Визуальные расхождения обычно возникают из-за смены семантики дочернего элемента, а не из-за какого-либо CSS-слоя Slot.

Примеры

Button asChild передаёт классы и data-атрибуты ссылке, поэтому она выглядит как второстепенная кнопка, но сохраняет семантику ссылки.

styled-link-action.tsx · 16 строк
import { Button, Icon } from '@vega-ui/react';
import { BookOpenIcon } from '@vega-ui/icons';

export default function StyledLinkAction() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-4)' }}>
      <Button type='button'>Create API key</Button>
      <Button asChild variant='secondary' appearance='ghost'>
        <a href='/docs/api/authentication'>
          <Icon size='sm'><BookOpenIcon /></Icon>
          Read the API guide
        </a>

Локальный NavItem владеет внешним видом и передаёт style и aria-current через Slot любой ссылке, которую рендерит роутер. Собственный onClick дочернего элемента всё равно срабатывает, потому что обработчики объединяются в цепочку.

forward-menu-item-styling-into-a-router-link.tsx · 49 строк
import type { AnchorHTMLAttributes, CSSProperties } from 'react';
import { Slot } from '@vega-ui/react';
import { useState } from 'react';

interface NavItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
  asChild?: boolean
  active?: boolean
}

function NavItem({ asChild, active, children, ...props }: NavItemProps) {
  const style: CSSProperties = {
    display: 'block',

Не переопределяйте

  • не придумывайте отдельный API токенов для Slot
  • не относитесь к Slot как к стилизованной обёртке
  • не рассчитывайте, что Slot исправит проблемы семантики или доступности, вызванные выбранным дочерним элементом