How to globally prefix all css rules generated by styled-components 5.3.5 with a parent class

Viewed 165

My app will be loaded into a parent div that has a specific class (e.g. .my-app).

Is there a way to preprend all the classes generated by styled-components with .my-app .

Given a component like

import React from 'react';
import styled from 'styled-components';

const Button = (props) => {
  return <StyledButton type="button">foo</StyledButton>;
};

const StyledButton = styled.button`
  color: blue;
`;

export default Button;

normally you might have output like

<style data-styled="active" data-styled-version="5.1.1">
    .cuetwY { color: blue; }
</style>
<div class="my-app">
    <button class="cuetwY">foo</button>
</div>

But I'm trying to achieve the following:

<style data-styled="active" data-styled-version="5.1.1">
    /* Note the additional selector prepended here */
    .my-app .cuetwY { color: blue; }
</style>
<div class="my-app">
    <button class="cuetwY">foo</button>
</div>

I have tried both babel-plugin-styled-components-css-namespace and stylis-plugin-extra-scope but neither seems to work with newer versions of styled-components and the older versions of sc don't work with React 18.

1 Answers

If i understand correctly you want to set your own class / classes in a component using styled-components. In this case, using the attrs method you can set your custom class.

This is a chainable method that attaches some props to a styled component. The first and only argument is an object that will be merged into the rest of the component's props. The attrs object accepts the following values: documentation

import styled from "styled-components";

const Style = styled.button.attrs((props) => ({
  className: `my-${props.random}`
}))`
  background-color: grey;
  color: white;
  padding: 1rem 2rem;
`;

export const Button = () => {
  const generatedStyleName = "DweDw32FS";
  return <Style random={generatedStyleName}>Click me</Style>;
};
Related