Skip to content

Commit

Permalink
Create the MatrixSingleSelect component
Browse files Browse the repository at this point in the history
  • Loading branch information
Viktor Riabkov committed Apr 4, 2024
1 parent 2874226 commit 9a1a9d2
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 4 deletions.
10 changes: 9 additions & 1 deletion src/entities/activity/ui/items/ItemPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AudioPlayerItem } from './AudioPlayerItem';
import { CheckboxItem } from './CheckboxItem';
import { DateItem } from './DateItem';
import { MatrixCheckboxItem } from './Matrix/MatrixMultiSelectItem';
import { MatrixRadioItem } from './Matrix/MatrixSingleSelectItem';
import { RadioItem } from './RadioItem';
import { SelectorItem } from './SelectorItem';
import { SliderItem } from './SliderItem';
Expand Down Expand Up @@ -104,7 +105,14 @@ export const ItemPicker = ({ item, onValueChange, isDisabled, replaceText }: Ite
);

case 'singleSelectRows':
return <div>boom</div>;
return (
<MatrixRadioItem
item={item}
values={item.answer}
onValueChange={onValueChange}
replaceText={replaceText}
/>
);

default:
return <></>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Props = {
values: MatrixMultiSelectAnswer;
};

export const StackedItemsGrid = ({ rows, options, onChange, values }: Props) => {
export const CheckboxGrid = ({ rows, options, onChange, values }: Props) => {
return (
<Box display="flex" flex={1} flexDirection="column">
<MatrixHeader options={options} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react';

import { StackedItemsGrid } from './StackedItemsGrid';
import { CheckboxGrid } from './CheckboxGrid';
import { MatrixMultiSelectAnswer, MultiSelectionRowsItem } from '../../../../lib';

type Props = {
Expand Down Expand Up @@ -57,7 +57,7 @@ export const MatrixCheckboxItem = ({ item, values, onValueChange, replaceText }:
};

return (
<StackedItemsGrid
<CheckboxGrid
options={memoizedOptions}
rows={memoizedRows}
onChange={handleValueChange}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Box from '@mui/material/Box';

import { MatrixCell } from '../MatrixCell';

import { RadioOption, SelectBaseBox } from '~/shared/ui';

type Props = {
id: string;
isChecked: boolean;
text: string;

onChange: () => void;
};

export const RadioButton = ({ id, text, isChecked, onChange }: Props) => {
return (
<Box flex={1} key={id}>
<MatrixCell>
<SelectBaseBox
color={null}
onHandleChange={onChange}
checked={isChecked}
justifyContent="center"
>
<RadioOption
id={id}
name={text}
value={text}
disabled={false}
defaultChecked={isChecked}
/>
</SelectBaseBox>
</MatrixCell>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Box from '@mui/material/Box';

import { RadioButton } from './RadioButton';
import { MatrixSelectOption, MatrixSelectRow, SingleMultiSelectAnswer } from '../../../../lib';
import { MatrixHeader } from '../MatrixHeader';
import { MatrixRow } from '../MatrixRow';

type Props = {
options: Array<MatrixSelectOption>;
rows: Array<MatrixSelectRow>;

onChange: (rowIndex: number, value: string) => void;
values: SingleMultiSelectAnswer;
};

export const RadioGrid = ({ rows, options, onChange, values }: Props) => {
return (
<Box display="flex" flex={1} flexDirection="column">
<MatrixHeader options={options} />

{rows.map((row, rowI) => {
const isEven = rowI % 2 === 0;

return (
<MatrixRow
key={row.id}
isEven={isEven}
item={{ id: row.id, imageUrl: row.rowImage, text: row.rowName, tooltip: row.tooltip }}
>
{options.map((option, optionI) => {

Check warning on line 30 in src/entities/activity/ui/items/Matrix/MatrixSingleSelectItem/RadioGrid.tsx

View workflow job for this annotation

GitHub Actions / ESLint

src/entities/activity/ui/items/Matrix/MatrixSingleSelectItem/RadioGrid.tsx#L30

'optionI' is defined but never used. Allowed unused args must match /^_/u (unused-imports/no-unused-vars)
const isChecked = option.text === values[rowI];

return (
<RadioButton
key={option.id}
id={option.id}
text={option.text}
isChecked={isChecked}
onChange={() => onChange(rowI, option.text)}
/>
);
})}
</MatrixRow>
);
})}
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useMemo } from 'react';

import { RadioGrid } from './RadioGrid';
import { SingleMultiSelectAnswer, SingleSelectionRowsItem } from '../../../../lib';

type Props = {
item: SingleSelectionRowsItem;
values: SingleMultiSelectAnswer;

onValueChange: (value: SingleMultiSelectAnswer) => void;
replaceText: (value: string) => string;
};

export const MatrixRadioItem = ({ item, values, onValueChange, replaceText }: Props) => {
const { options, rows } = item.responseValues;

const memoizedOptions = useMemo(() => {
return options.map((el) => ({
...el,
tooltip: el.tooltip ? replaceText(el.tooltip) : null,
}));
}, [options, replaceText]);

const memoizedRows = useMemo(() => {
return rows.map((el) => ({
...el,
tooltip: el.tooltip ? replaceText(el.tooltip) : null,
}));
}, [replaceText, rows]);

const memoizedValues = useMemo(() => {
const initialAnswer = memoizedRows.map(() => null);

return values.length ? values : initialAnswer;
}, [memoizedRows, values]);

const handleValueChange = (rowIndex: number, value: string) => {
const newValues = memoizedValues.map((row, i) => {
if (i === rowIndex) {
const hasAnswer = row !== null;
const isSameAnswer = row === value;

if (hasAnswer && isSameAnswer) {
return null;
} else {
return value;
}
}

return row;
});

onValueChange(newValues);
};

return (
<RadioGrid
options={memoizedOptions}
rows={memoizedRows}
onChange={handleValueChange}
values={memoizedValues}
/>
);
};

0 comments on commit 9a1a9d2

Please sign in to comment.