GuillaumeRZ
GuillaumeRZ

Reputation: 2934

How to pass from a react props to a sass variable?

I am using React and SASS, and I got a cube component, and I want to render it with a dynamic width. However, I am operating on this width in my .scss. There is an example.

My component:

<Cube style={{ width: '100px' }} />
<Cube style={{ width: '70px' }} />
<Cube style={{ width: '20px' }} />

My style.scss:

$cubeWidth: 150px;
$cubeHeight: $cubeWidth;
#cube {
      width: $cubeWidth;
      height: $cubeHeight;
}

// In this cube, I have -of course- 6 faces, and I operate in my style.scss:

.cubeFace1 {
     transform: translateZ($cubeWidth / 2);
}
... etc

How is it possible to get my $cubeWidth equal to my dynamic width ? Furthermore, .scss is loaded in index.js as follow:

// React index.js

import './css/style.scss';

render(<Router />, document.getElementById('root'));

Thank you !

Upvotes: 5

Views: 3120

Answers (2)

ADTC
ADTC

Reputation: 10086

I'm assuming you don't actually need it in SASS itself (for use in server-side pre-processing before the final CSS is generated), and you can simply pass the value over to final CSS (client-side).

If you need the dynamic value in the final CSS, you can make use of CSS variables to do this. (This is a pure CSS feature, but since SASS and SCSS compile to CSS, we can use it.)

In a functional React component, you can use the effect hook to set a variable dynamically to the root:

useEffect(() => {
  /* Note:
  Instead of :root you can also set this on the highest parent of your cube
  as it will limit the scope of the variable to that element and its children.
  */

  document.querySelector(':root').style
    .setProperty('--cubeWidth', widthVar);

  // OR:

  const rootStyle = document.querySelector(':root').style;
  rootStyle.setProperty('--cubeWidth', widthVar);
  rootStyle.setProperty('--cubeHeight', heightVar);
},
// this array optimizes the effect to run only on changes:
[widthVar, heightVar]);

For class-based React components, this can also be achieved with componentDidMount() and componentDidUpdate().

Then in your CSS, SCSS or SASS file, use the CSS variable as normal:

.cubeFace1 {
  transform: translateZ(calc(var(--cubeWidth, 150px) / 2));
}

You can optionally provide a default, like the 150px above. Note the use of CSS calc though.

Upvotes: 1

Mojo
Mojo

Reputation: 145

It's not possible to pass from react props to a sass variable. However, you can use styled-components: https://styled-components.com/docs/basics#installation

  1. npm i styled-components
  2. In your Cube component code, add at the top, after the import statements,
const Cube = styled.div`
      width: props.cubeWidth;
      height: props.cubeHeight;
`;

const CubeFaceOne = styled.span`
      transform: translateZ(props.cubeWidth / 2);
`;

Using this approach, Cube and CubeFace will need to be split into two separate components, and will be rendered in something of this form,

render() {
  return (
    <Cube>
      <CubeFaceOne />
      <CubeFace />
      <CubeFace />
      ...
    </Cube>
  )
}

Upvotes: 1

Related Questions