Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
d8660091 committed Jan 27, 2018
0 parents commit 04300da
Show file tree
Hide file tree
Showing 9 changed files with 5,982 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
yarn-error.log
node_modules
5 changes: 5 additions & 0 deletions .npmignore
@@ -0,0 +1,5 @@
.storybook
jsconfig.json
.prettierrc.yaml
yarn.lock
yarn-error.log
3 changes: 3 additions & 0 deletions .prettierrc.yaml
@@ -0,0 +1,3 @@
jsxBracketSameLine: true
semi: false
singleQuote: true
7 changes: 7 additions & 0 deletions .storybook/config.js
@@ -0,0 +1,7 @@
import { configure } from '@storybook/react'

function loadStories() {
require('./index.js')
}

configure(loadStories, module)
106 changes: 106 additions & 0 deletions .storybook/index.js
@@ -0,0 +1,106 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import { withInfo } from '@storybook/addon-info'
import Popper from '../src/index.js'

storiesOf('Popper', module)
.add(
'On right',
withInfo()(() => (
<div>
<Popper
renderRef={({ setReference, toggle }) => (
<span
ref={setReference}
onClick={toggle}
style={{
display: 'inline-block',
margin: '10px 3px 10px 3px',
padding: 10,
borderRadius: '.3rem',
backgroundColor: '#6c757d',
color: '#fff',
cursor: 'pointer'
}}>
Popover Right
</span>
)}
options={{
placement: 'right'
}}>
<div
style={{
backgroundColor: '#fff',
borderRadius: '.3rem',
border: '1px solid rgba(0,0,0,.2)',
padding: '8px 12px',
marginLeft: '5px'
}}>
And here's some amazing content. It's very engaging. Right?
</div>
<div
x-arrow="true"
style={{
borderWidth: '5px 5px 5px 0',
borderColor: 'rgba(0,0,0,.2)',
borderLeftColor: 'transparent',
borderTopColor: 'transparent',
borderBottomColor: 'transparent',
left: '-5px',
top: 'calc(50% - 5px)',
width: 0,
height: 0,
borderStyle: 'solid',
position: 'absolute',
margin: 5,
marginLeft: 0,
marginRight: 0
}}
/>
</Popper>
<br />
</div>
))
)
.add(
'On top',
withInfo()(() => (
<Popper
renderRef={({ setReference, toggle }) => (
<span
ref={setReference}
onClick={toggle}
style={{
display: 'inline-block',
margin: '100px 3px 10px 3px',
padding: 10,
borderRadius: '.3rem',
backgroundColor: '#6c757d',
color: '#fff',
cursor: 'pointer'
}}>
Popover Top
</span>
)}
options={{
placement: 'top',
modifiers: {
offset: {
offset: '5, 5'
}
}
}}>
<div
style={{
backgroundColor: '#fff',
borderRadius: '.3rem',
border: '1px solid rgba(0,0,0,.2)',
padding: '8px 12px',
marginLeft: '5px'
}}>
And here's some amazing content. It's very engaging. Right?
</div>
</Popper>
))
)
3 changes: 3 additions & 0 deletions jsconfig.json
@@ -0,0 +1,3 @@
{
"include": "src/**/**"
}
28 changes: 28 additions & 0 deletions package.json
@@ -0,0 +1,28 @@
{
"peerDepencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"dependencies": {
"lodash": "^4.17.4",
"popper.js": "^1.12.9",
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"recompose": "^0.26.0"
},
"name": "@d8660091/react-popper",
"version": "0.1.0",
"description": "A React component for displaying popper based on popper.js",
"main": "index.js",
"author": "Xu Deng",
"license": "MIT",
"devDependencies": {
"@storybook/addon-info": "^3.3.11",
"@storybook/react": "^3.3.10",
"babel-core": "^6.26.0"
},
"scripts": {
"storybook": "start-storybook -p 9001 -c .storybook"
}
}
86 changes: 86 additions & 0 deletions src/index.js
@@ -0,0 +1,86 @@
import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import Popper from 'popper.js'
import _ from 'lodash'

import * as rc from 'recompose'

const enhance = rc.compose(
rc.setDisplayName('Popper'),
rc.setPropTypes({
renderRef: PropTypes.any.isRequired,
children: PropTypes.any.isRequired,
options: PropTypes.object
}),
rc.withState('reference', 'setReference', null),
rc.withState('pop', 'setPop', null),
rc.withStateHandlers(
{
pop: null,
popper: null
},
{
setPop: ({ popper: prevPopper }, props) => pop => {
if (prevPopper) {
prevPopper.destroy()
}
const popper = pop
? new Popper(props.reference, pop, props.options)
: null
return { pop, popper }
}
}
),
rc.withStateHandlers(
{
isOpened: false
},
{
open: (_, props) => () => {
return {
isOpened: true
}
},
close: () => () => ({
isOpened: false
}),
toggle: ({ isOpened }, props) => () => {
return {
isOpened: !isOpened
}
}
}
),
rc.withHandlers({
onClick: props => e => {
if (props.reference) {
const isInsidePop = props.pop && props.pop.contains(e.target)
if (!props.reference.contains(e.target) && !isInsidePop) {
// click outside
props.close()
return
}
}
}
}),
rc.lifecycle({
componentWillMount() {
document.addEventListener('mousedown', this.props.onClick)
},
componentWillUnmount() {
document.removeEventListener('mousedown', this.props.onClick)
}
})
)

export default enhance(props => (
<React.Fragment>
{props.renderRef({ ...props })}
{props.isOpened &&
ReactDOM.createPortal(
<div ref={props.setPop}>{props.children}</div>,
document.body
)}
</React.Fragment>
))

0 comments on commit 04300da

Please sign in to comment.