Improve component composition (#1224)

* Improve component composition

* Delete unused file

* Update snapshots
This commit is contained in:
Dominik Żegleń 2021-07-12 15:48:01 +02:00 committed by GitHub
parent 2eae52d3df
commit bba8c75d31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 249 additions and 203 deletions

View file

@ -21,9 +21,9 @@ import {
InvalidFilters
} from "../types";
import FilterContentBody, { FilterContentBodyProps } from "./FilterContentBody";
import FilterContentBodyNameField from "./FilterContentBodyNameField";
import FilterContentHeader from "./FilterContentHeader";
import FilterErrorsList from "./FilterErrorsList";
import FilterGroupLabel from "./FilterGroupLabel";
const useExpanderStyles = makeStyles(
() => ({
@ -219,7 +219,7 @@ const FilterContent: React.FC<FilterContentProps> = ({
classes={summaryClasses}
onClick={() => handleFilterOpen(filter)}
>
<FilterContentBodyNameField
<FilterGroupLabel
filter={currentFilter}
onFilterPropertyChange={action =>
handleFilterPropertyGroupChange(action, filter)

View file

@ -1,12 +1,10 @@
import { FormControlLabel, Radio, TextField } from "@material-ui/core";
import { fade } from "@material-ui/core/styles/colorManipulator";
import { FormControlLabel, Radio } from "@material-ui/core";
import FormSpacer from "@saleor/components/FormSpacer";
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
import SingleSelectField from "@saleor/components/SingleSelectField";
import { makeStyles } from "@saleor/theme";
import classNames from "classnames";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useIntl } from "react-intl";
import Arrow from "../Arrow";
import FilterAutocompleteField, {
@ -15,45 +13,14 @@ import FilterAutocompleteField, {
import FilterOptionField from "../FilterOptionField";
import { FilterReducerAction } from "../reducer";
import { FieldType, FilterType, IFilterElement } from "../types";
import { getIsFilterMultipleChoices } from "./utils";
const useStyles = makeStyles(
theme => ({
andLabel: {
margin: theme.spacing(0, 2)
},
arrow: {
marginRight: theme.spacing(2)
},
filterSettings: {
background: fade(theme.palette.primary.main, 0.1),
padding: theme.spacing(2, 3)
},
input: {
padding: "12px 0 9px 12px"
},
inputRange: {
alignItems: "center",
display: "flex"
},
option: {
left: -theme.spacing(0.5),
position: "relative"
},
optionRadio: {
left: -theme.spacing(0.25)
}
}),
{ name: "FilterContentBody" }
);
const filterTestingContext = "filter-field";
import FilterRangeField from "./FilterRangeField";
import FilterTextField from "./FilterTextField";
import useStyles from "./styles";
import { filterTestingContext, getIsFilterMultipleChoices } from "./utils";
export interface FilterContentBodyProps<T extends string = string> {
children?: React.ReactNode;
filter: IFilterElement<T>;
currencySymbol?: string;
currencySymbol: string;
initialAutocompleteDisplayValues: FilterAutocompleteDisplayValues;
onFilterPropertyChange: React.Dispatch<FilterReducerAction<T>>;
autocompleteDisplayValues: FilterAutocompleteDisplayValues;
@ -78,28 +45,10 @@ const FilterContentBody: React.FC<FilterContentBodyProps> = ({
<div className={classes.filterSettings}>
{children}
{filter.type === FieldType.text && (
<TextField
data-test={filterTestingContext}
data-test-id={filter.name}
fullWidth
name={filter.name}
InputProps={{
classes: {
input: classes.input
}
}}
value={filter.value[0]}
onChange={event =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
value: [event.target.value, filter.value[1]]
}
},
type: "set-property"
})
}
<FilterTextField
currencySymbol={currencySymbol}
filter={filter}
onFilterPropertyChange={onFilterPropertyChange}
/>
)}
{[FieldType.date, FieldType.price, FieldType.number].includes(
@ -112,7 +61,7 @@ const FilterContentBody: React.FC<FilterContentBodyProps> = ({
value={filter.multiple ? FilterType.MULTIPLE : FilterType.SINGULAR}
InputProps={{
classes: {
input: classes.input
input: classes.fieldInput
}
}}
onChange={event =>
@ -133,101 +82,16 @@ const FilterContentBody: React.FC<FilterContentBodyProps> = ({
<Arrow className={classes.arrow} />
</div>
{filter.multiple ? (
<>
<TextField
data-test={filterTestingContext}
data-test-id={filter.name}
data-test-range-type="min"
fullWidth
name={filter.name + "_min"}
InputProps={{
classes: {
input: classes.input
},
endAdornment:
filter.type === FieldType.price && currencySymbol,
type: filter.type === FieldType.date ? "date" : "number"
}}
value={filter.value[0]}
onChange={event =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
value: [event.target.value, filter.value[1]]
}
},
type: "set-property"
})
}
/>
<span className={classes.andLabel}>
<FormattedMessage
defaultMessage="and"
description="filter range separator"
/>
</span>
<TextField
data-test={filterTestingContext}
data-test-id={filter.name}
data-test-range-type="max"
fullWidth
name={filter.name + "_max"}
InputProps={{
classes: {
input: classes.input
},
endAdornment:
filter.type === FieldType.price && currencySymbol,
type: filter.type === FieldType.date ? "date" : "number"
}}
value={filter.value[1]}
onChange={event =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
value: [filter.value[0], event.target.value]
}
},
type: "set-property"
})
}
/>
</>
<FilterRangeField
currencySymbol={currencySymbol}
filter={filter}
onFilterPropertyChange={onFilterPropertyChange}
/>
) : (
<TextField
data-test={filterTestingContext}
data-test-id={filter.name}
fullWidth
name={filter.name}
InputProps={{
classes: {
input: classes.input
},
endAdornment:
filter.type === FieldType.price && currencySymbol,
type:
filter.type === FieldType.date
? "date"
: [FieldType.number, FieldType.price].includes(
filter.type
)
? "number"
: "text"
}}
value={filter.value[0]}
onChange={event =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
value: [event.target.value, filter.value[1]]
}
},
type: "set-property"
})
}
<FilterTextField
currencySymbol={currencySymbol}
filter={filter}
onFilterPropertyChange={onFilterPropertyChange}
/>
)}
</div>

View file

@ -14,15 +14,15 @@ const useStyles = makeStyles(
padding: theme.spacing(1, 2.5)
}
}),
{ name: "FilterContentBodyNameField" }
{ name: "FilterGroupLabel" }
);
export interface FilterContentBodyNameFieldProps<T extends string = string> {
export interface FilterGroupLabelProps<T extends string = string> {
filter: IFilterElement<T>;
onFilterPropertyChange: React.Dispatch<FilterReducerAction<T>>;
}
const FilterContentBodyNameField: React.FC<FilterContentBodyNameFieldProps> = ({
const FilterGroupLabel: React.FC<FilterGroupLabelProps> = ({
filter,
onFilterPropertyChange
}) => {
@ -60,4 +60,4 @@ const FilterContentBodyNameField: React.FC<FilterContentBodyNameFieldProps> = ({
);
};
export default FilterContentBodyNameField;
export default FilterGroupLabel;

View file

@ -0,0 +1,87 @@
import { TextField } from "@material-ui/core";
import React from "react";
import { FormattedMessage } from "react-intl";
import { FilterReducerAction } from "../reducer";
import { FieldType, IFilterElement } from "../types";
import useStyles from "./styles";
import { filterTestingContext } from "./utils";
export interface FilterRangeFieldProps {
currencySymbol: string;
filter: IFilterElement;
onFilterPropertyChange: React.Dispatch<FilterReducerAction<string>>;
}
const FilterRangeField: React.FC<FilterRangeFieldProps> = ({
currencySymbol,
filter,
onFilterPropertyChange
}) => {
const classes = useStyles();
return (
<>
<TextField
data-test={filterTestingContext}
data-test-id={filter.name}
data-test-range-type="min"
fullWidth
name={filter.name + "_min"}
InputProps={{
classes: {
input: classes.fieldInput
},
endAdornment: filter.type === FieldType.price && currencySymbol,
type: filter.type === FieldType.date ? "date" : "number"
}}
value={filter.value[0]}
onChange={event =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
value: [event.target.value, filter.value[1]]
}
},
type: "set-property"
})
}
/>
<span className={classes.andLabel}>
<FormattedMessage
defaultMessage="and"
description="filter range separator"
/>
</span>
<TextField
data-test={filterTestingContext}
data-test-id={filter.name}
data-test-range-type="max"
fullWidth
name={filter.name + "_max"}
InputProps={{
classes: {
input: classes.fieldInput
},
endAdornment: filter.type === FieldType.price && currencySymbol,
type: filter.type === FieldType.date ? "date" : "number"
}}
value={filter.value[1]}
onChange={event =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
value: [filter.value[0], event.target.value]
}
},
type: "set-property"
})
}
/>
</>
);
};
FilterRangeField.displayName = "FilterRangeField";
export default FilterRangeField;

