Styled Component only pass some value to custom component

Hi I’m trying to configure the colour of a button base on it’s button type which will be put in a modal. In this case, either “Success” or “Danger”:

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

const ButtonStyled = styled.button`
    background-color: ${(props) =>
        props.btnType === "Success" ? "green" : "red"};
    border: none;
    color: white;
    outline: none;
    cursor: pointer;
    font: Regular 400;
    padding: 0.5rem 0;
    margin: 0.5rem 1rem;
    font-weight: bold;
    margin-left: 0;
    padding-left: 0;
`;

const Button = (props) => {
    console.log(props.btnType);
    return (
        <ButtonStyled btnType={props.btnType} onClick={props.clicked}>
            {props.children}
        </ButtonStyled>
    );
};

export default Button;

Here’s where I called the button:

import React from "react";
import Button from "../../UI/Button/Button";

const OrderSummary = (props) => {
    return (
        <div>
            <Button btnType="Danger" clicked={props.cancelPurchase}>
                Cancel
            </Button>
            <Button btnType="Success" clicked={props.continuePurchase}>
                Continue
            </Button>
        </div>
    );
};

export default OrderSummary;

Here is where the Order Summary being called:

import React, { useState } from "react";
import Modal from "../../components/UI/Modal/Modal";
import OrderSummary from "../../components/Burger/OrderSummary/OrderSummary";

const INGREDIENT_PRICES = {
    salad: 0.5,
    cheese: 0.4,
    meat: 1.3,
    bacon: 0.7,
};

const BurgerBuilder = () => {
    const [ingredients, setIngredients] = useState({
        salad: 0,
        bacon: 0,
        cheese: 0,
        meat: 0,
    });

    const [totalPrice, setTotalPrice] = useState(4);

    const [purchasing, setPurchasing] = useState(false);

    const purchaseCancelHandler = () => {
        setPurchasing(false);
    };

    const purchaseContinueHandler = () => {
        alert("continue");
    };

    return (
        <div>
            <Modal show={purchasing} modalClosed={purchaseCancelHandler}>
                <OrderSummary
                    continuePurchase={purchaseContinueHandler}
                    cancelPurchase={purchaseCancelHandler}
                    ingredients={ingredients}
                    price={totalPrice.toFixed(2)}
                />
            </Modal>
        </div>
    );
};

export default BurgerBuilder;

Down here is the modal where the Button being applied

import React from "react";
import styled from "styled-components";
import Backdrop from "../Backdrop/Backdrop";

const ModalWrapper = styled.div`
    box-shadow: 0 5px 16px rgba(0, 0, 0, 0.2);
    background: #fff;
    justify-content: center;
    align-items: center;
    color: #000;
    display: grid;
    grid-template-columns: 1fr 1fr;
    position: fixed;
    z-index: 500;
    border-radius: 10px;
    transition: all 0.3s ease-out;
    padding: 16px;
    left: 15%;
    top: 30%;

    @media (min-width: 600px) {
        width: 500px;
        left: calc(50% - 250px);
    }
`;

const ModalContent = styled.div`
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    line-height: 1.8;
    color: #141414;
    p {
        margin-bottom: 1rem;
    }
    button {
        padding: 10px 24px;
        background: #141414;
        // color: #fff;
        border: none;
    }
`;

const Modal = (props) => {
    return (
        <div>
            <Backdrop show={props.show} clicked={props.modalClosed} />
            <ModalWrapper
                style={{
                    transform: props.show ? "translateY(0)" : "translateY(-100vh)",
                    opacity: props.show ? "1" : "0",
                }}
            >
                <ModalContent>{props.children}</ModalContent>
            </ModalWrapper>
        </div>
        // <ModalStyled>{props.children}</ModalStyled>
    );
};

export default Modal;

As I did some testing, the values in the styled component Modal Content which state the button in that content will be that. Hence it affected the value of the styled component Button Styled. However, if I removed the value of button in Modal Content, the value of the color in ButtonStyled won’t be accepted. Does anyone happen to know why?

Answer

The button style defined in the ModalContent is overriding the button style you’ve defined in your Button component.

button {
    padding: 10px 24px;
    background: #141414; // <-- overrides button background color
    border: none;
}

With CSS the most specific selector will be the one that sets the style and I suspect the ModalContent styled component’s computed style results with a more specific selector for button elements than the one from ButtonStyled.

What you can do is bump the selector specificity of the ButtonStyled background color.

Pseudoelements, pseudoselectors, and nesting, the last section.

Finally, the ampersand can be used to increase the specificity of rules on the component; this can be useful if you are dealing with a mixed styled-components and vanilla CSS environment where there might be conflicting styles

const ButtonStyled = styled.button`
  && {
    background-color: ${(props) =>
      props.btnType === "Success" ? "green" : "red"};
  }
  border: none;
  color: white;
  outline: none;
  cursor: pointer;
  font: Regular 400;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  font-weight: bold;
  margin-left: 0;
  padding-left: 0;
`;

Edit styled-component-only-pass-some-value-to-custom-component

Leave a Reply

Your email address will not be published. Required fields are marked *