React Component string of string declaration overwriting each other
I have a React component that is passed a value object that looks like this:
{gridColumn: '1 / 3', gridRow: '2 / 5', gridArea: 'header'}
then add component style like:
this.cell.style.setProperty('grid-area', values.gridArea);
this.cell.style.setProperty('grid-column', values.gridColumn);
this.cell.style.setProperty('grid-row', values.gridRow);
However, using the grid-column and grid-row properties, they truncate to a shorthand declaration for "grid-area: 2/1/5/3" in the browser and overwrite the style of my grid.
This also happens if I set it in a loop:
for (let prop in values) {
this.cell.style[prop] = values[prop];
};
Is there a better way to do this?
source to share
From MDN:
- grid-area is an abbreviation for
grid-row-start
,grid-column-start
,grid-row-end
andgrid-column-end
- grid-column is shorthand for
grid-column-start
andgrid-column-end
- grid-row is shorthand for
grid-row-start
andgrid-row-end
.
So grid-area
is mutually exclusive with grid-column
and grid-row
. React is not meant to intelligently combine these CSS properties for you, it just lets the latter determine the win.
However, you can add logic to combine these properties yourself:
const mergedGridColumn = gridColumn.replace(/[0-9*]/g, value => `${value} ${gridArea}`);
const mergedGridRow = gridRow.replace(/[0-9*]/g, value => `${value} ${gridArea}`);
For values
:
{
const values = {
gridArea: 'header',
gridColumn: '1 / 3',
gridRow: '2 / 5',
}
This creates style
:
{
grid-area: 2 header / 1 header / 5 header / 3 header;
}
Complete example below:
const App = () => {
const values = {
gridArea: 'header',
gridColumn: '1 / 3',
gridRow: '2 / 5',
};
return (
<div className="App" style={{display: 'grid'}}>
<Header values={values} />
</div>
);
}
const Header = (props) => {
const { gridArea, gridColumn, gridRow } = props.values;
const mergedGridColumn = gridColumn.replace(/[0-9*]/g, value => `${value} ${gridArea}`);
const mergedGridRow = gridRow.replace(/[0-9*]/g, value => `${value} ${gridArea}`);
return (
<div
className="App-header"
style={{
gridColumn: mergedGridColumn,
gridRow: mergedGridRow,
}}
>
<h2>Welcome to React</h2>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.App {
text-align: center;
}
.App-header {
background-color: orchid;
color: white
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
source to share