UNPKG

@6thquake/react-material

Version:

React components that implement Google's Material Design.

471 lines (453 loc) 17.6 kB
import React from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import withStyles from '../styles/withStyles'; const styles = theme => ({ /* * Part of bubble rectangle & triangle style which will remain unchangeable. */ recStyle: { //position: 'relative', minWidth: 30, minHeight: 30, maxWidth: 200, padding: 10 }, triStyle: { width: 0, height: 0, display: 'inline-block' }, /* * Default left & right pointed bubble style which can be changed in real applications. */ customization: { fontSize: 15, fontFamily: 'calgary', borderRadius: 5, width: 'auto', height: 'auto' } }); class Bubble extends React.Component { static getDerivedStateFromProps(nextProps, prevState) { let self = nextProps.self; let index = nextProps.index; let ancestor = nextProps.ancestor; let floated = nextProps.floated; let direction = nextProps.direction; if (typeof ancestor !== 'string') { if (typeof index !== 'undefined') { // 有多个ancestor,应该改变ancestor与元素下标对应的 if (floated === 'false') { //非悬浮,不需要设置self样式 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } if (direction === 'right') { //左边 ancestor[index].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: row'); } else if (direction === 'left') { //右边 ancestor[index].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: row-reverse'); } else if (direction === 'top') { //上边 ancestor[index].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: column-reverse'); } else if (direction === 'bottom') { //下边 ancestor[index].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: column'); } } else { // 悬浮,不需要设置ancestor样式 if (typeof self !== 'undefined' && typeof self !== 'string') { if (ancestor[index].getAttribute('style') !== null) { ancestor[index].removeAttribute('style'); } if (direction === 'right') { // 左边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } else if (direction === 'left') { // 右边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } else if (direction === 'top') { // 上边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } else if (direction === 'bottom') { // 下边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } } } } else { // 只有一个ancestor,不存在改变flex-direction的情况 if (floated === 'false') { // 非悬浮,不需要设置self样式 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } if (direction === 'right') { // 左边 ancestor[0].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: row'); } else if (direction === 'left') { // 右边 ancestor[0].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: row-reverse'); } else if (direction === 'top') { // 上边 ancestor[0].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: column-reverse'); } else if (direction === 'bottom') { // 下边 ancestor[0].setAttribute('style', 'display: flex; justify-content: flex-start; align-items: center; flex-direction: column'); } } else { // 悬浮,不需要设置ancestor样式 if (typeof self !== 'undefined' && typeof self !== 'string') { if (ancestor[0].getAttribute('style') !== null) { ancestor[0].removeAttribute('style'); } if (direction === 'right') { // 左边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } else if (direction === 'left') { // 右边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } else if (direction === 'top') { // 上边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } else if (direction === 'bottom') { // 下边 if (typeof self !== 'undefined' && self.getAttribute('style') !== null) { self.removeAttribute('style'); } } } } } } return null; } componentDidUpdate(prevProps, prevStates) { // floated style if (document.getElementById('self') !== null) { if (prevProps.direction === 'right' && prevProps.floated === 'true') { // 悬浮+左边 const dis = Number(document.getElementById('self').getBoundingClientRect().height) / 2 + prevProps.parent.height / 2; const transDis = typeof prevProps.triSize === 'undefined' ? 22 : Number(prevProps.triSize) + 10; const lFXDis = typeof prevProps.parent === 'undefined' ? 0 : prevProps.parent.width + transDis; document.getElementById('self').setAttribute('style', 'transform: translate(' + lFXDis + 'px,' + -dis + 'px)'); } else if (prevProps.direction === 'left' && prevProps.floated === 'true') { // 悬浮+右边 const dis = Number(document.getElementById('self').getBoundingClientRect().height) / 2 + prevProps.parent.height / 2; document.getElementById('self').setAttribute('style', 'transform: translate(-100%,' + -dis + 'px)'); } else if (prevProps.direction === 'top' && prevProps.floated === 'true') { // 悬浮+上边 const dis = document.getElementById('self').getBoundingClientRect().height + prevProps.parent.height + (typeof prevProps.triSize === 'undefined' ? 22 : Number(prevProps.triSize) + 10); document.getElementById('self').setAttribute('style', 'transform: translate(' + -(prevProps.parent.width / 2) + 'px,' + -dis + 'px)'); } else if (prevProps.direction === 'bottom' && prevProps.floated === 'true') { // 悬浮+下边 const dis = typeof prevProps.triSize === 'undefined' ? 22 : Number(prevProps.triSize) + 10; document.getElementById('self').setAttribute('style', 'transform: translate(' + -(prevProps.parent.width / 2) + 'px,' + dis + 'px)'); } } } render() { const { direction, floated, index, triSize, bgColor, classes } = this.props; const halfSize = typeof triSize === 'undefined' ? 6 : Number(triSize) / 2; const recClassNames = classNames(classes.recStyle, classes.customization); const triClassNames = classNames(classes.triStyle); let triResult; /* * Floated bubble */ if (floated === 'true') { /* * Left sided arrow */ if (direction === 'right') { triResult = React.createElement("div", { className: triClassNames, style: { borderRightWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderRightStyle: 'solid', borderRightColor: typeof bgColor === 'undefined' ? 'white' : bgColor, borderTopWidth: halfSize + 'px', borderTopStyle: 'solid', borderTopColor: 'transparent', borderBottomWidth: halfSize + 'px', borderBottomStyle: 'solid', borderBottomColor: 'transparent', left: -(typeof triSize === 'undefined' ? '12' : triSize) + 'px', position: 'absolute', top: '50%', transform: 'translate(0, -50%)' } }); return React.createElement("div", { className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'white' : bgColor, position: 'relative' } }, triResult, this.props.children); } else if (direction === 'left') { /* * Right sided arrow */ triResult = React.createElement("div", { className: triClassNames, style: { borderLeftWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderLeftStyle: 'solid', borderLeftColor: typeof bgColor === 'undefined' ? 'green' : bgColor, borderTopWidth: halfSize + 'px', borderTopStyle: 'solid', borderTopColor: 'transparent', borderBottomWidth: halfSize + 'px', borderBottomStyle: 'solid', borderBottomColor: 'transparent', right: -(typeof triSize === 'undefined' ? '12' : triSize) + 'px', position: 'absolute', top: '50%', transform: 'translate(0, -50%)' } }); return React.createElement("div", { className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'green' : bgColor, position: 'relative' } }, triResult, this.props.children); } else if (direction === 'top') { /* * Bottom sided arrow */ triResult = React.createElement("div", { className: triClassNames, style: { borderTopWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderTopStyle: 'solid', borderTopColor: typeof bgColor === 'undefined' ? 'cyan' : bgColor, borderLeftWidth: halfSize + 'px', borderLeftStyle: 'solid', borderLeftColor: 'transparent', borderRightWidth: halfSize + 'px', borderRightStyle: 'solid', borderRightColor: 'transparent', bottom: -(typeof triSize === 'undefined' ? '12' : triSize) + 'px', position: 'absolute', left: '50%', transform: 'translate(-50%, 0)' } }); return React.createElement("div", { id: "self", className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'cyan' : bgColor, position: 'relative' } }, triResult, this.props.children); } else if (direction === 'bottom') { /* * Top sided arrow */ triResult = React.createElement("div", { className: triClassNames, style: { borderBottomWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderBottomStyle: 'solid', borderBottomColor: typeof bgColor === 'undefined' ? 'blue' : bgColor, borderLeftWidth: halfSize + 'px', borderLeftStyle: 'solid', borderLeftColor: 'transparent', borderRightWidth: halfSize + 'px', borderRightStyle: 'solid', borderRightColor: 'transparent', top: -(typeof triSize === 'undefined' ? '12' : triSize) + 'px', position: 'absolute', left: '50%', transform: 'translate(-50%, 0)' } }); return React.createElement("div", { className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'blue' : bgColor, position: 'relative' } }, triResult, this.props.children); } } else { /* * Non-floated bubble */ /* * Left sided arrow */ if (direction === 'right') { triResult = React.createElement("div", { className: triClassNames, style: { borderRightWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderRightStyle: 'solid', borderRightColor: typeof bgColor === 'undefined' ? 'white' : bgColor, borderTopWidth: halfSize + 'px', borderTopStyle: 'solid', borderTopColor: 'transparent', borderBottomWidth: halfSize + 'px', borderBottomStyle: 'solid', borderBottomColor: 'transparent' } }); return React.createElement("div", { style: { display: 'flex', justifyContent: 'flex-start', alignItems: 'center' } }, triResult, React.createElement("div", { className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'white' : bgColor } }, this.props.children)); } else if (direction === 'left') { /* * Right sided arrow */ triResult = React.createElement("div", { className: triClassNames, style: { borderLeftWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderLeftStyle: 'solid', borderLeftColor: typeof bgColor === 'undefined' ? 'green' : bgColor, borderTopWidth: halfSize + 'px', borderTopStyle: 'solid', borderTopColor: 'transparent', borderBottomWidth: halfSize + 'px', borderBottomStyle: 'solid', borderBottomColor: 'transparent' } }); return React.createElement("div", { style: { display: 'flex', justifyContent: 'flex-start', alignItems: 'center' } }, React.createElement("div", { className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'green' : bgColor } }, this.props.children), triResult); } else if (direction === 'top') { /* * Bottom sided arrow */ triResult = React.createElement("div", { className: triClassNames, style: { borderTopWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderTopStyle: 'solid', borderTopColor: typeof bgColor === 'undefined' ? 'cyan' : bgColor, borderLeftWidth: halfSize + 'px', borderLeftStyle: 'solid', borderLeftColor: 'transparent', borderRightWidth: halfSize + 'px', borderRightStyle: 'solid', borderRightColor: 'transparent' } }); return React.createElement("div", { id: "transform" }, React.createElement("div", { style: { display: 'flex', flexDirection: 'column', justifyContent: 'flex-start', alignItems: 'center' } }, React.createElement("div", { className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'cyan' : bgColor } }, this.props.children), triResult)); } else if (direction === 'bottom') { /* * Top sided arrow */ triResult = React.createElement("div", { className: triClassNames, style: { borderBottomWidth: (typeof triSize === 'undefined' ? '12' : triSize) + 'px', borderBottomStyle: 'solid', borderBottomColor: typeof bgColor === 'undefined' ? 'blue' : bgColor, borderLeftWidth: halfSize + 'px', borderLeftStyle: 'solid', borderLeftColor: 'transparent', borderRightWidth: halfSize + 'px', borderRightStyle: 'solid', borderRightColor: 'transparent' } }); return React.createElement("div", { style: { display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' } }, triResult, React.createElement("div", { className: recClassNames, style: { backgroundColor: typeof bgColor === 'undefined' ? 'blue' : bgColor } }, this.props.children)); } } } } process.env.NODE_ENV !== "production" ? Bubble.propTypes = { /** * the background color of bubble */ bgColor: PropTypes.string, /** * the direction of bubble */ direction: PropTypes.oneOf(['left', 'right', 'top', 'bottom']).isRequired, /** * */ floated: PropTypes.bool.isRequired, /** * */ triSize: PropTypes.number } : void 0; export default withStyles(styles, { name: 'RMBubble' })(Bubble);