FullStackOpen Part7-c More about styles メモ

Ready-made UI libraries

現在は数多くのUIライブラリが存在する
メジャーどころだとBootstrapMaterialUIがあり、これらには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;
`


いいなと思ったら応援しよう!