diff --git a/packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx b/packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx index 58abb4af0f..0da4c1b7b7 100644 --- a/packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx +++ b/packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx @@ -65,5 +65,9 @@ export default { }; export const Default = () => ( - + {}} + label="default" + subCategories={CHECKBOX_TREE_ITEMS} + /> ); diff --git a/packages/core/src/components/CheckboxTree/CheckboxTree.tsx b/packages/core/src/components/CheckboxTree/CheckboxTree.tsx index dc962ea0b5..f1dae684c7 100644 --- a/packages/core/src/components/CheckboxTree/CheckboxTree.tsx +++ b/packages/core/src/components/CheckboxTree/CheckboxTree.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useReducer } from 'react'; +import React, { useEffect, useReducer } from 'react'; import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; import { List, @@ -22,7 +22,7 @@ import { Checkbox, ListItemText, Collapse, - Typography + Typography, } from '@material-ui/core'; import ExpandLess from '@material-ui/icons/ExpandLess'; import ExpandMore from '@material-ui/icons/ExpandMore'; @@ -38,17 +38,17 @@ const useStyles = makeStyles((theme: Theme) => minWidth: 10, maxWidth: 360, backgroundColor: 'transparent', - "&:hover": { - backgroundColor: "transparent" - } + '&:hover': { + backgroundColor: 'transparent', + }, }, nested: { paddingLeft: theme.spacing(5), - height: '32px' + height: '32px', }, listItemIcon: { - minWidth: 10 - } + minWidth: 10, + }, }), ); @@ -76,9 +76,10 @@ type Option = { isChecked?: boolean; }; -type Props = { +export type CheckboxTreeProps = { subCategories: SubCategory[]; label: string; + onChange: (arg: any) => any; }; /* REDUCER */ @@ -168,7 +169,7 @@ const indexer = ( [el.label]: { label: el.label, isChecked: el.isChecked || false, - isOpen: true, + isOpen: false, options: indexer(el.options), }, }; @@ -179,7 +180,8 @@ const indexer = ( }; }, {}); -export const CheckboxTree = (props: Props) => { +export const CheckboxTree = (props: CheckboxTreeProps) => { + const { onChange } = props; const classes = useStyles(); const [state, dispatch] = useReducer(reducer, indexer(props.subCategories)); @@ -188,78 +190,99 @@ export const CheckboxTree = (props: Props) => { event.stopPropagation(); dispatch({ type: 'openCategory', payload: value }); }; + + const handleChange = () => { + const values = Object.values(state).map(category => ({ + category: category.label, + selected: Object.values(category.options) + .filter(option => option.isChecked) + .map(option => option.value), + })); + onChange(values); + }; + return (
- {props.label} - - {Object.values(state).map(item => { - const labelId = `checkbox-list-label-${item?.label}`; + {props.label} + + {Object.values(state).map(item => { + const labelId = `checkbox-list-label-${item?.label}`; - return ( -
- - dispatch({ - type: 'checkCategory', - payload: item.label, - }) - } - > - - - - - {item.options?.length ? ( - handleOpen(event, item.label)} /> - ) : ( - handleOpen(event, item.label)} /> - )} - - - - {Object.values(item.options).map(option => ( - - dispatch({ - type: 'checkOption', - payload: { - subCategoryLabel: item.label, - optionLabel: option.label, - }, - }) - } - > - - + { + await dispatch({ + type: 'checkCategory', + payload: item.label, + }); + handleChange(); + }} + > + + + + + {Object.values(item.options).length ? ( + <> + {item.isOpen ? ( + handleOpen(event, item.label)} /> - - - - ))} - - -
- ); - })} -
+ ) : ( + handleOpen(event, item.label)} + /> + )} + + ) : null} + + + + {Object.values(item.options).map(option => ( + { + await dispatch({ + type: 'checkOption', + payload: { + subCategoryLabel: item.label, + optionLabel: option.label, + }, + }); + handleChange(); + }} + > + + + + + + ))} + + +
+ ); + })} + ); }; diff --git a/packages/core/src/components/Select/Select.stories.tsx b/packages/core/src/components/Select/Select.stories.tsx index 38acb46c10..acb6f8afc8 100644 --- a/packages/core/src/components/Select/Select.stories.tsx +++ b/packages/core/src/components/Select/Select.stories.tsx @@ -38,7 +38,12 @@ const SELECT_ITEMS = [ ]; export const Default = () => ( - {}} + placeholder="All results" + label="Default" + items={SELECT_ITEMS} + /> ); export const Multiple = () => ( @@ -47,5 +52,6 @@ export const Multiple = () => ( label="Multiple" items={SELECT_ITEMS} multiple + onChange={el => {}} /> ); diff --git a/packages/core/src/components/Select/Select.tsx b/packages/core/src/components/Select/Select.tsx index 80422bb998..b518b37d6c 100644 --- a/packages/core/src/components/Select/Select.tsx +++ b/packages/core/src/components/Select/Select.tsx @@ -63,8 +63,8 @@ const BootstrapInput = withStyles((theme: Theme) => const useStyles = makeStyles((theme: Theme) => createStyles({ formControl: { - margin: theme.spacing(1), - minWidth: 315, + margin: `${theme.spacing(1)} 0px`, + maxWidth: 300, }, label: { transform: 'initial', @@ -84,6 +84,10 @@ const useStyles = makeStyles((theme: Theme) => margin: 2, }, checkbox: {}, + root: { + display: 'flex', + flexDirection: 'column', + }, }), ); @@ -92,15 +96,16 @@ type Item = { value: string | number; }; -type Props = { +export type SelectProps = { multiple?: boolean; items: Item[]; label: string; placeholder?: string; + onChange: (arg: any) => any; }; -export const SelectComponent = (props: Props) => { - const { multiple, items, label, placeholder } = props; +export const SelectComponent = (props: SelectProps) => { + const { multiple, items, label, placeholder, onChange } = props; const classes = useStyles(); const [value, setValue] = useState( multiple ? [] : '', @@ -108,7 +113,8 @@ export const SelectComponent = (props: Props) => { const [canOpen, setCanOpen] = React.useState(false); const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => { - setValue(event.target.value as string); + setValue(event.target.value as any); + onChange(event.target.value); }; const selectHandleOnOpen = () => { @@ -120,74 +126,74 @@ export const SelectComponent = (props: Props) => { }; return ( - - - {label} - - } + renderValue={selected => + multiple && (value as any[]).length !== 0 ? ( +
+ {(selected as string[]).map(selectedValue => ( + el.value === selectedValue)?.value} + label={items.find(el => el.value === selectedValue)?.label} + clickable + onDelete={handleDelete(selectedValue)} + className={classes.chip} + /> + ))} +
+ ) : ( + + {(value as any[]).length === 0 + ? placeholder || '' + : items.find(el => el.value === selected)?.label} + + ) + } + IconComponent={() => + !canOpen ? : + } + MenuProps={{ + anchorOrigin: { + vertical: 'bottom', + horizontal: 'left', + }, + transformOrigin: { + vertical: 'top', + horizontal: 'left', + }, + getContentAnchorEl: null, + }} + > + {placeholder && ( + + {placeholder} - ))} - -
+ )} + {items && + items.map(item => ( + + {multiple && ( + + )} + {item.label} + + ))} + + + ); };