Skip to content

Commit 8fe8792

Browse files
authored
fix: Require less cursor precision when moving from tooltip target to tooltip content (#3359)
1 parent d2a5d38 commit 8fe8792

File tree

8 files changed

+191
-216
lines changed

8 files changed

+191
-216
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165
{
166166
"path": "lib/components/internal/widget-exports.js",
167167
"brotli": false,
168-
"limit": "752 kB"
168+
"limit": "753 kB"
169169
}
170170
],
171171
"browserslist": [

src/app-layout/visual-refresh-toolbar/toolbar/trigger-button/index.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { ButtonProps } from '../../../../button/interfaces';
77
import { IconProps } from '../../../../icon/interfaces';
88
import Icon from '../../../../icon/internal';
99
import Tooltip from '../../../../internal/components/tooltip';
10-
import { registerTooltip } from '../../../../internal/components/tooltip/registry';
1110

1211
import testutilStyles from '../../../test-classes/styles.css.js';
1312
import styles from './styles.css.js';
@@ -185,15 +184,6 @@ function TriggerButton(
185184
}
186185
}, [containerRef, hasTooltip, tooltipValue]);
187186

188-
useEffect(() => {
189-
if (tooltipVisible) {
190-
return registerTooltip(() => {
191-
setShowTooltip(false);
192-
setSupressTooltip(false);
193-
});
194-
}
195-
}, [tooltipVisible]);
196-
197187
return (
198188
<div
199189
ref={containerRef}
@@ -238,7 +228,10 @@ function TriggerButton(
238228
trackRef={containerRef}
239229
value={tooltipValue}
240230
className={testutilStyles['trigger-tooltip']}
241-
onDismiss={() => setShowTooltip(false)}
231+
onDismiss={() => {
232+
setShowTooltip(false);
233+
setSupressTooltip(false);
234+
}}
242235
/>
243236
)}
244237
</div>

src/breadcrumb-group/item/item.tsx

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3-
import React, { useEffect, useRef, useState } from 'react';
3+
import React, { useRef, useState } from 'react';
44
import clsx from 'clsx';
55

66
import InternalIcon from '../../icon/internal';
77
import Tooltip from '../../internal/components/tooltip';
8-
import { registerTooltip } from '../../internal/components/tooltip/registry';
98
import { fireCancelableEvent, isPlainLeftClick } from '../../internal/events';
109
import { BreadcrumbGroupProps, BreadcrumbItemProps } from '../interfaces';
1110
import { getEventDetail } from '../utils';
@@ -28,40 +27,29 @@ const BreadcrumbItemWithPopover = <T extends BreadcrumbGroupProps.Item>({
2827
itemAttributes,
2928
children,
3029
}: BreadcrumbItemWithPopoverProps<T>) => {
31-
const [showPopover, setShowPopover] = useState(false);
32-
const textRef = useRef<HTMLElement>(null);
33-
const popoverContent = (
34-
<Tooltip trackRef={textRef} value={item.text} size="medium" onDismiss={() => setShowPopover(false)} />
35-
);
36-
37-
useEffect(() => {
38-
if (showPopover) {
39-
return registerTooltip(() => {
40-
setShowPopover(false);
41-
});
42-
}
43-
}, [showPopover]);
30+
const [showTooltip, setShowTooltip] = useState(false);
31+
const textRef = useRef<HTMLElement | null>(null);
4432

4533
return (
46-
<>
47-
<Item
48-
ref={textRef}
49-
isLast={isLast}
50-
onFocus={() => {
51-
setShowPopover(true);
52-
}}
53-
onBlur={() => setShowPopover(false)}
54-
onMouseEnter={() => {
55-
setShowPopover(true);
56-
}}
57-
onMouseLeave={() => setShowPopover(false)}
58-
anchorAttributes={anchorAttributes}
59-
{...itemAttributes}
60-
>
61-
{children}
62-
</Item>
63-
{showPopover && popoverContent}
64-
</>
34+
<Item
35+
ref={textRef}
36+
isLast={isLast}
37+
onFocus={() => {
38+
setShowTooltip(true);
39+
}}
40+
onBlur={() => setShowTooltip(false)}
41+
onMouseEnter={() => {
42+
setShowTooltip(true);
43+
}}
44+
onMouseLeave={() => setShowTooltip(false)}
45+
anchorAttributes={anchorAttributes}
46+
{...itemAttributes}
47+
>
48+
{children}
49+
{showTooltip && (
50+
<Tooltip trackRef={textRef} value={item.text} size="medium" onDismiss={() => setShowTooltip(false)} />
51+
)}
52+
</Item>
6553
);
6654
};
6755

