React UI library の antd について (1) - Button
React UI library の antd について (2) - Layout
React UI library の antd について (3) - redux-form
前回は antd のインストールとButton componentを見ました。簡単には使えましたが、BootstrapやMaterial-UIとの差があまりわかりませんでした。
React UI library の antd について (1) - Button
今回はLayoutを見ますが、他のUIライブラリと比べると、コードが論理的にスッキリと書けるような気がします。
#1.Grid
antd の Grid システムは以下のルールに従います。
- 行を row で表し、row の中に複数の列 col を配置します。
- colの中にコンテンツを配置します。row 直下の要素は col 以外は置けません。
- 各rowの中に24個までのcolを配置できます。24個を超えた場合は、溢れたcolは改行されます。
- Grid システムはFlex layoutをサポートしています。
1-1.シンプルな例
import React, { Component } from 'react';
import { Row, Col } from 'antd';
import './App.css';
const style1 = { background: "#66CDAA", padding: "20px", fontWeight: "bold" }
const style2 = { background: "#AFEEEE", padding: "20px" , fontWeight: "bold"}
class App extends Component {
render() {
return (
<div style={{ margin: '10px'}}>
<Row style={{ margin: '10px'}}>
<Col span={12} style={style1}>col-12</Col>
<Col span={12} style={style2}>col-12</Col>
</Row>
<Row style={{ margin: '10px'}}>
<Col span={8} style={style1}>col-8</Col>
<Col span={8} style={style2}>col-8</Col>
<Col span={8} style={style1}>col-8</Col>
</Row>
<Row style={{ margin: '10px'}}>
<Col span={6} style={style1}>col-6</Col>
<Col span={6} style={style2}>col-6</Col>
<Col span={6} style={style1}>col-6</Col>
<Col span={6} style={style2}>col-6</Col>
</Row>
</div>
);
}
}
export default App;
以下が実行例です。
1-2.Flex Layout
Flex Layoutを使うには、Rowで**type="flex"**を指定し、justifyでLayout ( start end center space-around space-between ) を指定します。
import React, { Component } from 'react';
import { Row, Col } from 'antd';
import './App.css';
const style1 = { background: "#66CDAA", padding: "20px", fontWeight: "bold" }
const style2 = { background: "#AFEEEE", padding: "20px" , fontWeight: "bold"}
class App extends Component {
render() {
return (
<div style={{ margin: '10px'}}>
<p>sub-element align left</p>
<Row type="flex" justify="start" style={{ margin: '10px'}}>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
</Row>
<p>sub-element align center</p>
<Row type="flex" justify="center" style={{ margin: '10px'}}>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
</Row>
<p>sub-element align right</p>
<Row type="flex" justify="end" style={{ margin: '10px'}}>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
</Row>
<p>sub-element monospaced arrangement</p>
<Row type="flex" justify="space-between" style={{ margin: '10px'}}>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
</Row>
<p>sub-element align full</p>
<Row type="flex" justify="space-around" style={{ margin: '10px'}}>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
<Col span={4} style={style1}>col-4</Col>
<Col span={4} style={style2}>col-4</Col>
</Row>
</div>
);
}
}
export default App;
以下のように表示されます。
##1-3. レスポンシブデザイン
レスポンシブデザインはBootstrap流の指定で実現できます。以下のコードと実行結果を参照してください。
import React, { Component } from 'react';
import { Row, Col } from 'antd';
import './App.css';
const style1 = { background: "#66CDAA", padding: "20px", fontWeight: "bold" }
const style2 = { background: "#AFEEEE", padding: "20px" , fontWeight: "bold"}
class App extends Component {
render() {
return (
<Row style={{ margin: '10px'}}>
<Col xs={2} sm={4} md={6} lg={8} xl={10} style={style1}>
Col
</Col>
<Col xs={20} sm={16} md={12} lg={8} xl={4} style={style2}>
Col
</Col>
<Col xs={2} sm={4} md={6} lg={8} xl={10} style={style1}>
Col
</Col>
</Row>
);
}
}
export default App;
以下ブラウザのサイズごとのレイアウトです。レスポンシブデザインが実現できていることが確認できます。
##1-4. 簡単なplayground - column数とgutter.
Sliderで、gutterとcolumn数を変化させ、レイアウトが動的に変わっていくのを確認します。
Rowの属性であるgutterはgrid間のスペースを指定するものです。Col間のスペースというよりは、Colのコンテンツ(以下の例ではdiv)間のスペースを取ってくれます。セレクタ [class~='ant-col'] > div で指定されるコンテンツ間のスペースです。
[class~='ant-col'] {
background: transparent;
border: 0;
}
[class~='ant-col'] > div {
background: #00a0e9;
height: 120px;
line-height: 120px;
font-size: 13px;
}
pre {
background: #f9f9f9;
border-radius: 6px;
font-size: 13px;
padding: 8px 16px;
}
Slide componentでgutterとcolumn数を変化させ、RowとColを定義・描画していきます。
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Row, Col, Slider } from 'antd';
class App extends React.Component {
gutters = {};
colCounts = {};
constructor() {
super();
this.state = {
gutterKey: 1,
colCountKey: 2,
};
[8, 16, 24, 32, 40, 48].forEach((value, i) => {
this.gutters[i] = value;
});
[2, 3, 4, 6, 8, 12].forEach((value, i) => {
this.colCounts[i] = value;
});
}
onGutterChange = gutterKey => {
this.setState({ gutterKey });
};
onColCountChange = colCountKey => {
this.setState({ colCountKey });
};
render() {
const { gutterKey, colCountKey } = this.state;
const cols = [];
const colCount = this.colCounts[colCountKey];
let colCode = '';
for (let i = 0; i < colCount; i++) {
cols.push(
<Col key={i.toString()} span={24 / colCount}>
<div>Column</div>
</Col>,
);
colCode += ` <Col span={${24 / colCount}} />\n`;
}
return (
<div>
<div style={{ marginBottom: 16 }}>
<span style={{ marginRight: 6 }}>Gutter (px): </span>
<div style={{ width: '50%' }}>
<Slider
min={0}
max={Object.keys(this.gutters).length - 1}
value={gutterKey}
onChange={this.onGutterChange}
marks={this.gutters}
step={null}
/>
</div>
<span style={{ marginRight: 6 }}>Column Count:</span>
<div style={{ width: '50%' }}>
<Slider
min={0}
max={Object.keys(this.colCounts).length - 1}
value={colCountKey}
onChange={this.onColCountChange}
marks={this.colCounts}
step={null}
/>
</div>
</div>
<Row gutter={this.gutters[gutterKey]}>{cols}</Row>
<pre>{`<Row gutter={${this.gutters[gutterKey]}}>\n${colCode}</Row>`}</pre>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
以下は実行結果です。
2.Layout
Layout Componentはページ全体のLayoutを記述します。
Layout Componentの概要
- Layout: Header、 Sider、 Content、 Footer または Layout自身のwrpper
- Header: トップ Layout
- Sider: sidebar
- Content: content layout
- Footer: ボトム Layout
##2-1.シンプルな例
Layoutのシンプルな例です。
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
ReactDOM.render(
<div>
<Layout>
<Sider>Sider</Sider>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
</Layout>
</div>,
document.getElementById('container'),
);
cssファイルです。
.ant-layout-header,
.ant-layout-footer {
background: #7dbcea;
color: #fff;
}
.ant-layout-footer {
line-height: 1.5;
}
.ant-layout-sider {
background: #3ba0e9;
color: #fff;
line-height: 120px;
}
.ant-layout-content {
background: rgba(16, 142, 233, 1);
color: #fff;
min-height: 120px;
line-height: 120px;
}
枠組みだけですが、ページ全体がレイアウトされています。
##2-2. レスポンシブデザイン
Siderはbreakpointを設定することで、レスポンシブデザインをサポートするようになります。windowの横幅がbreakpoint以下になったら、折りたたまれます。
Menu componentが簡単に使えて、Icon componentで様々なアイコンを指定できるのも便利です。他のUIライブラリに比べて、全体的に論理的にスッキリと書けるのではないでしょうか?
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Layout, Menu, Icon } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
ReactDOM.render(
<Layout>
<Sider
breakpoint="lg"
collapsedWidth="0"
onBreakpoint={broken => {
console.log(broken);
}}
onCollapse={(collapsed, type) => {
console.log(collapsed, type);
}}
>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['4']}>
<Menu.Item key="1">
<Icon type="user" />
<span className="nav-text">nav 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="video-camera" />
<span className="nav-text">nav 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="upload" />
<span className="nav-text">nav 3</span>
</Menu.Item>
<Menu.Item key="4">
<Icon type="user" />
<span className="nav-text">nav 4</span>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }} />
<Content style={{ margin: '24px 16px 0' }}>
<div style={{ padding: 24, background: '#fff', minHeight: 360 }}>content</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design c2018 Created by Ant UED</Footer>
</Layout>
</Layout>,
document.getElementById('root'),
);
小さいですがCSSです。
.logo {
height: 32px;
background: rgba(255, 255, 255, 0.2);
margin: 16px;
}
今回は以上です