Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/dschnare/react-slot

Slot-based content distribution component for React
https://github.com/dschnare/react-slot

Last synced: 3 months ago
JSON representation

Slot-based content distribution component for React

Awesome Lists containing this project

README

        

# React Slot

Slot-based content distribution component for React. The technique was highly
influenced by the content distribution techniques used by
[Vuejs](http://vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots).

## Install

```shell
npm install react@">=15" react-dom@">=15" react-slot -S
```

## Quick Start

```jsx
/*
LayoutDefault.js
Generates a slotted HTML layout like the following:


Welcome!

Copyright 2017



*/
import * as React from 'react'
import { Slot } from 'react-slot'

export default function LayoutDefault (props) {
const { children } = props
return (


Welcome!

Copyright 2017


)
}

/*
PageHome.js
Create a page that will insert content into a layout's slots.
Generates HTML like the following (depends on what layout is used):



Home


The main content

Copyright 2017



*/
import * as React from 'react'

export default PageHome extends React.Component {
static propsTypes = {
layout: PropTypes.func.isRequired
}

render () {
const { layout } = this.props

return (



Home



The main content



)
}
}

// App.js
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import PageHome from './PageHome'

const page =

ReactDOM.render(
page,
document.getElementById('app')
)
```

## API

### Slot

Slot is a component that is meant to compose your layouts with. These act
as the points where a layout can be altered by a parent using the layout
component. The slot without a name is known as the default slot.

**Props**

- `content` *[required]* The React children of the parent component
- `children` The default content to render if no content is inserted from the parent component
- `name` The name of this slot (inserted as class name 'slot-${name}')
- `id` The HTML id
- `className` Additional class names
- `dataset` *[default: {}]* An object with keys to set as 'data-' attributes (keys must not contain a 'data-' prefix)
- `role` The HTML role
- `as` *[default: 'div']* The type of React element (string or function) to create the root element as

Something to keep in mind, Slot elements will render nothing if they don't have
any default content and the parent component didn't insert any content.

```jsx

```

Full Example:

```jsx
/*
A layout that will render HTML like the following:


Welcome!

Copyright 2017



*/
const LayoutDefault = props => {
const { children } = props
return (

Welcome!

Copyright 2017


)
}
```

To insert content into a `Slot` the parent component using the layout needs to
designate React subtrees to use a slot by setting the `slot` prop on an element
to have its children inserted into the slot with the mathcing name (if one
exists). *Only the first matching React subtree will have its children inserted.*

```jsx

...inserted into the slot-name slot...

```

Any React elements with a `slot` set to `"default"`, or `true` will have thier
children inserted into the default slot (if one exists).

```jsx

...inserted into the default slot...

...inserted into the default slot...

```

Since only the children of a react subtree are inserted into a slot, all props
on the subtree root node are merged with the props defined on the ``
element in the layout.

```jsx
// in the layout...

// in the parent component...

The Footer

// Results in the footer slot being rendered as...


```

Also, if a default slot exists and no slotted subtree is found with the `slot`
prop set to `"default"` or `true`, then all React nodes without a slot
designation will be inserted into the default slot.

```jsx

...

Default content1

More default content

...

```

Example Usage of `LayoutDefault`:

```jsx
/*
A page component that uses LayoutDefault to structure its content. This
will render a page that looks like this:


Welcome!

Hello World!

This is some more content inserted into the default slot



Copyright 2018


*/
const Page = props => {
return (

Copyright 2018

Hello World!

This is some more content inserted into the default slot



)
}
```

Additionally, Slots can be nested to provide parent components with increasing
granularity when overriding slots.

```jsx

This is the content

This is the inner content

```

Then to insert into these slots you have a choice to override the entire `outer`
slot...

```jsx

...

```

...or just the `inner` slot.

```jsx

....

```

But if the `outer` slot is overrdden then the entirety of its contents will be
replaced.

### slot(name, children)

This function will pull out the children of any React subtree designated by the
`slot` prop that matches the `name` argument. This function will not render a
root node at all, this is left up to the parent component to provide. This gives
you more control over a slot's root element.

```jsx

Copyright {slot('copyrightYear', children) || '2017'}

```

Then in the parent component:

```jsx
// Replace the entire footer...

...

// ...or just replace the copyright year

2018

```

## Related Modules

- [react-layout](https://npmjs.org/react-layout)