An open API service indexing awesome lists of open source software.

https://github.com/maybebot/named-slots

Named slots for preact
https://github.com/maybebot/named-slots

Last synced: 3 months ago
JSON representation

Named slots for preact

Awesome Lists containing this project

README

        

# named-slots 🦥

Slots for preact, react and solid in under 0.2Kb, unzipped, unminified

```sh
npm i named-slots
```

Use declarative "holes" in your components with `` instead of an imperative prop based approach.
Inspired by slots in Vue/Svelte/Angular/WebComponents.

Fill them with any Component or HTML element in the slot with the `slot` attribute: `

`. Use the `` element to render only the contents of it, typically text or multiple elements.

See example below.

## Defining a Slot

| `Slot` props | |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| `name` | name of the slot |
| `from` | always the `children` of where the `Slot` is defined, to give the Slot control over it |
| `children`/content | Fallback content for when nothing has been slotted in. If nothing is slotted, and no fallback is given, it will not render at all |

Define Slots in the component where you want them them to render, for example a Card component, where you want a header, content and a footer.

```jsx
// Card.tsx
import { Slot, Slottable } from "named-slots";

export const Card = ({ children }: { children: Slottable }) => {
// optionally validate slots during development, see defineSlots below
return (

{/* header has no fallback, renders only if slot is provided */}


Fallback content




Fallback footer




);
};
```

## Consuming components with Slots

Now that the card accepts slots, you can insert them inside a `` with an slot attribute. Using the slot attribute on a `` element will render only the contents of the template.

```jsx
// Page.tsx
import { Slot } from "named-slots";

This div is not semantic



One

Two


;
```

This will render the following html:

```html


This div is not semantic

Some content

I'm a footer


```

## Solid.js

Since solid does not use a VDOM it has a dedicated import.

```ts
import { Slot } from "named-slots/solid";
```

In addition every element with `slot` needs to be an HTML element, not a Solid component (or wrapped in one like the ``). In the example above, `` would not work. `

` would.

## Type safety and validation

To type and validate slots it is recommended to use `defineSlots`, which returns a type-aware Slot component and provides runtime validation for slot usage, duplication and absence. Using `defineSlots` there is no need to specify `from={children}` on the Slots.

This is the recommended approach. The API is not the prettiest, requiring a Generic of the type and the values as well, but it provides extra security.

A third, optional, parameter can be passed to `defineSlots`, to improve debugging or to throw instead of console.logging. (example: `{ inComponent: Card, throws: true }`).

This will be stripped away in production to not add to the bundle (with a check on `process.env.NODE_ENV === "development"`).

```js
import { defineSlots, type Slottable } from "named-slots";

export const Card = ({ children }: { children: Slottable }) => {
type CardSlots = "header" | "content" | "footer";
const Slot = defineSlots(children, ["header", "content", "footer"], { inComponent: Card, throws: true });
return (




Fallback content




Fallback footer




);
};
```

Adding proper types and autocompletion for slot names during usage (not definition) has been a miserable failure so far, which is why runtime validation has been added.

---

Made with 🍕 in Amsterdam.