SelectTree: Move custom Option props to selectProps

This commit is contained in:
Gustav Hansen 2022-04-12 13:29:37 +02:00
parent 3647486db0
commit d39b4c6ae7
2 changed files with 30 additions and 30 deletions

View File

@ -15,21 +15,31 @@ const ToggleButton = styled.button`
margin-left: auto; margin-left: auto;
`; `;
const Option = ({ children, data, onToggle, isOpen, maxDisplayDepth, ...props }) => { const Option = ({ children, data, selectProps, ...props }) => {
const hasChildren = data?.children?.length > 0; const { depth, value, children: options } = data;
const { depth, value } = data; const { maxDisplayDepth, openValues, onOptionToggle } = selectProps;
const normalizedDepth = Math.min(depth, maxDisplayDepth); const isOpen = openValues.includes(value);
return ( return (
<> <>
<components.Option {...props}> <components.Option {...props}>
<Flex alignItems="start"> <Flex alignItems="start">
<Typography textColor="neutral800"> <Typography textColor="neutral800">
<span style={{ paddingLeft: `${normalizedDepth * 10}px` }}>{children}</span> <span style={{ paddingLeft: `${Math.min(depth, maxDisplayDepth) * 10}px` }}>
{children}
</span>
</Typography> </Typography>
{hasChildren && ( {options?.length > 0 && (
<ToggleButton type="button" onClick={event => onToggle(event, value)}> <ToggleButton
type="button"
onClick={event => {
event.preventDefault();
event.stopPropagation();
onOptionToggle(value);
}}
>
<Icon width={pxToRem(14)} color="neutral500" as={isOpen ? ChevronUp : ChevronDown} /> <Icon width={pxToRem(14)} color="neutral500" as={isOpen ? ChevronUp : ChevronDown} />
</ToggleButton> </ToggleButton>
)} )}
@ -39,17 +49,15 @@ const Option = ({ children, data, onToggle, isOpen, maxDisplayDepth, ...props })
); );
}; };
Option.defaultProps = {
isOpen: false,
maxDisplayDepth: 5,
};
Option.propTypes = { Option.propTypes = {
children: PropTypes.arrayOf(PropTypes.element).isRequired, children: PropTypes.arrayOf(PropTypes.element).isRequired,
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
isOpen: PropTypes.bool,
maxDisplayDepth: PropTypes.number,
onToggle: PropTypes.func.isRequired, onToggle: PropTypes.func.isRequired,
selectProps: PropTypes.shape({
maxDisplayDepth: PropTypes.number,
openValues: PropTypes.arrayOf([PropTypes.string, PropTypes.number]),
onOptionToggle: PropTypes.func,
}).isRequired,
}; };
export default Option; export default Option;

View File

@ -32,32 +32,24 @@ const SelectTree = ({ options: defaultOptions, maxDisplayDepth, defaultValue, ..
}); });
}, [openValues, flatDefaultOptions, optionsFiltered]); }, [openValues, flatDefaultOptions, optionsFiltered]);
function handleToggle(e, value) { const handleToggle = value => {
e.preventDefault();
e.stopPropagation();
if (openValues.includes(value)) { if (openValues.includes(value)) {
setOpenValues(prev => prev.filter(prevData => prevData !== value)); setOpenValues(prev => prev.filter(prevData => prevData !== value));
} else { } else {
setOpenValues(prev => [...prev, value]); setOpenValues(prev => [...prev, value]);
} }
} };
return ( return (
<Select <Select
components={{ components={{ Option }}
Option: props => (
<Option
{...props}
onToggle={(...args) => handleToggle(...args)}
// eslint-disable-next-line react/prop-types
isOpen={openValues.includes(props.data?.value)}
maxDisplayDepth={maxDisplayDepth}
/>
),
}}
options={options} options={options}
defaultValue={defaultValue} defaultValue={defaultValue}
/* -- custom props, used by the Option component */
maxDisplayDepth={maxDisplayDepth}
openValues={openValues}
onOptionToggle={handleToggle}
/* -- / custom props */
{...props} {...props}
/> />
); );