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코드를 분리했다.
// component/PanelList.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을 설정해주지는 않았다.
// component/Panels.css
...
.panel {
flex: 1;
justify-content: center;
display: flex;
flex-direction: column;
}.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를 포함하면 원래 위치로 돌아간다.
기존에 html코드로 작성되어 있던 panels를 store state에서 array로 관리하여 동적으로 변경가능하도록 수정하였다. panel에서 보여주는 위, 중간, 아래 텍스트들과 배경 이미지, 그리고 open여부도 state에서 관리한다.
action은 click 한 가지로, panel의 open state를 toggle해준다.
//components/PanelList.jsimport 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을 사용해주었다.
완성된 모습은 다음과 같다.