A super lightweight modern alternative to react-slot-fill with familiar API.
- Control sub-components rendering with
SlotandFill - Render content of sub-component in multiple places
- Speedy -
FillandSlotcommunicate directly with each other - Tested with
testing-library - Written in TypeScript
- Zero dependencies
- Only ~431 B
npm i -S nano-slotsyarn add nano-slotsimport { 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>
)import { SlotsProvider } from 'nano-slots'children: ReactNode— any valid react children element
Creates a context for Slot / Fill components.
import { Slot } from 'nano-slots'name: string— unique slot name for currentSlotsProviderchildren?: ReactNode— fallback in caseFillwith matchingnamenot provided, optionalonChange?(hasFilled: boolean): void— callback for detecting state changes, ontruechildren of matchingFillis rendered and fallback is hidden
Define the target slot for Fill component. Can be used multiple times with the same name inside each SlotsProvider.
import { Fill } from 'nano-slots'name: string— unique slot name for currentSlotsProviderchildren: ReactNode— will be rendered inside matchingSlot
Render children into matching Slot of current SlotsProvider.
import createSlots from 'nano-slots'Designed for more advanced usages and stronger types. Returns an object containing:
.Provider— same asSlotsProvider, but with different context.Slot— same asSlot, but with own context.Fill— same asFill, but with own context
Returned 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