React

JINO·2022년 6월 28일
0

대구AI스쿨

목록 보기
23/55

🔸 학습내용

(1) 에어비앤비 디자인 시스템 따라하기

1. 스토리북

  • 팀단위 프로젝트 진행 시 각각의 디자인을 쉽게 볼 수 있도록 스토리북이라는 UI 컴포넌트 개발도구에 등록해 개발을 진행.

  • 데모용 코드 작성에 도움을 주고, 공통적으로 사용될 컴포넌트를 팀원들과 편리하게 공유할 수 있다.

  • 구성단위는 스토리(Story)

  • 컴포넌트는 보통 하나 이상의 스토리를 가진다.

    • 장점
    1. 로직이 복잡하지 않다(독립적 환경에서 컴포넌트 개발 가능)
    2. 재사용을 위한 컴포넌트들을 스토리에서 조합해 테스트 가능
    3. 컴포넌트들을 문서화 할 수 있고, 디자인 시스템에 적용해 피그마의 컴포넌트들을 동기화 할 수 있다.

2. 실습 프로젝트 생성

  • CRA(Create React App) 방식으로 새 프로젝트 생성
    npx create-react-app 프로젝트명
  • 프로젝트 디렉터리로 이동
    cd 프로젝트명
  • 스토리북 설치
    npx -p storybook sb init
  • 스토리북 실행
    npm run storybook
  • 실행 후 보이는 화면

3. 컴포넌트 작성

// Input.jsx
import React, { Component } from "react";
import PropTypes from "prop-types";

class Input extends Component {
  constructor(props) {
    super(props);
    this.setRef = this.setRef.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    const { name, onChange } = this.props;
    if (onChange) {
      onChange(name, e.target.value);
    }
  }

  componentDidMount() {
    if (this.props.autoFocus) {
      this.ref.focus();
    }
  }

  componentDidUpdate() {
    if (this.props.autoFocus) {
      this.ref.focus();
    }
  }

  setRef(ref) {
    this.ref = ref;
  }

  render() {
    const { errorMessage, label, name, value, type, onFocus } = this.props;
    return (
      <label>
        {label}
        <input
          id={"input_${name}"}
          ref={this.setRef}
          onChange={this.handleChange}
          onFocus={onFocus}
          value={value}
          type={type}
        />
        {errorMessage && <span className="error">{errorMessage}</span>}
      </label>
    );
  }
}

Input.propTypes = {
  type: PropTypes.oneOf(["text", "number", "price"]),
  name: PropTypes.string.isRequired,
  value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  errorMessage: PropTypes.string,
  label: PropTypes.string,
  onChange: PropTypes.func,
  autoFocus: PropTypes.bool,
};

Input.defaultProps = {
  onChange: () => {},
  onFocus: () => {},
  autoFocus: false,
  type: "text",
};

export default Input;
// Input.stories.js
import React, { Component } from 'react';
import Input from "./Input";

export default{
    title : "Input",
    component : Input,
};

export const label = () => <Input name="name" label="이름 : "/>;
// Text.jsx
import React, { Component } from "react";
import PropTypes from "prop-types";

export function Text({ children, color, italic, underline }) {
  const style = {
    color: color,
    fontStyle: italic ? "italic" : "normal",
    textDecoration: underline ? "underline" : "none",
  };
  return <span style={style}>{children}</span>;
}

Text.propTypes = {
  children: PropTypes.string.isRequired,
  color: PropTypes.string,
  italic: PropTypes.bool,
  underline: PropTypes.bool,
};

Text.defaultProps = {
  color: "black",
  italic: false,
  underline: false,
};
// Text.stories.js
import React, { Component } from "react";
import {Text} from "./Text";

export default{
    title : "Text",
    component : Text,
};

const TEST_TEXT = "Story Text Test";
export const Default = () =><Text>{TEST_TEXT}</Text>;
export const Red = () =><Text color="red">{TEST_TEXT}</Text>;
export const Italic = () =><Text italic>{TEST_TEXT}</Text>;
export const Underline = () =><Text underline>{TEST_TEXT}</Text>;

[스토리북 실행화면]

profile
On your Mark

0개의 댓글