Search code examples
reactjsstyled-components

Styled-components extends props


I have a ready button like this , These are the features I want every button to have.

If I send props for the icon, I don't want the icon to be created, if I don't, I don't want it to be created.

    import Icon from 'components/icons/Icon';
import styled from 'styled-components';

const Button = styled.button`
  border-radius: 8px;
  color: white;
  cursor: pointer;
  outline: none;
  border: none;
  display: flex;
  font-family: 'DM Sans', sans-serif;
  font-weight: 700;
`;

const DefaultButton = ({ name, children }) => {
  return (
    <Button>
      {name && <Icon name={name}></Icon>}
      {children}
    </Button>
  );
};

export default DefaultButton;

I have a button component that I have customized like this. I want it to inherit its properties from the default button. But Primary's features do not appear on my button. I wonder what should I fix, thanks friend

import styled from 'styled-components';
import { sizes } from 'constants/components/button';
import { colors } from 'theme';
import DefaultButton from './DefaultButton';

const PrimaryButton = styled(DefaultButton)`
  padding: ${({ size }) => sizes[size]} 48px;
  background-color: ${colors.primary.color};
  font-size: 14px;
  font-style: bold;

  &:focus {
    border: 1px solid #ffffff;
    box-sizing: border-box;
    box-shadow: 0px 0px 0px 3px rgba(24, 207, 152, 1);
  }
  &:hover {
    background-color: ${colors.primary.pressed};
    box-shadow: 0px 14px 24px rgba(23, 207, 151, 0.3);
    color: white;
  }

  &:disabled {
    background-color: ${colors.primary.disabled};
    cursor: not-allowed;
    pointer-events: none;
    color: white;
  }
`;

export default PrimaryButton;

This is how I use my component and I want it to be like this

<PrimaryButton size="md" name="test">
        Sign in
      </PrimaryButton>

Solution

  • If you want to extend/override the styles of another component, you need to pass down the className prop, as mentioned in the docs.

    The styled method works perfectly on all of your own or any third-party component, as long as they attach the passed className prop to a DOM element.

    const DefaultButton = ({ name, children, className }) => {
      return (
        <Button className={className}>
          {name && <Icon name={name}></Icon>}
          {children}
        </Button>
      );
    };