Skip to content

Commit 84eef5c

Browse files
authored
fix(FilterBar): update search position to latest design specs (#5059)
1 parent 8f19421 commit 84eef5c

File tree

4 files changed

+62
-17
lines changed

4 files changed

+62
-17
lines changed

packages/main/src/components/FilterBar/FilterBar.cy.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ const variants = (
1212
</VariantManagement>
1313
);
1414

15-
const search = <Input placeholder={'Search'} />;
16-
1715
describe('FilterBar.cy.tsx', () => {
1816
it('Toggle FilterBar filters', () => {
1917
const toggle = cy.spy().as('toggleSpy');
@@ -249,7 +247,7 @@ describe('FilterBar.cy.tsx', () => {
249247

250248
it('toolbar', () => {
251249
cy.mount(
252-
<FilterBar search={search} header={variants} hideToolbar={false} showGoOnFB>
250+
<FilterBar header={variants} hideToolbar={false} showGoOnFB>
253251
<FilterGroupItem label="Classification" key="classification" data-testid="SELECT">
254252
<Select>
255253
<Option>Option 1</Option>
@@ -265,12 +263,11 @@ describe('FilterBar.cy.tsx', () => {
265263
cy.findByText('Filters');
266264
cy.findByText('Adapt Filters').should('not.exist');
267265
cy.findByText('Hide Filter Bar');
268-
cy.findByPlaceholderText('Search');
269266
cy.findByTestId('variantManagement');
270267
cy.findByTestId('SELECT');
271268

272269
cy.mount(
273-
<FilterBar search={search} header={variants} hideToolbar={true} showGoOnFB>
270+
<FilterBar header={variants} hideToolbar={true} showGoOnFB>
274271
<FilterGroupItem label="Classification" key="classification" data-testid="SELECT">
275272
<Select>
276273
<Option>Option 1</Option>
@@ -449,6 +446,26 @@ describe('FilterBar.cy.tsx', () => {
449446
cy.get('[show-colon="true"]').should('have.length', 2);
450447
});
451448

449+
it('FB search field', () => {
450+
cy.mount(
451+
<FilterBar search={<Input />}>
452+
<FilterGroupItem>
453+
<Input />
454+
</FilterGroupItem>
455+
<FilterGroupItem label="Input">
456+
<Input placeholder="Placeholder" />
457+
</FilterGroupItem>
458+
</FilterBar>
459+
);
460+
cy.get('[ui5-input]').each(($el, index) => {
461+
if (index === 0) {
462+
cy.wrap($el).should('be.visible').and('have.attr', 'data-component-name', 'FilterBarSearch');
463+
} else {
464+
cy.wrap($el).should('be.visible').and('not.have.attr', 'data-component-name', 'FilterBarSearch');
465+
}
466+
});
467+
});
468+
452469
mountWithCustomTagName(FilterBar);
453470

454471
cypressPassThroughTestsFactory(FilterBar);

packages/main/src/components/FilterBar/FilterBar.stories.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const meta = {
3333
title: 'Layouts & Floorplans / FilterBar',
3434
component: FilterBar,
3535
args: {
36-
search: <Input placeholder={'Search'} />,
36+
search: <Input />,
3737
header: <Title>Test</Title>,
3838
filterContainerWidth: '13.125rem'
3939
},
@@ -132,12 +132,18 @@ export const Default: Story = {
132132
};
133133

134134
export const WithLogic: Story = {
135-
render: () => {
135+
render: (args) => {
136136
const [age, setAge] = useState(37);
137137
const [countries, setCountries] = useState<Record<string, boolean>>({});
138138
const [currency, setCurrency] = useState('USD');
139139
const [date, setDate] = useState('');
140140
const [dateRange, setDateRange] = useState('');
141+
const [search, setSearch] = useState('');
142+
143+
const handleSearch = (e) => {
144+
setSearch(e.target.value);
145+
};
146+
141147
const handleAgeChange = (e) => {
142148
setAge(e.target.value);
143149
};
@@ -163,7 +169,7 @@ export const WithLogic: Story = {
163169
};
164170
return (
165171
<>
166-
<FilterBar>
172+
<FilterBar {...args} search={<Input onInput={handleSearch} />}>
167173
<FilterGroupItem label="Age" active={!!age} required>
168174
<StepInput value={age} onChange={handleAgeChange} required />
169175
</FilterGroupItem>
@@ -205,6 +211,10 @@ export const WithLogic: Story = {
205211
</FilterGroupItem>
206212
</FilterBar>
207213
<FlexBox direction={FlexBoxDirection.Column}>
214+
<FlexBox>
215+
<Label showColon>Search</Label>
216+
<Text>{search}</Text>
217+
</FlexBox>
208218
<FlexBox>
209219
<Label showColon>Age</Label>
210220
<Text>{age}</Text>

packages/main/src/components/FilterBar/index.tsx

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client';
22

3+
import searchIcon from '@ui5/webcomponents-icons/dist/search.js';
34
import { debounce, Device, enrichEventWithDetails, useI18nBundle } from '@ui5/webcomponents-react-base';
45
import { clsx } from 'clsx';
56
import type { CSSProperties, ElementType, ReactElement, ReactNode } from 'react';
@@ -13,6 +14,7 @@ import {
1314
GO,
1415
HIDE_FILTER_BAR,
1516
RESTORE,
17+
SEARCH,
1618
SHOW_FILTER_BAR
1719
} from '../../i18n/i18n-defaults.js';
1820
import type { CommonProps, Ui5CustomEvent } from '../../interfaces/index.js';
@@ -23,10 +25,10 @@ import type {
2325
TableDomRef,
2426
TableRowDomRef
2527
} from '../../webComponents/index.js';
26-
import { Button } from '../../webComponents/index.js';
28+
import { Button, Icon } from '../../webComponents/index.js';
29+
import { FilterGroupItem } from '../FilterGroupItem/index.js';
2730
import type { FilterGroupItemPropTypes } from '../FilterGroupItem/index.js';
2831
import { Toolbar } from '../Toolbar/index.js';
29-
import { ToolbarSeparator } from '../ToolbarSeparator/index.js';
3032
import { ToolbarSpacer } from '../ToolbarSpacer/index.js';
3133
import styles from './FilterBar.jss.js';
3234
import { FilterDialog } from './FilterDialog.js';
@@ -43,15 +45,18 @@ export interface FilterBarPropTypes extends CommonProps {
4345
*/
4446
children: ReactNode | ReactNode[];
4547
/**
46-
* Defines the search field next to the header of the `FilterBar`.
48+
* Defines the search field rendered as first filter item.
4749
*
48-
* __Note:__ If `hideToolbar` is `true` this prop has no effect.
50+
* __Note:__ Per default `placeholder`, `icon`, `noTypeahead` and `showClearIcon` are applied to the search input.
51+
*
52+
* __Note:__ The field is only available in the FilterBar not inside the filter configuration dialog.
4953
*/
5054
search?: ReactElement<InputPropTypes>;
5155
/**
5256
* Specifies header text or variant management that is shown in the toolbar on the first position
5357
*
5458
* __Note:__ Although this prop accepts all HTML Elements, it is strongly recommended that you only use `VariantManagement`, `Text` or `Title` in order to preserve the intended design.
59+
*
5560
* __Note:__ If `hideToolbar` is `true` this prop has no effect.
5661
*/
5762
header?: ReactNode;
@@ -272,6 +277,7 @@ const FilterBar = forwardRef<HTMLDivElement, FilterBarPropTypes>((props, ref) =>
272277
const showFilterBarText = i18nBundle.getText(SHOW_FILTER_BAR);
273278
const hideFilterBarText = i18nBundle.getText(HIDE_FILTER_BAR);
274279
const goText = i18nBundle.getText(GO);
280+
const searchText = i18nBundle.getText(SEARCH);
275281
const filtersText = !hideToolbar ? i18nBundle.getText(FILTERS) : i18nBundle.getText(ADAPT_FILTERS);
276282

277283
// dialog
@@ -649,14 +655,24 @@ const FilterBar = forwardRef<HTMLDivElement, FilterBarPropTypes>((props, ref) =>
649655
{!hideToolbar && (
650656
<Toolbar className={classes.filterBarHeader} toolbarStyle={ToolbarStyle.Clear}>
651657
{header}
652-
{header && search && <ToolbarSeparator />}
653-
{search && !isPhone && <div ref={searchRef}>{renderSearchWithValue(search, searchValue)}</div>}
654658
{hasButtons && <ToolbarSpacer />}
655659
{ToolbarButtons}
656660
</Toolbar>
657661
)}
658662
{mountFilters && (
659663
<div className={filterAreaClasses} style={{ position: 'relative' }} ref={filterAreaRef}>
664+
{search && (
665+
<FilterGroupItem data-in-fb visibleInFilterBar data-with-toolbar={!hideToolbar}>
666+
<div ref={searchRef}>
667+
{renderSearchWithValue(search, searchValue, {
668+
placeholder: searchText,
669+
icon: <Icon name={searchIcon} />,
670+
noTypeahead: true,
671+
showClearIcon: true
672+
})}
673+
</div>
674+
</FilterGroupItem>
675+
)}
660676
{calculatedChildren}
661677
{hideToolbar && (
662678
<>

packages/main/src/components/FilterBar/utils.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ export const filterValue = (ref, child) => {
3939
return filterItemProps;
4040
};
4141

42-
export const renderSearchWithValue = (renderSearchElement, searchValue) => {
42+
export const renderSearchWithValue = (renderSearchElement, searchValue, defaultProps = {}) => {
43+
const props = { ...defaultProps, ...renderSearchElement?.props };
4344
return cloneElement(renderSearchElement, {
44-
value: searchValue ?? renderSearchElement?.props?.value,
45-
'data-component-name': 'FilterBarSearch'
45+
...props,
46+
'data-component-name': 'FilterBarSearch',
47+
value: searchValue ?? renderSearchElement?.props?.value
4648
});
4749
};
4850

0 commit comments

Comments
 (0)