styled-componentsで再利用可能なグリッドレイアウトを作る
やること
Reactでコンポーネントを組み立ててUI作っていくのも楽なんですが、 styled-componentsでグリッドレイアウトのコンポーネントを作って、 それらを組み合わせて使うと非常に楽だということに気がつきました。
一度作ったやつを取っておけば再利用することもできますし:open_hands_tone2:
styled-componentsで書いたcssの記述も整理しやすいですし、おすすめです。 GitHub参考 => https://github.com/yutaro1204/styled-components-demo
前提
・styled-componentの使い方 ・CSSでのdisplay: grid;の使い方
TypeScriptでReactのコンポーネントを書いていきますので、tsxを使います。
導入
まず気楽にcreate-react-appを使います。
$ npx create-react-app app-name --typescript
create-react-appが入っている場合はnpxは不要です。
styled-componentsをインストールします。
$ yarn add styled-components @types/styled-components
アプリを立ち上げます。デフォルトはhttp://localhost:3000となります。
$ yarn start
コーディング
最終的にこんな感じの構造になります。
app-name/src ├── App.css ├── App.test.tsx ├── App.tsx ├── components │ ├── Header.tsx // 追加 │ ├── Main.tsx // 追加 │ └── Sidepane.tsx // 追加 ├── index.css ├── index.tsx ├── logo.svg ├── modules │ └── styled-components.ts // 追加 ├── react-app-env.d.ts └── serviceWorker.ts
デフォルトで入っているsrcディレクトリ配下にmodulesディレクトリみたいなのを作って、 styled-components用のファイルを作成します。
// styled-components.ts import style from 'styled-components' const styledComponents = { LayoutStyles: { Body: { Grid: style.div` display: grid; grid-template-columns: 300px 1fr; grid-template-rows: 80px 1fr; ` }, Header: { Grid: style.div` grid-column: 1 / 3; grid-row: 1 / 2; display: grid; grid-template-columns: 40px 1fr 1fr 1fr 1fr 40px; background-color: #008080; `, // 状況によってgrid-columnの値を変化させる Item: style.div` grid-column: ${ ({theme}) => theme.column }; max-height: 80px; ` }, Main: { Grid: style.div` grid-column: 2 / 3; grid-row: 2 / 3; display: grid; grid-template-columns: 100px 1fr 1fr 1fr 1fr 100px; height: calc(100vh - 80px); overflow-y: scroll; background-color: #ffe4c4; `, Item: style.div` grid-column: ${ ({theme}) => theme.column }; grid-row: ${ ({theme}) => theme.row }; height: 200px; `, }, Sidepane: { Grid: style.div` grid-column: 1 / 2; grid-row: 2 / 3; height: calc(100vh - 80px); overflow-y: scroll; background-color: #696969; `, Item: style.div` width: 100%; height: 200px; ` } }, ComponentStyles: { // As you prefer... } } export default styledComponents
ここでは、LayoutStylesにBodyやHeaderなどのCSS情報をまとめたものと、 その他の細かいコンポーネントのCSS情報をComponentsStylesにまとめるようにしています(ここには何も書いていません)。
上のstyled-components.tsに従ってtsxを書き換えるとこんな感じになりました:point_down_tone2:
// App.tsx import React from 'react' import styledComponents from './modules/styled-components' import Header from './components/Header' import Sidepane from './components/Sidepane' import Main from './components/Main' const BodyGrid = styledComponents.LayoutStyles.Body.Grid const App: React.FC = () => { return ( <BodyGrid> <Header /> <Sidepane /> <Main /> </BodyGrid> ) } export default App
んで、参考までにこのHeaderコンポーネントとなっているHeader.tsxはこんな感じに:point_down_tone2:
// Header.tsx import React from 'react' import styledComponents from '../modules/styled-components' const HeaderGrid = styledComponents.LayoutStyles.Header.Grid const HeaderItem = styledComponents.LayoutStyles.Header.Item const Header: React.FC = () => { return ( <HeaderGrid> <HeaderItem theme={{ column: '2 / 3' }}> <p>Grid1</p> </HeaderItem> <HeaderItem theme={{ column: '3 / 4' }}> <p>Grid2</p> </HeaderItem> <HeaderItem theme={{ column: '4 / 5' }}> <p>Grid3</p> </HeaderItem> <HeaderItem theme={{ column: '5 / 6' }}> <p>Grid4</p> </HeaderItem> </HeaderGrid> ) } export default Header
おんなじ要領でHeader、Sidepane、Mainを組み合わせると、こんな感じになります。
ちょっと地味ですが、ここから色々装飾すればそれなりになるかと:information_desk_person:
styled-componentsとreactDnDをつかってなんか作りたい今日この頃。。。