View file

@ -0,0 +1,57 @@
import { TextField } from "@material-ui/core";
import React from "react";
import { FilterReducerAction } from "../reducer";
import { FieldType, IFilterElement } from "../types";
import useStyles from "./styles";
import { filterTestingContext } from "./utils";
export interface FilterTextFieldProps {
currencySymbol: string | null;
filter: IFilterElement;
onFilterPropertyChange: React.Dispatch<FilterReducerAction<string>>;
}
const FilterTextField: React.FC<FilterTextFieldProps> = ({
currencySymbol,
filter,
onFilterPropertyChange
}) => {
const classes = useStyles();
return (
<TextField
data-test={filterTestingContext}
data-test-id={filter.name}
fullWidth
name={filter.name}
InputProps={{
classes: {
input: classes.fieldInput
},
endAdornment: filter.type === FieldType.price && currencySymbol,
type:
filter.type === FieldType.date
? "date"
: [FieldType.number, FieldType.price].includes(filter.type)
? "number"
: "text"
}}
value={filter.value[0]}
onChange={event =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
value: [event.target.value, filter.value[1]]
}
},
type: "set-property"
})
}
/>
);
};
FilterTextField.displayName = "FilterTextField";
export default FilterTextField;

View file

@ -0,0 +1,36 @@
import { fade } from "@material-ui/core";
import { makeStyles } from "@saleor/theme";
const useStyles = makeStyles(
theme => ({
andLabel: {
margin: theme.spacing(0, 2)
},
arrow: {
marginRight: theme.spacing(2)
},
filterSettings: {
background: fade(theme.palette.primary.main, 0.1),
padding: theme.spacing(2, 3)
},
inputRange: {
alignItems: "center",
display: "flex"
},
option: {
left: -theme.spacing(0.5),
position: "relative"
},
optionRadio: {
left: -theme.spacing(0.25)
},
fieldInput: {
padding: "12px 0 9px 12px"
}
}),
{ name: "Filter" }
);
export default useStyles;

