Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-tunnels

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-tunnels - npm Package Compare versions

Comparing version 1.0.1 to 1.0.2

46

lib/TunnelPlaceholder.js

@@ -66,37 +66,26 @@ 'use strict';

id = _props.id,
renderChildren = _props.children;
renderChildren = _props.children,
multiple = _props.multiple;
var tunnelProps = tunnelState.getTunnelProps(id);
if (Array.isArray(tunnelProps)) {
if (renderChildren) {
return (0, _react.createElement)(renderChildren, { items: tunnelProps });
}
if (tunnelProps.length > 0) {
return _react2.default.createElement(
_react.Fragment,
null,
tunnelProps.map(function (props) {
return props.children;
})
);
}
} else {
if (renderChildren) {
if (renderChildren) {
if (Array.isArray(tunnelProps) || multiple) {
return !tunnelProps ? (0, _react.createElement)(renderChildren, { items: [] }) : (0, _react.createElement)(renderChildren, {
items: Array.isArray(tunnelProps) ? tunnelProps : [tunnelProps]
});
} else {
return (0, _react.createElement)(renderChildren, tunnelProps || {});
}
}
if (!tunnelProps) {
return null;
}
return _react2.default.createElement(
_react.Fragment,
null,
tunnelProps.children
);
if (!tunnelProps) {
return null;
}
return null;
return _react2.default.createElement(
_react.Fragment,
null,
tunnelProps.children
);
}

@@ -110,3 +99,4 @@ }]);

children: _propTypes2.default.func,
id: _propTypes2.default.string.isRequired
id: _propTypes2.default.string.isRequired,
multiple: _propTypes2.default.bool
};

