@justeattakeaway/pie-tooltip 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +190 -7
- package/custom-elements.json +186 -1
- package/dist/index.d.ts +32 -2
- package/dist/index.js +256 -132
- package/dist/react.d.ts +33 -2
- package/dist/react.js +16 -12
- package/package.json +6 -6
- package/src/defs.ts +13 -1
- package/src/index.ts +325 -29
- package/src/react.ts +3 -1
- package/src/tooltip.scss +46 -2
package/README.md
CHANGED
|
@@ -35,11 +35,11 @@ Ideally, you should install the component using the **`@justeattakeaway/pie-webc
|
|
|
35
35
|
|
|
36
36
|
### Controlled component
|
|
37
37
|
|
|
38
|
-
`pie-tooltip` is a controlled component. It never writes to its own `isOpen
|
|
38
|
+
`pie-tooltip` is a controlled component. It never writes to its own `isOpen`, and it never opens or closes itself.
|
|
39
39
|
|
|
40
40
|
1. You own `isOpen`.
|
|
41
|
-
2. You listen for `pie-tooltip-close`.
|
|
42
|
-
3. You pass the value back.
|
|
41
|
+
2. You listen for `pie-tooltip-open` and `pie-tooltip-close`.
|
|
42
|
+
3. You pass the value back to open/close the tooltip.
|
|
43
43
|
|
|
44
44
|
### Properties
|
|
45
45
|
|
|
@@ -55,6 +55,7 @@ Ideally, you should install the component using the **`@justeattakeaway/pie-webc
|
|
|
55
55
|
| `heading` | Any string | The text to display in the panel's heading. In dialog mode this also provides the panel's accessible name. | `undefined` |
|
|
56
56
|
| `headingLevel` | `h2`, `h3`, `h4`, `h5`, `h6` | The HTML heading tag to use for the panel's heading. | `h2` |
|
|
57
57
|
| `aria` | `{ close?: string, label?: string }` | `close` names the close button. `label` names the panel in dialog mode when no `heading` is provided. | `undefined` |
|
|
58
|
+
| `triggers` | Array of `hover`, `focus`, `click` | Which interactions request that the panel opens and closes. A configured interaction emits an event; it never changes the panel's state on its own. Empty by default, so no interaction is watched at all. Configure `hover` and `focus` together for keyboard reachability. | `[]` |
|
|
58
59
|
|
|
59
60
|
### Slots
|
|
60
61
|
|
|
@@ -67,7 +68,8 @@ Ideally, you should install the component using the **`@justeattakeaway/pie-webc
|
|
|
67
68
|
|
|
68
69
|
| Event | Type | Description |
|
|
69
70
|
|---|---|---|
|
|
70
|
-
| `pie-tooltip-
|
|
71
|
+
| `pie-tooltip-open` | `Event` | Emitted when a configured trigger asks for the panel. Set `isOpen` to `true` in response. Bubbles and is composed. |
|
|
72
|
+
| `pie-tooltip-close` | `Event` | Emitted when the close button is clicked, or when a configured trigger asks to dismiss the panel. Set `isOpen` to `false` in response. Bubbles and is composed. |
|
|
71
73
|
|
|
72
74
|
### CSS Variables
|
|
73
75
|
|
|
@@ -84,7 +86,7 @@ Set both on the `pie-tooltip` element itself.
|
|
|
84
86
|
|
|
85
87
|
## Positioning
|
|
86
88
|
|
|
87
|
-
|
|
89
|
+
Place the tooltip next to its trigger element in the DOM for the best accessibility practice. The `position` element will place the tooltip near to the trigger based on which value is provided.
|
|
88
90
|
|
|
89
91
|
`position` names a side and, optionally, an alignment along the opposite axis:
|
|
90
92
|
|
|
@@ -95,7 +97,7 @@ left left-start left-end
|
|
|
95
97
|
right right-start right-end
|
|
96
98
|
```
|
|
97
99
|
|
|
98
|
-
In right-to-left languages, everything on the inline axis mirrors. The alignments follow the reading direction, so `top-start` aligns against the right-hand edge, and `left` and `right` swap: a panel asked for on the left appears on the right. The `-start` and `-end` alignments of `left` and `right` are on the block axis, which has no direction to mirror, so only the side moves.
|
|
100
|
+
In right-to-left languages, everything on the inline axis mirrors. The alignments follow the reading direction, so `top-start` aligns against the right-hand edge, and `left` and `right` swap: a panel asked for on the left appears on the right. The `-start` and `-end` alignments of `left` and `right` are on the block axis, which has no direction to mirror, so only the side moves.
|
|
99
101
|
|
|
100
102
|
## Sizing
|
|
101
103
|
|
|
@@ -131,8 +133,12 @@ A close button does not make the panel a dialog. Only the `action` slot does.
|
|
|
131
133
|
- Keeps the panel clear of the trigger at every placement, so the panel cannot obscure a focused trigger (WCAG 2.4.11).
|
|
132
134
|
- Wraps content.
|
|
133
135
|
|
|
136
|
+
It does not touch the trigger, and it does not move focus. The component never writes attributes to the element named by `trigger`, and never calls `focus()` on anything. Both are yours to declare: see [Wiring the trigger](#wiring-the-trigger) and [Managing focus](#managing-focus).
|
|
137
|
+
|
|
134
138
|
### What you need to do
|
|
135
139
|
|
|
140
|
+
- **Wire the trigger yourself.** The ARIA attributes that connect the trigger to the panel are yours to set. See [Wiring the trigger](#wiring-the-trigger) for what to set and when.
|
|
141
|
+
- **Move focus yourself in dialog mode.** The panel holds focusable content, so opening it should move focus in and closing it should put focus back. See [Managing focus](#managing-focus).
|
|
136
142
|
- **Give the trigger its own accessible name.** The tooltip is a description and never supplies a name. An icon-only trigger must set its own label; `pie-icon-button` already requires `aria.label`.
|
|
137
143
|
- **Use a natively interactive element as the trigger**, a button or a link, so focus and click behave correctly.
|
|
138
144
|
- **Own `isOpen`.** Listen for `pie-tooltip-close` and set `isOpen` to `false` in response.
|
|
@@ -142,6 +148,167 @@ A close button does not make the panel a dialog. Only the `action` slot does.
|
|
|
142
148
|
- **Provide a translated `aria.close`** whenever `isDismissible` is set.
|
|
143
149
|
- **Keep tooltip-mode content short and supplementary.** Anything essential or interactive belongs in dialog mode, or inline in the page.
|
|
144
150
|
|
|
151
|
+
### Wiring the trigger
|
|
152
|
+
|
|
153
|
+
The trigger lives outside the tooltip and the component leaves it untouched, so you declare the relationship. What to set depends on the mode.
|
|
154
|
+
|
|
155
|
+
| ARIA | Set it when | Value |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| `haspopup` | Dialog mode, so the trigger announces that it opens a dialog | `dialog` |
|
|
158
|
+
| `expanded` | You toggle the panel from the trigger with a click or a tap | Your `isOpen` value |
|
|
159
|
+
| `describedby` | Tooltip mode, and the trigger is a plain HTML element | The `id` of the element you put in the `content` slot |
|
|
160
|
+
|
|
161
|
+
Leave `expanded` off a hover-only or focus-only panel. Nothing is being toggled, so it has nothing to describe. There is no `controls` in the table because it adds nothing here: the description already carries the relationship, and support for it is patchy.
|
|
162
|
+
|
|
163
|
+
#### A description cannot cross a shadow boundary
|
|
164
|
+
|
|
165
|
+
`aria.describedby` takes an `id`, and an `id` only resolves inside the tree of the element that references it. The element you put in the `content` slot stays in your light DOM, so a plain `<button>` in the same document resolves it. The `<button>` inside `pie-icon-button` does not: it cannot see an `id` in your document, so `aria.describedby` is unusable for this purpose even though the property exists.
|
|
166
|
+
|
|
167
|
+
There is no way around this from outside the component. When the trigger is a PIE component and the panel is a plain tooltip, put the information in the trigger's name with `aria.label` instead, as in the first example below. It is the only route that reaches a screen reader.
|
|
168
|
+
|
|
169
|
+
Dialog mode is unaffected, because the panel is named by `heading` and needs no description at all.
|
|
170
|
+
|
|
171
|
+
#### A tooltip panel on an icon trigger
|
|
172
|
+
|
|
173
|
+
`hover` and `focus` together give the panel to both pointer and keyboard users. Nothing is toggled, so there is no `expanded`, and the name carries the content because a description cannot reach the button inside the trigger.
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
// main.js
|
|
177
|
+
import '@justeattakeaway/pie-webc/components/tooltip.js';
|
|
178
|
+
import '@justeattakeaway/pie-webc/components/icon-button.js';
|
|
179
|
+
import '@justeattakeaway/pie-icons-webc/dist/IconInfoCircle.js';
|
|
180
|
+
|
|
181
|
+
const trigger = document.querySelector('#delivery-info');
|
|
182
|
+
const panel = document.querySelector('#delivery-panel');
|
|
183
|
+
|
|
184
|
+
trigger.aria = { label: 'Delivery times: orders placed before 6pm arrive today' };
|
|
185
|
+
panel.triggers = ['hover', 'focus'];
|
|
186
|
+
|
|
187
|
+
panel.addEventListener('pie-tooltip-open', () => { panel.isOpen = true; });
|
|
188
|
+
panel.addEventListener('pie-tooltip-close', () => { panel.isOpen = false; });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```html
|
|
192
|
+
<script type="module" src="/main.js"></script>
|
|
193
|
+
|
|
194
|
+
<pie-icon-button id="delivery-info" variant="outline">
|
|
195
|
+
<icon-info-circle></icon-info-circle>
|
|
196
|
+
</pie-icon-button>
|
|
197
|
+
|
|
198
|
+
<pie-tooltip id="delivery-panel" trigger="delivery-info" type="icon">
|
|
199
|
+
<span slot="content">Orders placed before 6pm arrive today.</span>
|
|
200
|
+
</pie-tooltip>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The two handlers are the whole contract. Without them the panel never opens, because the component only ever asks.
|
|
204
|
+
|
|
205
|
+
#### A dialog panel toggled from the trigger
|
|
206
|
+
|
|
207
|
+
Filling the `action` slot makes the panel a dialog, so the trigger gets `haspopup` and, because a click toggles it, `expanded`. Both track the same state you already own.
|
|
208
|
+
|
|
209
|
+
```jsx
|
|
210
|
+
import { useRef, useState } from 'react';
|
|
211
|
+
import { PieButton } from '@justeattakeaway/pie-webc/react/button.js';
|
|
212
|
+
import { PieIconButton } from '@justeattakeaway/pie-webc/react/icon-button.js';
|
|
213
|
+
import { PieTooltip } from '@justeattakeaway/pie-webc/react/tooltip.js';
|
|
214
|
+
import { IconInfoCircle } from '@justeattakeaway/pie-icons-webc/dist/react/IconInfoCircle.js';
|
|
215
|
+
|
|
216
|
+
export function DeliveryTimes () {
|
|
217
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
218
|
+
const triggerRef = useRef(null);
|
|
219
|
+
const actionRef = useRef(null);
|
|
220
|
+
|
|
221
|
+
const open = () => {
|
|
222
|
+
setIsOpen(true);
|
|
223
|
+
// The panel is only focusable once it has rendered and been positioned.
|
|
224
|
+
requestAnimationFrame(() => actionRef.current?.focus({ preventScroll: true }));
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const close = () => {
|
|
228
|
+
// Only reclaim focus if it is still inside the panel. Closing on a hover-away or a
|
|
229
|
+
// click elsewhere must not yank focus from whatever the user has moved on to.
|
|
230
|
+
const panelHadFocus = document.activeElement?.closest('pie-tooltip');
|
|
231
|
+
|
|
232
|
+
setIsOpen(false);
|
|
233
|
+
|
|
234
|
+
if (panelHadFocus) {
|
|
235
|
+
triggerRef.current?.focus({ preventScroll: true });
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
return (
|
|
240
|
+
<>
|
|
241
|
+
<PieIconButton
|
|
242
|
+
id="delivery-info"
|
|
243
|
+
ref={triggerRef}
|
|
244
|
+
variant="outline"
|
|
245
|
+
aria={{
|
|
246
|
+
label: 'Delivery times',
|
|
247
|
+
haspopup: 'dialog',
|
|
248
|
+
expanded: isOpen,
|
|
249
|
+
}}>
|
|
250
|
+
<IconInfoCircle />
|
|
251
|
+
</PieIconButton>
|
|
252
|
+
|
|
253
|
+
<PieTooltip
|
|
254
|
+
trigger="delivery-info"
|
|
255
|
+
heading="Delivery times"
|
|
256
|
+
isOpen={isOpen}
|
|
257
|
+
isDismissible
|
|
258
|
+
aria={{ close: 'Close' }}
|
|
259
|
+
triggers={['click']}
|
|
260
|
+
onPieTooltipOpen={open}
|
|
261
|
+
onPieTooltipClose={close}>
|
|
262
|
+
<span slot="content">Orders placed before 6pm arrive today.</span>
|
|
263
|
+
<PieButton slot="action" size="xsmall" ref={actionRef} onClick={close}>
|
|
264
|
+
Got it
|
|
265
|
+
</PieButton>
|
|
266
|
+
</PieTooltip>
|
|
267
|
+
</>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`isDismissible` and Escape both route through `onPieTooltipClose`, so a single `close` covers the close button, Escape, a click outside and the action button.
|
|
273
|
+
|
|
274
|
+
The `closest('pie-tooltip')` check works because `document.activeElement` reports the outermost shadow host, so focus on the close button inside the panel's shadow root reads as the `pie-tooltip` element itself. Focus on your slotted action button reports that button, whose `closest` finds the same panel. One check covers both. See [Managing focus](#managing-focus).
|
|
275
|
+
|
|
276
|
+
#### Driving the panel without `triggers`
|
|
277
|
+
|
|
278
|
+
Leave `triggers` unset when the panel's timing is not an interaction with its trigger, such as a step in an onboarding tour. Nothing is watched, so `pie-tooltip-open` never fires and `expanded` has nothing to describe. The close button still emits `pie-tooltip-close`.
|
|
279
|
+
|
|
280
|
+
Escape is watched only while at least one trigger is configured, so a panel driven this way needs its own key handling if you want Escape to dismiss it.
|
|
281
|
+
|
|
282
|
+
```html
|
|
283
|
+
<template>
|
|
284
|
+
<pie-icon-button
|
|
285
|
+
id="delivery-info"
|
|
286
|
+
variant="outline"
|
|
287
|
+
:aria="{ label: 'Delivery times' }">
|
|
288
|
+
<icon-info-circle />
|
|
289
|
+
</pie-icon-button>
|
|
290
|
+
|
|
291
|
+
<pie-tooltip
|
|
292
|
+
trigger="delivery-info"
|
|
293
|
+
heading="Delivery times"
|
|
294
|
+
:isOpen="isOpen"
|
|
295
|
+
isDismissible
|
|
296
|
+
:aria="{ close: 'Close' }"
|
|
297
|
+
@pie-tooltip-close="isOpen = false">
|
|
298
|
+
<span slot="content">Orders placed before 6pm arrive today.</span>
|
|
299
|
+
</pie-tooltip>
|
|
300
|
+
</template>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Managing focus
|
|
304
|
+
|
|
305
|
+
In tooltip mode there is nothing to do. A tooltip must not take focus, and the close button that `isDismissible` renders is reachable by tabbing.
|
|
306
|
+
|
|
307
|
+
In dialog mode you own two moments:
|
|
308
|
+
|
|
309
|
+
- **On open, move focus into the panel.** Wait for the panel to render and be positioned first, because a `visibility: hidden` element cannot take focus. `await panel.updateComplete` followed by one animation frame is enough.
|
|
310
|
+
- **On close, put focus back**, but only if focus was still inside the panel. Closing on a hover-away or a click elsewhere must not pull focus away from whatever the user has moved on to.
|
|
311
|
+
|
|
145
312
|
## Usage Examples
|
|
146
313
|
|
|
147
314
|
**For HTML:**
|
|
@@ -149,6 +316,10 @@ A close button does not make the panel a dialog. Only the `action` slot does.
|
|
|
149
316
|
```js
|
|
150
317
|
// import as module into a js file e.g. main.js
|
|
151
318
|
import '@justeattakeaway/pie-webc/components/tooltip.js'
|
|
319
|
+
import '@justeattakeaway/pie-webc/components/button.js'
|
|
320
|
+
|
|
321
|
+
// `aria` takes an object, so it is set as a property rather than an attribute.
|
|
322
|
+
document.querySelector('#delivery-panel').aria = { close: 'Close' };
|
|
152
323
|
```
|
|
153
324
|
|
|
154
325
|
```html
|
|
@@ -160,7 +331,7 @@ import '@justeattakeaway/pie-webc/components/tooltip.js'
|
|
|
160
331
|
```html
|
|
161
332
|
<pie-button id="delivery-info">Delivery times</pie-button>
|
|
162
333
|
|
|
163
|
-
<pie-tooltip trigger="delivery-info" isOpen isDismissible>
|
|
334
|
+
<pie-tooltip id="delivery-panel" trigger="delivery-info" isOpen isDismissible>
|
|
164
335
|
<span slot="content">Orders placed before 6pm arrive today.</span>
|
|
165
336
|
</pie-tooltip>
|
|
166
337
|
```
|
|
@@ -218,7 +389,19 @@ export function DeliveryTimes () {
|
|
|
218
389
|
|
|
219
390
|
Filling the `action` slot switches the panel to a non-modal dialog, which then needs an accessible name.
|
|
220
391
|
|
|
392
|
+
```js
|
|
393
|
+
document.querySelector('#delivery-info').aria = {
|
|
394
|
+
label: 'Delivery times',
|
|
395
|
+
haspopup: 'dialog',
|
|
396
|
+
expanded: true,
|
|
397
|
+
};
|
|
398
|
+
```
|
|
399
|
+
|
|
221
400
|
```html
|
|
401
|
+
<pie-icon-button id="delivery-info" variant="outline">
|
|
402
|
+
<icon-info-circle></icon-info-circle>
|
|
403
|
+
</pie-icon-button>
|
|
404
|
+
|
|
222
405
|
<pie-tooltip trigger="delivery-info" isOpen heading="Delivery times">
|
|
223
406
|
<span slot="content">Orders placed before 6pm arrive today.</span>
|
|
224
407
|
<pie-button slot="action" size="xsmall">Next</pie-button>
|
package/custom-elements.json
CHANGED
|
@@ -52,6 +52,14 @@
|
|
|
52
52
|
},
|
|
53
53
|
"default": "['h2', 'h3', 'h4', 'h5', 'h6']"
|
|
54
54
|
},
|
|
55
|
+
{
|
|
56
|
+
"kind": "variable",
|
|
57
|
+
"name": "triggers",
|
|
58
|
+
"type": {
|
|
59
|
+
"text": "['hover', 'focus', 'click']"
|
|
60
|
+
},
|
|
61
|
+
"default": "['hover', 'focus', 'click']"
|
|
62
|
+
},
|
|
55
63
|
{
|
|
56
64
|
"kind": "variable",
|
|
57
65
|
"name": "modes",
|
|
@@ -77,6 +85,11 @@
|
|
|
77
85
|
},
|
|
78
86
|
"default": "'c-tooltip'"
|
|
79
87
|
},
|
|
88
|
+
{
|
|
89
|
+
"kind": "variable",
|
|
90
|
+
"name": "ON_TOOLTIP_OPEN_EVENT",
|
|
91
|
+
"default": "`${componentSelector}-open`"
|
|
92
|
+
},
|
|
80
93
|
{
|
|
81
94
|
"kind": "variable",
|
|
82
95
|
"name": "ON_TOOLTIP_CLOSE_EVENT",
|
|
@@ -132,6 +145,14 @@
|
|
|
132
145
|
"module": "src/defs.js"
|
|
133
146
|
}
|
|
134
147
|
},
|
|
148
|
+
{
|
|
149
|
+
"kind": "js",
|
|
150
|
+
"name": "triggers",
|
|
151
|
+
"declaration": {
|
|
152
|
+
"name": "triggers",
|
|
153
|
+
"module": "src/defs.js"
|
|
154
|
+
}
|
|
155
|
+
},
|
|
135
156
|
{
|
|
136
157
|
"kind": "js",
|
|
137
158
|
"name": "modes",
|
|
@@ -156,6 +177,14 @@
|
|
|
156
177
|
"module": "src/defs.js"
|
|
157
178
|
}
|
|
158
179
|
},
|
|
180
|
+
{
|
|
181
|
+
"kind": "js",
|
|
182
|
+
"name": "ON_TOOLTIP_OPEN_EVENT",
|
|
183
|
+
"declaration": {
|
|
184
|
+
"name": "ON_TOOLTIP_OPEN_EVENT",
|
|
185
|
+
"module": "src/defs.js"
|
|
186
|
+
}
|
|
187
|
+
},
|
|
159
188
|
{
|
|
160
189
|
"kind": "js",
|
|
161
190
|
"name": "ON_TOOLTIP_CLOSE_EVENT",
|
|
@@ -262,6 +291,16 @@
|
|
|
262
291
|
"privacy": "public",
|
|
263
292
|
"attribute": "aria"
|
|
264
293
|
},
|
|
294
|
+
{
|
|
295
|
+
"kind": "field",
|
|
296
|
+
"name": "triggers",
|
|
297
|
+
"type": {
|
|
298
|
+
"text": "TooltipProps['triggers']"
|
|
299
|
+
},
|
|
300
|
+
"privacy": "public",
|
|
301
|
+
"default": "[]",
|
|
302
|
+
"attribute": "triggers"
|
|
303
|
+
},
|
|
265
304
|
{
|
|
266
305
|
"kind": "field",
|
|
267
306
|
"name": "_assignedActionElements",
|
|
@@ -295,6 +334,33 @@
|
|
|
295
334
|
"privacy": "private",
|
|
296
335
|
"default": "false"
|
|
297
336
|
},
|
|
337
|
+
{
|
|
338
|
+
"kind": "field",
|
|
339
|
+
"name": "_isAnchorVisible",
|
|
340
|
+
"type": {
|
|
341
|
+
"text": "boolean"
|
|
342
|
+
},
|
|
343
|
+
"privacy": "private",
|
|
344
|
+
"default": "true"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"kind": "field",
|
|
348
|
+
"name": "_clippedTriggerElement",
|
|
349
|
+
"type": {
|
|
350
|
+
"text": "Element | null"
|
|
351
|
+
},
|
|
352
|
+
"privacy": "private",
|
|
353
|
+
"default": "null"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"kind": "field",
|
|
357
|
+
"name": "_triggerClippers",
|
|
358
|
+
"type": {
|
|
359
|
+
"text": "Array<Element>"
|
|
360
|
+
},
|
|
361
|
+
"privacy": "private",
|
|
362
|
+
"default": "[]"
|
|
363
|
+
},
|
|
298
364
|
{
|
|
299
365
|
"kind": "field",
|
|
300
366
|
"name": "_triggerTrackingController",
|
|
@@ -303,6 +369,14 @@
|
|
|
303
369
|
},
|
|
304
370
|
"privacy": "private"
|
|
305
371
|
},
|
|
372
|
+
{
|
|
373
|
+
"kind": "field",
|
|
374
|
+
"name": "_interactionController",
|
|
375
|
+
"type": {
|
|
376
|
+
"text": "AbortController | undefined"
|
|
377
|
+
},
|
|
378
|
+
"privacy": "private"
|
|
379
|
+
},
|
|
306
380
|
{
|
|
307
381
|
"kind": "field",
|
|
308
382
|
"name": "_directionObserver",
|
|
@@ -311,6 +385,14 @@
|
|
|
311
385
|
},
|
|
312
386
|
"privacy": "private"
|
|
313
387
|
},
|
|
388
|
+
{
|
|
389
|
+
"kind": "field",
|
|
390
|
+
"name": "_triggerObserver",
|
|
391
|
+
"type": {
|
|
392
|
+
"text": "ResizeObserver | undefined"
|
|
393
|
+
},
|
|
394
|
+
"privacy": "private"
|
|
395
|
+
},
|
|
314
396
|
{
|
|
315
397
|
"kind": "field",
|
|
316
398
|
"name": "_reanchorFrame",
|
|
@@ -329,6 +411,14 @@
|
|
|
329
411
|
"privacy": "private",
|
|
330
412
|
"default": "false"
|
|
331
413
|
},
|
|
414
|
+
{
|
|
415
|
+
"kind": "field",
|
|
416
|
+
"name": "_hoverCloseTimer",
|
|
417
|
+
"type": {
|
|
418
|
+
"text": "ReturnType<typeof setTimeout> | undefined"
|
|
419
|
+
},
|
|
420
|
+
"privacy": "private"
|
|
421
|
+
},
|
|
332
422
|
{
|
|
333
423
|
"kind": "field",
|
|
334
424
|
"name": "_mode",
|
|
@@ -388,6 +478,16 @@
|
|
|
388
478
|
}
|
|
389
479
|
}
|
|
390
480
|
},
|
|
481
|
+
{
|
|
482
|
+
"kind": "method",
|
|
483
|
+
"name": "_refreshTriggerClippers",
|
|
484
|
+
"privacy": "private",
|
|
485
|
+
"return": {
|
|
486
|
+
"type": {
|
|
487
|
+
"text": "void"
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
},
|
|
391
491
|
{
|
|
392
492
|
"kind": "method",
|
|
393
493
|
"name": "handleCloseButtonClick",
|
|
@@ -398,6 +498,76 @@
|
|
|
398
498
|
}
|
|
399
499
|
}
|
|
400
500
|
},
|
|
501
|
+
{
|
|
502
|
+
"kind": "method",
|
|
503
|
+
"name": "_getTriggerElement",
|
|
504
|
+
"privacy": "private",
|
|
505
|
+
"return": {
|
|
506
|
+
"type": {
|
|
507
|
+
"text": "Element | null"
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
"kind": "method",
|
|
513
|
+
"name": "_requestOpen",
|
|
514
|
+
"privacy": "private",
|
|
515
|
+
"return": {
|
|
516
|
+
"type": {
|
|
517
|
+
"text": "void"
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
"kind": "method",
|
|
523
|
+
"name": "_requestClose",
|
|
524
|
+
"privacy": "private",
|
|
525
|
+
"return": {
|
|
526
|
+
"type": {
|
|
527
|
+
"text": "void"
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
"kind": "method",
|
|
533
|
+
"name": "_startHoverCloseTimer",
|
|
534
|
+
"privacy": "private",
|
|
535
|
+
"return": {
|
|
536
|
+
"type": {
|
|
537
|
+
"text": "void"
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
"kind": "method",
|
|
543
|
+
"name": "_cancelHoverCloseTimer",
|
|
544
|
+
"privacy": "private",
|
|
545
|
+
"return": {
|
|
546
|
+
"type": {
|
|
547
|
+
"text": "void"
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
"kind": "method",
|
|
553
|
+
"name": "_rebuildInteractionListeners",
|
|
554
|
+
"privacy": "private",
|
|
555
|
+
"return": {
|
|
556
|
+
"type": {
|
|
557
|
+
"text": "void"
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"kind": "method",
|
|
563
|
+
"name": "_teardownInteractionListeners",
|
|
564
|
+
"privacy": "private",
|
|
565
|
+
"return": {
|
|
566
|
+
"type": {
|
|
567
|
+
"text": "void"
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
},
|
|
401
571
|
{
|
|
402
572
|
"kind": "method",
|
|
403
573
|
"name": "renderHeading",
|
|
@@ -424,7 +594,14 @@
|
|
|
424
594
|
"type": {
|
|
425
595
|
"text": "Event"
|
|
426
596
|
},
|
|
427
|
-
"description": "When
|
|
597
|
+
"description": "When a configured trigger asks for the panel. Set `isOpen` to `true` in response.",
|
|
598
|
+
"name": "pie-tooltip-open"
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
"type": {
|
|
602
|
+
"text": "Event"
|
|
603
|
+
},
|
|
604
|
+
"description": "When the close button is clicked, or a configured trigger asks to dismiss the panel. Set `isOpen` to `false` in response.",
|
|
428
605
|
"name": "pie-tooltip-close"
|
|
429
606
|
}
|
|
430
607
|
],
|
|
@@ -477,6 +654,14 @@
|
|
|
477
654
|
"text": "TooltipProps['aria']"
|
|
478
655
|
},
|
|
479
656
|
"fieldName": "aria"
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
"name": "triggers",
|
|
660
|
+
"type": {
|
|
661
|
+
"text": "TooltipProps['triggers']"
|
|
662
|
+
},
|
|
663
|
+
"default": "[]",
|
|
664
|
+
"fieldName": "triggers"
|
|
480
665
|
}
|
|
481
666
|
],
|
|
482
667
|
"superclass": {
|
package/dist/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare const componentClass = "c-tooltip";
|
|
|
19
19
|
|
|
20
20
|
export declare const componentSelector = "pie-tooltip";
|
|
21
21
|
|
|
22
|
-
export declare type DefaultProps = ComponentDefaultProps<TooltipProps, keyof Omit<TooltipProps, 'trigger' | 'heading' | 'aria'>>;
|
|
22
|
+
export declare type DefaultProps = ComponentDefaultProps<TooltipProps, keyof Omit<TooltipProps, 'trigger' | 'heading' | 'aria' | 'triggers'>>;
|
|
23
23
|
|
|
24
24
|
export declare const defaultProps: DefaultProps;
|
|
25
25
|
|
|
@@ -33,9 +33,12 @@ export declare const modes: readonly ["tooltip", "dialog"];
|
|
|
33
33
|
|
|
34
34
|
export declare const ON_TOOLTIP_CLOSE_EVENT = "pie-tooltip-close";
|
|
35
35
|
|
|
36
|
+
export declare const ON_TOOLTIP_OPEN_EVENT = "pie-tooltip-open";
|
|
37
|
+
|
|
36
38
|
/**
|
|
37
39
|
* @tagname pie-tooltip
|
|
38
|
-
* @event {Event} pie-tooltip-
|
|
40
|
+
* @event {Event} pie-tooltip-open - When a configured trigger asks for the panel. Set `isOpen` to `true` in response.
|
|
41
|
+
* @event {Event} pie-tooltip-close - When the close button is clicked, or a configured trigger asks to dismiss the panel. Set `isOpen` to `false` in response.
|
|
39
42
|
* @slot content - The descriptive content of the panel. Must not contain focusable elements.
|
|
40
43
|
* @slot action - An optional slot for interactive content such as a `pie-button`. Filling this slot switches the panel to a non-modal dialog.
|
|
41
44
|
*/
|
|
@@ -50,14 +53,21 @@ export declare class PieTooltip extends PieElement implements TooltipProps {
|
|
|
50
53
|
heading: TooltipProps['heading'];
|
|
51
54
|
headingLevel: "h2" | "h3" | "h4" | "h5" | "h6";
|
|
52
55
|
aria: TooltipProps['aria'];
|
|
56
|
+
triggers: TooltipProps['triggers'];
|
|
53
57
|
private _assignedActionElements;
|
|
54
58
|
private _originElement;
|
|
55
59
|
private _hasActionContent;
|
|
56
60
|
private _isPositioned;
|
|
61
|
+
private _isAnchorVisible;
|
|
62
|
+
private _clippedTriggerElement;
|
|
63
|
+
private _triggerClippers;
|
|
57
64
|
private _triggerTrackingController;
|
|
65
|
+
private _interactionController;
|
|
58
66
|
private _directionObserver;
|
|
67
|
+
private _triggerObserver;
|
|
59
68
|
private _reanchorFrame;
|
|
60
69
|
private _shouldResolveOverlayMode;
|
|
70
|
+
private _hoverCloseTimer;
|
|
61
71
|
static styles: CSSResult;
|
|
62
72
|
private get _mode();
|
|
63
73
|
protected firstUpdated(): void;
|
|
@@ -68,7 +78,15 @@ export declare class PieTooltip extends PieElement implements TooltipProps {
|
|
|
68
78
|
private resolveMode;
|
|
69
79
|
private resolveOverlayMode;
|
|
70
80
|
private projectOverTrigger;
|
|
81
|
+
private _refreshTriggerClippers;
|
|
71
82
|
private handleCloseButtonClick;
|
|
83
|
+
private _getTriggerElement;
|
|
84
|
+
private _requestOpen;
|
|
85
|
+
private _requestClose;
|
|
86
|
+
private _startHoverCloseTimer;
|
|
87
|
+
private _cancelHoverCloseTimer;
|
|
88
|
+
private _rebuildInteractionListeners;
|
|
89
|
+
private _teardownInteractionListeners;
|
|
72
90
|
private renderHeading;
|
|
73
91
|
private renderCloseButton;
|
|
74
92
|
render(): TemplateResult;
|
|
@@ -128,8 +146,20 @@ export declare interface TooltipProps {
|
|
|
128
146
|
* The ARIA labels used for various parts of the tooltip.
|
|
129
147
|
*/
|
|
130
148
|
aria?: AriaProps;
|
|
149
|
+
/**
|
|
150
|
+
* Which interactions request that the panel opens and closes. The component never opens or
|
|
151
|
+
* closes itself: a configured interaction emits `pie-tooltip-open` or `pie-tooltip-close`
|
|
152
|
+
* and the consumer decides whether to honour it by setting `isOpen`. Empty by default, so
|
|
153
|
+
* no interaction is watched at all. Configure `hover` and `focus` together for keyboard
|
|
154
|
+
* reachability, and `click` for pointer users.
|
|
155
|
+
*/
|
|
156
|
+
triggers?: Array<TooltipTrigger>;
|
|
131
157
|
}
|
|
132
158
|
|
|
159
|
+
export declare type TooltipTrigger = typeof triggers[number];
|
|
160
|
+
|
|
161
|
+
export declare const triggers: readonly ["hover", "focus", "click"];
|
|
162
|
+
|
|
133
163
|
export declare const types: readonly ["default", "icon"];
|
|
134
164
|
|
|
135
165
|
export declare const variants: readonly ["default", "inverse"];
|