Basically, I want something that acts similar to the following snippet. Notice how adding an item to one flex row increases the width of both.
function initItems() {
const numArr = Array.from(Array(3).keys());
const items = numArr.map(() => "item");
return items;
}
function FlexItems() {
const [items, setItems] = React.useState(initItems);
const addItem = () => setItems([...items, "item"]);
return (
<div className="flex-row">
<button onClick={addItem}>Add Item</button>
{items.map((item, idx)=><div className="item" key={idx}>{item}</div>)}
</div>
);
}
function StackedCenteredFlexItems() {
return (
<table>
<tr>
<td className="side first">.</td>
<td className="center first"><FlexItems/></td>
<td className="side first">.</td>
</tr>
<tr>
<td className="side second">.</td>
<td className="center second"><FlexItems/></td>
<td className="side second">.</td>
</tr>
</table>
)
}
ReactDOM.render(
<StackedCenteredFlexItems />,
document.getElementById("react")
);
.flex-row {
display: flex;
/* flex-wrap: wrap; */
border: 1px solid black;
}
table {
width: 100%;
border-collapse: collapse;
}
td.center {
width: 1px;
white-space: nowrap;
}
td.side {
padding: 0;
font-size: 1px;
color: transparent;
}
.first {
background: lightblue;
}
.second {
background: lightgreen;
}
.item {
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
This solution is close, the active ingredient being that the flex rows are in the center cells of a table with this applied:
td.center {
width: 1px;
white-space: nowrap;
}
In that example flex-wrap is set to nowrap, however, because with wrap turned on, all the items in the flex rows just stack on top of one another. But I need the items to wrap in response to window size, like this:
function initItems() {
const numArr = Array.from(Array(20).keys());
const items = numArr.map(() => "item");
return items;
}
function FlexItems({ className }) {
const [items, setItems] = React.useState(initItems);
const addItem = () => setItems([...items, "item"]);
return (
<div className={"flex-row " + className}>
<button onClick={addItem}>Add Item</button>
{items.map((item, idx)=><div className="item" key={idx}>{item}</div>)}
</div>
);
}
ReactDOM.render(
<div>
<FlexItems className="first" />
<FlexItems className="second" />
</div>,
document.getElementById("react")
);
.flex-row {
display: flex;
flex-wrap: wrap;
}
.first {
background: lightblue;
}
.second {
background: lightgreen;
}
.item {
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
The first example has most of what I want:
- The flex rows are centered in the window
- When an item is added to one flex row, the width of both increases
- To the left and right of each flex row, the background matches the flex row's color
The second example has the other thing:
- Flex wrap responds to the edges of the window
How can I get all of it?