简体   繁体   中英

Styled Component Button Extension

So my aim is to have a base button component and then a variant button which has the same markup as the base button but obviously has different styling, animations.

My base file is button.js

 import React from 'react';
import styled,{ keyframes, ThemeProvider} from 'styled-components';
import theme from '../../theme/default';

// import {rotatecw, rotateccw} from '../../../theme/keyframes';


const ButtonWrapper = styled.button`
  position: relative;
  color: ${(props) => props.theme.colors.primary};
  width: 256px;
  height: 64px;
  line-height: 64px;
  background: none;
  border: 1px solid ${(props) => props.theme.colors.primary};
    &:hover {
      cursor: pointer;
      color: ${(props) => props.theme.colors.grey};
      border: 1px solid ${(props) => props.theme.colors.grey};
    }
  }

`;

const ButtonText = styled.span`
  // transition: all 0.1s;
  // tranform: scale(1, 1);
`;


function Button(props) {
  return (
    <ThemeProvider theme={theme}>
      <ButtonWrapper>
        <ButtonText>  
          {props.text}
        </ButtonText>
      </ButtonWrapper>
    </ThemeProvider>
  );
}

export default Button;

So far so good. My AnimatedButton file is like that

    import React from 'react';
import Styled, { keyframes, ThemeProvider} from 'styled-components';
import theme from '../../theme/default';
import Button from '../../components/button/button'

// import {rotatecw, rotateccw} from '../../../theme/keyframes';

const rotatecw = keyframes`
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
`

const rotateccw = keyframes`
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(-360deg);
    }
`



const AnimatedButtonWrapper = Styled(Button)` 
transition: all 0.3s;
  &:before,
  &:after {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    bottom: 0;
    left: 0;
    z-index: 1;
    transition: all 0.3s;
    border: 1px solid ${(props) => props.theme.colors.primary};
  }
  &:hover {
    cursor: pointer;
    &:after {
      animation-name: ${rotatecw};
      animation-duration: 2s;
    }
    &:before {
      animation-name: ${rotateccw}; 
      animation-duration: 3s;
    }
    &:before,
    &:after {
      left: 96px;
      width: 64px;
      animation-iteration-count: infinite;
      animation-timing-function: linear;
    }
`;

function AnimatedButton(props) {
  return (
    <ThemeProvider theme={theme}>
      <AnimatedButtonWrapper>



      </AnimatedButtonWrapper>
    </ThemeProvider>
  );
}

export default AnimatedButton;

What confused me is the bottom part. seems like a repeat ... How do I ensure it generates the same markup as Button ? I want my animated button to extend the markup and the css. Eventually, is there a way to call my button this way

<Button animatedButton text="test"></Button>

When you extend a Button with styled(Button) , you are essentially creating a more specific version of it and is planning to use the new specific one instead.

But when you want to use the button as:

<Button animatedButton text="test"></Button>

which is a variant passing in animatedButton as a prop, you are looking to incorporate these changes in the ButtonComponent itself.

const ButtonWrapper = styled.button`
  All the normal button stuff

  ${props.animated && `
    All the animation stuff goes here
  `}
`
function Button(props) {
  return (
    <ThemeProvider theme={theme}>
      <ButtonWrapper animated={props.animatedButton}>
        <ButtonText>  
          {props.text}
        </ButtonText>
      </ButtonWrapper>
    </ThemeProvider>
  );
}

If you have lots of variants as such, creating styles for these like this can be excruciating. This is why styled-components has a helper library styled-theming that can help out. (It isn't going be much help for the animated part since that's pretty much adding code rather than changing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM