Skip to content

Commit b2bc8a0

Browse files
siddharthkpcolebemis
authored andcommitted
Tooltip: anchoredPosition + IconButton (primer#2006)
* Add breaking story * Add memex story * use behaviors deploy preview * add tooltip triangle * update snapshot * add label tooltips for story * update @primer/behaviors to latest * lint: remove unused import * Refactor Tooltip * Use Tooltip in IconButton * Add triangle styles for all directions * Add docs * Added delay * change ReactElement to ReactNode * keep ReactElement * Add tests! * compatible types :) * Fix docs * update snapshots * update behaviors to next minor * update snapshots * Fix IconButton duplicate label * missed a spot! * Fix Button story with tooltip * Apply suggestions from code review Co-authored-by: Cole Bemis <[email protected]> * fix alignment with span Co-authored-by: Cole Bemis <[email protected]>
1 parent 000fa72 commit b2bc8a0

25 files changed

+36515
-1084
lines changed

docs/content/IconButton.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ A separate component called `IconButton` is used if the action shows only an ico
3535
</>
3636
```
3737

38+
### Customize description / tooltip text
39+
40+
To add description for the button, wrap `IconButton` in a `Tooltip`. Make sure you pass `aria-label` to the button as well.
41+
42+
```jsx live
43+
<Tooltip text="You have no unread notifications">
44+
<IconButton icon={BellIcon} aria-label="Notifications" />
45+
</Tooltip>
46+
```
47+
3848
## API reference
3949

4050
Native `<button>` HTML attributes are forwarded to the underlying React `button` component and are not listed below.

docs/content/Tooltip.md

Lines changed: 0 additions & 34 deletions
This file was deleted.

docs/content/Tooltip.mdx

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
componentId: tooltip
3+
title: Tooltip
4+
status: Alpha
5+
source: https://github.com/primer/react/tree/main/src/Tooltip
6+
storybook: '/react/storybook?path=/story/composite-components-tooltip'
7+
description: Use tooltips to add context to elements on the page.
8+
---
9+
10+
Tooltip only appears on mouse hover or keyboard focus and contain a label or description text. Use tooltips sparingly and as a last resort. [Consider these alternatives](https://primer.style/design/accessibility/tooltip-alternatives).
11+
12+
import {Tooltip, IconButton, Button} from '@primer/react'
13+
import {BellIcon, MentionIcon} from '@primer/octicons-react'
14+
import InlineCode from '@primer/gatsby-theme-doctocat/src/components/inline-code'
15+
16+
<Box
17+
sx={{
18+
display: 'flex',
19+
justifyContent: 'center',
20+
border: '1px solid',
21+
borderColor: 'border.default',
22+
borderRadius: 2,
23+
padding: 6,
24+
paddingTop: 8,
25+
marginBottom: 3
26+
}}
27+
>
28+
<Tooltip text="You have no unread notifications" sx={{visibility: 'visible', opacity: 1}}>
29+
<IconButton icon={BellIcon} aria-label="Notifications" />
30+
</Tooltip>
31+
</Box>
32+
33+
When using a tooltip, follow the provided guidelines to avoid accessibility issues:
34+
35+
- Tooltip text should be brief and to the point.
36+
- Tooltips should contain only **non-essential text**. Tooltips can easily be missed and are not accessible on touch devices so never use tooltips to convey critical information.
37+
38+
## Examples
39+
40+
### As a description for icon-only button
41+
42+
If the tooltip content provides supplementary description, wrap the target in a `Tooltip`. The trigger element should also have a concise accessible label via `aria-label`.
43+
44+
```jsx live
45+
<Tooltip text="Directly mention a team or user">
46+
<IconButton aria-label="Mentions" icon={MentionIcon} variant="invisible" />
47+
</Tooltip>
48+
```
49+
50+
### As a description for a button with visible label
51+
52+
```jsx live
53+
<Tooltip text="This will immediately impact all organization members">
54+
<Button variant="primary">Save</Button>
55+
</Tooltip>
56+
```
57+
58+
### With direction
59+
60+
Set direction of tooltip with `direction`. The tooltip is responsive and will automatically adjust direction to avoid cutting off.
61+
62+
```jsx live
63+
<Box
64+
sx={{
65+
display: 'flex',
66+
flexDirection: 'column',
67+
gap: 8,
68+
marginY: 4,
69+
'[data-component=tooltip]': {visibility: 'visible', opacity: 1}
70+
}}
71+
>
72+
<Box sx={{display: 'flex', justifyContent: 'space-between', gap: 1}}>
73+
<Tooltip direction="nw" text="Tooltip text">
74+
<Button>North west</Button>
75+
</Tooltip>
76+
<Tooltip direction="n" text="Tooltip text">
77+
<Button>North</Button>
78+
</Tooltip>
79+
<Tooltip direction="ne" text="Tooltip text">
80+
<Button>North east</Button>
81+
</Tooltip>
82+
</Box>
83+
<Box sx={{display: 'flex', justifyContent: 'space-between', gap: 1}}>
84+
<Tooltip direction="e" text="Tooltip text">
85+
<Button>East</Button>
86+
</Tooltip>
87+
<Tooltip direction="w" text="Tooltip text">
88+
<Button>West</Button>
89+
</Tooltip>
90+
</Box>
91+
<Box sx={{display: 'flex', justifyContent: 'space-between', gap: 1}}>
92+
<Tooltip direction="sw" text="Tooltip text">
93+
<Button>South west</Button>
94+
</Tooltip>
95+
<Tooltip direction="s" text="Tooltip text">
96+
<Button>South</Button>
97+
</Tooltip>
98+
<Tooltip direction="se" text="Tooltip text">
99+
<Button>South east</Button>
100+
</Tooltip>
101+
</Box>
102+
</Box>
103+
```
104+
105+
## Props
106+
107+
### Tooltip
108+
109+
<PropsTable>
110+
<PropsTableRow name="children" required type="React.ReactNode" description="Tooltip target, single element" />
111+
112+
<PropsTableRow
113+
name="text"
114+
type="string"
115+
description="The text content of the tooltip. This should be brief and no longer than a sentence"
116+
/>
117+
<PropsTableRow
118+
deprecated
119+
name="aria-label"
120+
type="string"
121+
description={
122+
<>
123+
Use <InlineCode>text</InlineCode> instead
124+
</>
125+
}
126+
/>
127+
<PropsTableRow
128+
name="type"
129+
type="'description' | 'label'"
130+
defaultValue="'description'"
131+
description={
132+
<>
133+
Use <InlineCode>aria-describedby</InlineCode> or <InlineCode>aria-labelledby</InlineCode>
134+
</>
135+
}
136+
/>
137+
<PropsTableRow
138+
name="direction"
139+
type="'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w'"
140+
defaultValue="'n'"
141+
description="Sets where the tooltip renders in relation to the target"
142+
/>
143+
<PropsTableRow name="align" deprecated type="'left' | 'right'" description="Use direction instead. Alignment relative to target" />
144+
<PropsTableRow
145+
name="noDelay"
146+
type="boolean"
147+
defaultValue="false"
148+
description={
149+
<>
150+
When set to <InlineCode>true</InlineCode>, tooltip appears without any delay
151+
</>
152+
}
153+
/>
154+
<PropsTableRow
155+
name="wrap"
156+
type="boolean"
157+
deprecated
158+
description={
159+
<>
160+
Use to allow text within tooltip to wrap. Deprecated: always set to <InlineCode>true</InlineCode> now.
161+
</>
162+
}
163+
/>
164+
<PropsTableSxRow />
165+
</PropsTable>
166+
167+
## Status
168+
169+
<ComponentChecklist
170+
items={{
171+
propsDocumented: true,
172+
noUnnecessaryDeps: true,
173+
adaptsToThemes: true,
174+
adaptsToScreenSizes: true,
175+
fullTestCoverage: true,
176+
usedInProduction: true,
177+
usageExamplesDocumented: true,
178+
hasStorybookStories: true,
179+
designReviewed: false,
180+
a11yReviewed: false,
181+
stableApi: true,
182+
addressedApiFeedback: false,
183+
hasDesignGuidelines: false,
184+
hasFigmaComponent: true
185+
}}
186+
/>
187+
188+
## Further reading
189+
190+
- [Tooltip alternatives](https://primer.style/design/accessibility/tooltip-alternatives)
191+
192+
## Related components
193+
194+
- [IconButton](/IconButton)

0 commit comments

Comments
 (0)