Skip to content

Commit

Permalink
feat(filters): [publish_preview] insure that options and option group…
Browse files Browse the repository at this point in the history
…s are handled by the 'add filters' select input
  • Loading branch information
ByronDWall committed Oct 21, 2024
1 parent 487f737 commit eace951
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export const menuStyles = css`

const menuBodyStyle = css`
width: 100%;
overflow: hidden;
`;

function FilterMenu(props: TFilterMenuProps) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const mainActionButton = css`
z-index: 1;
border-radius: ${designTokens.borderRadius20};
&:focus {
box-shadow: 0px 0px 0px 2px ${designTokens.colorPrimary40};
box-shadow: 0 0 0 2px ${designTokens.colorPrimary40};
}
`;

Expand All @@ -76,6 +76,9 @@ export const removeButton = css`
display: flex;
svg {
fill: ${designTokens.colorNeutral40} !important;
&:hover {
fill: ${designTokens.colorPrimary40} !important;
}
}
`;

Expand Down
25 changes: 10 additions & 15 deletions packages/components/filters/src/filters.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import TextInput from '@commercetools-uikit/text-input';
import { MenuProps, MenuListProps } from 'react-select';
import Filters, { type TFiltersProps } from './filters';

//TODO: move example data and components to separate files
//TODO: better docs on different states and how to accomplish them

const primaryColorOptions = [
{ label: 'Blue', value: 'blue', key: 'blue', id: '2' },
{ label: 'Red', value: 'red', key: 'red', id: '4' },
Expand All @@ -22,10 +25,10 @@ const secondaryColorOptions = [
{ label: 'Silver', value: 'silver', key: 'silver', id: '10' },
];

// const filterGroups = [
// { key: 'secondaryColors', label: <div>Secondary Colors</div> },
// { key: 'primaryColors', label: <div>Primary Colors</div> },
// ];
const filterGroups = [
{ key: 'secondaryColors', label: <div>Secondary Colors</div> },
{ key: 'primaryColors', label: <div>Primary Colors</div> },
];

const CustomSelectMenu = ({
children,
Expand Down Expand Up @@ -57,14 +60,6 @@ const SearchComponent = () => {
);
};

// const RadioComponent = () => {
// const [v, setV] = useState('1');

// return (

// );
// };

const meta: Meta<typeof Filters> = {
title: 'components/Filters',
component: Filters,
Expand Down Expand Up @@ -144,7 +139,7 @@ export const BasicExample: Story = (_props: TFiltersProps) => {
{
key: 'primaryColors',
label: 'Primary Colors',
groupKey: 'primaryColors',
groupKey: 'notarealkey',
filterMenuConfiguration: {
renderMenuBody: () => (
<SelectInput
Expand Down Expand Up @@ -212,14 +207,14 @@ export const BasicExample: Story = (_props: TFiltersProps) => {
{
key: 'fruits',
label: 'Fruits',
groupKey: 'secondaryColors',
filterMenuConfiguration: {
renderMenuBody: () => (
<RadioInput.Group
id="fruit-selector"
name="fruits"
value={fruitsValue}
onChange={(e) => {
console.log(e);
setFruitsValue(e.target.value);
}}
>
Expand All @@ -237,7 +232,7 @@ export const BasicExample: Story = (_props: TFiltersProps) => {
<Filters
renderSearchComponent={SearchComponent}
filters={filters}
// filterGroups={filterGroups}
filterGroups={filterGroups}
appliedFilters={appliedFilters}
onClearAllRequest={clearAllFilters}
/>
Expand Down
85 changes: 60 additions & 25 deletions packages/components/filters/src/filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
FilterIcon,
PlusBoldIcon,
} from '@commercetools-uikit/icons';
import SelectInput from '@commercetools-uikit/select-input';
import SelectInput, {
TOption,
TOptionObject,
} from '@commercetools-uikit/select-input';
import Spacings from '@commercetools-uikit/spacings';
import { useIntl } from 'react-intl';
import { MenuProps, MenuListProps } from 'react-select';
Expand All @@ -25,6 +28,13 @@ import FilterMenu, {
import messages from './messages';
import { Badge } from './badge';

type TAddFilterSelectOption = {
value: string;
label: ReactNode;
isDisabled: boolean;
};

//TODO: JSDoc annotations of types that are arrays/objects for storybook
type TAppliedFilter = {
/**
* unique identifier for the filter
Expand Down Expand Up @@ -153,11 +163,19 @@ const menuListStyles = css`
gap: ${designTokens.spacing20};
`;

//TODO: better styling and set up scrolling when there are lots of options
const CustomSelectMenu = ({
children,
innerProps: { ref, ...restInnerProps },
}: MenuProps) => (
<div ref={ref} {...restInnerProps}>
<div
ref={ref}
{...restInnerProps}
css={css`
overflow: hidden auto;
max-width: 100%;
`}
>
{children}
</div>
);
Expand Down Expand Up @@ -211,24 +229,42 @@ function Filters(props: TFiltersProps) {

// TODO: handle options that don't have a group if `filterGroups` is passed
const getFilterOptions = () => {
let filterOptions: (TOption | (TOptionObject & { key: string }))[] = [];
// set option groups
if (props.filterGroups) {
return props.filterGroups.map((filterGroup) => ({
filterOptions = props.filterGroups.map((filterGroup) => ({
label: filterGroup.label,
options: props.filters
.filter((filter) => filter.groupKey === filterGroup.key)
.map((filter) => ({
key: filterGroup.key,
options: [],
}));
}
return props.filters.reduce((filterOptions, filter) => {
//if theres a groupkey and an filterGroups, add option to its group
if (filter.groupKey && props.filterGroups) {
const optionGroup = filterOptions.find(
//@ts-ignore
(option) => option?.key === filter.groupKey
);
if (optionGroup) {
//@ts-ignore
optionGroup?.options?.push({
value: filter.key,
label: filter.label,
isDisabled: filter.isDisabled,
})),
}));
} else {
return props.filters.map((filter) => ({
value: filter.key,
label: filter.label,
isDisabled: filter.isDisabled,
}));
}
});
return filterOptions;
}
}
// otherwise add option directly
return [
...filterOptions,
{
value: filter.key,
label: filter.label,
isDisabled: filter.isDisabled,
},
];
}, filterOptions);
};

const removeFilter = (filterKey: string) =>
Expand All @@ -238,9 +274,6 @@ function Filters(props: TFiltersProps) {
)
);

const locallyVisibleRemovableFilterCount =
localVisibleFilters.length - persistedFilterKeys.length;

return (
<>
<Spacings.Inline scale="m" alignItems="center">
Expand All @@ -254,16 +287,15 @@ function Filters(props: TFiltersProps) {
icon={<FilterIcon />}
onClick={handleFiltersClick}
/>
{locallyVisibleRemovableFilterCount > 1 && !showFilterControls && (
{props.appliedFilters.length > 1 && !showFilterControls && (
<Badge
id={'uikit-filters-selected-filter-count'}
label={`${locallyVisibleRemovableFilterCount}`}
label={`${props.appliedFilters.length}`}
/>
)}
</Spacings.Inline>
</Spacings.Inline>
<div css={horizontalDividerStyles} />

<hr css={horizontalDividerStyles} />
<CollapsibleMotion
isClosed={!showFilterControls}
onToggle={() => setShowFilterControls(!showFilterControls)}
Expand Down Expand Up @@ -333,8 +365,9 @@ function Filters(props: TFiltersProps) {
<Popover.Portal>
<Popover.Content side="bottom" align="start" css={menuStyles}>
<SelectInput
id="ui-kit-add-filters-select"
name="add filters"
options={getFilterOptions()}
options={getFilterOptions() as TOption[]}
onChange={(e) => {
setLocalVisibleFilters(
Array.prototype.concat(
Expand All @@ -351,14 +384,16 @@ function Filters(props: TFiltersProps) {
controlShouldRenderValue={false}
isMulti={true}
// @ts-ignore
isOptionDisabled={(option: unknown) => option.isDisabled}
isOptionDisabled={(option: TAddFilterSelectOption) =>
option.isDisabled
}
backspaceRemovesValue={false}
isClearable={false}
/>
</Popover.Content>
</Popover.Portal>
</Popover.Root>
{locallyVisibleRemovableFilterCount > 1 && (
{props.appliedFilters.length > 1 && (
<>
<div css={verticalDividerStyles} />
<FlatButton
Expand Down

0 comments on commit eace951

Please sign in to comment.