Stylemapper - React 애플리케이션의 스타일을 지정하는 더 나은 방법

15055 단어 webdevtailwindcssreact
React 애플리케이션의 스타일을 지정하는 방법에는 여러 가지가 있습니다. Emotion , Styled Components 또는 Stitches 과 같은 CSS-in-JS 라이브러리에서 CSS(또는 SCSS/SASS) 작성에 이르기까지 빌드 도구를 활용하여 모든 것을 통합합니다. 그들은 모두 잘 맞을 수 있지만 접근 방식에 100% 만족한 적은 없었습니다. 일부는 반복적인 코드로 이어지고 다른 일부는 기본 CSS 기능을 사용하기 어렵게 만듭니다. 스타일을 재사용하기 어려운 경우도 있고 사용자 정의하기 어려운 경우도 있습니다.

하지만 웹 개발 커뮤니티와 공유하고 싶은 새로운 방법을 찾았습니다.

Tailwind CSS와 같은 유틸리티 기반 CSS 프레임워크를 제가 작성한 Slicknode Stylemapper이라는 작은 라이브러리와 결합합니다.

왜 스타일매퍼인가?



나는 오랫동안 Tailwind CSS 회의론자였습니다. 나는 그것에 대해 많이 읽었고 내가 존경하는 개발자들의 열렬한 리뷰를 보았습니다. 하지만 한동안 큰 프로젝트를 위해 CSS 솔루션을 선택할 필요가 없었기 때문에 실제로 사용하지 않고 프레임워크만 주시했습니다.

최근에 저는 Tailwind CSS를 사용하여 대규모 코드베이스 작업을 시작했습니다. 여러 팀이 프로젝트에 참여하고 있으며 디자인 시스템을 확장하고 일관된 레이아웃을 유지하는 데 큰 도움이 됩니다. 유틸리티 기반 CSS 프레임워크 접근 방식은 처음에는 이상하게 느껴질 수 있지만 스타일을 JSX 코드에 바로 추가하는 것에 대한 초기 망설임을 극복하자 매우 생산적인 것으로 판명되었습니다.

그러나 React 프로젝트에서 Tailwind CSS를 사용하는 데 여전히 마음에 들지 않는 몇 가지 사항이 있습니다.

React의 Tailwind CSS는 추악합니다.



어쩌면 이것은 나일지도 모르지만 React에서 Tailwind CSS를 사용하는 것이 꽤 추악하다는 것을 알았습니다. CSS 클래스는 React 구성 요소 코드 전체에 흩어져 있어 읽기가 더 어렵습니다. 많은 스타일 정의가 너무 길어 내 큰 화면의 한 줄에 맞지 않습니다. 가로로 스크롤하거나 내 IDE에서 자동 줄 바꿈을 활성화해야 합니다. 다음은 TailwindCSS 웹사이트의 예입니다(반응성 및 다크 모드도 포함하지 않음).

export function ProjectListButton() {
  return (
    <a href="/new" class="hover:border-blue-500 hover:border-solid hover:bg-white hover:text-blue-500 group w-full flex flex-col items-center justify-center rounded-md border-2 border-dashed border-slate-300 text-sm leading-6 text-slate-900 font-medium py-3">
      New project
    </a>
  );
}


설명서에 따르면 현재까지 권장되는 접근 방식인 사용자 지정 구성 요소를 생성하여 이 엉망진창을 숨길 수 있지만 다음 지점으로 이동합니다.

수작업 반복 작업



일부 스타일을 추가하기 위해 모든 React 래퍼 구성 요소를 만드는 것은 지루합니다. 확장 가능한 방식으로 코드를 작성하려면 구성 요소 기본 스타일을 React 소품의 클래스 이름과 수동으로 병합해야 합니다. 그리고 Typescript를 사용하는 경우 모든 구성 요소에 대해 손으로 prop 유형 정의를 만들어야 합니다. refs, 이벤트 처리기, 확장성 및 간단한 변형 "selected"에 대한 지원을 통해 예제 중 하나는 다음과 같습니다.

