Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
147 lines
4.1 KiB
TypeScript
147 lines
4.1 KiB
TypeScript
import * as React from 'react';
|
|
import Grid from '@mui/material/Grid';
|
|
import List from '@mui/material/List';
|
|
import ListItemButton from '@mui/material/ListItemButton';
|
|
import ListItemIcon from '@mui/material/ListItemIcon';
|
|
import ListItemText from '@mui/material/ListItemText';
|
|
import Checkbox from '@mui/material/Checkbox';
|
|
import Button from '@mui/material/Button';
|
|
import Paper from '@mui/material/Paper';
|
|
|
|
function not(a: readonly number[], b: readonly number[]) {
|
|
return a.filter((value) => !b.includes(value));
|
|
}
|
|
|
|
function intersection(a: readonly number[], b: readonly number[]) {
|
|
return a.filter((value) => b.includes(value));
|
|
}
|
|
|
|
export default function TransferList() {
|
|
const [checked, setChecked] = React.useState<readonly number[]>([]);
|
|
const [left, setLeft] = React.useState<readonly number[]>([0, 1, 2, 3]);
|
|
const [right, setRight] = React.useState<readonly number[]>([4, 5, 6, 7]);
|
|
|
|
const leftChecked = intersection(checked, left);
|
|
const rightChecked = intersection(checked, right);
|
|
|
|
const handleToggle = (value: number) => () => {
|
|
const currentIndex = checked.indexOf(value);
|
|
const newChecked = [...checked];
|
|
|
|
if (currentIndex === -1) {
|
|
newChecked.push(value);
|
|
} else {
|
|
newChecked.splice(currentIndex, 1);
|
|
}
|
|
|
|
setChecked(newChecked);
|
|
};
|
|
|
|
const handleAllRight = () => {
|
|
setRight(right.concat(left));
|
|
setLeft([]);
|
|
};
|
|
|
|
const handleCheckedRight = () => {
|
|
setRight(right.concat(leftChecked));
|
|
setLeft(not(left, leftChecked));
|
|
setChecked(not(checked, leftChecked));
|
|
};
|
|
|
|
const handleCheckedLeft = () => {
|
|
setLeft(left.concat(rightChecked));
|
|
setRight(not(right, rightChecked));
|
|
setChecked(not(checked, rightChecked));
|
|
};
|
|
|
|
const handleAllLeft = () => {
|
|
setLeft(left.concat(right));
|
|
setRight([]);
|
|
};
|
|
|
|
const customList = (items: readonly number[]) => (
|
|
<Paper sx={{ width: 200, height: 230, overflow: 'auto' }}>
|
|
<List dense component="div" role="list">
|
|
{items.map((value: number) => {
|
|
const labelId = `transfer-list-item-${value}-label`;
|
|
|
|
return (
|
|
<ListItemButton
|
|
key={value}
|
|
role="listitem"
|
|
onClick={handleToggle(value)}
|
|
>
|
|
<ListItemIcon>
|
|
<Checkbox
|
|
checked={checked.includes(value)}
|
|
tabIndex={-1}
|
|
disableRipple
|
|
inputProps={{
|
|
'aria-labelledby': labelId,
|
|
}}
|
|
/>
|
|
</ListItemIcon>
|
|
<ListItemText id={labelId} primary={`List item ${value + 1}`} />
|
|
</ListItemButton>
|
|
);
|
|
})}
|
|
</List>
|
|
</Paper>
|
|
);
|
|
|
|
return (
|
|
<Grid
|
|
container
|
|
spacing={2}
|
|
sx={{ justifyContent: 'center', alignItems: 'center' }}
|
|
>
|
|
<Grid>{customList(left)}</Grid>
|
|
<Grid>
|
|
<Grid container direction="column" sx={{ alignItems: 'center' }}>
|
|
<Button
|
|
sx={{ my: 0.5 }}
|
|
variant="outlined"
|
|
size="small"
|
|
onClick={handleAllRight}
|
|
disabled={left.length === 0}
|
|
aria-label="move all right"
|
|
>
|
|
≫
|
|
</Button>
|
|
<Button
|
|
sx={{ my: 0.5 }}
|
|
variant="outlined"
|
|
size="small"
|
|
onClick={handleCheckedRight}
|
|
disabled={leftChecked.length === 0}
|
|
aria-label="move selected right"
|
|
>
|
|
>
|
|
</Button>
|
|
<Button
|
|
sx={{ my: 0.5 }}
|
|
variant="outlined"
|
|
size="small"
|
|
onClick={handleCheckedLeft}
|
|
disabled={rightChecked.length === 0}
|
|
aria-label="move selected left"
|
|
>
|
|
<
|
|
</Button>
|
|
<Button
|
|
sx={{ my: 0.5 }}
|
|
variant="outlined"
|
|
size="small"
|
|
onClick={handleAllLeft}
|
|
disabled={right.length === 0}
|
|
aria-label="move all left"
|
|
>
|
|
≪
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
<Grid>{customList(right)}</Grid>
|
|
</Grid>
|
|
);
|
|
}
|