Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
290 changes: 5 additions & 285 deletions packages/react-core/src/components/Tooltip/examples/Tooltip.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,68 +13,17 @@ import './TooltipExamples.css';

### Basic

```js
import React from 'react';
import { Tooltip } from '@patternfly/react-core';

<div style={{ margin: '100px' }}>
<Tooltip
content={
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.</div>
}
>
<span tabIndex="0" style={{ border: '1px dashed' }}>
I have a tooltip!
</span>
</Tooltip>
</div>;
```ts file="./TooltipBasic.tsx"
```

### Tooltip react ref

```js
import React from 'react';
import { Tooltip } from '@patternfly/react-core';

TooltipReactRef = () => {
const tooltipRef = React.useRef();
return (
<div style={{ margin: '100px' }}>
<button aria-describedby="tooltip-ref1" ref={tooltipRef}>
Tooltip attached via react ref
</button>
<Tooltip
id="tooltip-ref1"
content={
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
</div>
}
reference={tooltipRef}
/>
</div>
);
};
```ts file="./TooltipReactRef.tsx"
```

### Tooltip selector ref

```js
import React from 'react';
import { Tooltip } from '@patternfly/react-core';

<div style={{ margin: '100px' }}>
<button aria-describedby="tooltip-ref2" id="tooltip-selector">
Tooltip attached via selector ref
</button>
<Tooltip
id="tooltip-ref2"
content={
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.</div>
}
reference={() => document.getElementById('tooltip-selector')}
/>
</div>;
```ts file="./TooltipSelectorRef.tsx"
```

### On icon with dynamic content
Expand All @@ -83,239 +32,10 @@ When the tooltip is used as a wrapper and its content will dynamically update, t

When using a React or selector ref with a tooltip that has dynamic content, the `aria` and `aria-live` props do not need to be manually passed in.

```js
import React from 'react';
import { Tooltip, Button } from '@patternfly/react-core';
import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';

IconExample = () => {
const [showSuccessContent, setShowSuccessContent] = React.useState(false);
const copyText = 'Copy to clipboard';
const doneCopyText = 'Successfully copied to clipboard!';
const [content, setContent] = React.useState(copyText);
return (
<div style={{ margin: '100px' }}>
<Tooltip aria="none" aria-live="polite" content={showSuccessContent ? doneCopyText : copyText}>
<Button
aria-label="Clipboard"
variant="plain"
id="tt-ref"
onClick={() => setShowSuccessContent(!showSuccessContent)}
>
<CopyIcon />
</Button>
</Tooltip>
</div>
);
};
```ts file="./TooltipIcon.tsx"
```

### Options

