Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve multiple choices #172

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cypress/e2e/play/multipleChoices.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const checkCorrection = (selection: number[], showCorrection = true) => {
}
);

if (showCorrection || wasSelected) {
if (wasSelected && !isCorrect) {
cy.get(dataCyWrapper(buildMultipleChoiceHintPlayCy(idx))).should(
'contain',
explanation
Expand Down
31 changes: 0 additions & 31 deletions src/components/common/HeightObserver.tsx

This file was deleted.

141 changes: 0 additions & 141 deletions src/components/common/animations/ReorderAnimation.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/components/play/PlayViewQuestionType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ export const PlayViewQuestionType = ({
}
showCorrection={showCorrection}
showCorrectness={showCorrectness}
numberOfSubmit={numberOfSubmit}
numberOfRetry={numberOfRetry}
/>
);
Expand Down
124 changes: 84 additions & 40 deletions src/components/play/multipleChoices/ChoiceButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
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 @@ -14,41 +14,107 @@ const DEFAULT_COLOR = 'primary';
const CORRECT_COLOR = 'success';
const INCORRECT_COLOR = 'error';
const DEFAULT_DISABLED = 'whitesmoke';
const SUCCESS_COLOR = theme.palette.success.main;
const ERROR_COLOR = theme.palette.error.main;
const PRIMARY_COLOR = theme.palette.primary.main;

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);

const computeDisabledSx = (choiceState: ChoiceState | undefined) => {
const successColor = theme.palette.success.main;
const errorColor = theme.palette.error.main;

switch (choiceState) {
case ChoiceState.CORRECT:
return { backgroundColor: successColor, color: DEFAULT_DISABLED };
case ChoiceState.INCORRECT:
return { backgroundColor: errorColor, color: DEFAULT_DISABLED };
case ChoiceState.MISSING:
return { color: successColor, borderColor: successColor };
return { borderColor: SUCCESS_COLOR, color: SUCCESS_COLOR };
case ChoiceState.INCORRECT:
return { borderColor: ERROR_COLOR, color: ERROR_COLOR };
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,
endIcon: <CheckIcon />,
});
case ChoiceState.INCORRECT:
return styleButton({
...btn,
color: INCORRECT_COLOR,
endIcon: <CloseIcon />,
});
}
}

return styleButton(btn);
};

const computeCheckboxSx = ({
showState,
choiceState,
}: {
showState: boolean;
choiceState: number;
}) => {
let borderColor = PRIMARY_COLOR;

if (showState) {
switch (choiceState) {
case ChoiceState.CORRECT:
case ChoiceState.MISSING:
borderColor = SUCCESS_COLOR;
break;
case ChoiceState.INCORRECT:
borderColor = ERROR_COLOR;
break;
default:
borderColor = DEFAULT_DISABLED;
}
}

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

type Props = {
choice: MultipleChoicesChoice;
choiceState: ChoiceState;
Expand All @@ -68,34 +134,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 +144,20 @@ export const ChoiceButton = ({
return (
<Button
key={choice.value}
startIcon={
<Checkbox
checked={isSelected}
sx={computeCheckboxSx({ 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
Loading
Loading