I have this Button.jsx
file which exports a <Button />
component, that wraps a <StyledButton />
component, I need this wrap due to the optional args like loading
and spinner
, I mean, I don’t want to type { loading ? spinner : null }
everytime I need a loading spinner icon or another some props.
The <StyledButton />
component checks for a $hasIcon
prop to fix the width
based on an existing icon in the button.
// Button.jsx
import styled from 'styled-components';
const StyledButton = styled.button`
width: ${ ({ $hasIcon }) => $hasIcon ? 'fit-content' : '100%' };
background-color: red;
`;
export const Button = ({ loading, spinner, children, ...props }) => (
<StyledButton { ...props }>
{ children }
{ loading ? spinner : null }
</StyledButton>
);
Then, I use the <Button />
component from Button.jsx
in my whole project without problems, but things start to getting weird when I extend its styles to overwrite some of them.
// SomeComponent.jsx
import styled from 'styled-components';
import Button from '@components/Button';
import { SomeIcon } from '@icons';
const ExtendedStyleButton = styled(Button)`
background-color: green;
`;
export const SomeComponent = () => (
<ExtendedStyleButton $hasIcon>
<SomeIcon />
</ExtendedStyleButton>
);
Expected Behavior
$hasIcon
prop specified in <ExtendedStyleButton />
should reach <StyledButton />
through the extended style of <Button />
in order to fix the width.
Desired path:
$hasIcon
|
▼
<ExtendedStyleButton />
| $hasIcon
▼
<Button />
| $hasIcon
▼
<StyledButton /> // fixed width to fit-content due to $hasIcon prop correctly passed
Actual Behavior
Due to the fact that I’ve been debugging everything with console.log, I believe the $hasIcon
prop goes up to <ExtendedStyleButton />
and nothing else, which causes the width
not being fixed for an icon and taking a 100%
value.
Current path:
$hasIcon
|
▼
<ExtendedStyleButton />
|
▼
<Button />
|
▼
<StyledButton /> // fixed width to 100% because $hasIcon prop has not been received