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

View File

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