Tooltips
Tooltips are built with https://popper.js.org/ via https://github.com/popperjs/react-popper.
Somewhere in here is a tooltip.
/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
import React, { useState } from 'react';
import { Tooltip } from 'reactstrap';
const Example = (props) => {
const [tooltipOpen, setTooltipOpen] = useState(false);
const toggle = () => setTooltipOpen(!tooltipOpen);
return (
<div>
<p>Somewhere in here is a <span style={{textDecoration: "underline", color:"blue"}} href="#" id="TooltipExample">tooltip</span>.</p>
<Tooltip placement="right" isOpen={tooltipOpen} target="TooltipExample" toggle={toggle}>
Hello world!
</Tooltip>
</div>
);
}
export default Example;
Properties
Tooltip.propTypes = {
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
// space separated list of triggers (e.g. "click hover focus")
trigger: PropTypes.string,
// boundaries for popper, can be scrollParent, window, viewport, or any DOM element
boundariesElement: PropTypes.oneOfType([PropTypes.string, DOMElement]),
// boolean to control the state of the tooltip
isOpen: PropTypes.bool,
hideArrow: PropTypes.bool,
// callback for toggling isOpen in the controlling component. It will receive an object with info about the event that triggered it
toggle: PropTypes.func,
// target element or element ID, popover is attached to this element
target: PropTypes.oneOfType([
PropTypes.string,
PropTypes.func,
DOMElement, // instanceof Element (https://developer.mozilla.org/en-US/docs/Web/API/Element)
]).isRequired,
// Where to inject the popper DOM node, default to body
container: PropTypes.oneOfType([PropTypes.string, PropTypes.func, DOMElement]),
// optionally override show/hide delays - default { show: 0, hide: 50 }
delay: PropTypes.oneOfType([
PropTypes.shape({ show: PropTypes.number, hide: PropTypes.number }),
PropTypes.number
]),
className: PropTypes.string,
// Apply class to the popper component
popperClassName: PropTypes.string,
// Apply class to the inner-tooltip
innerClassName: PropTypes.string,
// Apply class to the arrow-tooltip ('arrow' by default)
arrowClassName: PropTypes.string,
// optionally hide tooltip when hovering over tooltip content - default true
autohide: PropTypes.bool,
// convenience attachments for popover
placement: PropTypes.oneOf([
'auto',
'auto-start',
'auto-end',
'top',
'top-start',
'top-end',
'right',
'right-start',
'right-end',
'bottom',
'bottom-start',
'bottom-end',
'left',
'left-start',
'left-end',
]),
// Custom modifiers that are passed to Popper.js, see https://popper.js.org/popper-documentation.html#modifiers
modifiers: PropTypes.object,
// Whether the element the tooltip is pointing to has "position: fixed" styling. This is passed to Popper.js and
// will make the tooltip itself have "position: fixed" as well
positionFixed: PropTypes.bool,
offset: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
// Custom ref handler that will be assigned to the "ref" of the <div> wrapping the tooltip elements
innerRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string,
PropTypes.object
]),
// Whether to show/hide the popover with a fade effect
// (default: true)
fade: PropTypes.bool,
// Whether to flip the direction of the popover if too close to
// the container edge
// (default: true)
flip: PropTypes.bool,
}
Sometimes you need to allow users to select text within a tooltip.
/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
import React, { useState } from 'react';
import { Tooltip } from 'reactstrap';
const Example = (props) => {
const [tooltipOpen, setTooltipOpen] = useState(false);
const toggle = () => setTooltipOpen(!tooltipOpen);
return (
<div>
<p>Sometimes you need to allow users to select text within a <span style={{textDecoration: "underline", color:"blue"}} href="#" id="DisabledAutoHideExample">tooltip</span>.</p>
<Tooltip placement="top" isOpen={tooltipOpen} autohide={false} target="DisabledAutoHideExample" toggle={toggle}>
Try to select this text!
</Tooltip>
</div>
);
}
export default Example;
/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
import React, { useState } from "react";
import { Button, Tooltip } from "reactstrap";
const TooltipItem = props => {
const { item, id } = props;
const [tooltipOpen, setTooltipOpen] = useState(false);
const toggle = () => setTooltipOpen(!tooltipOpen);
return (
<span>
<Button className="mr-1" color="secondary" id={"Tooltip-" + id}>
{item.text}
</Button>
<Tooltip
placement={item.placement}
isOpen={tooltipOpen}
target={"Tooltip-" + id}
toggle={toggle}
>
Tooltip Content!
</Tooltip>
</span>
);
};
const TooltipExampleMulti = props => {
return (
<>
{[
{
placement: "top",
text: "Top"
},
{
placement: "bottom",
text: "Bottom"
},
{
placement: "left",
text: "Left"
},
{
placement: "right",
text: "Right"
}
].map((tooltip, i) => {
return <TooltipItem key={i} item={tooltip} id={i} />;
})}
</>
);
};
export default TooltipExampleMulti;
For the most basic use-case an uncontrolled component can provide the functionality wanted without the need to manage/control the state of the component. UncontrolledTooltip
does not require isOpen
nor toggle
props to work.
Somewhere in here is a tooltip.
/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
import React from 'react';
import { UncontrolledTooltip } from 'reactstrap';
export default function Example() {
return (
<div>
<p>Somewhere in here is a <span style={{textDecoration: "underline", color:"blue"}} href="#" id="UncontrolledTooltipExample">tooltip</span>.</p>
<UncontrolledTooltip placement="right" target="UncontrolledTooltipExample">
Hello world!
</UncontrolledTooltip>
</div>
);
}
If you need to reposition a tooltip due to content changes or target placement changes, use the scheduleUpdate
function to manually reposition it. This function is exposed as a render prop for children
.
import React, { useState, useEffect } from 'react';
import { Button, UncontrolledTooltip } from 'reactstrap';
const shortText = 'Hi';
const longText = 'Long tooltip content to test scheduleUpdate';
const TooltipContent = ({ scheduleUpdate }) => {
const [text, setText] = useState(shortText);
useEffect(() => {
const intervalId = setInterval(() => {
setText(text === shortText ? longText : shortText);
scheduleUpdate();
}, 2000);
return () => clearInterval(intervalId);
});
return (
<>{text}</>
);
}
const Example = () => {
return (
<div className="text-center">
<Button id="ScheduleUpdateTooltip">Click me</Button>
<UncontrolledTooltip placement="top" target="ScheduleUpdateTooltip" trigger="click">
{({ scheduleUpdate }) => (
<TooltipContent scheduleUpdate={scheduleUpdate} />
)}
</UncontrolledTooltip>
</div>
);
}
export default Example;