Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/chilled-jobs-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@shopify/polaris': minor
'polaris.shopify.com': minor
---

Updated `IndexFilters` to support hiding both filters and search field
10 changes: 4 additions & 6 deletions polaris-react/src/components/AlphaFilters/AlphaFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ export function AlphaFilters({
const [localPinnedFilters, setLocalPinnedFilters] = useState<string[]>([]);
const hasMounted = useRef(false);

const enabledFilters = filters.filter((filter) => !filter.disabled);

useEffect(() => {
hasMounted.current = true;
});
Expand All @@ -143,14 +141,14 @@ export function AlphaFilters({
};
const appliedFilterKeys = appliedFilters?.map(({key}) => key);

const pinnedFiltersFromPropsAndAppliedFilters = enabledFilters.filter(
const pinnedFiltersFromPropsAndAppliedFilters = filters.filter(
({pinned, key}) =>
(Boolean(pinned) || appliedFilterKeys?.includes(key)) &&
// Filters that are pinned in local state display at the end of our list
!localPinnedFilters.find((filterKey) => filterKey === key),
);
const pinnedFiltersFromLocalState = localPinnedFilters
.map((key) => enabledFilters.find((filter) => filter.key === key))
.map((key) => filters.find((filter) => filter.key === key))
.reduce<FilterInterface[]>(
(acc, filter) => (filter ? [...acc, filter] : acc),
[],
Expand All @@ -161,7 +159,7 @@ export function AlphaFilters({
...pinnedFiltersFromLocalState,
];

const additionalFilters = enabledFilters
const additionalFilters = filters
.filter((filter) => !pinnedFilters.find(({key}) => key === filter.key))
.map((filter) => ({
content: filter.label,
Expand Down Expand Up @@ -204,7 +202,7 @@ export function AlphaFilters({
onClearAll?.();
};

const shouldShowAddButton = enabledFilters.some((filter) => !filter.pinned);
const shouldShowAddButton = filters.some((filter) => !filter.pinned);

const additionalContent = useMemo(() => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ export function FilterPill({
</Button>
);

if (disabled) {
return null;
}

return (
<div ref={elementRef}>
<Popover
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@ describe('<Filters />', () => {
});
});

it('will pass the disabled prop to the activator', () => {
it('will return null if disabled', () => {
const wrapper = mountWithApp(<FilterPill {...defaultProps} disabled />);
expect(wrapper).toContainReactComponent(UnstyledButton, {
disabled: true,
});
expect(wrapper!.domNode).toBeNull();
});

it('will invoked the onClick prop when clicked, if present', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,15 @@ describe('<AlphaFilters />', () => {
});
});

it('will not render a disabled filter', () => {
it('will not render a disabled filter if pinned', () => {
const scrollSpy = jest.fn();
HTMLElement.prototype.scroll = scrollSpy;
const filters = [
...defaultProps.filters,
{
key: 'disabled',
label: 'Disabled',
pinned: false,
pinned: true,
disabled: true,
filter: <div>Filter</div>,
},
Expand All @@ -158,6 +158,8 @@ describe('<AlphaFilters />', () => {
<AlphaFilters {...defaultProps} filters={filters} />,
);

expect(wrapper).toContainReactComponentTimes(FilterPill, 2);

wrapper.act(() => {
wrapper
.find('button', {
Expand All @@ -173,10 +175,6 @@ describe('<AlphaFilters />', () => {
],
});

expect(wrapper).not.toContainReactComponent(ActionList, {
items: expect.arrayContaining([
expect.objectContaining({content: 'Disabled'}),
]),
});
expect(wrapper.findAll(FilterPill)[1].domNode).toBeNull();
});
});
145 changes: 145 additions & 0 deletions polaris-react/src/components/IndexFilters/IndexFilters.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -948,3 +948,148 @@ export function Disabled() {
}
}
}

export function WithQueryFieldAndFiltersHidden() {
const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
const [itemStrings, setItemStrings] = useState([
'All',
'Unpaid',
'Open',
'Closed',
'Local delivery',
'Local pickup',
]);
const deleteView = (index: number) => {
const newItemStrings = [...itemStrings];
newItemStrings.splice(index, 1);
setItemStrings(newItemStrings);
setSelected(0);
};

const duplicateView = async (name: string) => {
setItemStrings([...itemStrings, name]);
setSelected(itemStrings.length);
await sleep(1);
return true;
};

const tabs: AlphaTabProps[] = itemStrings.map((item, index) => ({
content: item,
index,
onAction: () => {},
id: `${item}-${index}`,
isLocked: index === 0,
actions:
index === 0
? []
: [
{
type: 'rename',
onAction: () => {},
onPrimaryAction: async (value: string) => {
const newItemsStrings = tabs.map((item, idx) => {
if (idx === index) {
return value;
}
return item.content;
});
await sleep(1);
setItemStrings(newItemsStrings);
return true;
},
},
{
type: 'duplicate',
onPrimaryAction: async (name) => {
await sleep(1);
duplicateView(name);
return true;
},
},
{
type: 'edit',
},
{
type: 'delete',
onPrimaryAction: async (id: string) => {
await sleep(1);
deleteView(index);
return true;
},
},
],
}));
const [selected, setSelected] = useState(0);
const onCreateNewView = async (value: string) => {
await sleep(500);
setItemStrings([...itemStrings, value]);
setSelected(itemStrings.length);
return true;
};
const sortOptions: IndexFiltersProps['sortOptions'] = [
{label: 'Order', value: 'order asc', directionLabel: 'Ascending'},
{label: 'Order', value: 'order desc', directionLabel: 'Descending'},
{label: 'Customer', value: 'customer asc', directionLabel: 'A-Z'},
{label: 'Customer', value: 'customer desc', directionLabel: 'Z-A'},
{label: 'Date', value: 'date asc', directionLabel: 'A-Z'},
{label: 'Date', value: 'date desc', directionLabel: 'Z-A'},
{label: 'Total', value: 'total asc', directionLabel: 'Ascending'},
{label: 'Total', value: 'total desc', directionLabel: 'Descending'},
];
const [sortSelected, setSortSelected] = useState(['order asc']);
const {mode, setMode} = useSetIndexFiltersMode();
const onHandleCancel = () => {};

const onHandleSave = async () => {
await sleep(1);
return true;
};

const primaryAction: IndexFiltersProps['primaryAction'] =
selected === 0
? {
type: 'save-as',
onAction: onCreateNewView,
disabled: false,
loading: false,
}
: {
type: 'save',
onAction: onHandleSave,
disabled: false,
loading: false,
};

return (
<Card>
<IndexFilters
sortOptions={sortOptions}
sortSelected={sortSelected}
queryValue=""
queryPlaceholder="Searching in all"
onQueryChange={() => {}}
onQueryClear={() => {}}
onSort={setSortSelected}
primaryAction={primaryAction}
cancelAction={{
onAction: onHandleCancel,
disabled: false,
loading: false,
}}
tabs={tabs}
selected={selected}
onSelect={setSelected}
canCreateNewView
onCreateNewView={onCreateNewView}
filters={[]}
onClearAll={() => {}}
mode={mode}
setMode={setMode}
hideQueryField
hideFilters
/>
<Table />
</Card>
);
}
26 changes: 14 additions & 12 deletions polaris-react/src/components/IndexFilters/IndexFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,20 @@ export function IndexFilters({
{isLoading && !mdDown && <Spinner size="small" />}
{mode === IndexFiltersMode.Default ? (
<>
<SearchFilterButton
onClick={handleClickFilterButton}
aria-label={searchFilterAriaLabel}
tooltipContent={searchFilterTooltip}
disabled={disabled}
hideFilters={hideFilters}
hideQueryField={hideQueryField}
style={{
...defaultStyle,
...transitionStyles[state],
}}
/>
{hideFilters && hideQueryField ? null : (
<SearchFilterButton
onClick={handleClickFilterButton}
aria-label={searchFilterAriaLabel}
tooltipContent={searchFilterTooltip}
disabled={disabled}
hideFilters={hideFilters}
hideQueryField={hideQueryField}
style={{
...defaultStyle,
...transitionStyles[state],
}}
/>
)}
{sortMarkup}
</>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ examples:
- fileName: index-filters-with-no-filters.tsx
title: With no filters
description: An IndexFilters component with only view management, search, and sorting.
- fileName: index-filters-with-no-search-or-filters.tsx
title: With no search or filters
description: An IndexFilters component with only view management and sorting.
---

Merchants use filters to:
Expand Down
6 changes: 3 additions & 3 deletions polaris.shopify.com/pages/examples/index-filters-default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function IndexFiltersDefault() {
{
type: 'rename',
onAction: () => {},
onPrimaryAction: async (value: string) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
const newItemsStrings = tabs.map((item, idx) => {
if (idx === index) {
return value;
Expand All @@ -66,9 +66,9 @@ function IndexFiltersDefault() {
},
{
type: 'duplicate',
onPrimaryAction: async (name) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
await sleep(1);
duplicateView(name);
duplicateView(value);
return true;
},
},
Expand Down
6 changes: 3 additions & 3 deletions polaris.shopify.com/pages/examples/index-filters-disabled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function IndexFiltersDisabled() {
{
type: 'rename',
onAction: () => {},
onPrimaryAction: async (value: string) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
const newItemsStrings = tabs.map((item, idx) => {
if (idx === index) {
return value;
Expand All @@ -66,9 +66,9 @@ function IndexFiltersDisabled() {
},
{
type: 'duplicate',
onPrimaryAction: async (name) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
await sleep(1);
duplicateView(name);
duplicateView(value);
return true;
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function IndexFiltersWithFilteringMode() {
{
type: 'rename',
onAction: () => {},
onPrimaryAction: async (value: string) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
const newItemsStrings = tabs.map((item, idx) => {
if (idx === index) {
return value;
Expand All @@ -67,9 +67,9 @@ function IndexFiltersWithFilteringMode() {
},
{
type: 'duplicate',
onPrimaryAction: async (name) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
await sleep(1);
duplicateView(name);
duplicateView(value);
return true;
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function IndexFiltersWithNoFiltersExample() {
{
type: 'rename',
onAction: () => {},
onPrimaryAction: async (value: string) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
const newItemsStrings = tabs.map((item, idx) => {
if (idx === index) {
return value;
Expand All @@ -63,9 +63,9 @@ function IndexFiltersWithNoFiltersExample() {
},
{
type: 'duplicate',
onPrimaryAction: async (name) => {
onPrimaryAction: async (value: string): Promise<boolean> => {
await sleep(1);
duplicateView(name);
duplicateView(value);
return true;
},
},
Expand Down
Loading