Skip to content

Commit

Permalink
feat: add checkbox to the choice button
Browse files Browse the repository at this point in the history
  • Loading branch information
ReidyT committed Sep 12, 2024
1 parent c1c6f65 commit d1cb9ca
Showing 1 changed file with 69 additions and 40 deletions.
109 changes: 69 additions & 40 deletions src/components/play/multipleChoices/ChoiceButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import { Button, Typography } from '@mui/material';
import { Button, Checkbox, Typography } from '@mui/material';

import { buildMultipleChoicesButtonCy } from '../../../config/selectors';
import theme from '../../../layout/theme';
Expand All @@ -17,19 +15,14 @@ const DEFAULT_DISABLED = 'whitesmoke';

const styleButton = ({
color,
isSelected,
dataCy,
endIcon,
}: {
color: StatusColor;
isSelected: boolean;
dataCy: string;
endIcon?: JSX.Element;
}) =>
({
color,
variant: isSelected ? 'contained' : 'outlined',
endIcon,
variant: 'outlined',
'data-cy': dataCy,
} as const);

Expand All @@ -39,16 +32,74 @@ const computeDisabledSx = (choiceState: ChoiceState | undefined) => {

switch (choiceState) {
case ChoiceState.CORRECT:
case ChoiceState.MISSING:
return { backgroundColor: successColor, color: DEFAULT_DISABLED };
case ChoiceState.INCORRECT:
return { backgroundColor: errorColor, color: DEFAULT_DISABLED };
case ChoiceState.MISSING:
return { color: successColor, borderColor: successColor };
default:
return {};
}
};

const computeStyles = ({
isSelected,
idx,
showState,
choiceState,
}: {
isSelected: boolean;
idx: number;
showState: boolean;
choiceState: number;
}) => {
const btn = {
color: DEFAULT_COLOR,
isSelected: isSelected,
dataCy: buildMultipleChoicesButtonCy(idx, isSelected),
} as const; // const is needed to allow color strings

if (showState) {
switch (choiceState) {
case ChoiceState.CORRECT:
case ChoiceState.MISSING:
return styleButton({
...btn,
color: CORRECT_COLOR,
});
case ChoiceState.INCORRECT:
return styleButton({
...btn,
color: INCORRECT_COLOR,
});
}
}

return styleButton(btn);
};

const computeCheckboxSx = ({
isSelected,
showState,
choiceState,
}: {
isSelected: boolean;
showState: boolean;
choiceState: number;
}) => {
const borderColor =
(showState && choiceState !== ChoiceState.UNSELECTED) || isSelected
? DEFAULT_DISABLED
: DEFAULT_COLOR;
const color = isSelected && showState ? DEFAULT_DISABLED : DEFAULT_COLOR;

return {
'&.Mui-checked': {
color,
},
color: borderColor,
};
};

type Props = {
choice: MultipleChoicesChoice;
choiceState: ChoiceState;
Expand All @@ -68,34 +119,6 @@ export const ChoiceButton = ({
showState,
onClick,
}: Props) => {
const computeStyles = () => {
const btn = {
color: DEFAULT_COLOR,
isSelected: isSelected,
dataCy: buildMultipleChoicesButtonCy(idx, isSelected),
} as const; // const is needed to allow color strings

if (showState) {
switch (choiceState) {
case ChoiceState.CORRECT:
case ChoiceState.MISSING:
return styleButton({
...btn,
color: CORRECT_COLOR,
endIcon: <CheckIcon />,
});
case ChoiceState.INCORRECT:
return styleButton({
...btn,
color: INCORRECT_COLOR,
endIcon: <CloseIcon />,
});
}
}

return styleButton(btn);
};

const handleClick = () => {
if (isReadonly) {
return;
Expand All @@ -106,14 +129,20 @@ export const ChoiceButton = ({
return (
<Button
key={choice.value}
startIcon={
<Checkbox
checked={isSelected}
sx={computeCheckboxSx({ isSelected, showState, choiceState })}
/>
}
onClick={handleClick}
fullWidth
sx={{
'&.MuiButton-root': {
'&.Mui-disabled': computeDisabledSx(choiceState),
},
}}
{...computeStyles()}
{...computeStyles({ isSelected, idx, choiceState, showState })}
disabled={isReadonly}
>
<Typography variant="body1" sx={{ fontWeight: 500 }}>
Expand Down

0 comments on commit d1cb9ca

Please sign in to comment.