UNPKG

@wordpress/components

Version:
117 lines (88 loc) 3.35 kB
# Slot Fill Slot and Fill are a pair of components which enable developers to render elsewhere in a React element tree, a pattern often referred to as "portal" rendering. It is a pattern for component extensibility, where a single Slot may be occupied by an indeterminate number of Fills elsewhere in the application. Slot Fill is heavily inspired by the [`react-slot-fill` library](https://github.com/camwest/react-slot-fill), but uses React's own portal rendering API. ## Usage At the root of your application, you must render a `SlotFillProvider` which coordinates Slot and Fill rendering. Then, render a Slot component anywhere in your application, giving it a name. Any Fill will automatically occupy this Slot space, even if rendered elsewhere in the application. You can either use the Fill component directly, or a wrapper component type as in the below example to abstract the slot name from consumer awareness. ```jsx 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> ); }; ``` There is also `createSlotFill` helper method which was created to simplify the process of matching the corresponding `Slot` and `Fill` components: ```jsx const { Fill, Slot } = createSlotFill( 'Toolbar' ); const ToolbarItem = () => <Fill>My item</Fill>; const Toolbar = () => ( <div className="toolbar"> <Slot /> </div> ); ``` ## Props The `SlotFillProvider` component does not accept any props. Both `Slot` and `Fill` accept a `name` string prop, where a `Slot` with a given `name` will render the `children` of any associated `Fill`s. `Slot` accepts a `bubblesVirtually` prop which changes the event bubbling behaviour: - By default, events will bubble to their parents on the DOM hierarchy (native event bubbling) - If `bubblesVirtually` is set to true, events will bubble to their virtual parent in the React elements hierarchy instead. `Slot` with `bubblesVirtually` set to true also accept optional `className` and `style` props to add to the slot container. `Slot` **without** `bubblesVirtually` accepts an optional `children` function prop, which takes `fills` as a param. It allows you to perform additional processing and wrap `fills` conditionally. _Example_: ```jsx 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> ); ``` Props can also be passed from a `Slot` to a `Fill` by using the prop `fillProps` on the `Slot`: ```jsx const { Fill, Slot } = createSlotFill( 'Toolbar' ); const ToolbarItem = () => ( <Fill> { ( { hideToolbar } ) => { <Button onClick={ hideToolbar }>Hide</Button>; } } </Fill> ); const Toolbar = () => { const hideToolbar = () => { console.log( 'Hide toolbar' ); }; return ( <div className="toolbar"> <Slot fillProps={ { hideToolbar } } /> </div> ); }; ```