View file

@ -3,6 +3,8 @@ import { IntlShape } from "react-intl";
import { FilterType } from "../types";
export const filterTestingContext = "filter-field";
export function getIsFilterMultipleChoices(
intl: IntlShape
): SingleAutocompleteChoiceType[] {

View file

@ -5808,7 +5808,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -5898,7 +5898,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="MuiFormControl-root-id SingleSelectField-formControl-id"
@ -5912,7 +5912,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
>
<div
aria-haspopup="listbox"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
role="button"
tabindex="0"
>
@ -5954,11 +5954,11 @@ exports[`Storyshots Generics / Filter default 1`] = `
class="FormSpacer-spacer-id"
/>
<div
class="FilterContentBody-inputRange-id"
class="Filter-inputRange-id"
>
<div>
<svg
class="FilterContentBody-arrow-id"
class="Filter-arrow-id"
fill="none"
height="21"
viewBox="0 0 18 21"
@ -5984,7 +5984,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="createdAt_min"
type="date"
value="2019-09-09"
@ -6006,7 +6006,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
</div>
</div>
<span
class="FilterContentBody-andLabel-id"
class="Filter-andLabel-id"
>
and
</span>
@ -6021,7 +6021,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="createdAt_max"
type="date"
value="2019-10-23"
@ -6064,7 +6064,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -6148,7 +6148,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="FilterOptionField-root-id"
@ -6324,7 +6324,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -6408,7 +6408,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="MuiFormControl-root-id SingleSelectField-formControl-id"
@ -6422,7 +6422,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
>
<div
aria-haspopup="listbox"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
role="button"
tabindex="0"
>
@ -6464,11 +6464,11 @@ exports[`Storyshots Generics / Filter default 1`] = `
class="FormSpacer-spacer-id"
/>
<div
class="FilterContentBody-inputRange-id"
class="Filter-inputRange-id"
>
<div>
<svg
class="FilterContentBody-arrow-id"
class="Filter-arrow-id"
fill="none"
height="21"
viewBox="0 0 18 21"
@ -6494,7 +6494,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="price_min"
type="number"
value="20.00"
@ -6516,7 +6516,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
</div>
</div>
<span
class="FilterContentBody-andLabel-id"
class="Filter-andLabel-id"
>
and
</span>
@ -6531,7 +6531,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="price_max"
type="number"
value="100.00"
@ -6574,7 +6574,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -6664,7 +6664,7 @@ exports[`Storyshots Generics / Filter default 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="FilterOptionField-root-id"
@ -6908,7 +6908,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -6998,7 +6998,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="MuiFormControl-root-id SingleSelectField-formControl-id"
@ -7012,7 +7012,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
>
<div
aria-haspopup="listbox"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
role="button"
tabindex="0"
>
@ -7054,11 +7054,11 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
class="FormSpacer-spacer-id"
/>
<div
class="FilterContentBody-inputRange-id"
class="Filter-inputRange-id"
>
<div>
<svg
class="FilterContentBody-arrow-id"
class="Filter-arrow-id"
fill="none"
height="21"
viewBox="0 0 18 21"
@ -7084,7 +7084,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="createdAt_min"
type="date"
value="2019-09-09"
@ -7106,7 +7106,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
</div>
</div>
<span
class="FilterContentBody-andLabel-id"
class="Filter-andLabel-id"
>
and
</span>
@ -7121,7 +7121,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="createdAt_max"
type="date"
value="2019-10-23"
@ -7164,7 +7164,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -7248,7 +7248,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="FilterOptionField-root-id"
@ -7424,7 +7424,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -7508,7 +7508,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="MuiFormControl-root-id SingleSelectField-formControl-id"
@ -7522,7 +7522,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
>
<div
aria-haspopup="listbox"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiSelect-root-id MuiSelect-select-id MuiSelect-selectMenu-id MuiSelect-outlined-id MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
role="button"
tabindex="0"
>
@ -7564,11 +7564,11 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
class="FormSpacer-spacer-id"
/>
<div
class="FilterContentBody-inputRange-id"
class="Filter-inputRange-id"
>
<div>
<svg
class="FilterContentBody-arrow-id"
class="Filter-arrow-id"
fill="none"
height="21"
viewBox="0 0 18 21"
@ -7594,7 +7594,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="price_min"
type="number"
value="20.00"
@ -7616,7 +7616,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
</div>
</div>
<span
class="FilterContentBody-andLabel-id"
class="Filter-andLabel-id"
>
and
</span>
@ -7631,7 +7631,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id FilterContentBody-input-id"
class="MuiInputBase-input-id MuiOutlinedInput-input-id Filter-fieldInput-id"
name="price_max"
type="number"
value="100.00"
@ -7674,7 +7674,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
class="MuiExpansionPanelSummary-content-id FilterContentExpanderSummary-content-id"
>
<div
class="FilterContentBodyNameField-container-id"
class="FilterGroupLabel-container-id"
>
<label
class="MuiFormControlLabel-root-id"
@ -7764,7 +7764,7 @@ exports[`Storyshots Generics / Filter interactive 1`] = `
role="region"
>
<div
class="FilterContentBody-filterSettings-id"
class="Filter-filterSettings-id"
>
<div
class="FilterOptionField-root-id"