Поскольку вы .map()
поверх checkboxItems
, они отображаются в порядке появления, тогда как вам нужно сделать их транспонированными.
Чтобы получить желаемый результат, общий подход состоит в том, чтобы сломать ваш источник массив на фрагменты длиной 3 (количество столбцов), транспонированных в соответствии с желаемым порядком:
itemsToRender = Array(Math.ceil(checkboxItems.length/3))
.fill()
.map((_, i, s) =>
Array(3)
.fill()
.map((_,j) =>
checkboxItems[i+j*s.length]))
Ниже приводится живая демонстрация этого подхода:
const { render } = ReactDOM,
rootNode = document.getElementById('root')
const App = () => {
const checkboxItems = ['First name','Last name','Email','Phone','Address','Gender','City','Postcode','Country/State','Country','Lifetime value','Tickets in period','Revenue in period','Permission to contact','Customer ID','Account ID','AS Customer tags','Product/Event','Price Category','Section','Row','Seat'],
itemsToRender = Array(Math.ceil(checkboxItems.length/3))
.fill()
.map((_, i, s) =>
Array(3)
.fill()
.map((_,j) =>
checkboxItems[i+j*s.length]))
return (
<div className="wrapper">
{
itemsToRender.map((row, rowIdx) => (
<div key={rowIdx} className="row">
{
row.map((item, itemPos) => item && (
<label key={itemPos} className="cell">
<input type="checkbox" value={item} />
{item}
</label>
))
}
</div>
))
}
</div>
)
}
render (
<App />,
rootNode
)
.wrapper {
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
}
.cell {
width: 150px;
height: 50px;
margin: 5px;
background-color: cadetblue;
color: #fff;
display: flex;
align-items: center;
justify-content: flex-start;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>
Другой подход (продолжить компоновку grid
и переупорядочить элементы, используя, в частности, функции CSS и repeat()
) состоит в том, чтобы сделать использование стиля Material-UI (как в данном случае) и динамическая установка grid-template-rows
в зависимости от количества строк, необходимых для обертывания вашего списка:
const { render } = ReactDOM,
{ FormControlLabel, Checkbox } = MaterialUI,
{ makeStyles } = MaterialUI
const rootNode = document.getElementById('root')
const useStyles = rowNum => makeStyles({
wrapper: {
display: 'grid',
gridTemplateRows: `repeat(${rowNum}, 1fr)`,
gridAutoFlow: 'column'
}
})
const App = () => {
const checkboxItems = ['First name','Last name','Email','Phone','Address','Gender','City','Postcode','Country/State','Country','Lifetime value','Tickets in period','Revenue in period','Permission to contact','Customer ID','Account ID','AS Customer tags','Product/Event','Price Category','Section','Row','Seat'],
classes = useStyles(Math.ceil(checkboxItems.length/3))()
return(
<div className={classes.wrapper}>
{
checkboxItems.map((item, itemIdx) => (
<FormControlLabel
key={itemIdx}
control={
<Checkbox
name={item}
/>
}
label={item}
/>
))
}
</div>
)
}
render (
<App />,
rootNode
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js"></script><div id="root"></div>