@justeattakeaway/pie-tooltip 0.3.0 → 0.5.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 CHANGED
@@ -15,6 +15,7 @@
15
15
  - [Documentation](#documentation)
16
16
  - [Controlled component](#controlled-component)
17
17
  - [Properties](#properties)
18
+ - [Methods](#methods)
18
19
  - [Slots](#slots)
19
20
  - [Events](#events)
20
21
  - [CSS Variables](#css-variables)
@@ -47,16 +48,22 @@ Ideally, you should install the component using the **`@justeattakeaway/pie-webc
47
48
  |---|---|---|---|
48
49
  | `trigger` | Any string | The `id` of the element the panel is anchored to. The trigger lives elsewhere in the DOM and is never slotted into the tooltip. | `undefined` |
49
50
  | `isOpen` | `true`, `false` | When true, the panel is visible. The component never writes to this property. | `false` |
50
- | `position` | `top`, `top-start`, `top-end`, `bottom`, `bottom-start`, `bottom-end`, `left`, `left-start`, `left-end`, `right`, `right-start`, `right-end` | The side of the trigger the panel sits on, and its alignment along the cross axis. | `top` |
51
+ | `position` | `top`, `top-start`, `top-end`, `bottom`, `bottom-start`, `bottom-end`, `left`, `left-start`, `left-end`, `right`, `right-start`, `right-end` | The preferred side of the trigger the panel sits on, and its alignment along the cross axis. The panel repositions itself when this would collide with the viewport or a clipping scroll container. | `top` |
51
52
  | `size` | `default`, `fit-to-content`, `fill-container` | How the panel sizes itself. `default` is a fixed 280px and wraps, `fit-to-content` is as wide as its content, and `fill-container` matches the inline size of the trigger's parent element. Not applied when `type` is `icon`. | `default` |
52
53
  | `variant` | `default`, `inverse` | The colour treatment of the panel. `default` is the dark panel, `inverse` the light one. | `default` |
53
54
  | `type` | `default`, `icon` | The presentation of the panel. `icon` is the compact treatment intended for icon triggers: it has no arrow and is always as wide as its content, so `size` and `--tooltip-width` have no effect on it. | `default` |
54
- | `isDismissible` | `true`, `false` | When true, a close button is rendered inside the panel. | `false` |
55
+ | `isDismissible` | `true`, `false` | When true, a close button is rendered inside the panel, and the panel presents as a non-modal dialog, so it needs `heading` or `aria.label` for its accessible name. | `false` |
55
56
  | `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
57
  | `headingLevel` | `h2`, `h3`, `h4`, `h5`, `h6` | The HTML heading tag to use for the panel's heading. | `h2` |
57
58
  | `aria` | `{ close?: string, label?: string }` | `close` names the close button. `label` names the panel in dialog mode when no `heading` is provided. | `undefined` |
58
59
  | `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. | `[]` |
59
60
 
61
+ ### Methods
62
+
63
+ | Method | Returns | Description |
64
+ |---|---|---|
65
+ | `focusPanel()` | `Promise<boolean>` | Moves focus to the panel's content in dialog mode, so screen readers announce the content, followed by the dialog's name and role, once each. Only needed when the panel contains interactive elements, such as a close button or an action button, which make it a dialog. Call it straight after setting `isOpen`: it waits for the panel's opening update to commit, then retries the focus move until it lands. Resolves `true` once focus is in place, or `false` if the panel is closed or in tooltip mode. The content is `tabindex="-1"`, so it is never reached by Tab. See [Managing focus](#managing-focus). |
66
+
60
67
  ### Slots
61
68
 
62
69
  | Slot | Description |
@@ -69,7 +76,7 @@ Ideally, you should install the component using the **`@justeattakeaway/pie-webc
69
76
  | Event | Type | Description |
70
77
  |---|---|---|
71
78
  | `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. |
79
+ | `pie-tooltip-close` | `Event` | Emitted when the close button is clicked, Escape is pressed, or a configured trigger asks to dismiss the panel. Set `isOpen` to `false` in response. Bubbles and is composed. |
73
80
 
74
81
  ### CSS Variables
75
82
 
@@ -86,7 +93,7 @@ Set both on the `pie-tooltip` element itself.
86
93
 
87
94
  ## Positioning
88
95
 
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.
96
+ Place the tooltip next to its trigger element in the DOM for the best accessibility practice. The `position` property will place the tooltip near to the trigger based on which value is provided.
90
97
 
91
98
  `position` names a side and, optionally, an alignment along the opposite axis:
92
99
 
@@ -99,6 +106,17 @@ right right-start right-end
99
106
 
100
107
  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.
101
108
 
109
+ ### Collision detection
110
+
111
+ `position` is a preference, not a guarantee. Before the panel is shown, and on every scroll, resize or direction change while it is open, the component measures the panel against the space available and repositions it if the preferred position would collide.
112
+
113
+ - It flips to the opposite side first: `top` to `bottom`, and so on.
114
+ - It then tries the remaining sides.
115
+ - Within a side, it shifts the alignment (for example `top-start` to `top-end`) so the panel stays fully in view.
116
+ - If no position fits entirely, it uses whichever position shows the most of the panel.
117
+
118
+ The available space is the viewport, narrowed by any ancestor that clips the panel. Collision detection is always on and cannot be disabled.
119
+
102
120
  ## Sizing
103
121
 
104
122
  | `size` | Behaviour |
@@ -115,25 +133,26 @@ In right-to-left languages, everything on the inline axis mirrors. The alignment
115
133
 
116
134
  The panel presents as one of two patterns, inferred from the `action` slot contents. They carry different obligations.
117
135
 
118
- | | `action` slot empty | `action` slot filled |
136
+ | | `action` slot empty and not dismissible | `action` slot filled or `isDismissible` |
119
137
  |---|---|---|
120
138
  | Panel role | `tooltip` | `dialog` |
121
139
  | Contains focusable content | No | Yes |
122
140
  | Accessible name on panel | None | Required, from `heading` or `aria.label` |
123
141
  | In the accessibility tree while closed | Yes, as the trigger's description | No |
124
142
 
125
- A close button does not make the panel a dialog. Only the `action` slot does.
143
+ A close button makes the panel a dialog: it invites the user inside, and a panel the user enters is announced through focus, not through a description. The same applies to any panel toggled by a click or a tap, so use the `action` slot there. Tooltip mode is for hover- and focus-followed panels only.
126
144
 
127
145
  ### What the component does
128
146
 
129
- - Sets `role="tooltip"` or `role="dialog"` from the `action` slot, resolved on the client before the first paint.
147
+ - Sets `role="tooltip"` or `role="dialog"` from the `action` slot and `isDismissible`, resolved on the client before the first paint.
130
148
  - Names the dialog panel from `heading`, falling back to `aria.label`.
131
- - Removes the dialog panel from the accessibility tree while closed. In tooltip mode the content stays in the DOM so that a description referring to it still resolves.
149
+ - Exposes `focusPanel()` for dialog mode, which moves focus to the panel's content so the content, followed by the dialog's name and role, are announced once each on every screen reader. The panel carries no `aria-describedby`; see [Managing focus](#managing-focus).
150
+ - Removes the dialog panel from the accessibility tree while closed. In tooltip mode the panel stays in the DOM, so a description referring to the tooltip still resolves.
132
151
  - Names the close button from `aria.close` and places it in the tab sequence inside the panel.
133
152
  - Keeps the panel clear of the trigger at every placement, so the panel cannot obscure a focused trigger (WCAG 2.4.11).
134
153
  - Wraps content.
135
154
 
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).
155
+ It does not touch the trigger, and it does not move focus on its own; `focusPanel()` moves it only when you call it. The component never writes attributes to the element named by `trigger`. See [Wiring the trigger](#wiring-the-trigger) and [Managing focus](#managing-focus).
137
156
 
138
157
  ### What you need to do
139
158
 
@@ -143,8 +162,9 @@ It does not touch the trigger, and it does not move focus. The component never w
143
162
  - **Use a natively interactive element as the trigger**, a button or a link, so focus and click behave correctly.
144
163
  - **Own `isOpen`.** Listen for `pie-tooltip-close` and set `isOpen` to `false` in response.
145
164
  - **Keep focusable content out of the `content` slot.** Interactive content belongs in the `action` slot, which switches the panel to a dialog.
165
+ - **Make click-toggled or dismissible panels dialogs.** A panel opened by a click or a tap appears with no focus change, so screen readers stay silent; a close button puts the user inside the panel. Both are dialog interactions, so fill the `action` slot and follow [Managing focus](#managing-focus).
146
166
  - **Place `<pie-tooltip>` immediately after its trigger in the DOM.** The component anchors by `id` and can sit anywhere, but reading and tab order follow DOM order.
147
- - **In dialog mode, provide `heading` or `aria.label`** so the dialog has an accessible name.
167
+ - **In dialog mode, provide `heading` or `aria.label`** so the dialog has an accessible name. This includes every dismissible panel, which is a dialog.
148
168
  - **Provide a translated `aria.close`** whenever `isDismissible` is set.
149
169
  - **Keep tooltip-mode content short and supplementary.** Anything essential or interactive belongs in dialog mode, or inline in the page.
150
170
 
@@ -152,25 +172,50 @@ It does not touch the trigger, and it does not move focus. The component never w
152
172
 
153
173
  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
174
 
175
+ > The [Screen readers stories](https://webc.pie.design/?path=/story/components-tooltip-screen-readers--docs) show every wiring in this section as live, runnable examples.
176
+
155
177
  | ARIA | Set it when | Value |
156
178
  |---|---|---|
157
179
  | `haspopup` | Dialog mode, so the trigger announces that it opens a dialog | `dialog` |
158
180
  | `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 |
181
+ | `describedby` | Tooltip mode, and the trigger is a plain HTML element | The `id` of the `pie-tooltip` element itself |
160
182
 
161
183
  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
184
 
185
+ #### Point the description at the tooltip itself
186
+
187
+ In tooltip mode, give the `<pie-tooltip>` element an `id` and set `aria-describedby` on the trigger to that `id`. The tooltip and a plain HTML trigger live in the same tree, so the reference resolves, and the browser reads the panel's text through the tooltip's shadow root. No `id` is needed on the element in the `content` slot.
188
+
189
+ ```html
190
+ <button id="delivery-info" aria-describedby="delivery-panel">Delivery times</button>
191
+
192
+ <pie-tooltip id="delivery-panel" trigger="delivery-info">
193
+ <span slot="content">Orders placed before 6pm arrive today.</span>
194
+ </pie-tooltip>
195
+ ```
196
+
163
197
  #### A description cannot cross a shadow boundary
164
198
 
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.
199
+ `aria-describedby` takes an `id`, and an `id` only resolves inside the tree of the element that references it. The `<button>` inside `pie-icon-button` lives in the component's shadow root, so it cannot see the tooltip's `id` in your document, and `aria.describedby` is unusable for this purpose even though the property exists.
166
200
 
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.
201
+ There is no way around this from outside the component. When the trigger is a PIE component, pass the panel's text as the trigger's own description instead. `pie-button` and `pie-icon-button` accept an `aria.description`, which they render as an `aria-description` attribute on their internal element, and a string crosses the shadow boundary where an IDREF cannot:
168
202
 
169
- Dialog mode is unaffected, because the panel is named by `heading` and needs no description at all.
203
+ ```js
204
+ trigger.aria = {
205
+ label: 'Delivery times',
206
+ description: 'Orders placed before 6pm arrive today.',
207
+ };
208
+ ```
209
+
210
+ Keep the name short and let the description carry the panel's text. As with `aria-describedby`, the description must stay in step with the content in the `content` slot.
211
+
212
+ Dialog mode is unaffected: the panel's content is announced when focus moves into it, so it needs no trigger-side description at all.
213
+
214
+ Dialog mode is unaffected: the panel's content is announced when focus moves into it, so it needs no trigger-side description at all.
170
215
 
171
216
  #### A tooltip panel on an icon trigger
172
217
 
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.
218
+ `hover` and `focus` together give the panel to both pointer and keyboard users. Nothing is toggled, so there is no `expanded`. The trigger is a PIE component, so a description cannot cross the shadow boundary by `id`, so the panel's text travels in the trigger's `aria.description` instead (see [A description cannot cross a shadow boundary](#a-description-cannot-cross-a-shadow-boundary)).
174
219
 
175
220
  ```js
176
221
  // main.js
@@ -181,7 +226,10 @@ import '@justeattakeaway/pie-icons-webc/dist/IconInfoCircle.js';
181
226
  const trigger = document.querySelector('#delivery-info');
182
227
  const panel = document.querySelector('#delivery-panel');
183
228
 
184
- trigger.aria = { label: 'Delivery times: orders placed before 6pm arrive today' };
229
+ trigger.aria = {
230
+ label: 'Delivery times',
231
+ description: 'Orders placed before 6pm arrive today.',
232
+ };
185
233
  panel.triggers = ['hover', 'focus'];
186
234
 
187
235
  panel.addEventListener('pie-tooltip-open', () => { panel.isOpen = true; });
@@ -216,12 +264,13 @@ import { IconInfoCircle } from '@justeattakeaway/pie-icons-webc/dist/react/IconI
216
264
  export function DeliveryTimes () {
217
265
  const [isOpen, setIsOpen] = useState(false);
218
266
  const triggerRef = useRef(null);
219
- const actionRef = useRef(null);
267
+ const tooltipRef = useRef(null);
220
268
 
221
269
  const open = () => {
222
270
  setIsOpen(true);
223
- // The panel is only focusable once it has rendered and been positioned.
224
- requestAnimationFrame(() => actionRef.current?.focus({ preventScroll: true }));
271
+ // `focusPanel()` waits for the panel's opening update to commit, then moves focus to
272
+ // the content so screen readers announce it with the dialog's name and role.
273
+ tooltipRef.current?.focusPanel();
225
274
  };
226
275
 
227
276
  const close = () => {
@@ -251,6 +300,7 @@ export function DeliveryTimes () {
251
300
  </PieIconButton>
252
301
 
253
302
  <PieTooltip
303
+ ref={tooltipRef}
254
304
  trigger="delivery-info"
255
305
  heading="Delivery times"
256
306
  isOpen={isOpen}
@@ -260,7 +310,7 @@ export function DeliveryTimes () {
260
310
  onPieTooltipOpen={open}
261
311
  onPieTooltipClose={close}>
262
312
  <span slot="content">Orders placed before 6pm arrive today.</span>
263
- <PieButton slot="action" size="xsmall" ref={actionRef} onClick={close}>
313
+ <PieButton slot="action" size="xsmall" onClick={close}>
264
314
  Got it
265
315
  </PieButton>
266
316
  </PieTooltip>
@@ -275,9 +325,7 @@ The `closest('pie-tooltip')` check works because `document.activeElement` report
275
325
 
276
326
  #### Driving the panel without `triggers`
277
327
 
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.
328
+ 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 and Escape still emit `pie-tooltip-close`.
281
329
 
282
330
  ```html
283
331
  <template>
@@ -302,24 +350,27 @@ Escape is watched only while at least one trigger is configured, so a panel driv
302
350
 
303
351
  ### Managing focus
304
352
 
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.
353
+ In tooltip mode there is nothing to do. A tooltip must not take focus, and a panel that is dismissible or click-toggled is not a tooltip, so it is a dialog and the focus contract below applies to it.
306
354
 
307
355
  In dialog mode you own two moments:
308
356
 
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.
357
+ - **On open, call `focusPanel()`.** It moves focus to the content carrying the panel's descriptive text, so screen readers announce the content, followed by the dialog's name and role. It waits for the panel's opening update to commit, then retries the focus move until it lands, and resolves to `true` once focus is in place, or `false` if the panel is closed or in tooltip mode. No waiting on your side is needed: call it straight after setting `isOpen`. Only needed when the panel contains interactive elements, such as a close button or an action button, which make it a dialog.
358
+
359
+ The heading names the panel through `aria-labelledby`; the content is announced by the focus move itself. The panel carries no `aria-describedby`: VoiceOver never announces a dialog's description on focus entry ([WebKit bug 282773](https://bugs.webkit.org/show_bug.cgi?id=282773)), and NVDA and JAWS announce it in addition to the focused content, so a description either does nothing or says the content twice. This follows the [WAI-ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/#keyboard-interaction)'s static-text focus recommendation: the content is `tabindex="-1"`, never reached by Tab, and the panel's own controls stay next in the tab sequence. If you move focus anywhere else, the content is not announced on open, though it stays readable inside the dialog.
360
+
310
361
  - **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
362
 
312
363
  ## Usage Examples
313
364
 
365
+ > The examples below are for illustration only and are not production ready. They are kept deliberately minimal: wire up error handling, state management and focus behaviour as your application requires.
366
+
314
367
  **For HTML:**
315
368
 
369
+ The trigger below is a plain HTML button, so the wiring is the trigger's own `aria-describedby` pointing at the tooltip's `id`.
370
+
316
371
  ```js
317
372
  // import as module into a js file e.g. main.js
318
373
  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' };
323
374
  ```
324
375
 
325
376
  ```html
@@ -329,13 +380,15 @@ document.querySelector('#delivery-panel').aria = { close: 'Close' };
329
380
  ```
330
381
 
331
382
  ```html
332
- <pie-button id="delivery-info">Delivery times</pie-button>
383
+ <button id="delivery-info" aria-describedby="delivery-panel">Delivery times</button>
333
384
 
334
385
  <pie-tooltip id="delivery-panel" trigger="delivery-info" isOpen isDismissible>
335
386
  <span slot="content">Orders placed before 6pm arrive today.</span>
336
387
  </pie-tooltip>
337
388
  ```
338
389
 
390
+ When the trigger is a PIE component such as `pie-button`, an IDREF cannot cross its shadow boundary, so pass the text through the trigger's `aria` property with `description` instead.
391
+
339
392
  **For Native JS Applications, Vue, Angular, Svelte etc.:**
340
393
 
341
394
  ```js
@@ -345,9 +398,14 @@ import '@justeattakeaway/pie-webc/components/tooltip.js'
345
398
 
346
399
  ```html
347
400
  <template>
348
- <pie-button id="delivery-info">Delivery times</pie-button>
401
+ <pie-button
402
+ id="delivery-info"
403
+ :aria="{ label: 'Delivery times', description: 'Orders placed before 6pm arrive today.' }">
404
+ Delivery times
405
+ </pie-button>
349
406
 
350
407
  <pie-tooltip
408
+ id="delivery-panel"
351
409
  trigger="delivery-info"
352
410
  :isOpen="isOpen"
353
411
  isDismissible
@@ -358,6 +416,8 @@ import '@justeattakeaway/pie-webc/components/tooltip.js'
358
416
  </template>
359
417
  ```
360
418
 
419
+ The trigger is a PIE component, so the text travels in its `aria.description` rather than `aria-describedby` (see [A description cannot cross a shadow boundary](#a-description-cannot-cross-a-shadow-boundary)).
420
+
361
421
  **For React Applications:**
362
422
 
363
423
  ```jsx
@@ -370,9 +430,15 @@ export function DeliveryTimes () {
370
430
 
371
431
  return (
372
432
  <>
373
- <PieButton id="delivery-info">Delivery times</PieButton>
433
+ {/* A PIE component trigger carries the text in its description, not `aria-describedby`. */}
434
+ <PieButton
435
+ id="delivery-info"
436
+ aria={{ label: 'Delivery times', description: 'Orders placed before 6pm arrive today.' }}>
437
+ Delivery times
438
+ </PieButton>
374
439
 
375
440
  <PieTooltip
441
+ id="delivery-panel"
376
442
  trigger="delivery-info"
377
443
  isOpen={isOpen}
378
444
  isDismissible
@@ -402,7 +468,7 @@ document.querySelector('#delivery-info').aria = {
402
468
  <icon-info-circle></icon-info-circle>
403
469
  </pie-icon-button>
404
470
 
405
- <pie-tooltip trigger="delivery-info" isOpen heading="Delivery times">
471
+ <pie-tooltip id="delivery-panel" trigger="delivery-info" isOpen heading="Delivery times">
406
472
  <span slot="content">Orders placed before 6pm arrive today.</span>
407
473
  <pie-button slot="action" size="xsmall">Next</pie-button>
408
474
  </pie-tooltip>
@@ -67,7 +67,7 @@
67
67
  "text": "['tooltip', 'dialog']"
68
68
  },
69
69
  "default": "['tooltip', 'dialog']",
70
- "description": "The two patterns the panel can present as. Inferred from the `action` slot rather than\nconfigured: an empty `action` slot is a tooltip, a filled one is a non-modal dialog."
70
+ "description": "The two patterns the panel can present as, inferred from the `action` slot."
71
71
  },
72
72
  {
73
73
  "kind": "variable",
@@ -343,6 +343,14 @@
343
343
  "privacy": "private",
344
344
  "default": "true"
345
345
  },
346
+ {
347
+ "kind": "field",
348
+ "name": "_resolvedPosition",
349
+ "type": {
350
+ "text": "TooltipProps['position'] | undefined"
351
+ },
352
+ "privacy": "private"
353
+ },
346
354
  {
347
355
  "kind": "field",
348
356
  "name": "_clippedTriggerElement",
@@ -361,6 +369,33 @@
361
369
  "privacy": "private",
362
370
  "default": "[]"
363
371
  },
372
+ {
373
+ "kind": "field",
374
+ "name": "_overlayClippers",
375
+ "type": {
376
+ "text": "Array<Element>"
377
+ },
378
+ "privacy": "private",
379
+ "default": "[]"
380
+ },
381
+ {
382
+ "kind": "field",
383
+ "name": "_collisionSignature",
384
+ "type": {
385
+ "text": "string | null"
386
+ },
387
+ "privacy": "private",
388
+ "default": "null"
389
+ },
390
+ {
391
+ "kind": "field",
392
+ "name": "_overlayModeDirty",
393
+ "type": {
394
+ "text": "boolean"
395
+ },
396
+ "privacy": "private",
397
+ "default": "true"
398
+ },
364
399
  {
365
400
  "kind": "field",
366
401
  "name": "_triggerTrackingController",
@@ -404,7 +439,15 @@
404
439
  },
405
440
  {
406
441
  "kind": "field",
407
- "name": "_shouldResolveOverlayMode",
442
+ "name": "_hoverCloseTimer",
443
+ "type": {
444
+ "text": "ReturnType<typeof setTimeout> | undefined"
445
+ },
446
+ "privacy": "private"
447
+ },
448
+ {
449
+ "kind": "field",
450
+ "name": "_openedByClick",
408
451
  "type": {
409
452
  "text": "boolean"
410
453
  },
@@ -413,11 +456,18 @@
413
456
  },
414
457
  {
415
458
  "kind": "field",
416
- "name": "_hoverCloseTimer",
459
+ "name": "_instanceId",
460
+ "privacy": "private",
461
+ "readonly": true
462
+ },
463
+ {
464
+ "kind": "field",
465
+ "name": "_headingId",
417
466
  "type": {
418
- "text": "ReturnType<typeof setTimeout> | undefined"
467
+ "text": "string"
419
468
  },
420
- "privacy": "private"
469
+ "privacy": "private",
470
+ "readonly": true
421
471
  },
422
472
  {
423
473
  "kind": "field",
@@ -428,6 +478,16 @@
428
478
  "privacy": "private",
429
479
  "readonly": true
430
480
  },
481
+ {
482
+ "kind": "method",
483
+ "name": "focusPanel",
484
+ "privacy": "public",
485
+ "return": {
486
+ "type": {
487
+ "text": "Promise<boolean>"
488
+ }
489
+ }
490
+ },
431
491
  {
432
492
  "kind": "method",
433
493
  "name": "startTrackingTrigger",
@@ -478,6 +538,76 @@
478
538
  }
479
539
  }
480
540
  },
541
+ {
542
+ "kind": "method",
543
+ "name": "resolveCollision",
544
+ "privacy": "private",
545
+ "return": {
546
+ "type": {
547
+ "text": "void"
548
+ }
549
+ },
550
+ "parameters": [
551
+ {
552
+ "name": "anchorRect",
553
+ "type": {
554
+ "text": "DOMRect"
555
+ }
556
+ }
557
+ ]
558
+ },
559
+ {
560
+ "kind": "method",
561
+ "name": "_setResolvedPosition",
562
+ "privacy": "private",
563
+ "return": {
564
+ "type": {
565
+ "text": "void"
566
+ }
567
+ },
568
+ "parameters": [
569
+ {
570
+ "name": "position",
571
+ "type": {
572
+ "text": "TooltipProps['position']"
573
+ }
574
+ }
575
+ ]
576
+ },
577
+ {
578
+ "kind": "method",
579
+ "name": "_getCollisionBoundary",
580
+ "privacy": "private",
581
+ "return": {
582
+ "type": {
583
+ "text": "DOMRect | null"
584
+ }
585
+ }
586
+ },
587
+ {
588
+ "kind": "method",
589
+ "name": "_getCandidatePositions",
590
+ "privacy": "private",
591
+ "return": {
592
+ "type": {
593
+ "text": "Array<{ side: TooltipSide; alignment: TooltipAlignment }>"
594
+ }
595
+ },
596
+ "parameters": [
597
+ {
598
+ "name": "preferredSide",
599
+ "type": {
600
+ "text": "TooltipSide"
601
+ }
602
+ },
603
+ {
604
+ "name": "preferredAlignment",
605
+ "type": {
606
+ "text": "TooltipAlignment"
607
+ }
608
+ }
609
+ ]
610
+ },
481
611
  {
482
612
  "kind": "method",
483
613
  "name": "_refreshTriggerClippers",
@@ -601,7 +731,7 @@
601
731
  "type": {
602
732
  "text": "Event"
603
733
  },
604
- "description": "When the close button is clicked, or a configured trigger asks to dismiss the panel. Set `isOpen` to `false` in response.",
734
+ "description": "When the close button is clicked, Escape is pressed, or a configured trigger asks to dismiss the panel. Set `isOpen` to `false` in response.",
605
735
  "name": "pie-tooltip-close"
606
736
  }
607
737
  ],