Search code examples
javascriptreactjsstyled-components

How to extend Link and NavLink with same styles using Styled Components


New to Styled Components and I'm trying to figure out a better way to extend and share styles.

I have something like:

import styled from 'styled-components'
import { Link, NavLink } from 'react-router-dom';

const StyledNavLink = styled(Link)`
  position: relative;
  display: flex;
  height: 100%;
  text-decoration: none;
`;

const StyledNavLink = styled(NavLink)`
  position: relative;
  display: flex;
  height: 100%;
  text-decoration: none;
`;

Is there a way to define the same proper only once for both components?

EDIT: I think I have one way to do it (using css helper function)

import styled, {css} from 'styled-components'
import { Link, NavLink } from 'react-router-dom';

const sharedStyle = css`
  position: relative;
  display: flex;
  height: 100%;
  text-decoration: none;
`

const StyledNavLink = styled(Link)`
  ${sharedStyle}
`;

const StyledNavLink = styled(NavLink)`
  ${sharedStyle}
`;

Solution

  • One way is the way from your answer:

    import styled, {css} from 'styled-components'
    import { Link, NavLink } from 'react-router-dom';
    
    const sharedStyle = css`
      position: relative;
      display: flex;
      height: 100%;
      text-decoration: none;
    `
    
    const StyledNavLink = styled(Link)`
      ${sharedStyle}
    `;
    
    const StyledNavLink = styled(NavLink)`
      ${sharedStyle}
    `;
    

    The other could be to create a dedicated function:

    import styled, {css} from 'styled-components'
    import { Link, NavLink } from 'react-router-dom';
    
    const withLinkStyles = (component) => styled(component)`
      position: relative;
      display: flex;
      height: 100%;
      text-decoration: none;
    `;
    
    const StyledNavLink = withLinkStyles(Link);
    const StyledNavLink = withLinkStyles(NavLink);
    

    I would choose the first one, as it seems more expressive and in-line with the declarative way styled-components authors intended the library to be used.