Search code examples
javascriptreactjsuser-interfacefunctional-programmingstyled-components

defaultProps with styled-components


Hello guys I been looking in the internet trying to apply defaultProps to my components but nothing is working atm.

I will show you my code:

import styled from "styled-components";

const Button = styled.button`
  text-transform: uppercase;
  font-weight: bold;
  font-size: 12px;
  padding: 10px 20px;
  border-radius: 5px;
  border-style: none;
  :focus {
    outline: none;
  }
  ${props =>
    props.primary &&
    `
    background-color: ${props.theme.colors.primary};
    color: ${props.theme.colors.blank};
    :hover {
        background-color: ${props.theme.colors.blank};
        color: ${props.theme.colors.primary};
        border-style: solid;  
        border-color: ${props.theme.colors.primary}
    }
  `}
  ${props =>
    props.secondary &&
    `
    background-color: ${props.theme.colors.secondary};
    color: ${props.theme.colors.blank};
    :hover {
        background-color: ${props.theme.colors.blank};
        color: ${props.theme.colors.secondary};
        border-style: solid;  
        border-color: ${props.theme.colors.secondary}
    }
  `}
  ${props =>
    props.success &&
    `
    background-color: ${props.theme.colors.success};
    color: ${props.theme.colors.blank};
    :hover {
        background-color: ${props.theme.colors.blank};
        color: ${props.theme.colors.success};
        border-style: solid;  
        border-color: ${props.theme.colors.success}
    }
  `}
   ${props =>
     props.warning &&
     `
    background-color: ${props.theme.colors.warning};
    color: ${props.theme.colors.blank};
    :hover {
        background-color: ${props.theme.colors.blank};
        color: ${props.theme.colors.warning};
        border-style: solid;  
        border-color: ${props.theme.colors.warning}
    }
  `}
`;

export default Button;

I just want to setup defaultProps to give some styled by default if I dont do for example:

<Button primary>Text</>

Here is another example, this is a bit different:

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

const Wrap = styled.input`
  ${props =>
    props.primary &&
    `
    border: 2px ${props.theme.colors.primary} solid;
  `}
  ${props =>
    props.secondary &&
    `
    border: 2px ${props.theme.colors.secondary} solid;
  `}
  padding: 5px 10px;
  background-color: transparent;
  border-radius: 5px;
  text-align: center;
  :focus {
    outline: none;
  }
`;

const Input = ({
  type,
  onChange,
  placeholder,
  primary,
  secondary,
  className,
  value,
  name,
  ref,
  children
}) => {
  return (
    <Wrap
      type={type}
      onChange={onChange}
      placeholder={placeholder}
      primary={primary}
      secondary={secondary}
      value={value}
      name={name}
      ref={ref}
      className={className}
    >
      {children}
    </Wrap>
  );
};

export default Input;

Any help will be useful, Im trying to make a Theme for myself as clean as possible. Thank you.


Solution

  • Adding defaultProps to components works out of the box, even with components created from Styled Components. You need to define the defaultProps on the component. Here's a complete example from a fresh create-react-app application:

    import React from 'react';
    import './App.css';
    import styled from 'styled-components';
    
    
    const ButtonBlue = styled.button`
      background-color: ${props => props.actuallyMakeItGreen ? 'green' : 'blue'};
    `;
    
    ButtonBlue.defaultProps = {
      actuallyMakeItGreen : true
    }
    
    function App() {
      return (
        <div className="App">
            <ButtonBlue>Cool</ButtonBlue>
        </div>
      );
    }
    
    export default App;
    
    

    Creates a button that looks like this:

    enter image description here

    import React from 'react';
    import './App.css';
    import styled from 'styled-components';
    
    
    const ButtonBlue = styled.button`
      background-color: ${props => props.actuallyMakeItGreen ? 'green' : 'blue'};
    `;
    
    function App() {
        return (
            <div className="App">
                <ButtonBlue>Cool</ButtonBlue>
            </div>
        );
    }
    
    export default App;
    

    enter image description here

    The only thing changing here is inside the defaultProps property, where we default actuallyMakeItGreen to true rather than false.