Reactはコンポーネントベースのフレームワークです。
今回は、ヘッダーコンポーネントを作成してみます。
サンプル
ディレクトリ
└── ReactApp/
└── src/
├── components/
│ └── ui/
│ └── header.tsx
└── App.tsx
インストールするモジュール
1.ShadcnのSheetモジュール
npx shadcn@latest add sheet
2.react-router-domモジュール
npm install react-router-dom
コード
header.tsx
// src/components/header.tsx
import * as React from "react"
import { Link } from "react-router-dom"
import { Button } from "@/components/ui/button"
import { Menu } from "lucide-react" // アイコン
import {
Sheet,
SheetContent,
SheetHeader,
SheetTrigger,
} from "@/components/ui/sheet"
export function Header() {
return (
<header className="sticky top-0 z-50 border-b bg-background/80 backdrop-blur">
<div className="container flex h-16 items-center justify-between">
{/* Left: ロゴ */}
<Link to="/" className="font-bold text-lg">
MyApp
</Link>
{/* Middle: ナビゲーション(PC表示時) */}
<nav className="hidden md:flex items-center gap-6 text-sm font-medium">
<Link to="/about" className="hover:text-primary">About</Link>
<Link to="/services" className="hover:text-primary">Services</Link>
<Link to="/contact" className="hover:text-primary">Contact</Link>
</nav>
{/* Right: CTA ボタン(例) */}
<div className="hidden md:block">
<Button asChild>
<Link to="/login">Login</Link>
</Button>
</div>
{/* Mobile Menu */}
<div className="md:hidden">
<Sheet>
<SheetTrigger asChild>
<Button variant="ghost" size="icon">
<Menu className="h-5 w-5" />
</Button>
</SheetTrigger>
<SheetContent side="right">
<SheetHeader>
<h2 className="text-lg font-semibold">Menu</h2>
</SheetHeader>
<nav className="mt-4 flex flex-col gap-4">
<Link to="/about">About</Link>
<Link to="/services">Services</Link>
<Link to="/contact">Contact</Link>
<Button asChild>
<Link to="/login">Login</Link>
</Button>
</nav>
</SheetContent>
</Sheet>
</div>
</div>
</header>
)
}
header.tsxでreact-router-domのLinkを使っているため
アプリ全体を BrowserRouter でラップする必要があります。
Tailwindcssでは、よくflexやjustify-center、items-centerといったプロパティを使用するかと思います。(⇩)
| プロパティ | 役目 |
|---|---|
flex
|
子要素を横並びにする |
justify-center
|
中央寄せ |
items-center
|
中央寄せ |
今回は、👆は使用しません。
ヘッダーを上部固定にしたいのでfixedを使用しました。
fixed にすると、ヘッダーの高さ(例:h-16)ぶん、
下のコンテンツが上に押し上げられず隠れてしまうことがあります。
その場合、main の上にマージンを追加して対処します:
App.tsx
(略)
<main className="flex-grow flex justify-center items-center p-8 mt-16">
<UserForm />
</main>
App.tsx
import React,{ useState } from 'react';
import Login from './Login';
import Register from './Register';
import axios from 'axios';
import { BugReportForm } from './Form';
import { UserForm } from './features/user/UserForm';
import { Header } from './components/ui/header';
import { BrowserRouter } from 'react-router-dom';
const App = ()=>{
return (
<BrowserRouter>
{/* 全体を縦方向に並べる */}
<div className="flex flex-col min-h-screen bg-gray-50">
{/* 上部固定ヘッダー */}
<Header />
<main className="flex-grow flex justify-center items-center p-8">
<UserForm />
</main>
</div>
</BrowserRouter>
)
}
export default App;
サイト