@@ -113,0 +103,0 @@ TunnelPlaceholder.contextTypes = {

{
"name": "react-tunnels",
"version": "1.0.1",
"version": "1.0.2",
"description": "A easy way to communicate rendering logic and data to ancestor components in React.",

@@ -5,0 +5,0 @@ "main": "./lib/index.js",

@@ -1,2 +0,2 @@

# React Tunnels 🚇 [![npm](https://img.shields.io/npm/v/react-tunnels.svg?style=flat)](https://www.npmjs.org/package/react-tunnels)
# React Tunnels 🚇 [![npm](https://img.shields.io/npm/v/react-tunnels.svg?style=flat)](https://www.npmjs.org/package/react-tunnels)[![Build Status](http://img.shields.io/travis/javivelasco/react-tunnels/master.svg?style=flat-square)](https://travis-ci.org/javivelasco/react-tunnels)

@@ -13,7 +13,7 @@ Render React components in placeholders that are placed somewhere else in the component tree.

There is a common use case in React apps where you want to define a `Layout` where the content of some elements are defined by child components. For example, you want define `Layout` just once and reuse it for every page but it has a breadcrumb whose steps depend on children components. This tiny library allows you to define "tunnels" to render from a element to whatever other element in the app, even elements on top of the tree. It's like `Portal` but the target is a component instead of a DOM element.
There is a common use case in React apps where you want to define a `Layout` where the content of some elements are defined by `children` components. For example, you want define `Layout` just once and reuse it for every page but it has a breadcrumb whose steps depend on `children` components. This tiny library allows you to define *tunnels* to render from a element to whatever other element in the App, even elements located on top of the tree. It's like `Portal` but the target is a *component* instead of a *DOM element*.
### Usage
Define a `TunnelPlaceholder` identified by an `id` and decide what properties are going to be passed to its render function by defining `Tunnel` components with the same id anywhere else in the app. If you define just a single `Tunnel` its props will be passed, if there are more than once tunnel for an `id`, the tunnel will receive an array of `props`. Let's see some examples.
Define a `TunnelPlaceholder` identified by an `id` and decide what properties are going to be passed to its `render` function by defining `Tunnel` components with the **same id** anywhere else in the app. If you define just a single `Tunnel` its props will be passed straight to the `render` function, if there are more than one `Tunnel` for a single `id`, the placeholder `render` function will receive a `item` argument which is an Array containing the `props` for each `Tunnel`. Let's see some examples.

@@ -25,3 +25,3 @@ ### Simple example: tunneling children

```jsx
import { TunnelsProvider, TunnelPlaceholder, Tunnel } from 'preact-slots'
import { TunnelsProvider, TunnelPlaceholder, Tunnel } from 'react-tunnels'

@@ -75,3 +75,3 @@ render(

- [React Slot Fill](https://github.com/camwest/react-slot-fill): [@camwest](https://github.com/camwest) has built a similar project but with a different API and a bit more limited use cases. The main difference is that you can't pass content to a placeholder from multiple entry points while react-tunnels does it by passing an array with the props defined by each tunnel to the render function of the placeholder. For simple cases, it is pretty similar.
- [React Slots](https://github.com/developit/preact-slots): A library similar to React Slot Fill but for [Preact](https://github.com/developit/preact) developed by [Jason Miller](https://twitter.com/_developit).
- [Preact Slots](https://github.com/developit/preact-slots): A library similar to React Slot Fill but for [Preact](https://github.com/developit/preact) developed by [Jason Miller](https://twitter.com/_developit).

@@ -78,0 +78,0 @@ ## License

@@ -8,2 +8,3 @@ import PropTypes from 'prop-types'

id: PropTypes.string.isRequired,
multiple: PropTypes.bool,
}

@@ -33,26 +34,22 @@

const { tunnelState } = this.context
const { id, children: renderChildren } = this.props
const { id, children: renderChildren, multiple } = this.props
const tunnelProps = tunnelState.getTunnelProps(id)
if (Array.isArray(tunnelProps)) {
if (renderChildren) {
return createElement(renderChildren, { items: tunnelProps })
}
if (tunnelProps.length > 0) {
return <Fragment>{tunnelProps.map(props => props.children)}</Fragment>
}
} else {
if (renderChildren) {
if (renderChildren) {
if (Array.isArray(tunnelProps) || multiple) {
return !tunnelProps
? createElement(renderChildren, { items: [] })
: createElement(renderChildren, {
items: Array.isArray(tunnelProps) ? tunnelProps : [tunnelProps],
})
} else {
return createElement(renderChildren, tunnelProps || {})
}
}
if (!tunnelProps) {
return null
}
return <Fragment>{tunnelProps.children}</Fragment>
if (!tunnelProps) {
return null
}
return null
return <Fragment>{tunnelProps.children}</Fragment>
}

@@ -59,0 +56,0 @@ }

@@ -25,3 +25,3 @@ import { configure, mount } from 'enzyme'

</TunnelPlaceholder>
<Tunnel id={TUNNEL_ID} props={props} />
<Tunnel id={TUNNEL_ID} {...props} />
</div>

@@ -47,14 +47,37 @@ </TunnelProvider>,

it('should render passing a component', () => {
it('should render multiple tunnels props when there is a multiple prop', () => {
const wrapper = mount(
<TunnelProvider>
<div>
<TunnelPlaceholder id={TUNNEL_ID} component={Msg} />
<Tunnel id={TUNNEL_ID} props={props} />
<TunnelPlaceholder id={TUNNEL_ID} multiple>
{({ items = [] }) =>
items.map((props, i) => <div key={i}>{props.message}</div>)
}
</TunnelPlaceholder>
<Tunnel id={TUNNEL_ID} message="Foo" />
</div>
</TunnelProvider>,
)
assertTunnelPlaceholderContent(wrapper, props.message)
expect(wrapper.contains([<div key={0}>Foo</div>])).toEqual(true)
})
it('should render multiple tunnels props when there are many tunnels', () => {
const wrapper = mount(
<TunnelProvider>
<div>
<TunnelPlaceholder id={TUNNEL_ID}>
{({ items = [] }) =>
items.map((props, i) => <div key={i}>{props.message}</div>)
}
</TunnelPlaceholder>
<Tunnel id={TUNNEL_ID} message="Foo" />
<Tunnel id={TUNNEL_ID} message="Bar" />
</div>
</TunnelProvider>,
)
expect(
wrapper.contains([<div key={0}>Foo</div>, <div key={1}>Bar</div>]),
).toEqual(true)
})
describe('given Tunnel is not defined', () => {

@@ -72,13 +95,2 @@ it('should render TunnelPlaceholder children passing empty props', () => {

it('should render TunnelPlaceholder component passing empty props', () => {
const wrapper = mount(
<TunnelProvider>
<div>
<TunnelPlaceholder id={TUNNEL_ID} component={Msg} />
</div>
</TunnelProvider>,
)
assertTunnelPlaceholderContent(wrapper, 'defaultMessage')
})
it('should render empty is TunnelPlaceholder does not have children', () => {

@@ -124,3 +136,3 @@ const wrapper = mount(

it.only('should update TunnelPlaceholder when Tunnel is unmounted', () => {
it('should update TunnelPlaceholder when Tunnel is unmounted', () => {
const wrapper = mount(<Component msg={msg1} visible />)

@@ -127,0 +139,0 @@ assertTunnelPlaceholderContent(wrapper, msg1)

import TunnelState from '../src/TunnelState'
const TUNNEL_ID = 'GroompyTunnel'
const ITEM_ID = 'GroomyItem'
const ITEM_ID = 'GroompyItem'
const ITEM_ID2 = 'GroompyItem2'
const props = { message: 'Aihop!' }
const props2 = { message: 'Auhip!' }

@@ -52,2 +54,9 @@ describe('TunnelState', () => {

})
it('allows to retrieve an array of props when there are multiple items', () => {
const state = new TunnelState()
state.setTunnelProps(TUNNEL_ID, ITEM_ID, props)
state.setTunnelProps(TUNNEL_ID, ITEM_ID2, props2)
expect(state.getTunnelProps(TUNNEL_ID)).toEqual([props, props2])
})
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc