본문 바로가기
개발 이야기/React

React용 UI 프레임워크 gestalt 사용해보기

by 농개 2019. 4. 22.

gestalt는 react용 UI프레임워크의 한 종류입니다.

https://github.com/pinterest/gestalt

https://pinterest.github.io/gestalt/#/

 

Gestalt

 

pinterest.github.io

웹 UI프레임워크 중 널리 알려져 있는 것 중 하나가 바로 bootstrap입니다.

bootstrap은 jquery를 기반으로 동작하며, jquery와 해당 라이브러리를 참조하면

깔끔하게 디자인된 레이아웃, 폼, 버튼, 모달창 등을 사용할 수 있습니다. 

 

gestalt는 bootrap과 유사합니다. react에서 사용 가능하며, bootrap처럼 많은 UI 컴포넌트가 제공됩니다. (반응형도 갖춰져있습니다.)

gestalt를 사용해서 간단하게 포트폴리오 사이트 레이아웃을 잡아보겠습니다.


01. React 프로젝트 생성

create-react-app을 통해서 프로젝트를 생성해보겠습니다.(windows 10, power shell 사용)

PS C:\mynode> create-react-app portfolio

위 명령어를 입력하면 portfolio라는 디렉토리가 생성되고 안에 아래와 같은 파일들이 생성됩니다.

create-react-app으로 프로젝트 생성시 패키지 구조

 

 

02. gestalt 설치 및 dependency 추가

PS C:\mynode\portfolio> npm install gestalt --save

위 명령어로 간단하게 설치 할 수 있습니다.

 

 

 

 

03. Wrapper추가 - Box

gestalt에서는 Box를 div와 같은 역할을 수행합니다.

App.js를 열어 아래와 같이 수정 해보겠습니다.

import React, { Component } from "react";
import { Box } from "gestalt";
import "gestalt/dist/gestalt.css";

class App extends Component {
  render() {
    return (
      <Box
        column={12}
        color="lightGray"
        display="flex"
        justifyContent="center"
        minHeight={1028}
      >
      </Box>
    );
  }
};

export default App;

import { Box } from "gestalt";

import "gestalt/dist/gestalt.css";

기본적으로 위와 같이 참조하여 gestalt를 사용할 수 있습니다.

column값 12는 전체(?)라고 보시면 됩니다. grid 단위를 의미하며 0~12까지 줄 수 있습니다. 

justifyContent는 center로 주어 중앙에 배치되도록 하였습니다.

실행 시켜보면 아래와 같은 화면입니다.

실행 화면

 

 

 

04. Header추가 - Text, Heading

Header.js파일을 생성하여 아래와 같이 작성 합니다.

import React from "react";
import { Heading, Text } from "gestalt";
import "gestalt/dist/gestalt.css";

const Header = () => {
  return (
    <Text align="center" bold>
      <Heading size="md" color="white">
        Portfolio
      </Heading>
    </Text>
  );
}

export default Header;

 

Text와 Heading 컴포넌트를 사용하여서 "Portfolio"라는 대제목을 만들려고합니다.

 

App.js파일을 다시 열어서 Header를 추가시켜 봅시다.

import React, { Component } from "react";
import { Box } from "gestalt";
import "gestalt/dist/gestalt.css";

import Header from "./Header";

class App extends Component {
  render() {
    return (
      <Box
        column={12}
        color="lightGray"
        display="flex"
        justifyContent="center"
        minHeight={1028}
      >
      	<Box maxWidth={960} column={12} color="white" shape="rounded">
          <Box color="eggplant" shape="roundedTop">
            <Header />
          </Box>
          <Box padding={5}>
            contents
          </Box>
        </Box>
      </Box>
    );
  }
};

export default App;

최초의 Wrapper역할의 Box 컴포넌트 내부에 Container 역할을 Box를 하나더 만들었습니다.

<Box maxWidth={960} column={12} color="white" shape="rounded">

 

또한 그 안에 header와 menu를 추가 할 Box 컴포넌트를 더 추가했습니다.

<Box color="eggplant" shape="roundedTop">

 

실행 시켜 보면 아래와 같은 화면이 뜹니다.

 

 

05. Menu 추가 - Link

음... gestalt에 Tabs라는 컴포넌트가 있습니다. 이걸로 대체해도 상관없을 것 같은데요. 모양이 이쁘게 안나와서 그냥 Box + Link 로 작성해보겠습니다.

Menu.js라는 파일을 만들어 아래와 같이 작성합니다.

import React, {useState} from "react";
import { Box, Text, Link } from "gestalt";
import "gestalt/dist/gestalt.css";

const Menu = () => {
  const [menuIdx, setMenuInx] = useState(0)

  const onHandleChange = (idx) => {
    setMenuInx(idx)
  }
  
  const memuItems = () => {
    const arr = [
      {link:'#', name:'About Me'},
      {link:'#', name:'Skills'},
      {link:'#', name:'Projects'}
    ];

    return arr.map((obj,idx) => {
      const active = (idx === menuIdx?true:false)
      return (
        <Text color="white" size={active?'lg':'md'} bold={active}>
          <Link href={obj.link} onClick={() => onHandleChange(idx)}>
            <Box padding={3}>{obj.name}</Box>
          </Link>
        </Text>
      )
    })
  }

  return (
    <Box display="flex" column={12} justifyContent="center" color="orchid">
      {memuItems()}
    </Box>
  )
}

export default Menu;

 

다른 컴포넌트에 비해 좀 길게 작성 됬는데 별거 없습니다.

map을 사용해서 반복되는 컴포넌트를 렌더링 하는 기법으로 react에서는 자주 사용되는 기법입니다.

// 예시
const mapToComponet => { 
	return map(() => {
		return (
			<div>~~~</div>
		)
	});
}

 

menuItems 함수가 메뉴 개수 만큼 아래의 코드를 추가 합니다.

<Text color="white" size={active?'lg':'md'} bold={active}>
  <Link href={obj.link} onClick={() => onHandleChange(idx)}>
  	<Box padding={3}>{obj.name}</Box>
  </Link>
</Text>

위 코드를 잠깐 설명하자면, active 변수로 활성화된 메뉴를 식별합니다.

활성화된 메뉴라면 size를 크게하고 bold 처리합니다

Link 컴포넌트에 onClick 이벤트를 추가 할 수 있습니다.

여기서는 단순히 Hook을 이용해서 menuIdx를 클릭 시 메뉴인덱스로 변경합니다.

 

App.js 파일을 열어서 Menu 컴포넌트로 추가 해봅시다.

import React, { Component } from "react";
import { Box } from "gestalt";
import "gestalt/dist/gestalt.css";

import Header from "./Header";
import Menu from "./Menu";

class App extends Component {
  render() {
    return (
      <Box
        column={12}
        color="lightGray"
        display="flex"
        justifyContent="center"
        minHeight={1028}
      >
      	<Box maxWidth={960} column={12} color="white" shape="rounded">
          <Box color="eggplant" shape="roundedTop">
            <Header />
            <Menu />
          </Box>
          <Box padding={5}>
            contents
          </Box>
        </Box>
      </Box>
    );
  }
};

export default App;

실행 해보면 아래와 같은 layout이 구성된걸 확인 할 수 있습니다.

간단한 레이아웃 구성