/
githubmirror
/
material-ui
Обзор
Документация
Войти
/
githubmirror
/
material-ui
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
docs/data/material/components/transfer-list/SelectAllTransferList.js
199 строк
5 KB
Silviu Alexandru Avram
[docs] Improve TransferList examples (#48845)
24 июл 2026, 12:25
Не верифицирован
24 июл 2026, 12:25
4d5fe72
Код
Авторство
О чём код?
import * as React from 'react'; import PropTypes from 'prop-types'; import Grid from '@mui/material/Grid'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import ListItemText from '@mui/material/ListItemText'; import ListItemIcon from '@mui/material/ListItemIcon'; import Checkbox from '@mui/material/Checkbox'; import Button from '@mui/material/Button'; import Divider from '@mui/material/Divider'; import Stack from '@mui/material/Stack'; import MenuItem from '@mui/material/MenuItem'; import MenuList from '@mui/material/MenuList'; function not(a, b) { return a.filter((value) => !b.includes(value)); } function intersection(a, b) { return a.filter((value) => b.includes(value)); } function union(a, b) { return [...a, ...not(b, a)]; } const CustomList = React.forwardRef(function CustomList(props, ref) { const { title, items, checked, handleToggle, handleToggleAll, numberOfChecked } = props; return ( <Card> <CardHeader sx={{ px: 2, py: 0.5 }} avatar={ <Checkbox size="small" onClick={handleToggleAll(items)} checked={numberOfChecked(items) === items.length && items.length !== 0} indeterminate={ numberOfChecked(items) !== items.length && numberOfChecked(items) !== 0 } disabled={items.length === 0} slotProps={{ input: { 'aria-label': 'all items selected' }, }} /> } title={title} subheader={`${numberOfChecked(items)}/${items.length} selected`} /> <Divider /> <MenuList sx={{ width: 200, height: 230, bgcolor: 'background.paper', overflow: 'auto', }} dense component="div" role="list" ref={ref} > {items.map((value) => { const labelId = `transfer-list-all-item-${value}-label`; return ( <MenuItem component="div" key={value} role="listitem" onClick={handleToggle(value)} > <ListItemIcon> <Checkbox checked={checked.includes(value)} tabIndex={-1} disableRipple slotProps={{ input: { 'aria-labelledby': labelId }, }} /> </ListItemIcon> <ListItemText id={labelId} primary={`List item ${value + 1}`} /> </MenuItem> ); })} </MenuList> </Card> ); }); CustomList.propTypes = { checked: PropTypes.arrayOf(PropTypes.number).isRequired, handleToggle: PropTypes.func.isRequired, handleToggleAll: PropTypes.func.isRequired, items: PropTypes.arrayOf(PropTypes.number).isRequired, numberOfChecked: PropTypes.func.isRequired, title: PropTypes.node, }; export default function SelectAllTransferList() { const [checked, setChecked] = React.useState([]); const [left, setLeft] = React.useState([0, 1, 2, 3]); const [right, setRight] = React.useState([4, 5, 6, 7]); const leftChecked = intersection(checked, left); const rightChecked = intersection(checked, right); const leftListRef = React.useRef(null); const rightListRef = React.useRef(null); const handleToggle = (value) => () => { const currentIndex = checked.indexOf(value); const newChecked = [...checked]; if (currentIndex === -1) { newChecked.push(value); } else { newChecked.splice(currentIndex, 1); } setChecked(newChecked); }; const numberOfChecked = (items) => intersection(checked, items).length; const handleToggleAll = (items) => () => { if (numberOfChecked(items) === items.length) { setChecked(not(checked, items)); } else { setChecked(union(checked, items)); } }; const handleCheckedRight = () => { setRight(right.concat(leftChecked)); setLeft(not(left, leftChecked)); setChecked(not(checked, leftChecked)); rightListRef.current?.focus(); }; const handleCheckedLeft = () => { setLeft(left.concat(rightChecked)); setRight(not(right, rightChecked)); setChecked(not(checked, rightChecked)); leftListRef.current?.focus(); }; return ( <Grid container spacing={2} sx={{ justifyContent: 'center', alignItems: 'center' }} > <CustomList ref={leftListRef} title="Choices" items={left} checked={checked} handleToggle={handleToggle} handleToggleAll={handleToggleAll} numberOfChecked={numberOfChecked} /> <Stack> <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> </Stack> <CustomList ref={rightListRef} title="Chosen" items={right} checked={checked} handleToggle={handleToggle} handleToggleAll={handleToggleAll} numberOfChecked={numberOfChecked} /> </Grid> ); }