ヘッダーHeaderExperimental
ロゴ、主要ナビゲーション、右側の操作をページ上部にまとめて表示します。
プレビュー
状態とバリエーション
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| Header | header | - | ブランド、主要ナビゲーション、操作を横並びにするルート。 |
| HeaderBrand | div | - | ロゴやサービス名を入れる左側スロット。 |
| HeaderNavLink.active | boolean | - | 現在ページのリンクを強調します。 |
| HeaderActions | div | - | 検索、ログイン、テーマ切替などの操作スロット。 |
使い方
import * as React from "react"
import { IconLanguage as Languages, IconMoon as Moon, IconSearch as Search, IconSun as Sun } from "@tabler/icons-react"
import { useTheme } from "next-themes"
import { Button, CommandPalette, Header, HeaderActions, HeaderBrand, HeaderNav, HeaderNavLink, TooltipButton } from "@gunjo/ui"
type Locale = "ja" | "en"
function getNavLinks(isJa: boolean) {
return [
{ label: isJa ? "ドキュメント" : "Docs", href: "/docs" },
{ label: isJa ? "コンポーネント" : "Components", href: "/docs/components" },
{ label: isJa ? "料金" : "Pricing", href: "/pricing" },
]
}
function BrandLogo() {
return (
<span
aria-label="Gunjo UI"
role="img"
className="block h-8 w-[3.75rem] bg-primary [mask:url('/gunjo-logo.svg')_center/contain_no-repeat] [-webkit-mask:url('/gunjo-logo.svg')_center/contain_no-repeat]"
/>
)
}
export function SiteHeader() {
const [locale, setLocale] = React.useState<Locale>("ja")
const [commandOpen, setCommandOpen] = React.useState(false)
const [mounted, setMounted] = React.useState(false)
const { resolvedTheme, setTheme } = useTheme()
const isJa = locale === "ja"
const isDark = mounted && resolvedTheme === "dark"
const navLinks = getNavLinks(isJa)
const commandGroups = [
{
heading: isJa ? "ページ" : "Pages",
items: navLinks.map((link) => ({
id: link.href,
label: link.label,
action: () => setCommandOpen(false),
})),
},
]
React.useEffect(() => {
setMounted(true)
}, [])
return (
<>
<Header>
<HeaderBrand>
<BrandLogo />
</HeaderBrand>
<HeaderNav>
{navLinks.map((link, index) => (
<HeaderNavLink key={link.href} href={link.href} active={index === 0}>
{link.label}
</HeaderNavLink>
))}
</HeaderNav>
<HeaderActions>
<TooltipButton
type="button"
size="icon"
variant="ghost"
tooltip={isJa ? "コマンドパレットを開く" : "Open command palette"}
aria-label={isJa ? "コマンドパレットを開く" : "Open command palette"}
onClick={() => setCommandOpen(true)}
>
<Search className="h-4 w-4" aria-hidden />
</TooltipButton>
<TooltipButton
type="button"
size="icon"
variant="ghost"
tooltip={isJa ? "英語に切り替え" : "日本語に切り替え"}
aria-label={isJa ? "英語に切り替え" : "日本語に切り替え"}
onClick={() => setLocale(isJa ? "en" : "ja")}
>
<Languages className="h-4 w-4" aria-hidden />
</TooltipButton>
<TooltipButton
type="button"
size="icon"
variant="ghost"
tooltip={isDark ? "ライトテーマに切り替え" : "ダークテーマに切り替え"}
aria-label={isDark ? "ライトテーマに切り替え" : "ダークテーマに切り替え"}
onClick={() => setTheme(isDark ? "light" : "dark")}
>
{isDark ? <Sun className="h-4 w-4" aria-hidden /> : <Moon className="h-4 w-4" aria-hidden />}
</TooltipButton>
<Button size="sm">{isJa ? "ログイン" : "Sign in"}</Button>
</HeaderActions>
</Header>
<CommandPalette
open={commandOpen}
onOpenChange={setCommandOpen}
groups={commandGroups}
placeholder={isJa ? "ドキュメントを検索" : "Search documentation"}
emptyMessage={isJa ? "一致する結果がありません。" : "No matching results."}
dialogTitle={isJa ? "コマンドパレット" : "Command palette"}
clearLabel={isJa ? "検索をクリア" : "Clear search"}
/>
</>
)
}