src/internal/components/tooltip/__tests__/registry.test.ts

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

src/internal/components/tooltip/registry.ts

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

src/popover/container.scss

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,60 @@
66
@use '../internal/styles' as styles;
77
@use '../internal/styles/tokens' as awsui;
88

9+
$arrow-height: 10px;
10+
911
.container {
1012
display: inline-block;
1113
position: fixed;
1214
inset-block-start: -9999px;
1315
inset-inline-start: -9999px;
1416
z-index: 2000;
17+
18+
// A little pseudoelement to extend the container to the space between the
19+
// popover and the trigger to avoid hover-based popovers/tooltips from
20+
// closing too eagerly when the cursor goes between them.
21+
&::before {
22+
content: '';
23+
position: absolute;
24+
}
25+
26+
&:has(&-arrow-position-bottom-left),
27+
&:has(&-arrow-position-bottom-center),
28+
&:has(&-arrow-position-bottom-right) {
29+
&::before {
30+
inset-inline: 0;
31+
inset-block-start: -$arrow-height;
32+
block-size: $arrow-height;
33+
}
34+
}
35+
36+
&:has(&-arrow-position-top-left),
37+
&:has(&-arrow-position-top-center),
38+
&:has(&-arrow-position-top-right) {
39+
&::before {
40+
inset-inline: 0;
41+
inset-block-end: -$arrow-height;
42+
block-size: $arrow-height;
43+
}
44+
}
45+
46+
&:has(&-arrow-position-right-top),
47+
&:has(&-arrow-position-right-bottom) {
48+
&::before {
49+
inset-block: 0;
50+
inset-inline-start: -$arrow-height;
51+
inline-size: $arrow-height;
52+
}
53+
}
54+
55+
&:has(&-arrow-position-left-top),
56+
&:has(&-arrow-position-left-bottom) {
57+
&::before {
58+
inset-block: 0;
59+
inset-inline-end: -$arrow-height;
60+
inline-size: $arrow-height;
61+
}
62+
}
1563
}
1664

1765
.container-body {

src/slider/__tests__/slider.test.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,19 @@ describe('Slider events', () => {
286286
expect(screen.queryByText('50')).not.toBeInTheDocument();
287287
});
288288

289+
test('show tooltip on touch start', () => {
290+
const wrapper = renderSlider({
291+
min: 0,
292+
max: 100,
293+
value: 50,
294+
});
295+
fireEvent.touchStart(wrapper.findNativeInput()!.getElement());
296+
expect(screen.queryByText('50')).toBeInTheDocument();
297+
298+
fireEvent.touchEnd(wrapper.findNativeInput()!.getElement());
299+
expect(screen.queryByText('50')).not.toBeInTheDocument();
300+
});
301+
289302
test('close tooltip on Esc keydown', () => {
290303
const wrapper = renderSlider({
291304
min: 0,
@@ -326,7 +339,8 @@ describe('Slider i18n', () => {
326339
});
327340

328341
describe('Slider a11y', () => {
329-
test('Validates a11y', () => {
342+
// FIXME: This test was never functional. This will be fixed in a subsequent PR.
343+
test.skip('Valides a11y', async () => {
330344
const wrapper = renderSlider({
331345
min: 0,
332346
max: 100,
@@ -337,7 +351,7 @@ describe('Slider a11y', () => {
337351
ariaLabel: 'aria label',
338352
});
339353

340-
expect(wrapper.getElement()).toValidateA11y();
354+
await expect(wrapper.getElement()).toValidateA11y();
341355
});
342356

343357
test('Renders correct aria label', () => {

0 commit comments

Comments
 (0)