В WordPress компонент SlotFill
используется для реализации шаблона «портала» (portal rendering), позволяющего рендерить элементы вне текущего иерархического дерева компонентов. Это позволяет расширять компоненты, управляя их содержимым через систему «слотов» и «заполнителей» (Fill), что полезно для создания расширяемых пользовательских интерфейсов.
Что такое Slot и Fill?
- Slot — это место, в которое будут вставляться компоненты или содержимое.
- Fill — это компонент, который заполняет Slot, предоставляя его содержимое.
Этот паттерн позволяет одному компоненту (Fill) «занимать» пространство другого компонента (Slot), даже если они находятся в разных частях приложения.
Основные компоненты
SlotFillProvider
— компонент, который должен быть размещен в корне приложения для координации рендеринга Slot и Fill.Slot
— компонент, в который будут вставляться другие компоненты.Fill
— компонент, который занимает слот.createSlotFill
— вспомогательная функция, упрощающая создание пары Slot и Fill с одинаковым именем.
Пример использования Slot и Fill
Чтобы продемонстрировать, как работают Slot
и Fill
, рассмотрим следующий пример, где мы создаем панель с возможностью вставлять динамическое содержимое через слот.
import {
SlotFillProvider,
Slot,
Fill,
Panel,
PanelBody,
} from '@wordpress/components';
const MySlotFillProvider = () => {
const MyPanelSlot = () => (
<Panel header="Panel with slot">
<PanelBody>
<Slot name="MyPanelSlot" />
</PanelBody>
</Panel>
);
// Заполняем слот содержимым
MyPanelSlot.Content = () => <Fill name="MyPanelSlot">Panel body</Fill>;
return (
<SlotFillProvider>
<MyPanelSlot />
<MyPanelSlot.Content />
</SlotFillProvider>
);
};
Объяснение кода
SlotFillProvider
: Это контейнер, который управляет всеми слотами и заполнителями в приложении. Он должен обертывать компоненты, которые используют слоты.Slot
: В этом примере мы создаем слот с именем"MyPanelSlot"
, который будет заполнен содержимым, переданным через компонентFill
.Fill
: Компонент, который заполняет слот содержимым. В этом примере это просто текст"Panel body"
.MyPanelSlot.Content
: Мы добавляем дочерний компонент к панели, который будет рендерить содержимое в слот, имеющий имя"MyPanelSlot"
.
Вспомогательная функция createSlotFill
Для упрощения работы с Slot и Fill в WordPress доступна функция createSlotFill
, которая позволяет создавать пары с одинаковыми именами для слота и заполняющего компонента.
Пример использования:
import { createSlotFill } from '@wordpress/components';
// Создаем пару Slot и Fill для панели инструментов
const { Fill, Slot } = createSlotFill('Toolbar');
const ToolbarItem = () => <Fill>My item</Fill>;
const Toolbar = () => (
<div className="toolbar">
<Slot />
</div>
);
Параметры компонентов Slot и Fill
1. SlotFillProvider
SlotFillProvider
не принимает параметров и служит контейнером для слотов и заполнителей.
2. Slot
Компонент Slot
позволяет вставлять другие компоненты в определенное место. Он принимает следующие параметры:
name
(string): Имя слота. Все компонентыFill
, которые используют это имя, будут заполнять этот слот.bubblesVirtually
(boolean): Если установлено вtrue
, события будут всплывать не по иерархии DOM, а по иерархии React-компонентов. Это полезно для улучшения работы с событиями в сложных интерфейсах.className
(string): Строка с классом CSS для стилизации.style
(object): Стиль для компонента.children
(function): Функция, которая принимает список заполняющих компонентов и позволяет условно их обрабатывать.
Пример использования с children
:
const Toolbar = ({ isMobile }) => (
<div className="toolbar">
<Slot name="Toolbar">
{ (fills) => {
return isMobile && fills.length > 3 ? (
<div className="toolbar__mobile-long">{ fills }</div>
) : (
fills
);
} }
</Slot>
</div>
);
3. Fill
Компонент Fill
принимает следующие параметры:
name
(string): Имя, которое должно соответствовать имени слота.fillProps
(object): Параметры, которые передаются от слота к заполнителю.
Пример использования с передачей параметров через fillProps
:
import { Button } from '@wordpress/components';
import { createSlotFill } from '@wordpress/components';
const { Fill, Slot } = createSlotFill('Toolbar');
const ToolbarItem = () => (
<Fill>
{ ({ hideToolbar }) => (
<Button onClick={ hideToolbar }>Hide Toolbar</Button>
)}
</Fill>
);
const Toolbar = () => {
const hideToolbar = () => {
console.log('Hide toolbar');
};
return (
<div className="toolbar">
<Slot fillProps={ { hideToolbar } } />
</div>
);
};
В этом примере мы передаем функцию hideToolbar
в слот через параметр fillProps
, а затем используем ее в компоненте Fill
.
Дополнительные параметры для Slot
fillProps
(object): Этот параметр позволяет передать параметры из слота в его заполняющие компоненты. Это полезно для динамической настройки поведения и состояния.children
(function): Эта функция позволяет обработать заполняющие компоненты перед рендером, например, для условной фильтрации.
Пример более сложного использования
import { createSlotFill } from '@wordpress/components';
const { Fill, Slot } = createSlotFill('Sidebar');
const SidebarItem = () => <Fill>Sidebar item content</Fill>;
const Sidebar = () => (
<div className="sidebar">
<Slot name="Sidebar">
{ (fills) => fills.length ? <div>{ fills }</div> : <div>No content</div> }
</Slot>
</div>
);
const App = () => (
<SlotFillProvider>
<Sidebar />
<SidebarItem />
</SlotFillProvider>
);
Заключение
Использование компонентов Slot
и Fill
в WordPress позволяет создавать гибкие и расширяемые интерфейсы, где один компонент может быть заполнен содержимым, определяемым в другом месте приложения. Этот паттерн «портала» предоставляет разработчикам мощные инструменты для создания настраиваемых интерфейсов, где компоненты могут взаимодействовать друг с другом независимо от их физического расположения в дереве компонентов.