diff --git a/packages/zent/src/timeline/Item.js b/packages/zent/src/timeline/Item.js index 1d50c7b61b..92d2f145b4 100644 --- a/packages/zent/src/timeline/Item.js +++ b/packages/zent/src/timeline/Item.js @@ -1,34 +1,22 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import Popover from 'popover'; import cx from 'classnames'; import PropTypes from 'prop-types'; import { TimelineDot } from './Dot'; -const position = Popover.Position.create( - (anchorBoundingBox, containerBoundingBox, contentDimension, options) => { - const x = anchorBoundingBox.left + options.cushion; - const middle = (anchorBoundingBox.top + anchorBoundingBox.bottom) / 2; - const y = middle - contentDimension.height / 2; - - return { - getCSSStyle() { - return { - position: 'absolute', - left: `${Math.round(x)}px`, - top: `${Math.round(y)}px`, - }; - }, - - name: 'timeline-tip-position', - }; - } -); - -const TimelineItemOptionalPop = ({ children, tip, display, prefix }) => { +const TimelineItemOptionalPop = ({ + children, + tip, + display, + prefix, + position, + popoverRef, +}) => { if (tip) { return ( { return children; }; -export class TimelineItem extends Component { +export class TimelineItem extends PureComponent { static propTypes = { size: PropTypes.number, color: PropTypes.string, @@ -68,6 +56,46 @@ export class TimelineItem extends Component { dotColor: '#4b0', }; + mousePosition = { + x: 0, + y: 0, + }; + + onMouseMove = e => { + this.mousePosition.x = e.clientX; + this.mousePosition.y = e.clientY; + this.popover && this.popover.adjustPosition(); + }; + + position = Popover.Position.create( + (anchorBoundingBox, containerBoundingBox, contentDimension) => { + const x = anchorBoundingBox.left; + const middle = (anchorBoundingBox.top + anchorBoundingBox.bottom) / 2; + const y = middle - contentDimension.height / 2; + + return { + getCSSStyle: () => { + if (this.props.type === 'horizontal') { + return { + position: 'absolute', + left: `${Math.round(this.mousePosition.x)}px`, + top: `${Math.round(y - 40)}px`, + }; + } + return { + position: 'absolute', + left: `${Math.round(x + 20)}px`, + top: `${Math.round(this.mousePosition.y)}px`, + }; + }, + + name: 'timeline-tip-position', + }; + } + ); + + popoverRef = el => (this.popover = el); + render() { const { size, @@ -87,8 +115,18 @@ export class TimelineItem extends Component { const key = type === 'vertical' ? 'height' : 'width'; return ( -
  • - +
  • +
    { + if (isString(item)) { + return { + key: item, + label: item, + }; + } + const { id, percent, ...others } = item; + return { + key: id || index, + size: percent && percent * size, + ...others, + }; + }); +} + export class Timeline extends PureComponent { static propTypes = { - size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - timeline: validateProps, type: PropTypes.oneOf(['vertical', 'horizontal']), className: PropTypes.string, style: PropTypes.object, @@ -27,28 +41,10 @@ export class Timeline extends PureComponent { static Item = TimelineItem; static Legend = TimelineLegend; - normalize = () => { - const { timeline, size } = this.props; - return timeline.map((item, index) => { - if (isString(item)) { - return { - key: item, - label: item, - }; - } - const { id, percent, ...others } = item; - return { - key: id || index, - size: percent && percent * size, - ...others, - }; - }); - }; - renderChildren() { - const { children, timeline, type } = this.props; + const { children, timeline, type, size } = this.props; if (timeline && timeline.length) { - return this.normalize(timeline).reduce((ret, item) => { + return normalize(timeline, size).reduce((ret, item) => { ret.push(); return ret; }, []);