@workday/canvas-kit-docs
Version:
Documentation components of Canvas Kit components
213 lines (151 loc) • 9.1 kB
text/mdx
import {ExampleCodeBlock, SymbolDoc, Specifications} from '@workday/canvas-kit-docs';
import {InformationHighlight} from '@workday/canvas-kit-preview-react/information-highlight';
import {StatusIndicator} from '@workday/canvas-kit-preview-react/status-indicator';import Default from './examples/Default';
import CustomContent from './examples/CustomContent';
import DelayedTooltip from './examples/DelayedTooltip';
import DescriptionType from './examples/DescriptionType';
import DescribeType from './examples/DescribeType';
import Muted from './examples/Muted';
import Placements from './examples/Placements';
import Ellipsis from './examples/Ellipsis';
import LineClamp from './examples/LineClamp';
import UseTooltip from './examples/UseTooltip';
# Canvas Kit React Tooltips
A Tooltip component that renders information/text when the user hovers over an element. A tooltip is
used to label or describe an element. By default, a tooltip will label an element. This is useful
for buttons with icons. A tooltip can also be used to describe additional information about an
element
[> Workday Design Reference](https://design.workday.com/components/popups/tooltips)
## Installation
```sh
yarn add @workday/canvas-kit-react
```
## Usage
This component follows the
[W3 Tooltip specification](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/). Tooltips are used to
label buttons with icons and provide additional context to elements.
### When to use tooltips
Use a tooltip when you want to display additional information for users to better understand the
purpose, context, or interaction.
### When not to use tooltips
When the visual text will be the exact same as what is visually displayed to the user without the
tooltip being visible
- Does this element need additional context or information?
- No: Don't use a tooltip
- Yes:
- Is the tooltip text useful to screen reader users?
- No: Use `type="muted"` which will not make the tooltip visible to screen reader users
- Yes:
- Is the tooltip text different from the visual text displayed to users?
- No text: Use `type="label"` which will add `aria-label` like the icon example
- Yes: Use `type="describe"` which will add `aria-describedby`
- No: Don't use a tooltip
### Basic Example
Here is a basic example of a `TertiaryButton` that renders an icon using a tooltip to label the
icon. This labels the button for both sighted users and screen readers. A tooltip provides an
`aria-label` to child elements for the accessibility tree and a visual tooltip during mouse hover
and focus events.
<ExampleCodeBlock code={Default} />
### Describing an Element
<InformationHighlight variant={'caution'} className='sb-unstyled'>
<InformationHighlight.Icon />
<InformationHighlight.Heading> Caution: Describe type has been deprecated </InformationHighlight.Heading>
<InformationHighlight.Body>
Assistive technology may ignore <StatusIndicator variant='gray'><StatusIndicator.Label cs={{textTransform: 'lowercase'}}>type="describe"</StatusIndicator.Label></StatusIndicator> techniques based on verbosity settings. Please use <StatusIndicator cs={{textTransform: 'lowercase'}} variant='gray'><StatusIndicator.Label cs={{textTransform: 'lowercase'}}>type="description"</StatusIndicator.Label></StatusIndicator> on Tooltips.
</InformationHighlight.Body>
</InformationHighlight>
The default mode for a tooltip is to label content via `aria-label`. If a tooltip is meant to
provide ancillary information, the `type` can be set to `describe`. This will add `aria-describedby`
to the target element. This will allow screen reader users to hear the name of the control that is
being focused and the ancillary tooltip information.
<ExampleCodeBlock code={DescribeType} />
### Description of an Element
The default mode for a tooltip is to assign a name to the target element with an `aria-label`
string. If a tooltip is meant to provide ancillary information, the `type` can be set to `description`.
This will add `aria-description` strings to the target element instead. This variant is useful on
text buttons and other components that already have a label or name. Use this type instead of `describe` to ensure proper aria attributes are added to the dom regardless if the tooltip is visible.
> **Note:** If you use `description` type and want to pass `jsx`, it **must* be inline and **not** a component to ensure the inner text is properly read by voiceover.
>
> ```jsx
> // The text will be understood as: You must accept terms and conditions
> <Tooltip type="description" title={<span>You<i>must</i> accept terms and conditions</span>}/>
>
> // This will render a string including the html and will not be properly understood by voice over.
> const MyComponent = () => <span>You<i>must</i> accept terms and conditions</span>
> <Tool
<ExampleCodeBlock code={DescriptionType} />
### Muted Tooltips
If a tooltip does not need to be visible to screen reader users, or you handle accessibility of the
tooltip yourself, you can set the `type` to `muted`. This will not add any special ARIA attributes
to the target element.
<ExampleCodeBlock code={Muted} />
### Custom Content
A tooltip can contain HTML, but should not contain any focusable elements or semantically meaningful
formatting. The content will lose all semantic meaning when read by a screen reader. If complex
content or a focusable element is needed by your UI, a tooltip is not a good choice. Consider using
a dialog instead.
<ExampleCodeBlock code={CustomContent} />
### Delayed Tooltip
The default delay for showing and hiding a tooltip are 300ms and 100ms, respectively. You can
control the length of the delay by providing custom `showDelay` and `hideDelay` in ms.
<ExampleCodeBlock code={DelayedTooltip} />
### Placements
The tooltip allows for a `placement` configuration. The tooltip uses
[PopperJS](https://popper.js.org/) to position tooltips, so any valid PopperJS placement is valid
for tooltips.
<ExampleCodeBlock code={Placements} />
### Tooltips on overflowing content
The `OverflowTooltip` component can be applied to any element that has some type of overflow
applied, or has a child element that has overflow applied. The most common and widely supported type
of truncation is the ellipsis.
```css
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
```
**Note**: Text truncation should be avoided if possible. A user should not have to activate a
tooltip to access important content. If user-generated content is being truncated, the following
situation might occur which is a bad user experience. Consider the following list:
- Home Site A
- Home Site B
- Home Site C
If the list items get truncated via an ellipsis, this is what the user could see:
- Home Sit...
- Home Sit...
- Home Sit...
Here are suggestions to try to avoid truncation:
- Allow content to wrap instead
- Limit character count in admin interfaces if possible to avoid need for truncation
- Avoid fixed container sizes if possible to allow content to flow naturally
If truncation is required, here are a few guidelines to insure minimal impact on users:
- Only truncate text of elements that naturally receive focus.
- Keyboard users can only activate tooltips with focus. Adding `tabindex=0` can give focus to
non-focusable elements, but increase the amount of tab stops for keyboard users.
- Provide the full content elsewhere in the UI
Canvas Kit Buttons have this style applied to the text inside them. `OverflowTooltip` in combination
with a max-width can show a tooltip only when overflow is detected:
<ExampleCodeBlock code={Ellipsis} />
### Line Clamp
The `OverflowTooltip` can support various types of overflow. The component will first look for
`text-overflow: ellipsis` and `-webkit-line-clamp`, but will fall back to
`overflow: auto | scroll | clip | hidden`. These properties will be used to determine which
`element` is experiencing an overflow. Overflow detection is as follows where `element` is
determined by the above style properties:
```js
element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight;
```
Here's an example using the `-webkit-line-clamp` property (multi-line ellipsis which works in all
browsers):
<ExampleCodeBlock code={LineClamp} />
Other truncation techniques should be supported as well, even JavaScript ones as long as overflow is
triggered somehow and detectable differences in scroll size and client size.
### The UseTooltip Hook
The `Tooltip` component is a combination of the `TooltipContainer` (a styled element), `Popper`
(which uses PopperJS and the popup stack), the `useTooltip` hook and some behavior. If custom
behavior is required, these sub-components can be composed in a custom container element. This
example uses those parts directly while being functionally equivalent to the original basic example.
<ExampleCodeBlock code={UseTooltip} />
## Component API
<SymbolDoc name="Tooltip" fileName="/react/" />
## Specifications
<Specifications file="Tooltip.spec.ts" name="Tooltip" />