@fluentui/react-tooltip 0.0.0-nightlyff78d1e27a20220217.1 → 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.json +583 -17
- package/CHANGELOG.md +280 -111
- package/MIGRATION.md +51 -43
- package/Spec.md +201 -337
- package/dist/{react-tooltip.d.ts → index.d.ts} +42 -35
- package/{lib → dist}/tsdoc-metadata.json +0 -0
- package/lib/components/Tooltip/Tooltip.js.map +1 -1
- package/lib/components/Tooltip/Tooltip.types.js.map +1 -1
- package/lib/components/Tooltip/renderTooltip.js +3 -1
- package/lib/components/Tooltip/renderTooltip.js.map +1 -1
- package/lib/components/Tooltip/useTooltip.js +14 -12
- package/lib/components/Tooltip/useTooltip.js.map +1 -1
- package/lib/components/Tooltip/useTooltipStyles.js +20 -18
- package/lib/components/Tooltip/useTooltipStyles.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib-commonjs/components/Tooltip/Tooltip.js.map +1 -1
- package/lib-commonjs/components/Tooltip/renderTooltip.js +3 -1
- package/lib-commonjs/components/Tooltip/renderTooltip.js.map +1 -1
- package/lib-commonjs/components/Tooltip/useTooltip.js +13 -11
- package/lib-commonjs/components/Tooltip/useTooltip.js.map +1 -1
- package/lib-commonjs/components/Tooltip/useTooltipStyles.js +21 -19
- package/lib-commonjs/components/Tooltip/useTooltipStyles.js.map +1 -1
- package/lib-commonjs/index.js +32 -2
- package/lib-commonjs/index.js.map +1 -1
- package/package.json +20 -25
- package/lib/Tooltip.d.ts +0 -1
- package/lib/components/Tooltip/Tooltip.d.ts +0 -7
- package/lib/components/Tooltip/Tooltip.types.d.ts +0 -108
- package/lib/components/Tooltip/index.d.ts +0 -5
- package/lib/components/Tooltip/private/constants.d.ts +0 -12
- package/lib/components/Tooltip/renderTooltip.d.ts +0 -5
- package/lib/components/Tooltip/useTooltip.d.ts +0 -10
- package/lib/components/Tooltip/useTooltipStyles.d.ts +0 -6
- package/lib/index.d.ts +0 -1
- package/lib-commonjs/Tooltip.d.ts +0 -1
- package/lib-commonjs/components/Tooltip/Tooltip.d.ts +0 -7
- package/lib-commonjs/components/Tooltip/Tooltip.types.d.ts +0 -108
- package/lib-commonjs/components/Tooltip/index.d.ts +0 -5
- package/lib-commonjs/components/Tooltip/private/constants.d.ts +0 -12
- package/lib-commonjs/components/Tooltip/renderTooltip.d.ts +0 -5
- package/lib-commonjs/components/Tooltip/useTooltip.d.ts +0 -10
- package/lib-commonjs/components/Tooltip/useTooltipStyles.d.ts +0 -6
- package/lib-commonjs/index.d.ts +0 -1
package/Spec.md
CHANGED
@@ -44,31 +44,42 @@ v0 tooltips use a `trigger` property to render the tooltip's target component. H
|
|
44
44
|
|
45
45
|
# Sample Code
|
46
46
|
|
47
|
-
|
47
|
+
Label tooltip for an icon-only button:
|
48
48
|
|
49
|
-
|
49
|
+
```tsx
|
50
|
+
<Tooltip content="Copy" relationship="label">
|
51
|
+
<Button icon={<CopyRegular />} />
|
52
|
+
</Tooltip>
|
53
|
+
```
|
50
54
|
|
51
|
-
|
52
|
-
- A render function that takes the extra props to be added to the trigger element.
|
55
|
+
Description tooltip for a link:
|
53
56
|
|
54
57
|
```tsx
|
55
|
-
<
|
56
|
-
<a href="http://example.com">
|
57
|
-
|
58
|
-
|
59
|
-
</TooltipTrigger>
|
60
|
-
|
61
|
-
<TooltipTrigger tooltip="Label for an icon button" type="label">
|
62
|
-
<button href="http://example.com">
|
63
|
-
<SomeIcon />
|
64
|
-
</button>
|
65
|
-
</TooltipTrigger>
|
58
|
+
<Tooltip content="This is an example" relationship="description">
|
59
|
+
<a href="http://example.com">A link</a>
|
60
|
+
</Tooltip>
|
61
|
+
```
|
66
62
|
|
67
|
-
|
68
|
-
<ThirdPartyComponent />
|
69
|
-
</TooltipTrigger>
|
63
|
+
Tooltip with custom JSX content:
|
70
64
|
|
71
|
-
|
65
|
+
```tsx
|
66
|
+
<Tooltip content={<b>The content can be JSX</b>} relationship="label">
|
67
|
+
<Button />
|
68
|
+
</Tooltip>
|
69
|
+
```
|
70
|
+
|
71
|
+
Custom component as a trigger:
|
72
|
+
|
73
|
+
```tsx
|
74
|
+
<Tooltip content="Supports any component that accepts HTML attributes" relationship="label">
|
75
|
+
<FancyButton />
|
76
|
+
</Tooltip>
|
77
|
+
```
|
78
|
+
|
79
|
+
Render function for the trigger:
|
80
|
+
|
81
|
+
```tsx
|
82
|
+
<Tooltip content="The child can be a render function" relationship="description">
|
72
83
|
{triggerProps => (
|
73
84
|
<>
|
74
85
|
<div>
|
@@ -76,34 +87,37 @@ TooltipTrigger only supports a single child element, which can be either:
|
|
76
87
|
</div>
|
77
88
|
</>
|
78
89
|
)}
|
79
|
-
</
|
90
|
+
</Tooltip>
|
91
|
+
```
|
80
92
|
|
81
|
-
|
93
|
+
```tsx
|
94
|
+
<Tooltip
|
95
|
+
content="It can target an element other than its trigger"
|
96
|
+
relationship="description"
|
97
|
+
positioning={{ target: targetElement }}
|
98
|
+
>
|
82
99
|
<button>
|
83
|
-
Custom target:{
|
84
|
-
<div ref={targetRef} style={{ display: 'inline-block', width: '8px', height: '8px', background: 'red' }} />
|
100
|
+
Custom target: <div ref={setTargetElement} />
|
85
101
|
</button>
|
86
|
-
</
|
102
|
+
</Tooltip>
|
87
103
|
```
|
88
104
|
|
89
105
|
# Variants
|
90
106
|
|
91
|
-
- The tooltip
|
92
|
-
- The tooltip
|
107
|
+
- The tooltip supports higher contrast colors with `appearance="inverted"`.
|
108
|
+
- The tooltip supports rendering an arrow pointing to the target element, using `withArrow`.
|
93
109
|
|
94
110
|
# API
|
95
111
|
|
96
|
-
|
112
|
+
To attach a tooltip to an element, wrap it with a `Tooltip`. There is a `content` slot for the text of the tooltip itself.
|
113
|
+
|
114
|
+
Unlike most components, Tooltip doesn't have a root slot and doesn't allow native DOM props on the Tooltip itself. This is because it doesn't render any nodes inline around its trigger (it does _not_ wrap the element with a `<div>` for example). Instead, it attaches listeners to the child by cloning the JSX object and adding `onPointerEnter`, etc. listeners.
|
97
115
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
- [`TooltipTrigger`](#tooltiptrigger)
|
104
|
-
- [**@fluentui/react-tooltip**](#fluentuireact-tooltip)
|
105
|
-
- [`Tooltip`](#tooltip)
|
106
|
-
- [`TooltipProvider`](#tooltipprovider)
|
116
|
+
Tooltip only supports a single child element, which can be either:
|
117
|
+
|
118
|
+
- A native element or component that supports DOM attributes (the child can't be a string, for example).
|
119
|
+
- A render function that takes the extra props to be added to the trigger element.
|
120
|
+
- It is allowed to have a tooltip without a child (trigger) element, in which case it _must_ have a target set via the `positioning` prop, and its visibility must be controlled with the `visible` prop.
|
107
121
|
|
108
122
|
_A note about the terminology used for the elements that the tooltip is attached to:_
|
109
123
|
|
@@ -111,400 +125,250 @@ _A note about the terminology used for the elements that the tooltip is attached
|
|
111
125
|
- _The **target** is the element that the tooltip is anchored to (and the arrow points to)._
|
112
126
|
- _Almost always, these will both be the same element, but it is possible to specify them separately, so the tooltip can show up adjacent to a different element than the one that triggered it._
|
113
127
|
|
114
|
-
##
|
115
|
-
|
116
|
-
`react-tooltip-trigger` is a lightweight package that allows any component to add a tooltip without taking a dependency on the full `react-tooltip` package. It provides the basic functionality to render the tooltip; but it will only work if the `TooltipProvider` context is present.
|
128
|
+
## Types
|
117
129
|
|
118
|
-
###
|
130
|
+
### `Tooltip`
|
119
131
|
|
120
|
-
|
132
|
+
From [Tooltip.types.tsx](https://github.com/microsoft/fluentui/blob/master/packages/react-tooltip/src/components/Tooltip/Tooltip.types.tsx) in `@fluentui/react-tooltip`:
|
121
133
|
|
122
134
|
```ts
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
* but the tooltip may be flipped to the other side if there is not enough room.
|
128
|
-
*
|
129
|
-
* @defaultvalue above
|
130
|
-
*/
|
131
|
-
position?: 'above' | 'below' | 'before' | 'after';
|
132
|
-
|
133
|
-
/**
|
134
|
-
* How to align the tooltip along the edge of the target element.
|
135
|
-
*
|
136
|
-
* @defaultvalue center
|
137
|
-
*/
|
138
|
-
align?: 'top' | 'bottom' | 'start' | 'end' | 'center';
|
139
|
-
|
140
|
-
/**
|
141
|
-
* Color variant with a subtle look
|
142
|
-
*/
|
143
|
-
subtle?: boolean;
|
144
|
-
|
145
|
-
/**
|
146
|
-
* Do not render an arrow pointing to the target element
|
147
|
-
*/
|
148
|
-
noArrow?: boolean;
|
149
|
-
|
150
|
-
/**
|
151
|
-
* Distance between the tooltip and the target element, in pixels
|
152
|
-
*
|
153
|
-
* @defaultvalue 4
|
154
|
-
*/
|
155
|
-
offset?: number;
|
156
|
-
|
157
|
-
/**
|
158
|
-
* The arrow that points to the target element. This will be rendered by default unless `noArrow` is specified.
|
159
|
-
*/
|
160
|
-
arrow?: ShorthandProps<React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement>>;
|
161
|
-
|
162
|
-
/**
|
163
|
-
* Imperative handle to show and hide the tooltip
|
164
|
-
*/
|
165
|
-
componentRef?: React.Ref<TooltipImperativeHandle>;
|
166
|
-
};
|
167
|
-
```
|
168
|
-
|
169
|
-
### TooltipImperativeHandle
|
170
|
-
|
171
|
-
The `TooltipImperativeHandle` is the imperative API used by `TooltipManager` to show and hide the tooltip.
|
172
|
-
|
173
|
-
```ts
|
174
|
-
export interface TooltipImperativeHandle {
|
135
|
+
/**
|
136
|
+
* Slot properties for Tooltip
|
137
|
+
*/
|
138
|
+
export type TooltipSlots = {
|
175
139
|
/**
|
176
|
-
*
|
140
|
+
* The text or JSX content of the tooltip.
|
177
141
|
*/
|
178
|
-
|
142
|
+
content: NonNullable<Slot<'div'>>;
|
143
|
+
};
|
179
144
|
|
145
|
+
/**
|
146
|
+
* Properties for Tooltip
|
147
|
+
*/
|
148
|
+
export type TooltipProps = ComponentProps<TooltipSlots> & {
|
180
149
|
/**
|
181
|
-
*
|
150
|
+
* (Required) Specifies whether this tooltip is acting as the description or label of its trigger element.
|
151
|
+
*
|
152
|
+
* * `label` - The tooltip sets the trigger's aria-label or aria-labelledby attribute. This is useful for buttons
|
153
|
+
* displaying only an icon, for example.
|
154
|
+
* * `description` - The tooltip sets the trigger's aria-description or aria-describedby attribute.
|
155
|
+
* * `inaccessible` - No aria attributes are set on the trigger. This makes the tooltip's content inaccessible to
|
156
|
+
* screen readers, and should only be used if the tooltip's text is available by some other means.
|
182
157
|
*/
|
183
|
-
|
158
|
+
relationship: 'label' | 'description' | 'inaccessible';
|
184
159
|
|
185
160
|
/**
|
186
|
-
*
|
161
|
+
* The tooltip can have a single JSX child, or a render function that accepts TooltipTriggerProps.
|
162
|
+
*
|
163
|
+
* If no child is provided, the tooltip's target must be set with the `positioning` prop, and its
|
164
|
+
* visibility must be controlled with the `visible` prop.
|
187
165
|
*/
|
188
|
-
|
189
|
-
}
|
190
|
-
|
191
|
-
|
192
|
-
### TooltipManager
|
193
|
-
|
194
|
-
The `TooltipManager` is responsible for managing the visibiltiy of the tooltips, including ensuring that only one tooltip is visible at once, and handling the delay to show or hide a tooltip.
|
195
|
-
|
196
|
-
This imperative interface is implemented by `TooltipProvider`, and used by `TooltipTrigger` to show and hide its tooltip based on events on the trigger element.
|
197
|
-
|
198
|
-
```ts
|
199
|
-
/**
|
200
|
-
* The tooltip manager is responsible for managing the visibiltiy of the tooltips,
|
201
|
-
* including ensuring that only one tooltip is visible at once, and handling the
|
202
|
-
* delay to show or hide a tooltip.
|
203
|
-
*
|
204
|
-
* This imperative interface is used by TooltipTrigger to show and hide its tooltip
|
205
|
-
* based on events on the trigger element.
|
206
|
-
*/
|
207
|
-
export interface TooltipManager {
|
208
|
-
showTooltip: (args: ShowTooltipArgs, reason: TooltipTriggerReason) => void;
|
209
|
-
hideTooltip: (trigger: HTMLElement, reason: TooltipTriggerReason) => void;
|
210
|
-
|
211
|
-
hideAll: () => void;
|
212
|
-
|
213
|
-
onPointerEnterTooltip: (tooltipRoot: HTMLElement) => void;
|
214
|
-
onPointerLeaveTooltip: (tooltipRoot: HTMLElement) => void;
|
215
|
-
}
|
216
|
-
|
217
|
-
/**
|
218
|
-
* The arguments to TooltipManager.showTooltip
|
219
|
-
*/
|
220
|
-
export type ShowTooltipArgs = {
|
221
|
-
tooltip: TooltipImperativeHandle;
|
222
|
-
trigger: HTMLElement;
|
223
|
-
target: HTMLElement;
|
224
|
-
showDelay: number;
|
225
|
-
hideDelay: number;
|
226
|
-
onlyIfTruncated?: boolean;
|
227
|
-
};
|
228
|
-
|
229
|
-
/**
|
230
|
-
* The source of the event that caused the tooltip to be shown or hidden
|
231
|
-
*/
|
232
|
-
export type TooltipTriggerReason = 'focus' | 'pointer';
|
233
|
-
```
|
234
|
-
|
235
|
-
### useTooltipContext
|
236
|
-
|
237
|
-
The tooltip hooks get the actual implementation of the TooltipManagerApi and Tooltip renderer via React context. By default this is `undefined`, and requires a `TooltipProvider` to provide the actual implementations.
|
238
|
-
|
239
|
-
```ts
|
240
|
-
export type TooltipContext = {
|
241
|
-
Tooltip: React.FC<TooltipProps & React.RefAttributes<HTMLElement>>;
|
242
|
-
manager: TooltipManager | undefined;
|
243
|
-
portalRoot: HTMLElement;
|
244
|
-
};
|
166
|
+
children?:
|
167
|
+
| (React.ReactElement & { ref?: React.Ref<unknown> })
|
168
|
+
| ((props: TooltipTriggerProps) => React.ReactElement | null)
|
169
|
+
| null;
|
245
170
|
|
246
|
-
export const internal__TooltipContext = React.createContext<TooltipContext>({
|
247
|
-
// These default values are replaced by TooltipProvider
|
248
|
-
Tooltip: () => null,
|
249
|
-
manager: undefined,
|
250
|
-
portalRoot: document.body,
|
251
|
-
});
|
252
|
-
|
253
|
-
export const useTooltipContext = () => React.useContext(internal__TooltipContext);
|
254
|
-
```
|
255
|
-
|
256
|
-
### TooltipTrigger
|
257
|
-
|
258
|
-
`TooltipTrigger` allows tooltips to be added to any focusable component that doesn't have its own `tooltip` prop. It supports a single JSX child, and works by cloning the JSX element in order to add the same `onPointerDown`, etc. listeners that are added by `useTooltipSlot`.
|
259
|
-
|
260
|
-
```ts
|
261
|
-
export type TooltipTriggerProps
|
262
|
-
= Pick<TooltipProps, 'position' | 'align' | 'subtle' | 'noArrow' | 'offset'> & {
|
263
171
|
/**
|
264
|
-
* The
|
265
|
-
*
|
266
|
-
*
|
267
|
-
*
|
172
|
+
* The tooltip's visual appearance.
|
173
|
+
* * `normal` - Uses the theme's background and text colors.
|
174
|
+
* * `inverted` - Higher contrast variant that uses the theme's inverted colors.
|
175
|
+
*
|
176
|
+
* @defaultvalue normal
|
268
177
|
*/
|
269
|
-
|
270
|
-
| React.ReactElement<React.HTMLAttributes<HTMLElement>>
|
271
|
-
| ((props: TooltipTriggerChildProps) => React.ReactNode);
|
178
|
+
appearance?: 'normal' | 'inverted';
|
272
179
|
|
273
180
|
/**
|
274
|
-
*
|
181
|
+
* Render an arrow pointing to the target element
|
182
|
+
*
|
183
|
+
* @defaultvalue false
|
275
184
|
*/
|
276
|
-
|
185
|
+
withArrow?: boolean;
|
277
186
|
|
278
187
|
/**
|
279
|
-
*
|
280
|
-
* This determines whether to set aria-describedby or aria-labelledby on the trigger element.
|
188
|
+
* Configure the positioning of the tooltip
|
281
189
|
*
|
282
|
-
* @defaultvalue
|
190
|
+
* @defaultvalue above
|
283
191
|
*/
|
284
|
-
|
192
|
+
positioning?: PositioningShorthand;
|
285
193
|
|
286
194
|
/**
|
287
|
-
*
|
195
|
+
* Control the tooltip's visibility programatically.
|
288
196
|
*
|
289
|
-
*
|
197
|
+
* This can be used in conjunction with onVisibleChange to modify the tooltip's show and hide behavior.
|
198
|
+
*
|
199
|
+
* If not provided, the visibility will be controlled by the tooltip itself, based on hover and focus events on the
|
200
|
+
* trigger (child) element.
|
290
201
|
*/
|
291
|
-
|
202
|
+
visible?: boolean;
|
292
203
|
|
293
204
|
/**
|
294
|
-
*
|
295
|
-
*
|
296
|
-
* @defaultvalue 250
|
205
|
+
* Notification when the visibility of the tooltip is changing
|
297
206
|
*/
|
298
|
-
|
207
|
+
onVisibleChange?: (
|
208
|
+
event: React.PointerEvent<HTMLElement> | React.FocusEvent<HTMLElement> | undefined,
|
209
|
+
data: OnVisibleChangeData,
|
210
|
+
) => void;
|
299
211
|
|
300
212
|
/**
|
301
|
-
*
|
213
|
+
* Delay before the tooltip is shown, in milliseconds.
|
214
|
+
*
|
215
|
+
* @defaultvalue 250
|
302
216
|
*/
|
303
|
-
|
217
|
+
showDelay?: number;
|
304
218
|
|
305
219
|
/**
|
306
|
-
*
|
220
|
+
* Delay before the tooltip is hidden, in milliseconds.
|
307
221
|
*
|
308
|
-
*
|
222
|
+
* @defaultvalue 250
|
309
223
|
*/
|
310
|
-
|
311
|
-
}
|
224
|
+
hideDelay?: number;
|
225
|
+
};
|
312
226
|
|
313
227
|
/**
|
314
|
-
* The
|
228
|
+
* The properties that are added to the trigger of the Tooltip
|
315
229
|
*/
|
316
|
-
export type
|
230
|
+
export type TooltipTriggerProps = {
|
231
|
+
ref?: React.Ref<never>;
|
232
|
+
} & Pick<
|
317
233
|
React.HTMLAttributes<HTMLElement>,
|
318
|
-
'onPointerEnter' | 'onPointerLeave' | 'onFocus' | 'onBlur' | 'aria-describedby' | 'aria-labelledby'
|
234
|
+
'onPointerEnter' | 'onPointerLeave' | 'onFocus' | 'onBlur' | 'aria-describedby' | 'aria-labelledby' | 'aria-label'
|
319
235
|
>;
|
320
236
|
|
321
237
|
/**
|
322
|
-
*
|
323
|
-
*/
|
324
|
-
export type TooltipTriggerShorthandProps = typeof tooltipTriggerShorthandProps[number];
|
325
|
-
|
326
|
-
/**
|
327
|
-
* Names of TooltipTriggerProps that have a default value in useTooltipTrigger
|
238
|
+
* Data for the Tooltip's onVisibleChange event.
|
328
239
|
*/
|
329
|
-
export type
|
330
|
-
|
331
|
-
|
332
|
-
ResolvedShorthandProps<
|
333
|
-
TooltipTriggerProps & {
|
334
|
-
manager: TooltipManager | undefined;
|
335
|
-
portalRoot: HTMLElement;
|
336
|
-
tooltipRef: React.MutableRefObject<TooltipImperativeHandle | null>;
|
337
|
-
},
|
338
|
-
TooltipTriggerShorthandProps
|
339
|
-
>,
|
340
|
-
TooltipTriggerDefaultedProps
|
240
|
+
export type OnVisibleChangeData = {
|
241
|
+
visible: boolean;
|
242
|
+
};
|
341
243
|
```
|
342
244
|
|
343
|
-
|
344
|
-
|
345
|
-
The `react-tooltip` package contains the bulk of the implementation of tooltips, including rendering, styling, positioning, lifetime management, etc.
|
245
|
+
### `TooltipContext`
|
346
246
|
|
347
|
-
|
247
|
+
The context is included at the app root on `FluentProvider` and is used by `Tooltip` to ensure that only one is visible at once.
|
348
248
|
|
349
|
-
|
350
|
-
|
351
|
-
The `TooltipProps` interface is defined in the `react-tooltip-trigger` package.
|
249
|
+
From [TooltipContext.ts](https://github.com/microsoft/fluentui/blob/master/packages/react-shared-contexts/src/TooltipContext/TooltipContext.ts) in `@fluentui/react-shared-contexts`:
|
352
250
|
|
353
251
|
```ts
|
354
|
-
import { TooltipProps } from '@fluentui/react-tooltip-trigger';
|
355
|
-
|
356
|
-
export { TooltipProps };
|
357
|
-
|
358
252
|
/**
|
359
|
-
*
|
253
|
+
* The context provided by TooltipProvider
|
360
254
|
*/
|
361
|
-
export type
|
255
|
+
export type TooltipContextType = {
|
256
|
+
/**
|
257
|
+
* When a tooltip is shown, it sets itself as the visibleTooltip.
|
258
|
+
* The next tooltip to become visible can use it to hide the previous tooltip immediately.
|
259
|
+
*/
|
260
|
+
visibleTooltip?: {
|
261
|
+
hide: () => void;
|
262
|
+
};
|
263
|
+
};
|
362
264
|
|
363
265
|
/**
|
364
|
-
*
|
266
|
+
* Context shared by all of the tooltips in the app
|
365
267
|
*/
|
366
|
-
export
|
367
|
-
|
368
|
-
export type TooltipState = ComponentState<
|
369
|
-
React.Ref<HTMLElement>,
|
370
|
-
TooltipProps & {
|
371
|
-
visible: boolean;
|
372
|
-
},
|
373
|
-
TooltipShorthandProps,
|
374
|
-
TooltipDefaultedProps
|
375
|
-
>;
|
376
|
-
```
|
377
|
-
|
378
|
-
### TooltipProvider
|
379
|
-
|
380
|
-
`TooltipProvider` is responsible for providing the actual implementation of `TooltipManager` and `Tooltip`. It uses a React context to that contains those when it is included in the tree. This context will also be included into `FluentContext`.
|
381
|
-
|
382
|
-
```ts
|
383
|
-
export type TooltipProviderProps = ComponentProps &
|
384
|
-
React.HTMLAttributes<HTMLElement> & {
|
385
|
-
// TooltipProvider has no additional props
|
386
|
-
};
|
387
|
-
|
388
|
-
export type TooltipProviderState = ComponentState<
|
389
|
-
React.RefObject<HTMLElement>,
|
390
|
-
TooltipProviderProps & {
|
391
|
-
manager: TooltipManager;
|
392
|
-
portalRoot: HTMLElement;
|
393
|
-
}
|
394
|
-
>;
|
268
|
+
export const TooltipContext = React.createContext<TooltipContextType>({});
|
395
269
|
```
|
396
270
|
|
397
271
|
# Structure
|
398
272
|
|
399
|
-
##
|
273
|
+
## Tooltip as a label
|
274
|
+
|
275
|
+
### JSX tree
|
400
276
|
|
401
277
|
```tsx
|
402
|
-
<
|
403
|
-
<
|
404
|
-
<
|
405
|
-
</
|
406
|
-
|
407
|
-
<button>...</button>
|
408
|
-
</TooltipTrigger>
|
409
|
-
</TooltipProvider>
|
278
|
+
<Tooltip content="Example" relationship="label">
|
279
|
+
<button>
|
280
|
+
<svg>...</svg>
|
281
|
+
</button>
|
282
|
+
</Tooltip>
|
410
283
|
```
|
411
284
|
|
412
|
-
|
285
|
+
### DOM
|
413
286
|
|
414
|
-
|
287
|
+
Tooltip with `relationship="label"` is not rendered when it is not visible. Its content is used as the `aria-label` of the control. The Tooltip will be rendered once it is visible; see the next example for what the DOM structure looks like in that case.
|
415
288
|
|
416
|
-
```
|
289
|
+
```html
|
417
290
|
<body>
|
418
|
-
|
419
|
-
|
420
|
-
<button aria-
|
421
|
-
|
422
|
-
|
423
|
-
<div role="tooltip" id="tooltip-1" {/* Tooltip */}>
|
424
|
-
<div {/* Arrow */} />
|
425
|
-
Example tooltip
|
426
|
-
</div>
|
427
|
-
<div role="tooltip" id="tooltip-2" class="... (display: none) ..." {/* Tooltip */}>
|
428
|
-
<div {/* Arrow */} />
|
429
|
-
Button with a tooltip for a label
|
430
|
-
</div>
|
431
|
-
</div>
|
291
|
+
<!-- App root -->
|
292
|
+
<div>
|
293
|
+
<button aria-label="Example" onPointerEnter="{...}" onPointerLeave="{...}" onFocus="{...}" onBlur="{...}">
|
294
|
+
<svg>...</svg>
|
295
|
+
</button>
|
432
296
|
</div>
|
433
297
|
</body>
|
434
298
|
```
|
435
299
|
|
436
|
-
##
|
300
|
+
## Tooltip as a description
|
437
301
|
|
438
|
-
|
302
|
+
### JSX tree
|
439
303
|
|
440
304
|
```tsx
|
441
|
-
<
|
442
|
-
|
443
|
-
|
444
|
-
portalRoot: state.portalRoot,
|
445
|
-
Tooltip,
|
446
|
-
}}
|
447
|
-
>
|
448
|
-
{children}
|
449
|
-
<slots.root {...rootProps} />
|
450
|
-
</internal__TooltipContext.Provider>
|
305
|
+
<Tooltip content="Example description of the button" relationship="description" withArrow>
|
306
|
+
<button>The Button</button>
|
307
|
+
</Tooltip>
|
451
308
|
```
|
452
309
|
|
453
|
-
|
454
|
-
|
455
|
-
```tsx
|
456
|
-
<slots.root {...slotProps.root}>
|
457
|
-
<slots.arrow {...slotProps.arrow} />
|
458
|
-
{state.children}
|
459
|
-
</slots.root>
|
460
|
-
```
|
310
|
+
### DOM
|
461
311
|
|
462
|
-
`
|
312
|
+
Tooltip with `relationship="description"` is always rendered because it's used as the `aria-describedby` of the control, which always has to point to a valid DOM element even if it's not visible.
|
463
313
|
|
464
|
-
|
314
|
+
```html
|
315
|
+
<body>
|
316
|
+
<!-- App root -->
|
317
|
+
<div>
|
318
|
+
<button aria-describedby="tooltip-2" onPointerEnter="{...}" onPointerLeave="{...}" onFocus="{...}" onBlur="{...}">
|
319
|
+
The Button
|
320
|
+
</button>
|
321
|
+
</div>
|
465
322
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
323
|
+
<!-- Portal for Tooltip -->
|
324
|
+
<div>
|
325
|
+
<div role="tooltip" id="tooltip-2" class="{tooltip}">
|
326
|
+
<div class="{arrow}"></div>
|
327
|
+
Example description of the button
|
328
|
+
</div>
|
329
|
+
</div>
|
330
|
+
</body>
|
471
331
|
```
|
472
332
|
|
473
333
|
# Migration
|
474
334
|
|
475
|
-
See MIGRATION.md.
|
335
|
+
See [MIGRATION.md](./MIGRATION.md).
|
476
336
|
|
477
337
|
# Behaviors
|
478
338
|
|
479
|
-
|
480
|
-
|
481
|
-
- There is only ever one tooltip visible at once.
|
482
|
-
- The tooltip shows 250ms (by default) after the trigger element receives either mouse/pointer hover or keyboard focus, with the following exceptions:
|
483
|
-
- If another tooltip is currently visible, the new tooltip will immediately replace the old one without any delay.
|
484
|
-
- If `onlyIfTruncated` is true, then the tooltip will only show if the target element's content is overflowing.
|
485
|
-
- The tooltip hides 250ms (by default) after the trigger element loses focus, with the following exceptions:
|
486
|
-
- The tooltip will not hide if the pointer is hovering on the tooltip itself
|
487
|
-
- If the tooltip was triggered by getting focus, then moving the mouse out of the element won't hide it (it'll hide when the element loses focus, or another tooltip is triggered).
|
488
|
-
- The tooltip hides immediately when the user presses Esc.
|
339
|
+
## Visibility
|
489
340
|
|
490
|
-
-
|
341
|
+
- The tooltip shows:
|
342
|
+
- After `showDelay` (250ms default) from when the mouse/pointer enters the trigger.
|
343
|
+
- After `showDelay` (250ms default) from when the trigger gets keyboard focus.
|
344
|
+
- _Immediately_ (ignoring `showDelay`) if it is triggered while another tooltip is currently visible.
|
345
|
+
- The tooltip hides:
|
346
|
+
- After `hideDelay` (250ms default) from when the mouse/pointer leaves BOTH the trigger AND the tooltip itself.
|
347
|
+
- _Immediately_ when the trigger loses keyboard focus.
|
348
|
+
- _Immediately_ when the ESC key is pressed.
|
349
|
+
- _Immediately_ when another tooltip is shown.
|
491
350
|
|
492
|
-
|
493
|
-
- The placement is handled by the react-positioning package, which uses PopperJS.
|
351
|
+
There is only ever one tooltip visible at once (coordinated using `TooltipContext`). If another tooltip is triggered while there's one currently visible, the previous one hides and the new one shows immediately, without delay.
|
494
352
|
|
495
|
-
|
353
|
+
### Placement
|
496
354
|
|
497
|
-
|
355
|
+
The tooltip is placed relative to its target element based on the `positioning` prop. The placement is handled by the `@fluentui/react-positioning` package, which uses PopperJS.
|
498
356
|
|
499
|
-
|
357
|
+
### Focus
|
500
358
|
|
501
|
-
|
359
|
+
Content within the tooltip is not focusable, and can't be interacted with directly by keyboard or mouse.
|
502
360
|
|
503
361
|
# Accessibility
|
504
362
|
|
505
|
-
- ARIA design pattern:
|
506
|
-
- The Tooltip
|
507
|
-
-
|
508
|
-
- The
|
363
|
+
- ARIA design pattern: https://www.w3.org/TR/wai-aria-practices-1.2/#tooltip.
|
364
|
+
- The Tooltip content element has `role="tooltip"`.
|
365
|
+
- If Tooltip has `relationship="label"` with simple string content:
|
366
|
+
- The content is set as the trigger's `aria-label`.
|
367
|
+
- The tooltip is only rendered while it is visible.
|
368
|
+
- If Tooltip has `relationship="label"` with JSX content, OR `relationship="description"` (string or JSX):
|
369
|
+
- The tooltip's ID is set as the trigger's `aria-labelledby` or `aria-describedby` (an ID is generated if not provided).
|
370
|
+
- The tooltip is always rendered, even while hidden.
|
371
|
+
- While hidden, the tooltip itself is styled with `display: none`.
|
509
372
|
- The Tooltip itself can never receive focus.
|
510
373
|
- The Tooltip should never contain focusable elements.
|
374
|
+
- The trigger for the Tooltip should be focusable.
|