A super lightweight modern alternative to react-slot-fill
with familiar API.
- Control sub-components rendering with
Slot
andFill
- Render content of sub-component in multiple places
- Speedy -
Fill
andSlot
communicate directly with each other - Tested with
testing-library
- Written in TypeScript
- Zero dependencies
- Only ~431 B
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>
)
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 currentSlotsProvider
children?: ReactNode
β fallback in caseFill
with matchingname
not provided, optionalonChange?(hasFilled: boolean): void
β callback for detecting state changes, ontrue
children of matchingFill
is 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 currentSlotsProvider
children: 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