Skip to content

Commit b4306cb

Browse files
feat(20772): added tooltip for expanded search icon (#21034)
* feat(20772): added tooltip for expanded search icon * feat(20772): fixed the test cases
1 parent 25d619e commit b4306cb

File tree

5 files changed

+85
-33
lines changed

5 files changed

+85
-33
lines changed

e2e/components/Search/Search-test.avt.e2e.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,19 @@ test.describe('@avt Search', () => {
115115
await expect(searchButton).not.toHaveAttribute('aria-expanded', 'true');
116116
await expect(search).toBeHidden();
117117
});
118+
119+
test('@avt-keyboard-nav tooltip on focus', async ({ page }) => {
120+
await visitStory(page, {
121+
component: 'Search',
122+
id: 'components-search--expandable',
123+
globals: {
124+
theme: 'white',
125+
},
126+
});
127+
128+
await expect(page.getByRole('button')).toBeVisible();
129+
await page.keyboard.press('Tab');
130+
await expect(page.getByRole('button')).toBeFocused();
131+
await expect(page.getByRole('tooltip')).toHaveText('Search');
132+
});
118133
});

packages/react/src/components/ExpandableSearch/ExpandableSearch-test.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import React from 'react';
99
import ExpandableSearch from './ExpandableSearch';
1010
import userEvent from '@testing-library/user-event';
11-
import { render, screen } from '@testing-library/react';
11+
import { render, screen, act } from '@testing-library/react';
1212

1313
const prefix = 'cds';
1414

@@ -63,7 +63,12 @@ describe('ExpandableSearch', () => {
6363
<ExpandableSearch labelText="test-search" />
6464
);
6565

66-
await screen.getAllByRole('button')[0].focus();
66+
const expandControl = container.querySelector('.cds--search-magnifier');
67+
expect(expandControl).not.toBeNull();
68+
69+
await act(async () => {
70+
expandControl.focus();
71+
});
6772

6873
await userEvent.keyboard('[Enter]');
6974

@@ -75,7 +80,12 @@ describe('ExpandableSearch', () => {
7580
<ExpandableSearch labelText="test-search" />
7681
);
7782

78-
await screen.getAllByRole('button')[0].focus();
83+
const expandControl = container.querySelector('.cds--search-magnifier');
84+
expect(expandControl).not.toBeNull();
85+
86+
await act(async () => {
87+
expandControl.focus();
88+
});
7989

8090
await userEvent.keyboard('[Space]');
8191

packages/react/src/components/Search/Search.stories.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,16 @@ export const Disabled = () => {
5353

5454
export const Expandable = () => {
5555
return (
56-
<ExpandableSearch
57-
size="lg"
58-
labelText="Search"
59-
closeButtonLabelText="Clear search input"
60-
id="search-expandable-1"
61-
onChange={() => {}}
62-
onKeyDown={() => {}}
63-
/>
56+
<div style={{ marginTop: '50px' }}>
57+
<ExpandableSearch
58+
size="lg"
59+
labelText="Search"
60+
closeButtonLabelText="Clear search input"
61+
id="search-expandable-1"
62+
onChange={() => {}}
63+
onKeyDown={() => {}}
64+
/>
65+
</div>
6466
);
6567
};
6668

packages/react/src/components/Search/Search.tsx

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { useMergedRefs } from '../../internal/useMergedRefs';
2828
import { deprecate } from '../../prop-types/deprecate';
2929
import { FormContext } from '../FluidForm';
3030
import { noopFn } from '../../internal/noopFn';
31+
import { Tooltip } from '../Tooltip';
3132

3233
type InputPropsBase = Omit<HTMLAttributes<HTMLInputElement>, 'onChange'>;
3334
export interface SearchProps extends InputPropsBase {
@@ -244,29 +245,46 @@ const Search = React.forwardRef<HTMLInputElement, SearchProps>(
244245
}
245246
}
246247

248+
const magnifierButton = (
249+
<div
250+
aria-labelledby={onExpand ? searchId : undefined}
251+
role={onExpand ? 'button' : undefined}
252+
className={`${prefix}--search-magnifier`}
253+
onClick={onExpand}
254+
onKeyDown={handleExpandButtonKeyDown}
255+
tabIndex={onExpand && !isExpanded ? 0 : -1}
256+
ref={expandButtonRef}
257+
aria-expanded={
258+
onExpand && isExpanded
259+
? true
260+
: onExpand && !isExpanded
261+
? false
262+
: undefined
263+
}
264+
aria-controls={onExpand ? uniqueId : undefined}>
265+
<CustomSearchIcon icon={renderIcon} />
266+
</div>
267+
);
268+
269+
// Wrap magnifierButton in a tooltip if it's expandable
270+
const magnifierWithTooltip =
271+
onExpand && !isExpanded ? (
272+
<Tooltip
273+
className={`${prefix}--search-tooltip ${prefix}--search-magnifier-tooltip`}
274+
align="top"
275+
label="Search">
276+
{magnifierButton}
277+
</Tooltip>
278+
) : (
279+
magnifierButton
280+
);
281+
247282
return (
248283
<div role="search" aria-label={placeholder} className={searchClasses}>
284+
{magnifierWithTooltip}
249285
{/* the magnifier is used in ExpandableSearch as a click target to expand,
250286
however, it does not need a keyboard event bc the input element gets focus on keyboard nav and expands that way*/}
251-
{}
252-
<div
253-
aria-labelledby={onExpand ? searchId : undefined}
254-
role={onExpand ? 'button' : undefined}
255-
className={`${prefix}--search-magnifier`}
256-
onClick={onExpand}
257-
onKeyDown={handleExpandButtonKeyDown}
258-
tabIndex={onExpand && !isExpanded ? 0 : -1}
259-
ref={expandButtonRef}
260-
aria-expanded={
261-
onExpand && isExpanded
262-
? true
263-
: onExpand && !isExpanded
264-
? false
265-
: undefined
266-
}
267-
aria-controls={onExpand ? uniqueId : undefined}>
268-
<CustomSearchIcon icon={renderIcon} />
269-
</div>
287+
270288
<label id={searchId} htmlFor={uniqueId} className={`${prefix}--label`}>
271289
{labelText}
272290
</label>

packages/styles/scss/components/search/_search.scss

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,7 @@
334334
.#{$prefix}--search--expandable .#{$prefix}--search-input {
335335
padding: 0;
336336
inline-size: 0;
337-
transition:
338-
padding $duration-fast-01 motion(standard, productive),
339-
width 0s linear $duration-fast-01;
337+
transition: transform $duration-fast-01 motion(standard, productive);
340338

341339
&::placeholder {
342340
position: relative;
@@ -389,4 +387,13 @@
389387
.#{$prefix}--search--expandable.#{$prefix}--search--disabled svg {
390388
fill: $icon-disabled;
391389
}
390+
391+
.#{$prefix}--search-magnifier-tooltip {
392+
display: flex;
393+
align-items: center;
394+
justify-content: center;
395+
.#{$prefix}--search-magnifier {
396+
position: relative;
397+
}
398+
}
392399
}

0 commit comments

Comments
 (0)