Skip to content

Commit

Permalink
fix: fix checkbox group all selection
Browse files Browse the repository at this point in the history
  • Loading branch information
glenkurniawan-adslot committed Mar 5, 2024
1 parent 4711886 commit 5ba803c
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/components/CheckboxGroup/CheckboxGroup.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ export const NestedCheckboxes: Story = {
<CheckboxGroup indent>
<CheckboxGroup.All label="Sports" values={allHobbies.sports} />
{allHobbies.sports.map((item) => (
<CheckboxGroup.Item key={item} value={item} label={_.capitalize(item)} />
<CheckboxGroup.Item key={item} value={item} label={_.capitalize(item)} disabled={item === 'swimming' }/>
))}
</CheckboxGroup>
<CheckboxGroup indent>
<CheckboxGroup.All label="Other" values={allHobbies.other} />
{allHobbies.other.map((item) => (
<CheckboxGroup.Item key={item} value={item} label={_.capitalize(item)} />
<CheckboxGroup.Item key={item} value={item} label={_.capitalize(item)} disabled/>
))}
</CheckboxGroup>
</CheckboxGroup>
Expand Down
15 changes: 13 additions & 2 deletions src/components/CheckboxGroup/CheckboxGroupContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const CheckboxGroupProvider = ({
const name = parentCtx.name || nameProp;
const value = parentCtx.value || valueProp;

const [disabledValues, setDisabledValues] = React.useState([]);

const context = React.useMemo(() => {
const getIsItemChecked = (checkboxValue) => {
if (getIsChecked) return getIsChecked(checkboxValue, value);
Expand All @@ -28,11 +30,11 @@ const CheckboxGroupProvider = ({
};

const getIsAllChecked = (values) => {
if (_.isEmpty(values)) return false;
const result = _(values)
.map((item) => getIsItemChecked(item))
.uniq()
.value();

return result.length === 1 ? result[0] : 'partial';
};

Expand All @@ -54,6 +56,12 @@ const CheckboxGroupProvider = ({
}
};

const registerDisabledValue = (disabledValue) => {
if (!_.includes(disabledValues, disabledValue)) {
setDisabledValues((prevValues) => [...prevValues, disabledValue]);
}
};

return {
variant,
value,
Expand All @@ -64,8 +72,11 @@ const CheckboxGroupProvider = ({
getIsAllChecked,
onItemChange,
onAllChange,

registerDisabledValue,
disabledValues,
};
}, [getIsChecked, value, name, onChange, variant]);
}, [getIsChecked, value, name, onChange, variant, disabledValues]);

return <CheckboxGroupContext.Provider value={context}>{children}</CheckboxGroupContext.Provider>;
};
Expand Down
19 changes: 14 additions & 5 deletions src/components/CheckboxGroup/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ import CheckboxGroupProvider, { useCheckboxGroup } from './CheckboxGroupContext'
import '../RadioGroup/style.css';
import './styles.css';

const CheckboxGroupItem = ({ value, ...rest }) => {
const CheckboxGroupItem = ({ value, disabled, ...rest }) => {
const groupCtx = useCheckboxGroup();
invariant(!_.isEmpty(groupCtx), 'CheckboxGroup.Item: must be used as children of CheckboxGroup');
invariant(!rest.name, 'CheckboxGroup.Item: name will be overridden by CheckboxGroup name');
invariant(!rest.variant, 'CheckboxGroup.Item: variant will be overridden by CheckboxGroup variant');
invariant(!rest.onChange, 'CheckboxGroup.Item: onChange will be overridden by CheckboxGroup onChange');

const { onItemChange, getIsItemChecked, name, variant } = groupCtx;
const { onItemChange, getIsItemChecked, name, variant, registerDisabledValue } = groupCtx;

React.useEffect(() => {
if (disabled) {
registerDisabledValue(value);
}
}, [disabled, registerDisabledValue, value]);

return (
<Checkbox
Expand All @@ -26,6 +32,7 @@ const CheckboxGroupItem = ({ value, ...rest }) => {
variant={variant}
checked={getIsItemChecked(value)}
onChange={() => onItemChange(value)}
disabled={disabled}
/>
);
};
Expand All @@ -36,17 +43,19 @@ const CheckboxGroupAll = ({ className, label = 'All', values, ...rest }) => {
const groupCtx = useCheckboxGroup();
invariant(!_.isEmpty(groupCtx), 'CheckboxGroup.All: must be used as children of CheckboxGroup');

const { onAllChange, getIsAllChecked, name, variant } = groupCtx;
const { onAllChange, getIsAllChecked, name, variant, disabledValues } = groupCtx;
const enabledValues = _.filter(values, (value) => !_.includes(disabledValues, value));

return (
<Checkbox
{...rest}
className={classnames(className, 'is-all')}
name={name}
label={label}
checked={getIsAllChecked(values)}
onChange={onAllChange(values)}
checked={getIsAllChecked(enabledValues)}
onChange={onAllChange(enabledValues)}
variant={variant}
disabled={_.isEqual(values, disabledValues)}
/>
);
};
Expand Down

0 comments on commit 5ba803c

Please sign in to comment.