Flex panels image Gallery 만들기

CSS Flex property를 이용한 image gallery를 react로 만들어보겠다.

초기 소스코드는 다음 사이트에 있다.

index-START.html파일에 있는 코드를 react 구조에 맞게 옮겼다.

App component와 PanelList, Panel component, PanelListContainer component로 분리하고 css파일도 App.css와 PanelList.css, Panel.css로 css코드를 분리했다.

.panels {
min-height: 100vh;
overflow: hidden;
display: flex;
}

panel들을 감싸고 있는 panels class의 display property를 flex로 정의해준다.

flex는 layout을 잡을 때 사용하는 css 속성으로 container와 item역할을 하는 두 종류의 DOM들을 사용하여 효과적으로 웹 상의 그리드를 조정한다.

flex를 사용하기 위해서는 먼저 container의 display 속성을 flex로 지정해주고, flex-direction을 이용해 정렬방식을 정해준다.

default flex direction이 row이고, 우리는 panels를 row로 정렬할 것이기 때문에 추가적으로 direction을 설정해주지는 않았다.

.panel > * {  ...
flex: 1 0 auto;
display: flex;
justify-content: center;
align-items: center;
...
}
.panel > *:first-child {
transform: translateY(-100%);
}

.panel.open-active > *:first-child {
transform: translateY(0);
}

.panel > *:last-child {
transform: translateY(100%);
}

.panel.open-active > *:last-child {
transform: translateY(0);
}

flex를 1로 설정주면(flex-grow: 1) container의 전체 넓이를 1:1:1…로 나누어 가져가게 되어 item들(panels)이 여백없이 화면에 꽉 차게 된다.

각 panels 텍스트들의 정렬을 위해 justify-content: center값을 주었다.

텍스트들 역시 flex로 이번에는 column으로 정렬해준다.

panel이 활성화(open) 되면 해당 panel의 안 보이던 위 아래 텍스트들이 가운데로 모여 보이게 된다. translateY(-100%), translateY(100%)로 화면 범위 밖에 위치해 있다가 open-active class를 포함하면 원래 위치로 돌아간다.

reducers/index.js

기존에 html코드로 작성되어 있던 panels를 store state에서 array로 관리하여 동적으로 변경가능하도록 수정하였다. panel에서 보여주는 위, 중간, 아래 텍스트들과 배경 이미지, 그리고 open여부도 state에서 관리한다.

action은 click 한 가지로, panel의 open state를 toggle해준다.

import React, { Component } from 'react';
import './PanelList.css';

import Panel from './Panel';

class PanelList extends Component {
render() {
const {panels, onClick} = this.props;

return (
<div className="panels">
{panels.map((panel, index) => {
return <Panel
key={index}
index={index}
{...panel}
onClick={onClick}
/>
})}
</div>
);
}
}


export default PanelList;

PanelList.js에서는 panels state의 각 panel들을 Panel Component를 통해 만들어준다.

Panel은 panel state를 전달받아 component로 만들어준다.

componentDidMount()에서는 이번에 새로 알게 된 findDomNode() function을 통해 각 panel component로 생성 된 html DOM을 선택해준다. 해당 DOM이 click event를 받아 state의 변경으로 인해 ‘open’ class가 추가되면 transition이 일어나고, transitionend event를 감지한 시점에서 ‘open-active’ class역시 추가해주면 DOM이 늘어난 이후 텍스트들이 보인다.

튜토리얼에서는 classList.toggle() function을 사용했지만 현재 작성한 코드에서는 state변경으로 인해 panel open이 비활성화 되면 자동으로 ‘open-active’ class도 없는 component로 업데이트되기 때문에 classList.add() function을 사용해주었다.

완성된 모습은 다음과 같다.

Github Source Code

woohyun