0
votes

I’m fairly new to styled-components and trying to extract / refactor styles to separate files. I have problem with circular dependency - probably because of lacks of experience in styled-components good practices. This is the situation:

// A.js
import { StyledA } from './styles';

export default () => (
  <StyledA>
    <SomeOtherComponent />
  </StyledA>
);

// B.js
import { StyledA1 } from './styles';

export default () => (
   <SomeWrapperComponent>
     <StyledA1 />
   </SomeWrapperComponent>
);

// styles.js
import styled from 'styled-components';
import A from './A.js';

export const StyledA = styled.div`...`;
export const StyledA1 = styled(A)`...`; // causes dependency circle error

What I'm trying to achieve, is to extend A component styles and keep it's children components (for file B.js).

  • export const StyledA1 = styled(StyledA) doesn't work because I lose component A structure.
  • ...and import A in styles.js causes eslint "dependency-cycle" error because of imports A.js → styles.js → A.js.

What should I do to keep HTML structure of extended component and resolve dependency cycle issue?

1
Firstly, can you reproduce the error in a sandbox? Secondly, if you want to re-use styles such way is not a good practice, if you have specific problems you trying to solve and looking for a recommendation please explain it and show examples.Dennis Vash
Well, in sandbox this "dependency cycle" error doesn't appear and everything works fine - maybe because of standard eslint configuration (my project uses Airbnb config). Anyway, this is the link. In components/B.js file you can see (commented out) code before extracting styles to separate file.chudy91
I will add an answer of a good practice example, you never export styled components, see it as a workaround solution instead of trying to fix this specific problem.Dennis Vash

1 Answers

1
votes

When working with CSS-in-JS (like styled-components) you usually keep the components generated by style in the same file.

So how do you export the className generated with CSS-in-JS constructor? By using compound components.

export const StyledA = styled.div`
  background: red;
  font-size: 20px;
`;

const A = ({ className }) => (
  <StyledA className={className}>
    <div>Display me always!</div>
  </StyledA>
);

// Can use any naming here
A.className = StyledA;

export default A;

Also, when you want to reuse styles, you create file like styles.js and declare reusable css blocks:

import { css } from 'styled-components';

const border = css`
  border: 2px black solid;
`;

export { border };

Full usage:

import A from './components/A';
import styled from 'styled-components';
import { border } from './components/styles';

const StyledA = styled(A)`
  background-color: palevioletred;
`;

const StyledASelector = styled.div`
  ${A.className} {
    background-color: paleturquoise;
    margin: 5px;
    ${border}
  }
`;

const App = () => {
  return (
    <>
      <A />
      <StyledA />
      <StyledASelector>
        <A />
      </StyledASelector>
    </>
  );
};

Edit interesting-heyrovsky-sgujh