import * as React from 'react';

export interface NavProps extends React.ComponentPropsWithoutRef<'div'> {
  selected?: boolean;
}

export const Nav = React.forwardRef<HTMLDivElement, NavProps>((props, ref) => {
  const { className, children, selected, ...rest } = props;
  return (
    <div
      {...rest}
      ref={ref}
      className={`py-4 px-6 text-sm ${
        selected ? 'font-bold' : 'font-medium'
      } ${className}`}
    >
      {' '}
      <ul className="flex space-x-3"> {children} </ul>{' '}
    </div>
  );
});

<Button/> (위험, 기본, 중립), intent , outline , disabled 와 같은 여러 변형이 있는 size 구성 요소를 상상해 보십시오.

Slicknode Stylemapper 입력



위의 모든 문제를 해결하고 구성 요소 코드를 크게 단순화하는 작은 유틸리티 라이브러리를 작성했습니다. Stitches에서 영감을 받아 유사한 API를 유틸리티 기반 CSS 프레임워크에 도입하고 싶었습니다. npm을 통해 설치하고 사용자 지정 구성 요소 구축을 시작할 수 있습니다.

스타일이 지정된 구성 요소 만들기




import {styled} from '@slicknode/stylemapper';

// Create styled components with CSS classes
const Menu = styled('ul', 'space-x-2 flex');
const MenuItem = styled('li', 'w-9 h-9 flex items-center justify-center');

// Then use the components in your app
const App = () => {
  return (
    <Menu>
      <MenuItem>Home</MenuItem>
      <MenuItem>Product</MenuItem>
      <MenuItem>Signup Now</MenuItem>
    </Menu>
  );
};


변형이 있는 구성요소



소품을 기반으로 스타일을 변경하는 여러 변형으로 구성 요소를 쉽게 만들 수 있습니다. Stylemapper는 소품 유형을 자동으로 유추하고 엄격한 유형의 구성요소를 생성합니다.

이렇게 하면 구성 요소 코드에서 스타일 관리 논리가 제거되고 애플리케이션 코드에서 다음 사항을 더 쉽게 추론할 수 있습니다.

const Button = styled('button', {
  variants: {
    intent: {
      neutral: 'bg-slate-300 border border-slate-500',
      danger: 'bg-red-300 border border-red-500',
      success: 'bg-green-300 border border-green-500',
    },
    size: {
      small: 'p-2',
      medium: 'p-4',
      large: 'p-8',
    },
    // Add any number of variants...
  },
  // Optionally set default variant values
  defaultVariants: {
    intent: 'neutral',
    size: 'medium',
  },
});

const App = () => {
  return (
    <Button intent={'danger'} size={'large'}>
      Delete Account
    </Button>
  );
};


맞춤 구성요소



Stylemapper는 className 소품이 있는 모든 구성 요소와 함께 작동합니다. 따라서 Headless UI , Radix UIReach UI 과 같은 헤드리스 UI 라이브러리에 완벽하게 맞습니다. 구성 요소를 첫 번째 인수로 전달하기만 하면 됩니다.

import {FancyComponent} from './fancy-component`;

const StyledFancyComponent = styled(FancyComponent, 'py-2 px3', {
  variants: {
    intent: {
      danger: 'bg-red-300 border border-red-500',
      success: 'bg-green-300 border border-green-500',
    },
  },
});


시작하다



Slicknode Stylemapper은 이제 MIT 라이선스에 따라 npm에서 사용할 수 있습니다. 전체 API를 보고 시작하려면 Github repository 을 확인하십시오. 여러분의 피드백을 듣고 싶습니다! Slicknode community on Slack 에 가입하거나 가입할 수 있습니다.

좋은 웹페이지 즐겨찾기