2021-10-12 14:23:52 +00:00
# Checkout - Slot Fill <!-- omit in toc -->
2021-02-08 11:37:55 +00:00
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.
2021-10-12 14:23:52 +00:00
This module is an abstraction on top of the Slot/Fill implementation in WordPress and is meant to be used internally, therefore the documentation only touches the abstraction part. You can read more about Slot Fill in [@wordpress/components documentation ](https://github.com/WordPress/gutenberg/tree/c53d26ea79bdcb1a3007a994078e1fc9e0195466/packages/components/src/slot-fill ).
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
## Table of Contents <!-- omit in toc -->
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
- [`createSlotFill( slotName )` ](#createslotfill-slotname- )
- [Usage ](#usage )
- [Options ](#options )
- [`slotName (string, required)` ](#slotname-string-required )
- [`onError (Function)` ](#onerror-function )
- [`Slot` Component ](#slot-component )
- [Usage ](#usage-1 )
- [Options ](#options-1 )
- [`as (string|element)` ](#as-stringelement )
- [`className (string)` ](#classname-string )
- [`fillProps (object)` ](#fillprops-object )
- [`Fill` Component ](#fill-component )
- [Extending Checkout via Slot Fills ](#extending-checkout-via-slot-fills )
- [Available Slot Fills ](#available-slot-fills )
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
## `createSlotFill( slotName )`
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
Calling `createSlotFill` with a `slotName` returns two components: `Slot` and `Fill` . Slots are implemented in WooCommerce Blocks, while Fills can be used by extensions to add content within the Slot. A Slot must be called in a tree that has `SlotFillProvider` in it.
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
### Usage
2021-02-08 11:37:55 +00:00
```jsx
2021-10-12 14:23:52 +00:00
// Aliased import
2021-02-08 11:37:55 +00:00
import { createSlotFill } from '@woocommerce/blocks-checkout';
2021-10-12 14:23:52 +00:00
// Global import
// const { createSlotFill } = wc.blocksCheckout;
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const slotName = '__experimentalSlotName';
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const { Fill, Slot } = createSlotFill( slotName );
```
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
### Options
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
`createSlotFill` accepts the following options:
#### `slotName (string, required)`
The name of slot to be created.
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
#### `onError (Function)`
If a `Fill` causes an error, and the current user is an admin user, this function will be called. You can customize the error shown to admins by passing `onError` to `createSlotFill` .
2021-02-08 11:37:55 +00:00
```jsx
2021-10-12 14:23:52 +00:00
// Aliased import
2021-02-08 11:37:55 +00:00
import { createSlotFill } from '@woocommerce/blocks-checkout';
2021-10-12 14:23:52 +00:00
// Global import
// const { createSlotFill } = wc.blocksCheckout;
const slotName = '__experimentalSlotName';
2021-02-08 11:37:55 +00:00
const onError = ( errorMessage ) => {
return (
< div className = "my-custom-error" >
2021-10-12 14:23:52 +00:00
You got an error! < br / >
{ errorMessage }
Contact support at{ ' ' }
< a href = "mailto:help@example.com" > help@example.com< / a >
2021-02-08 11:37:55 +00:00
< / div >
2021-10-12 14:23:52 +00:00
);
};
const { Fill, Slot } = createSlotFill( slotName, onError );
2021-02-08 11:37:55 +00:00
```
2021-10-12 14:23:52 +00:00
### `Slot` Component
`createSlotFill` returns a `Slot` component. This is rendered in the app and will render any Fills within it.
#### Usage
2021-02-08 11:37:55 +00:00
```jsx
2021-10-12 14:23:52 +00:00
// Aliased import
2021-02-08 11:37:55 +00:00
import { createSlotFill } from '@woocommerce/blocks-checkout';
2021-10-12 14:23:52 +00:00
// Global import
// const { createSlotFill } = wc.blocksCheckout;
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const slotName = '__experimentalSlotName';
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const { Fill: FillComponent, Slot: SlotComponent } = createSlotFill( slotName );
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const Slot = ( { className } ) => {
return < SlotComponent className = { ' my-slot-component ' } / > ;
};
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
// Assign your Slot to your Fill.
FillComponent.Slot = Slot;
export default FillComponent;
2021-02-08 11:37:55 +00:00
```
2021-10-12 14:23:52 +00:00
#### Options
`Slot` accepts the following options:
##### `as (string|element)`
Element used to render the slot. By default, `Slot` would render a `div` , but you can customize what gets rendered instead.
##### `className (string)`
A class name applied to the rendered element.
##### `fillProps (object)`
Props passed to each fill implementation.
2021-02-08 11:37:55 +00:00
```jsx
2021-10-12 14:23:52 +00:00
// Aliased import
import { createSlotFill } from '@woocommerce/blocks-checkout';
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
// Global import
// const { createSlotFill } = wc.blocksCheckout;
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const slotName = '__experimentalSlotName';
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const { Fill: FillComponent, Slot: SlotComponent } = createSlotFill(
slotName
);
const Slot = ( { className } ) => {
return (
< SlotComponent
className={ 'my-slot-component' }
fillProps={ { // ...custom data goes here and is passed to all fills } }
/>
);
};
// Assign your Slot to your Fill.
FillComponent.Slot = Slot;
export default FillComponent;
2021-02-08 11:37:55 +00:00
```
2021-10-12 14:23:52 +00:00
#### `Fill` Component
Each `Fill` receives any `fillProps` from the `Slot` , and also renders an [errorBoundary ](https://reactjs.org/docs/error-boundaries.html ) inside of it. This catches broken fills and prevents them from breaking other fills.
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
## Extending Checkout via Slot Fills
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
Slot/Fills are exported and available for use by extensions. One such Slot Fill is `ExperimentalOrderMeta` [exported from here ](../components/order-meta/index.js ). This provides the Slot, and within it, you can define your fill:
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
```jsx
import { registerPlugin } from '@wordpress/plugins';
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
// Aliased import
import { ExperimentalOrderMeta } from '@woocommerce/blocks-checkout';
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
// Global import
// const { ExperimentalOrderMeta } = wc.blocksCheckout;
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
// extensions and cartData are both fillProps.
const MyComponent = ( { extensions, cartData } ) => {
const { myPlugin } = extensions;
return < Meta data = { myPlugin } / > ;
};
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
const render = () => {
return (
< ExperimentalOrderMeta >
< MyComponent / >
< / ExperimentalOrderMeta >
);
};
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
registerPlugin( 'my-plugin', { render } );
```
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
## Available Slot Fills
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
Slot Fills are implemented throughout the Cart and Checkout Blocks, as well as some components. For a list of available Slot Fills, [see this document ](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/trunk/docs/extensibility/available-slot-fills.md ).
2021-02-08 11:37:55 +00:00
2021-10-12 14:23:52 +00:00
< br / > < br / > < p align = "center" >
< a href = "https://woocommerce.com/" >
< img src = "https://woocommerce.com/wp-content/themes/woo/images/logo-woocommerce@2x.png" alt = "WooCommerce" height = "28px" style = "filter: grayscale ( 100 % ) ;
opacity: 0.2;" />
< / a > < br / > < a href = "https://woocommerce.com/careers/" > We're hiring< / a > ! Come work with us!< / p >