A super lightweight slots implementation for React
A super lightweight modern alternative to react-slot-fill
with familiar API.
Slot
and Fill
Fill
and Slot
communicate directly with each othertesting-library
npm i -S nano-slots
yarn add nano-slots
import { Box, Flex } from 'theme-ui'
import { SlotsProvider, Slot } from 'nano-slots'
export const MediaObject = ({ children }) => (
<SlotsProvider>
<Flex>
<Box mr={3}>
<Slot name="media-side" />
</Box>
<Box>
<Box mb={2}>
<Slot name="media-title" />
</Box>
<Box>
<Slot name="media-description" />
</Box>
{children}
</Box>
</Flex>
</SlotsProvider>
)
import { Fill } from 'nano-slots'
import { MediaObject } from './media-object'
const MyApp = () => (
<MediaObject>
<Fill name="media-side">
<img src='https://placekitten.com/200' alt="Kitten" />
</Fill>
<Fill name="media-title">
<h3>Mew</h3>
</Fill>
<Fill name="media-description">
<p>Purr purr purr</p>
</Fill>
</MediaObject>
)
SlotsProvider
import { SlotsProvider } from 'nano-slots'
children: ReactNode
— any valid react children elementCreates a context for Slot
/ Fill
components.
Slot
import { Slot } from 'nano-slots'
name: string
— unique slot name for current SlotsProvider
children?: ReactNode
— fallback in case Fill
with matching name
not provided, optionalonChange?(hasFilled: boolean): void
— callback for detecting state changes, on true
children of matching Fill
is rendered and fallback is hiddenDefine the target slot for Fill
component. Can be used multiple times with the same name inside each SlotsProvider
.
Fill
import { Fill } from 'nano-slots'
name: string
— unique slot name for current SlotsProvider
children: ReactNode
— will be rendered inside matching Slot
Render children into matching Slot
of current SlotsProvider
.
createSlots
import createSlots from 'nano-slots'
Designed for more advanced usages and stronger types. Returns an object containing:
.Provider
— same as SlotsProvider
, but with different context.Slot
— same as Slot
, but with own context.Fill
— same as Fill
, but with own contextReturned Slot
and Fill
can be used without a Provider
.
export interface ProviderProps {
children: React.ReactNode;
}
export function SlotsProvider(props: ProviderProps): JSX.Element;
export interface SlotProps<Names extends PropertyKey> {
name: Names;
children?: React.ReactNode;
}
export function Slot(props: SlotProps): JSX.Element;
export interface FillProps<Names extends PropertyKey> {
name: Names;
children?: React.ReactNode;
}
export function Fill(props: FillProps): null;
export default function createSlots<Names extends PropertyKey>(): {
Provider: (props: SlotsProviderProps): JSX.Element;
Slot: (props: SlotProps<Names>): JSX.Element;
Fill: (props: FillProps<Names>): null;
}
react-slot-fill
- abandoned project that inspired this onereact-view-slot
- more modern approach, but 12x times bigger
MIT © John Grishin