ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 9. Styled-components : Polished 스타일 유틸 함수 사용 - 컴포넌트 스타일링 | 벨로퍼트
    Front-end/React.js 2020. 7. 20. 11:08
    반응형

     

    Sass 를 사용 할 때에는 lighten() 또는 darken() 과 같은 유틸 함수를 사용하여 색상에 변화를 줄 수 있었는데요, CSS in JS 에서도 비슷한 유틸 함수를 사용하고 싶다면 polished 라는 라이브러리를 사용하면 됩니다.

     

    우선, 패키지를 설치를 해주세요.

    $ yarn add polished

     

    그럼, 기존에 색상 부분을 polished 의 유틸 함수들로 대체를 해보겠습니다.

    /src/components/Button.js :

    // ...
    import { darken, lighten } from 'polished';
    
    const StyledButton = styled.button`
      // ...
    
      /* 색상 */
      background: #228be6;
      &:hover {
        background: ${lighten(0.1, '#228be6')};
      }
      &:active {
        background: ${darken(0.1, '#228be6')};
      }
    
      // ...
    `;
    

    버튼에 커서를 올렸을 때 색상이 잘 바뀌고 있나요?

     

    이제 회색, 핑크색 버튼들을 만들어볼건데요, 색상 코드를 지닌 변수를 Button.js 에서 선언을 하는 대신에 ThemeProvider 라는 기능을 사용하여 styled-components 로 만드는 모든 컴포넌트에서 조회하여 사용 할 수 있는 전역적인 값을 설정해보겠습니다.

     

    App.js 를 다음과 같이 수정해보세요.

    /src/App.js : 

    import React from 'react';
    import styled, { ThemeProvider } from 'styled-components';
    import Button from './components/Button';
    
    // ...
    
    function App() {
      return (
        <ThemeProvider
          theme={{
            palette: {
              blue: '#228be6',
              gray: '#495057',
              pink: '#f06595'
            }
          }}
        >
          <AppBlock>
            <Button>BUTTON</Button>
          </AppBlock>
        </ThemeProvider>
      );
    }

    이렇게 해서 theme 을 설정하면 ThemeProvider 내부에 렌더링된 styled-components 로 만든 컴포넌트에서 palette 를 조회하여 사용 할 수 있습니다. 한번 Button 컴포넌트에서 우리가 방금 선언한 palette.blue 값을 조회해봅시다.

    /src/components/Button.js :

    // ...
    import styled, { css } from 'styled-components';
    
    const StyledButton = styled.button`
      // ...
      
      /* 색상 */
      ${props => {
        const selected = props.theme.palette.blue;
        return css`
          background: ${selected};
          &:hover {
            background: ${lighten(0.1, selected)};
          }
          &:active {
            background: ${darken(0.1, selected)};
          }
        `;
      }}
    
      // ...
    `;

    ThemeProvider 로 설정한 값은 styled-components 에서 props.theme 로 조회 할 수 있습니다. 지금은 selected 값을 무조건 blue 값을 가르키게 했는데요, 이 부분을 Button 컴포넌트가 color props를 통하여 받아오게 될 색상을 사용하도록 수정해보겠습니다.

    /src/components/Button.js :

    const StyledButton = styled.button`
      // ...
      
      /* 색상 */
      ${props => {
        const selected = props.theme.palette[props.color];
        return css`
          background: ${selected};
          &:hover {
            background: ${lighten(0.1, selected)};
          }
          &:active {
            background: ${darken(0.1, selected)};
          }
        `;
      }}
    
      // ...
    `;
    
    function Button({ children, color ...rest }) {
      return <StyledButton {...rest}>{children}</StyledButton>
    }
    
    Button.defaultProps = {
      color: 'blue'
    };

    지금은 기본 색상이 blue 가 되도록 설정해주었습니다.

     

    이제 App 컴포넌트를 열어서 회색, 핑크색 버튼을 렌더링해봅시다.

    /src/App.js :

     

    // ...
    function App() {
      return (
        <ThemeProvider
          theme={{
            palette: {
              blue: '#228be6',
              gray: '#495057',
              pink: '#f06595'
            }
          }}
        >
          <AppBlock>
            <Button>BUTTON</Button>
            <Button color="gray">BUTTON</Button>
            <Button color="pink">BUTTON</Button>
          </AppBlock>
        </ThemeProvider>
      );
    }
    // ...

    결과가 잘 나타났나요?

     

    Button 컴포넌트의 코드는 다음과 같이 리팩토링 할 수 있습니다.

    /src/components/Button.js :

    const StyledButton = styled.button`
      // ...
    
      /* 색상 */
      ${({ theme, color }) => {
        const selected = theme.palette[color];
        return css`
          background: ${selected};
          &:hover {
            background: ${lighten(0.1, selected)};
          }
          &:active {
            background: ${darken(0.1, selected)};
          }
        `;
      }}
      
      // ...
    `;
    
    function Button({ children, color, ...rest }) {
      return <StyledButton color={color} {...rest}>{children}</StyledButton>;
    }

    props.theme.palette.blue 이런식으로 값을 조회하는 대신에 비구조화 할당 문법을 사용하여 가독성을 높여주었습니다.

     

    참고로 위 로직은 다음과 같이 색상에 관련된 코드를 분리하여 사용 할 수도 있습니다.

    /src/components/Button.js :

    const colorStyles = css`
      ${({ theme, color }) => {
        const selected = theme.palette[color];
        return css`
          background: ${selected};
          &:hover {
            background: ${lighten(0.1, selected)};
          }
          &:active {
            background: ${darken(0.1, selected)};
          }
        `;
      }}
    `;
    
    const StyledButton = styled.button`
      // ... 
      
      /* 색상 */
      ${colorStyles}
    
      // ... 
    `;
    

    작업을 다 하셨다면, 이전과 동일하게 작동하는지 확인해보세요.

    반응형

    댓글

Luster Sun