FullStackOpen Part7-c More about styles メモ
Ready-made UI libraries
現在は数多くのUIライブラリが存在する
メジャーどころだとBootstrapやMaterialUIがあり、これらにはReactバージョンのライブラリも存在する
React Bootstrap
react-bootstrapをインストールする
npm install react-bootstrap
./public/index.htmlのヘッドに以下を追記する
<head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65"
crossorigin="anonymous"
/>
// ...
</head>
Bootstrapではコンテンツは基本container中にレンダーされる
コンテナにするにはdivタグにclassName='container'を指定する
const App = () => {
// ...
return (
<div className="container">
// ...
</div>
)
}
そうすると今まで端の方まで文字が表示されていたのが、余白ありになった
よく使うやつその1: Table
import { Table } from 'react-bootstrap'でインポート
Table-tbody-tr-tdのように入れ子にして作成
const AnecdoteList = ({ anecdotes }) => (
<div>
<h2>Anecdotes</h2>
<Table striped>
<tbody>
{anecdotes.map(anecdote =>
<tr key={anecdote.id} >
<td>
<Link to={`/anecdotes/${anecdote.id}`}>{anecdote.content}</Link>
</td>
<td>
{anecdote.author}
</td>
</tr>)}
</tbody>
</Table>
</div>
)
よく使うやつその2: Form
import { Form, Button } from 'react-bootstrap'でインポート
Form-(Form.Label, Form.Control, Button)のようにして作成
return (
<div>
<h2>create a new anecdote</h2>
<Form onSubmit={handleSubmit}>
<Form.Group>
<Form.Label>content</Form.Label>
<Form.Control
name='content'
{...content}
/>
<Form.Label>author</Form.Label>
<Form.Control
name='author'
{...author}
/>
<Form.Label>url for more info</Form.Label>
<Form.Control
name='info'
{...info}
/>
<Button variant='primary' type='submit'>
create
</Button>
<Button variant='secondary' onClick={resetField}>
reset
</Button>
</Form.Group>
</Form>
</div>
)
よく使うやつその3: Alert
通知メッセージによく使う
import { Alert } from 'react-bootstrap'
const Notification = ({ notification }) => {
return (
<div className='container'>
{notification &&
<Alert variant='success'>
{notification}
</Alert>}
</div>
)
}
よく使うやつその3: Navbar
import { Navbar, Nav } from 'react-bootstrap'
以下のように使う(少々わかりづらい?)
const Menu = () => {
const padding = {
paddingRight: 5
}
return (
<div>
<Navbar collapseOnSelect expand='lg' bg='dark' variant='dark'>
<Navbar.Toggle aria-controls='responsive-navbar-nav' />
<Navbar.Collapse id='responsive-navbar-nav'>
<Nav className='me-auto'>
<Nav.Link href='#' as='span'>
<Link to='/' style={padding}>anecdotes</Link>
</Nav.Link>
<Nav.Link href='#' as='span'>
<Link to='/create' style={padding}>create new</Link>
</Nav.Link>
<Nav.Link href='#' as='span'>
<Link to='/about' style={padding}>about</Link>
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
</div>
)
}
MaterialUI
Googleが開発したマテリアルデザインのUIフレームワーク
npm install @mui/material @emotion/react @emotion/styled
Bootstrapと似ている
コンテナはこんな感じ
import { Container } from '@mui/material'
const App = () => {
// ...
return (
<Container>
// ...
</Container>
)
}
Table
Bootstrapより名前がわかりやすいが、インポートする必要があるものが多いかも
Table-TableBody-TableRow-TableCell
const Notes = ({ notes }) => (
<div>
<h2>Notes</h2>
<TableContainer component={Paper}>
<Table>
<TableBody>
{notes.map(note => (
<TableRow key={note.id}>
<TableCell>
<Link to={`/notes/${note.id}`}>{note.content}</Link>
</TableCell>
<TableCell>
{note.user}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
)
Form
TextFieldだけ使用し、後はformを使う。
すっきりしている
return (
<div>
<h2>create a new anecdote</h2>
<form onSubmit={handleSubmit}>
<div>
<TextField label='content' {...content} />
</div>
<div>
<TextField label='author' {...author} />
</div>
<div>
<TextField label='info' {...info} />
</div>
<div>
<Button variant='contained' color='primary' type='submit'>create</Button>
<Button variant='contained' color='secondary' onClick={resetField}>reset</Button>
</div>
</form>
</div>
)
Notification
あんま変わらない。
属性がseverityになった
<div>
{(message &&
<Alert severity="success">
{message}
</Alert>
)}
</div>
Navigation
Bootstrapに比べてだいぶシンプルで見やすい
<AppBar position="static">
<Toolbar>
<Button color="inherit" component={Link} to="/">
home
</Button>
<Button color="inherit" component={Link} to="/notes">
notes
</Button>
<Button color="inherit" component={Link} to="/users">
users
</Button>
{user
? <em>{user} logged in</em>
: <Button color="inherit" component={Link} to="/login">
login
</Button>
}
</Toolbar>
</AppBar>
Closing Thoughts
ポピュラリティ的には大差ない。
好きな方を使うべし。
個人的にはMaterialUIの方がデザイン的にも書き方的にもあっている気がする
Other UI frameworks
Styled components
スタイルを付ける別の方法としてstyled-componentsがある
npm install styled-components
Javascript中でCSSのようにスタイル定義して使える
例えば以下のようにデフォルトのbuttonとinputに対して`を使ってスタイルを定義し追加して、それでいて通常のbuttonのように使えるようになる
import styled from 'styled-components'
const Button = styled.button`
background: Bisque;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid Chocolate;
border-radius: 3px;
`
const Input = styled.input`
margin: 0.25em;
`