fk-react-ui-components
Version:
Step 1 : Create a file in [ Seeds / Plants / Trees ] <br> Step 2 : It should export an Object with component name and story Component [Refer other components] <br> Step 3 : Story Component should return a react component <br> Step 3 : Created file should
203 lines (173 loc) • 5.52 kB
JavaScript
import React from 'react';
import { PropTypes } from 'prop-types';
import Portal from './Portal';
import { Popover as StyledPopover, OverlayPopup as StyledOverlayPopup } from './styles';
const POSITION = {
LEFT: 'left',
RIGHT: 'right',
TOP: 'top',
CENTER: 'center',
MIDDLE: 'middle',
BOTTOM: 'bottom'
};
export default class Popover extends React.PureComponent {
constructor(props) {
super(props);
this.computePopoverPosition = () => {
const boundingRect = this.state.anchorElem.getBoundingClientRect();
const { top, left, height, width } = boundingRect;
const style = {};
const anchorOrigin = this.props.anchorOrigin || {
horizontal: POSITION.LEFT,
vertical: POSITION.TOP
};
const targetOrigin = this.props.targetOrigin || {
horizontal: POSITION.LEFT,
vertical: POSITION.TOP
};
if (anchorOrigin.horizontal === POSITION.LEFT) {
style.left = `${left}px`;
} else if (anchorOrigin.horizontal === POSITION.MIDDLE) {
style.left = `${left + width / 2}px`;
} else if (anchorOrigin.horizontal === POSITION.RIGHT) {
style.left = `${left + width}px`;
}
if (anchorOrigin.vertical === POSITION.TOP) {
style.top = `${top - 8}px`;
} else if (anchorOrigin.vertical === POSITION.CENTER) {
style.top = `${top + height / 2}px`;
} else if (anchorOrigin.vertical === POSITION.BOTTOM) {
style.top = `${top + height + 8}px`;
}
let transform = '';
if (targetOrigin.horizontal === POSITION.MIDDLE) {
transform += 'translateX(-50%) ';
} else if (targetOrigin.horizontal === POSITION.RIGHT) {
transform += 'translateX(-100%) ';
}
if (targetOrigin.vertical === POSITION.CENTER) {
transform += 'translateY(-50%) ';
} else if (targetOrigin.vertical === POSITION.BOTTOM) {
transform += 'translateY(-100%) ';
}
style.transform = transform;
return style;
};
this.handleClickAwayLayer = () => {
this.setState({
open: false
});
if (this.props.onRequestClose) {
this.props.onRequestClose();
}
};
this.popoverRef = ref => {
this.popoverElem = ref;
if (this.props.popoverRef) {
this.props.popoverRef(ref);
}
};
this.state = {
open: !!props.open,
anchorElem: props.anchorElem || document.body
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.open !== this.props.open) {
this.setState({
open: nextProps.open,
anchorElem: nextProps.anchorElem
});
}
}
/**
* Computes the popover position with respect to the anchor element
*/
/**
* Hides the popover when click away layer is clicked
*/
/**
* Sets the popover reference
*/
render() {
const computedStyle = this.computePopoverPosition();
const { clickAwayLayer = true } = this.props;
const popover = React.createElement(
StyledPopover,
{
innerRef: this.popoverRef,
style: computedStyle,
onClick: e => e.stopPropagation()
},
this.props.children
);
return React.createElement(
Portal,
{ open: this.state.open },
clickAwayLayer ? React.createElement(
StyledOverlayPopup,
{
tabIndex: 0,
onClick: this.handleClickAwayLayer
},
popover
) : popover
);
}
}
Popover.propTypes = {
/**
* Shows popover if this is true
*/
open: PropTypes.bool,
/**
* children
*/
children: PropTypes.element.isRequired,
/**
* Sets the position of popover
*/
anchorOrigin: PropTypes.shape({
vertical: PropTypes.oneOf([POSITION.TOP, POSITION.BOTTOM]),
horizontal: PropTypes.oneOf([POSITION.LEFT, POSITION.RIGHT])
}),
/**
* Sets the position of popover with respect to target
*/
targetOrigin: PropTypes.shape({
vertical: PropTypes.oneOf([POSITION.TOP, POSITION.BOTTOM]),
horizontal: PropTypes.oneOf([POSITION.LEFT, POSITION.RIGHT])
}),
/**
* Dummy layer which hides the popover when clicked on
*/
clickAwayLayer: PropTypes.bool,
/**
* DOM Element reference for popover to open
*/
anchorElem: PropTypes.element,
/**
* Callback for popover reference
*/
popoverRef: PropTypes.func,
/**
* Callback when popover is closed
*/
onRequestClose: PropTypes.func
};
Popover.defaultProps = {
open: false,
anchorOrigin: {
vertical: POSITION.BOTTOM,
horizontal: POSITION.LEFT
},
targetOrigin: {
horizontal: POSITION.LEFT,
vertical: POSITION.TOP
},
clickAwayLayer: true,
anchorElem: null,
popoverRef: () => {},
onRequestClose: () => {}
};
//# sourceMappingURL=index.js.map