Skip to content

A super lightweight slots implementation for React

License

Notifications You must be signed in to change notification settings

exah/nano-slots

Repository files navigation

nano-slots

A super lightweight modern alternative to react-slot-fill with familiar API.

  • Control sub-components rendering with Slot and Fill
  • Render content of sub-component in multiple places
  • Speedy - Fill and Slot communicate directly with each other
  • Tested with testing-library
  • Uses nanoevents under hood
  • Only 421 B (including deps)

📦 Install

npm i -S nano-slots
yarn add nano-slots

💻 Usage

Create a component and define 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>
)

Render elements directly inside each slot

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>
)

Edit nano-slots

📖 API

SlotsProvider

import { SlotsProvider } from 'nano-slots'

Props

  • children: ReactNode — any valid react children element

Description

Creates a context for Slot / Fill components.

Slot

import { Slot } from 'nano-slots'

Props

  • name: string — unique slot name for current SlotsProvider
  • children?: ReactNode — fallback in case Fill with matching name not provided, optional

Description

Define the target slot for Fill component, can be used multiple times with the same name inside each SlotsProvider

Fill

import { Fill } from 'nano-slots'

Props

  • name: string — unique slot name for current SlotsProvider
  • children: ReactNode — will be rendered inside matching Slot

Description

Render children into matching Slot of current SlotsProvider.

Types

export interface SlotsProviderProps {
  children: React.ReactNode;
}

export function SlotsProvider(props: SlotsProviderProps): JSX.Element;

export interface SlotProps {
  name: string;
  children?: React.ReactNode;
}

export function Slot(props: SlotProps): JSX.Element;

export interface FillProps {
  name: string;
  children?: React.ReactNode;
}

export function Fill(props: FillProps): null;

Alternatives


MIT © John Grishin