diff --git a/.changeset/serious-vans-sin.md b/.changeset/serious-vans-sin.md
new file mode 100644
index 00000000000..9ba84efa91b
--- /dev/null
+++ b/.changeset/serious-vans-sin.md
@@ -0,0 +1,5 @@
+---
+'@shopify/polaris': minor
+---
+
+[FiltersBar] Fixed bug where filters would disappear from the FiltersBar when clicking the Clear all button
diff --git a/polaris-react/src/components/Filters/Filters.stories.tsx b/polaris-react/src/components/Filters/Filters.stories.tsx
index dfefa8900db..338eb97c34a 100644
--- a/polaris-react/src/components/Filters/Filters.stories.tsx
+++ b/polaris-react/src/components/Filters/Filters.stories.tsx
@@ -1516,3 +1516,204 @@ export function WithFilterBarHidden() {
);
}
+
+export function WithAllFiltersPinned() {
+ const [accountStatus, setAccountStatus] = useState(null);
+ const [moneySpent, setMoneySpent] = useState(null);
+ const [taggedWith, setTaggedWith] = useState('');
+ const [queryValue, setQueryValue] = useState('');
+
+ const handleAccountStatusChange = useCallback(
+ (value) => setAccountStatus(value),
+ [],
+ );
+ const handleMoneySpentChange = useCallback(
+ (value) => setMoneySpent(value),
+ [],
+ );
+ const handleTaggedWithChange = useCallback(
+ (value) => setTaggedWith(value),
+ [],
+ );
+ const handleFiltersQueryChange = useCallback(
+ (value) => setQueryValue(value),
+ [],
+ );
+ const handleAccountStatusRemove = useCallback(
+ () => setAccountStatus(null),
+ [],
+ );
+ const handleMoneySpentRemove = useCallback(() => setMoneySpent(null), []);
+ const handleTaggedWithRemove = useCallback(() => setTaggedWith(''), []);
+ const handleQueryValueRemove = useCallback(() => setQueryValue(''), []);
+ const handleFiltersClearAll = useCallback(() => {
+ handleAccountStatusRemove();
+ handleMoneySpentRemove();
+ handleTaggedWithRemove();
+ handleQueryValueRemove();
+ }, [
+ handleAccountStatusRemove,
+ handleMoneySpentRemove,
+ handleQueryValueRemove,
+ handleTaggedWithRemove,
+ ]);
+
+ const filters = [
+ {
+ key: 'accountStatus',
+ label: 'Account status',
+ filter: (
+
+ ),
+ shortcut: true,
+ pinned: true,
+ },
+ {
+ key: 'taggedWith',
+ label: 'Tagged with',
+ filter: (
+
+ ),
+ shortcut: true,
+ pinned: true,
+ },
+ {
+ key: 'moneySpent',
+ label: 'Money spent',
+ filter: (
+
+ ),
+ shortcut: true,
+ pinned: true,
+ },
+ ];
+
+ const appliedFilters: FiltersProps['appliedFilters'] = [];
+ if (!isEmpty(accountStatus)) {
+ const key = 'accountStatus';
+ appliedFilters.push({
+ key,
+ label: disambiguateLabel(key, accountStatus),
+ onRemove: handleAccountStatusRemove,
+ });
+ }
+ if (!isEmpty(moneySpent)) {
+ const key = 'moneySpent';
+ appliedFilters.push({
+ key,
+ label: disambiguateLabel(key, moneySpent),
+ onRemove: handleMoneySpentRemove,
+ });
+ }
+ if (!isEmpty(taggedWith)) {
+ const key = 'taggedWith';
+ appliedFilters.push({
+ key,
+ label: disambiguateLabel(key, taggedWith),
+ onRemove: handleTaggedWithRemove,
+ });
+ }
+
+ return (
+
+
+
+ }
+ flushFilters
+ items={[
+ {
+ id: '341',
+ url: '#',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: '256',
+ url: '#',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ ]}
+ renderItem={(item) => {
+ const {id, url, name, location} = item;
+ const media = ;
+
+ return (
+
+
+ {name}
+
+ {location}
+
+ );
+ }}
+ />
+
+
+ );
+
+ function disambiguateLabel(key, value) {
+ switch (key) {
+ case 'moneySpent':
+ return `Money spent is between $${value[0]} and $${value[1]}`;
+ case 'taggedWith':
+ return `Tagged with ${value}`;
+ case 'accountStatus':
+ return value.map((val) => `Customer ${val}`).join(', ');
+ default:
+ return value;
+ }
+ }
+
+ function isEmpty(value) {
+ if (Array.isArray(value)) {
+ return value.length === 0;
+ } else {
+ return value === '' || value == null;
+ }
+ }
+}
diff --git a/polaris-react/src/components/Filters/components/FiltersBar/FiltersBar.tsx b/polaris-react/src/components/Filters/components/FiltersBar/FiltersBar.tsx
index 019b6eb7299..489c14a9278 100644
--- a/polaris-react/src/components/Filters/components/FiltersBar/FiltersBar.tsx
+++ b/polaris-react/src/components/Filters/components/FiltersBar/FiltersBar.tsx
@@ -78,6 +78,10 @@ export function FiltersBar({
};
const appliedFilterKeys = appliedFilters?.map(({key}) => key);
+ const pinnedFromPropsKeys = filters
+ .filter(({pinned}) => pinned)
+ .map(({key}) => key);
+
const pinnedFiltersFromPropsAndAppliedFilters = filters.filter(
({pinned, key}) => {
const isPinnedOrApplied =
@@ -182,17 +186,23 @@ export function FiltersBar({
);
const handleClearAllFilters = () => {
- setLocalPinnedFilters([]);
+ setLocalPinnedFilters(pinnedFromPropsKeys);
onClearAll?.();
};
- const shouldShowAddButton = filters.some((filter) => !filter.pinned);
+ const shouldShowAddButton =
+ filters.some((filter) => !filter.pinned) ||
+ filters.length !== localPinnedFilters.length;
const pinnedFiltersMarkup = pinnedFilters.map(
({key: filterKey, ...pinnedFilter}) => {
const appliedFilter = appliedFilters?.find(({key}) => key === filterKey);
const handleFilterPillRemove = () => {
setLocalPinnedFilters((currentLocalPinnedFilters) =>
- currentLocalPinnedFilters.filter((key) => key !== filterKey),
+ currentLocalPinnedFilters.filter((key) => {
+ const isMatchedFilters = key === filterKey;
+ const isPinnedFilterFromProps = pinnedFromPropsKeys.includes(key);
+ return !isMatchedFilters || isPinnedFilterFromProps;
+ }),
);
appliedFilter?.onRemove(filterKey);
};
@@ -236,26 +246,25 @@ export function FiltersBar({
) : null;
- const clearAllMarkup =
- appliedFilters?.length || localPinnedFilters.length ? (
-
+
- ) : null;
+ {i18n.translate('Polaris.Filters.clearFilters')}
+
+
+ ) : null;
return (
', () => {
let originalScroll: any;
@@ -388,4 +389,58 @@ describe('', () => {
],
});
});
+
+ it('will keep a pinned filter from props pinned when clearing', () => {
+ const appliedFilters = [
+ {
+ ...defaultProps.filters[1],
+ label: 'Bar 2',
+ value: ['Bar 2'],
+ onRemove: jest.fn(),
+ },
+ ];
+ const scrollSpy = jest.fn();
+ HTMLElement.prototype.scroll = scrollSpy;
+ const wrapper = mountWithApp(
+ ,
+ );
+
+ wrapper
+ .find(FilterPill, {
+ label: 'Bar 2',
+ })!
+ .trigger('onRemove');
+
+ expect(wrapper).toContainReactComponentTimes(FilterPill, 1);
+ });
+
+ it('will keep a pinned filter from props pinned when clearing all', () => {
+ const appliedFilters = [
+ {
+ ...defaultProps.filters[0],
+ label: 'Bar 2',
+ value: ['Bar 2'],
+ onRemove: jest.fn(),
+ },
+ {
+ ...defaultProps.filters[2],
+ label: 'Bar 2',
+ value: ['Bar 2'],
+ onRemove: jest.fn(),
+ },
+ ];
+ const scrollSpy = jest.fn();
+ HTMLElement.prototype.scroll = scrollSpy;
+ const wrapper = mountWithApp(
+ ,
+ );
+
+ wrapper
+ .find(Button, {
+ children: 'Clear all',
+ })!
+ .trigger('onClick');
+
+ expect(wrapper).toContainReactComponentTimes(FilterPill, 1);
+ });
});