Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"presets": [
"metalab"
["@babel/preset-env", {
"shippedProposals": true
}],
"@babel/preset-react",
"@babel/preset-flow"
],
"plugins": [
"@babel/plugin-proposal-class-properties"
]
}
10 changes: 8 additions & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
*.js
!src/**/*.js
/flow-typed
/*.js
match/**/*
internal/**/*
test/*.js
lib/**/*
node_modules
/coverage
6 changes: 5 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
extends:
- metalab
- metalab/react
overrides:
-
files: "*.spec.js"
env:
jest: true
13 changes: 13 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[ignore]
.*\.flow
[include]

[libs]

[lints]
all=error

[options]
emoji=true
include_warnings=true
suppress_comment=\\(.\\|\n\\)*\\$ExpectError
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
node_modules
*.log
*.js
*.js.map
!src/**/*.js
coverage
/*.js
/*.js.map
/coverage
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
parser: flow
semi: true
singleQuote: true
trailingComma: all
bracketSpacing: false
arrowParens: always
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ sudo: false
language: node_js
matrix:
include:
- node_js: '6'
- node_js: '8'
- node_js: '10'

after_success:
- cat ./coverage/coverage.json | ./node_modules/.bin/adana -F adana-format-istanbul > ./coverage/istanbul.json
- bash <(curl -s https://codecov.io/bash) -f ./coverage/istanbul.json
- bash <(curl -s https://codecov.io/bash)
181 changes: 178 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,180 @@
# Relocation
# relocation

[![npm version](https://img.shields.io/npm/v/relocation.svg)](https://www.npmjs.com/package/relocation)
Complex portal behaviour for `react^16.3`.

Relocation works with [React Redux](https://github.com/rackt/react-redux) to manage modals, lightboxes, alerts, and overlays.
![build status](http://img.shields.io/travis/metalabdesign/relocation/master.svg?style=flat)
![coverage](https://img.shields.io/codecov/c/github/metalabdesign/relocation/master.svg?style=flat)
![license](http://img.shields.io/npm/l/relocation.svg?style=flat)
![version](http://img.shields.io/npm/v/relocation.svg?style=flat)
![downloads](http://img.shields.io/npm/dm/relocation.svg?style=flat)

## Examples

### Modal Dialogs

```jsx
import createRelocation from 'relocation';

const ModalRelocation = createRelocation();

const ModalRoot = () => (
<div style={{position: 'fixed'}}>
<ModalRelocation.Consumer>
{(modals) => modals[0] && modals[0].child}
</ModalRelocation.Consumer>
</div>
);

const Modal = ({children}) => (
<ModalRelocation.Component>
<div style={{width: 500, background: '#fff'}}>
Modal!
{children}
</div>
</ModalRelocation.Component>
);

const App = (
<ModalRelocation.Provider>
<div>
<ModalRoot/>
<Modal>Modal A</Modal>
<Modal>Modal B</Modal>
</div>
</ModalRelocation.Provider>
);
```

### Tooltips


```jsx
import createRelocation from 'relocation';

const TooltipRelocation = createRelocation();

const TooltipDisplay = ({id}) => (
<TooltipRelocation.Consumer>
{(tooltips) => {
const result = tooltips.find(({meta}) => meta.id === id);
if (result) {
return result.child;
}
return null;
}}
</TooltipRelocation.Consumer>
);

class TooltipTarget {
id = cuid();
state = {element: null}
open = (element = this.props.tooltip) => {
this.setState({element});
}
close = () => {
this.setState({element: null});
}
toggle = (element = this.props.tooltip) => {
this.setState((state) => state.element ? null : element)
}
render() {
const {element} = this.state;
return (
<React.Fragment>
<TooltipDisplay id={this.id}/>
{children({open, close, toggle})}
{element && (
<TooltipRelocation.Component meta={{id}}>
{element}
</TooltipRelocation.Component>
)}
</React.Fragment>
)
}
}


const App = (
<TooltipRelocation.Provider>
<div>
<TooltipTarget tooltip={<div>My tooltip</div>}>
{(toggle) => (
<button onClick={() => toggle()}>Click me!</button>
)}
</TooltipTarget>
</div>
</TooltipRelocation.Provider>
);
```

### Managing `head` Element

```jsx
import createRelocation from 'relocation';

const HeadRelocation = createRelocation();

const head =
typeof document !== 'undefined'
? document.getElementsByTagName('head')[0]
: null;

class HeadPortal extends React.Component<*> {
componentDidMount() {
if (head) {
// Strip out server-side components
head.querySelectorAll('[data-rh=true]').forEach((e) => {
e.remove();
});
}
}
render() {
return head ? (
<HeadRelocation.Consumer>
{(children) => ReactDOM.createPortal(mapChildren(children), head)}
</HeadRelocation.Consumer>
) : null;
}
}

const Head = ({render}) => (
<HeadRelocation.Component>
{render({'data-rh': 'true'})}
</HeadRelocation.Component>
);

const Title = ({children}) => (
<Head>
{(props)} => (
<title {...props}>{children}</title>
)}
</Head>
);

const App = ({head}) => (
<HeadRelocation.Provider collector={head}>
<HeadPortal/>
<Title>My Page</Title>
</HeadRelocation.Provider>
);
```

And on the server:

```jsx
const render = () => {
const headCollector = new HeadRelocation.Collector();

const markup = React.renderToString(<App head={headCollector}/>);
return React.renderToStaticMarkup((
<html>
<head>
{head.getElements()}
</head>
<body>
{markup}
</body>
</html>
));
};
```
18 changes: 18 additions & 0 deletions flow-typed/npm/cuid_vx.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// flow-typed signature: 52ccdf49283c60a4552ab3bff8fcd227
// flow-typed version: <<STUB>>/cuid_v1.3.8/flow_v0.70.0

/**
* This is an autogenerated libdef stub for:
*
* 'cuid'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/

declare module 'cuid' {
declare module.exports: () => string;
}
Loading