```js
import React from 'react';
import { Button, Tooltip, Checkbox, Select, SelectOption, TextInput } from '@patternfly/react-core';

OptionsTooltip = () => {
const [trigger, setTrigger] = React.useState(['mouseenter', 'focus']);
const [isVisible, setIsVisible] = React.useState(true);
const [contentLeftAligned, setContentLeftAligned] = React.useState(false);
const [enableFlip, setEnableFlip] = React.useState(true);
const [position, setPosition] = React.useState('top');
const [positionSelectOpen, setPositionSelectOpen] = React.useState(false);
const [flipSelectOpen, setFlipSelectOpen] = React.useState(false);
const [flipBehavior, setFlipBehavior] = React.useState('flip');
const [entryDelayInput, setEntryDelayInput] = React.useState(0);
const [exitDelayInput, setExitDelayInput] = React.useState(0);
const [animationDuration, setAnimationDuration] = React.useState(300);
const tipBoxRef = React.useRef(null);

const scrollToRef = ref => {
if (ref && ref.current) {
ref.current.scrollTop = 400;
ref.current.scrollLeft = 300;
}
};

React.useEffect(() => {
scrollToRef(tipBoxRef);
}, []);

return (
<>
<div>
<div style={{ border: '1px solid' }}>
<Checkbox
label="trigger: mouseenter"
isChecked={trigger.includes('mouseenter')}
onChange={checked => {
let updatedTrigger;
checked && (updatedTrigger = trigger.concat('mouseenter'));
!checked && (updatedTrigger = trigger.filter(t => t !== 'mouseenter'));
setIsVisible(false);
setTrigger(updatedTrigger);
}}
aria-label="trigger: mouseenter"
id="trigger_mouseenter"
/>
<Checkbox
label="trigger: focus"
isChecked={trigger.includes('focus')}
onChange={checked => {
let updatedTrigger;
checked && (updatedTrigger = trigger.concat('focus'));
!checked && (updatedTrigger = trigger.filter(t => t !== 'focus'));
setIsVisible(false);
setTrigger(updatedTrigger);
}}
aria-label="trigger: focus"
id="trigger_focus"
/>
<Checkbox
label="trigger: click"
isChecked={trigger.includes('click')}
onChange={checked => {
let updatedTrigger;
checked && (updatedTrigger = trigger.concat('click'));
!checked && (updatedTrigger = trigger.filter(t => t !== 'click'));
setIsVisible(false);
setTimeout(() => setTrigger(updatedTrigger));
}}
aria-label="trigger: click"
id="trigger_click"
/>
<Checkbox
label="trigger: manual"
isChecked={trigger.includes('manual')}
onChange={checked => {
let updatedTrigger;
checked && (updatedTrigger = trigger.concat('manual'));
!checked && (updatedTrigger = trigger.filter(t => t !== 'manual'));
setIsVisible(false);
setTrigger(updatedTrigger);
}}
aria-label="trigger: manual"
id="trigger_manual"
/>
</div>
<div style={{ border: '1px solid' }}>
<Checkbox
label="content left-aligned"
isChecked={contentLeftAligned}
onChange={checked => setContentLeftAligned(checked)}
aria-label="content left-aligned"
id="content_left_aligned"
/>
</div>
<div style={{ border: '1px solid' }}>
<Checkbox
label="enableFlip"
isChecked={enableFlip}
onChange={checked => setEnableFlip(checked)}
aria-label="enableFlip"
id="enable_flip"
/>
</div>
<div style={{ border: '1px solid' }}>
position (will flip if enableFlip is true). The 'auto' position requires enableFlip to be set to true.
<Select
onToggle={() => setPositionSelectOpen(!positionSelectOpen)}
onSelect={(event, selection) => {
setPosition(selection);
setPositionSelectOpen(false);
}}
isOpen={positionSelectOpen}
selections={position}
menuAppendTo={() => document.body}
>
<SelectOption value="auto" />
<SelectOption value="top" />
<SelectOption value="bottom" />
<SelectOption value="left" />
<SelectOption value="right" />
<SelectOption value="top-start" />
<SelectOption value="top-end" />
<SelectOption value="bottom-start" />
<SelectOption value="bottom-end" />
<SelectOption value="left-start" />
<SelectOption value="left-end" />
<SelectOption value="right-start" />
<SelectOption value="right-end" />
</Select>
</div>
<div style={{ border: '1px solid' }}>
<Checkbox
label="isVisible (also set trigger to only manual to programmatically control it)"
isChecked={isVisible}
onChange={checked => setIsVisible(checked)}
aria-label="isVisible"
id="is_visible"
/>
</div>
<div style={{ border: '1px solid' }}>
Entry delay (ms){' '}
<TextInput
value={entryDelayInput}
type="number"
onChange={val => setEntryDelayInput(val)}
aria-label="entry delay"
/>
Exit delay (ms) <TextInput
value={exitDelayInput}
type="number"
onChange={val => setExitDelayInput(val)}
aria-label="exit delay"
/>
Animation duration (ms){' '}
<TextInput
value={animationDuration}
type="number"
onChange={val => setAnimationDuration(val)}
aria-label="animation duration"
/>
</div>
<div style={{ border: '1px solid' }}>
flip behavior examples (enableFlip has to be true). "flip" will try to flip the tooltip to the opposite of the
starting position. The second option ensures that there are 3 escape positions for every possible starting
position (default). This setting is ignored if position prop is set to 'auto'.
<Select
onToggle={() => setFlipSelectOpen(!flipSelectOpen)}
onSelect={(event, selection) => {
console.log(selection);
setFlipBehavior(selection);
setFlipSelectOpen(false);
}}
isOpen={flipSelectOpen}
selections={flipBehavior}
menuAppendTo={() => document.body}
>
<SelectOption value="flip" />
<SelectOption value="clockwise">['top', 'right', 'bottom', 'left', 'top', 'right', 'bottom']</SelectOption>
</Select>
</div>
</div>
<div id="tooltip-boundary" className="tooltip-box" ref={tipBoxRef}>
<Tooltip
content={
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
</div>
}
trigger={trigger.join(' ')}
enableFlip={enableFlip}
flipBehavior={flipBehavior === 'flip' ? 'flip' : ['top', 'right', 'bottom', 'left', 'top', 'right', 'bottom']}
position={position}
isVisible={isVisible}
entryDelay={entryDelayInput}
exitDelay={exitDelayInput}
animationDuration={animationDuration}
isContentLeftAligned={contentLeftAligned}
appendTo={() => document.getElementById('tooltip-boundary')}
>
<Button className="tooltip-button">Tooltip</Button>
</Tooltip>
</div>
</>
);
};
```ts file="./TooltipOptions.tsx"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { Button, Tooltip } from '@patternfly/react-core';

export const TooltipBasic: React.FunctionComponent = () => (
<div style={{ margin: '100px' }}>
<Tooltip
content={
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
</div>
}
>
<Button>I have a tooltip!</Button>
</Tooltip>
</div>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { Tooltip, Button } from '@patternfly/react-core';
import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';

export const TooltipIcon: React.FunctionComponent = () => {
const [showSuccessContent, setShowSuccessContent] = React.useState(false);
const copyText: string = 'Copy to clipboard';
const doneCopyText: string = 'Successfully copied to clipboard!';

return (
<div style={{ margin: '100px' }}>
<Tooltip aria="none" aria-live="polite" content={showSuccessContent ? doneCopyText : copyText}>
<Button
aria-label="Clipboard"
variant="plain"
id="tt-ref"
onClick={() => setShowSuccessContent(!showSuccessContent)}
>
<CopyIcon />
</Button>
</Tooltip>
</div>
);
};
Loading