Skip to content

Commit

Permalink
Prettier tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatum committed Jun 7, 2017
1 parent 5a54e3b commit 17c01cf
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 30 deletions.
4 changes: 4 additions & 0 deletions src/content/components/FlameChartCanvas.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
left: 0;
}

/**
* This tooltip is multi-line and more intense, so add additional whitespace to make it
* more readable.
*/
.flameChartCanvasTooltip {
padding: 5px;
}
6 changes: 3 additions & 3 deletions src/content/components/IntervalMarkerOverview.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class IntervalMarkerOverview extends PureComponent {
this._scheduleDraw();
const { className, isSelected } = this.props;
const { mouseDownItem, hoveredItem, mouseX, mouseY } = this.state;
const tooltipText = !mouseDownItem && hoveredItem ? hoveredItem.title : null;
const tooltipContents = !mouseDownItem && hoveredItem ? hoveredItem.title : null;
const canvasClassName = className.split(' ').map(name => `${name}Canvas`).join(' ');

return (
Expand All @@ -169,12 +169,12 @@ class IntervalMarkerOverview extends PureComponent {
onMouseUp={this._onMouseUp}
onMouseOut={this._onMouseOut}/>
{
tooltipText
tooltipContents
? <Tooltip mouseX={mouseX}
mouseY={mouseY}
offsetParent={this._takeCanvasRef}
boundedAtBottom={false}>
{tooltipText}
{tooltipContents}
</Tooltip>
: null
}
Expand Down
9 changes: 4 additions & 5 deletions src/content/components/TimelineCanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default class TimelineCanvas extends Component {
hover: hoveredItem !== null,
});

const tooltipText = this._getHoveredItemInfo();
const tooltipContents = this._getHoveredItemInfo();

return (
<div>
Expand All @@ -161,11 +161,10 @@ export default class TimelineCanvas extends Component {
onMouseOut={this._onMouseOut}
onDoubleClick={this._onDoubleClick} />
{
!isDragging && tooltipText
!isDragging && tooltipContents
? <Tooltip mouseX={mouseX}
mouseY={mouseY}
ref={tooltipText}>
{tooltipText}
mouseY={mouseY}>
{tooltipContents}
</Tooltip>
: null
}
Expand Down
46 changes: 45 additions & 1 deletion src/content/components/Tooltip.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
.tooltip {
position: relative;
max-width: 100%;
padding: 2px 5px;
box-sizing: border-box;
display: inline-block;
padding: 2px 5px;
border: 1px solid #ccc;
background-color: #f9f9f9;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
Expand Down Expand Up @@ -67,3 +68,46 @@
width: 60px;
color: var(--theme-highlight-gray);
}

.tooltipTiming {
padding-right: 0.5em;
color: var(--theme-highlight-green);
font-weight: bold;
}

.tooltipOneLine {
display: flex;
max-width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
}

.tooltipName {
flex: 1;
text-overflow: ellipsis;
overflow: hidden;
}

.tooltipSwatch {
width: 10px;
height: 10px;
display: inline-block;
border: 1px solid #888;
margin-right: 3px;
}

.tooltipHeader {
padding-bottom: 10px;
margin-bottom: 10px;
border-bottom: 1px solid var(--theme-highlight-gray);
}

.tooltipDetails {
margin: 5px 0;
}

.tooltipLabel {
display: block;
width: 60px;
color: #666;
}
50 changes: 29 additions & 21 deletions src/content/components/Tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ export default class Tooltip extends PureComponent {

state: {
interiorElement: HTMLElement | null,
interiorElementRAF: HTMLElement | null,
isNewContentLaidOut: boolean,
};

_isMounted: boolean;
_mountElement: ?HTMLElement;

constructor(props: Props) {
super(props);
(this: any)._getMountElement = this._getMountElement.bind(this);
(this: any)._setMountElement = this._setMountElement.bind(this);
this.state = {
interiorElement: null,
interiorElementRAF: null,
isNewContentLaidOut: false,
};
}

_getMountElement(el: HTMLElement) {
_setMountElement(el: HTMLElement) {
this.setState({ interiorElement: el });
}

Expand Down Expand Up @@ -67,26 +67,34 @@ export default class Tooltip extends PureComponent {

componentWillReceiveProps(nextProps: Props) {
if (nextProps.children !== this.props.children) {
this.setState({interiorElementRAF: null });
this._allowInteriorElementLayout();
// If the children are different, allow them to do an initial lay out on the DOM.
this.setState({isNewContentLaidOut: false });
this._forceUpdateAfterRAF();
}
}

componentDidUpdate() {
this._allowInteriorElementLayout();
// Force an additional update to this component if the children content is
// different as it needs to fully lay out one time on the DOM to proper calculate
// sizing and positioning.
const { interiorElement, isNewContentLaidOut } = this.state;
if (interiorElement && !isNewContentLaidOut) {
this._forceUpdateAfterRAF();
}

this._renderTooltipContents();
}

_allowInteriorElementLayout() {
const { interiorElement, interiorElementRAF } = this.state;
if (interiorElement && !interiorElementRAF) {
// Allow the interior element to fully lay out, then update the sizing.
requestAnimationFrame(() => {
if (this._isMounted) {
this.setState({ interiorElementRAF: interiorElement });
}
});
}
/**
* Children content needs to be on the DOM (not just virtual DOM) in order to correctly
* calculate the sizing and positioning of the tooltip.
*/
_forceUpdateAfterRAF() {
requestAnimationFrame(() => {
if (this._isMounted) {
this.setState({ isNewContentLaidOut: true });
}
});
}

/**
Expand Down Expand Up @@ -116,14 +124,14 @@ export default class Tooltip extends PureComponent {
};

ReactDOM.render(
<div className='tooltip' style={style} ref={this._getMountElement}>
{children}
</div>,
<div className='tooltip' style={style} ref={this._setMountElement}>
{children}
</div>,
this._mountElement
);
}

render() {
return <div/>;
return null;
}
}

0 comments on commit 17c01cf

Please sign in to comment.