Improve options field
This commit is contained in:
parent
6e68c0b4da
commit
a30f52e2d8
5 changed files with 99 additions and 66 deletions
|
@ -128,6 +128,15 @@ const Filter: React.FC<FilterProps> = props => {
|
||||||
transition
|
transition
|
||||||
disablePortal
|
disablePortal
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
|
modifiers={{
|
||||||
|
flip: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
preventOverflow: {
|
||||||
|
boundariesElement: "scrollParent",
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{({ TransitionProps, placement }) => (
|
{({ TransitionProps, placement }) => (
|
||||||
<Grow
|
<Grow
|
||||||
|
|
|
@ -9,16 +9,13 @@ import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
|
||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import Checkbox from "../Checkbox";
|
import Checkbox from "../Checkbox";
|
||||||
import Hr from "../Hr";
|
import Hr from "../Hr";
|
||||||
import { IFilterElement } from "./types";
|
import { FilterBaseFieldProps } from "./types";
|
||||||
import { FilterReducerAction } from "./reducer";
|
|
||||||
|
|
||||||
interface FilterAutocompleteFieldProps {
|
interface FilterAutocompleteFieldProps extends FilterBaseFieldProps {
|
||||||
displayValues: Record<string, MultiAutocompleteChoiceType[]>;
|
displayValues: Record<string, MultiAutocompleteChoiceType[]>;
|
||||||
filterField: IFilterElement<string>;
|
|
||||||
setDisplayValues: (
|
setDisplayValues: (
|
||||||
values: Record<string, MultiAutocompleteChoiceType[]>
|
values: Record<string, MultiAutocompleteChoiceType[]>
|
||||||
) => void;
|
) => void;
|
||||||
onFilterPropertyChange: React.Dispatch<FilterReducerAction<string>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
|
|
@ -11,22 +11,18 @@ import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { TextField } from "@material-ui/core";
|
import { TextField } from "@material-ui/core";
|
||||||
import { toggle } from "@saleor/utils/lists";
|
|
||||||
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
|
|
||||||
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||||
import Hr from "../Hr";
|
import Hr from "../Hr";
|
||||||
import Checkbox from "../Checkbox";
|
import Checkbox from "../Checkbox";
|
||||||
import SingleSelectField from "../SingleSelectField";
|
import SingleSelectField from "../SingleSelectField";
|
||||||
import { SingleAutocompleteChoiceType } from "../SingleAutocompleteSelectField";
|
import { SingleAutocompleteChoiceType } from "../SingleAutocompleteSelectField";
|
||||||
import FormSpacer from "../FormSpacer";
|
import FormSpacer from "../FormSpacer";
|
||||||
import MultiAutocompleteSelectField, {
|
import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
|
||||||
MultiAutocompleteChoiceType
|
|
||||||
} from "../MultiAutocompleteSelectField";
|
|
||||||
import Link from "../Link";
|
|
||||||
import { IFilter, FieldType, FilterType } from "./types";
|
import { IFilter, FieldType, FilterType } from "./types";
|
||||||
import Arrow from "./Arrow";
|
import Arrow from "./Arrow";
|
||||||
import { FilterReducerAction } from "./reducer";
|
import { FilterReducerAction } from "./reducer";
|
||||||
import FilterAutocompleteField from "./FilterAutocompleteField";
|
import FilterAutocompleteField from "./FilterAutocompleteField";
|
||||||
|
import FilterOptionField from "./FilterOptionField";
|
||||||
|
|
||||||
export interface FilterContentProps<T extends string = string> {
|
export interface FilterContentProps<T extends string = string> {
|
||||||
currencySymbol: string;
|
currencySymbol: string;
|
||||||
|
@ -341,61 +337,12 @@ const FilterContent: React.FC<FilterContentProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{filterField.type === FieldType.options &&
|
{filterField.type === FieldType.options && (
|
||||||
(filterField.multiple ? (
|
<FilterOptionField
|
||||||
filterField.options.map(option => (
|
filterField={filterField}
|
||||||
<div className={classes.option} key={option.value}>
|
onFilterPropertyChange={onFilterPropertyChange}
|
||||||
<FormControlLabel
|
/>
|
||||||
control={
|
)}
|
||||||
<Checkbox
|
|
||||||
checked={filterField.value.includes(
|
|
||||||
option.value
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={option.label}
|
|
||||||
name={filterField.name}
|
|
||||||
onChange={() =>
|
|
||||||
onFilterPropertyChange({
|
|
||||||
payload: {
|
|
||||||
name: filterField.name,
|
|
||||||
update: {
|
|
||||||
value: toggle(
|
|
||||||
option.value,
|
|
||||||
filterField.value,
|
|
||||||
(a, b) => a === b
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
type: "set-property"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<SingleSelectField
|
|
||||||
choices={filterField.options}
|
|
||||||
name={filterField.name}
|
|
||||||
value={filterField.value[0]}
|
|
||||||
InputProps={{
|
|
||||||
classes: {
|
|
||||||
input: classes.input
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={event =>
|
|
||||||
onFilterPropertyChange({
|
|
||||||
payload: {
|
|
||||||
name: filterField.name,
|
|
||||||
update: {
|
|
||||||
value: [event.target.value]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
type: "set-property"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
{filterField.type === FieldType.boolean &&
|
{filterField.type === FieldType.boolean &&
|
||||||
filterField.options.map(option => (
|
filterField.options.map(option => (
|
||||||
<div
|
<div
|
||||||
|
|
74
src/components/Filter/FilterOptionField.tsx
Normal file
74
src/components/Filter/FilterOptionField.tsx
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||||
|
import Radio from "@material-ui/core/Radio";
|
||||||
|
import React from "react";
|
||||||
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
import { toggle } from "@saleor/utils/lists";
|
||||||
|
import Checkbox from "../Checkbox";
|
||||||
|
import { FilterBaseFieldProps } from "./types";
|
||||||
|
|
||||||
|
const useStyles = makeStyles(
|
||||||
|
theme => ({
|
||||||
|
option: {
|
||||||
|
left: -theme.spacing(0.5),
|
||||||
|
position: "relative"
|
||||||
|
},
|
||||||
|
optionRadio: {
|
||||||
|
left: -theme.spacing(0.25)
|
||||||
|
},
|
||||||
|
root: {}
|
||||||
|
}),
|
||||||
|
{ name: "FilterOptionField" }
|
||||||
|
);
|
||||||
|
|
||||||
|
const FilterOptionField: React.FC<FilterBaseFieldProps> = ({
|
||||||
|
filterField,
|
||||||
|
onFilterPropertyChange
|
||||||
|
}) => {
|
||||||
|
const classes = useStyles({});
|
||||||
|
const handleSelect = (value: string) =>
|
||||||
|
onFilterPropertyChange({
|
||||||
|
payload: {
|
||||||
|
name: filterField.name,
|
||||||
|
update: {
|
||||||
|
value: filterField.multiple
|
||||||
|
? toggle(value, filterField.value, (a, b) => a === b)
|
||||||
|
: [value]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type: "set-property"
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.root}>
|
||||||
|
{filterField.options.map(option => (
|
||||||
|
<div
|
||||||
|
className={classNames(classes.option, {
|
||||||
|
[classes.optionRadio]: !filterField.multiple
|
||||||
|
})}
|
||||||
|
key={option.value}
|
||||||
|
>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
filterField.multiple ? (
|
||||||
|
<Checkbox checked={filterField.value.includes(option.value)} />
|
||||||
|
) : (
|
||||||
|
<Radio
|
||||||
|
checked={filterField.value[0] === option.value}
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
label={option.label}
|
||||||
|
name={filterField.name}
|
||||||
|
onChange={() => handleSelect(option.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterOptionField.displayName = "FilterOptionField";
|
||||||
|
export default FilterOptionField;
|
|
@ -1,5 +1,6 @@
|
||||||
import { FetchMoreProps, SearchPageProps } from "@saleor/types";
|
import { FetchMoreProps, SearchPageProps } from "@saleor/types";
|
||||||
import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
|
import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
|
||||||
|
import { FilterReducerAction } from "./reducer";
|
||||||
|
|
||||||
export enum FieldType {
|
export enum FieldType {
|
||||||
autocomplete,
|
autocomplete,
|
||||||
|
@ -28,6 +29,11 @@ export interface IFilterElement<T extends string = string>
|
||||||
type: FieldType;
|
type: FieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FilterBaseFieldProps<T extends string = string> {
|
||||||
|
filterField: IFilterElement<T>;
|
||||||
|
onFilterPropertyChange: React.Dispatch<FilterReducerAction<T>>;
|
||||||
|
}
|
||||||
|
|
||||||
export type IFilter<T extends string = string> = Array<IFilterElement<T>>;
|
export type IFilter<T extends string = string> = Array<IFilterElement<T>>;
|
||||||
|
|
||||||
export enum FilterType {
|
export enum FilterType {
|
||||||
|
|
Loading…
Reference in a new issue