パンくずリストブロック
Breadcrumbs は、MUI Breadcrumbs をベースにしたナビゲーションのパンくずリストで、プライマリーバー風のスタイルと chevron 区切りを備えています。
インストール
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-breadcrumb-block
yarn add @nodeblocks/frontend-breadcrumb-block
pnpm add @nodeblocks/frontend-breadcrumb-block
bun add @nodeblocks/frontend-breadcrumb-block
必要なもの
| 項目 | 理由 |
|---|---|
items (optional) | { label, url? } 形式のセグメントからパンくずを描画します(デフォルトのパターン) |
Breadcrumbs.Item (optional) | items の代わりにコンパウンド子要素でパンくずを構成します |
onNavigate (optional) | クライアントサイドルーティング用に、クリックされたセグメントの href とともに呼び出されます |
children (function, optional) | defaultBlocks と blockOrder を上書きします |
最も簡単なパンくずには items prop を使ってください(クイックスタートを参照)。セグメントごとに完全な制御が必要な場合は Breadcrumbs.Item のコンパウンド子要素を使ってください。children が JSX 要素(関数ではない)である場合、items prop は無視されます。defaultBlocks と blockOrder を使う 関数 child を使えば、カスタムキー、順序、リンクではないノードを設定できます。blockOrder ブロックより 前に これらのセグメントを描画したい場合を除き、items は省略してください。MUI は子要素の間に区切り記号を挿入するため、手動で chevron 要素を追加しないでください。
コード例
- クイックスタート
- 項目とナビゲーション
- コンパウンドコンポーネント
- ブロックのオーバーライド
function Example() { const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs items={[ { label: 'Home', url: '#home' }, { label: 'Products', url: '#products' }, { label: 'Shoes' }, ]} onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} /> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
折りたたみの動作を制御し、セグメントのクリックからナビゲーションを処理します。
function Example() { const items = [ { label: 'Home', url: '#home' }, { label: 'Products', url: '#products' }, { label: 'Electronics', url: '#electronics' }, { label: 'Computers', url: '#computers' }, { label: 'Laptops', url: '#laptops' }, { label: 'MacBook Pro' }, ]; const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs items={items} maxItems={4} itemsBeforeCollapse={1} itemsAfterCollapse={2} onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} /> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
最後の items エントリでは url を省略し(または最後の Breadcrumbs.Item では href を省略し)、現在のページをリンクなしで表示します。
Breadcrumbs.Item を各セグメントに使います。MUI はルートの separator(デフォルトは ChevronRight アイコン)を通じて chevron を描画します。
function Example() { const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs items={undefined} onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} > <Breadcrumbs.Item href="#home">Home</Breadcrumbs.Item> <Breadcrumbs.Item href="#products">Products</Breadcrumbs.Item> <Breadcrumbs.Item>Shoes</Breadcrumbs.Item> </Breadcrumbs> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
デモに items 引数が残っている場合、コンパウンド子要素へ切り替える際にそれを消して、props パネルが JSX 子要素パターンを反映するようにしてください。コンポーネント自体は、children が関数ではなく JSX の場合に限り items を無視します。
関数 child を使ってカスタムブロックと順序を設定します。blockOrder ブロックより前に items のパンくずを描画したい場合を除き、items は省略してください。
function Example() { const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} > {({ defaultBlocks, defaultBlockOrder }) => ({ blocks: { ...defaultBlocks, home: <Breadcrumbs.Item href="#home">Home</Breadcrumbs.Item>, products: <Breadcrumbs.Item href="#products">Products</Breadcrumbs.Item>, current: ( <span style={{ fontSize: 12, color: 'inherit', opacity: 0.9 }}>Shoes</span> ), }, blockOrder: ['home', 'products', 'current'], })} </Breadcrumbs> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
ブロックのオーバーライドを使うタイミング
固定のブロック順、リンクではない現在のページ、またはトレイル内のカスタムノードが必要で、かつデフォルトのバーのスタイルと MUI の区切り記号の動作を維持したい場合にオーバーライドを使います。デフォルトの blockOrder は ['item'](defaultBlockOrder)です。デフォルトの item ブロックは、そのキーが blockOrder に含まれ、かつ blocks に存在する場合にのみ描画されます。
セグメントを追加するには(Storybook パターン):
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
suffix: <Breadcrumbs.Item href="#more">More</Breadcrumbs.Item>,
},
blockOrder: [...defaultBlockOrder, 'suffix'],
})}
defaultBlocks を展開しているがプレースホルダーの item ブロックは表示したくない場合は、blockOrder から 'item' を省略してください。
重要なプロパティ
コアプロパティ
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
items | readonly { label: ReactNode; url?: string; onClick?: React.MouseEventHandler<HTMLAnchorElement> }[] | いいえ | undefined | パンくずのセグメント。現在のページでは url を省略し、項目ごとの onClick を任意で指定できます |
onNavigate | (url: string) => void | いいえ | undefined | href / url を持つセグメントがクリックされたときに呼び出されます(ある場合はそのセグメントの onClick の後に実行されます) |
maxItems | number | いいえ | 8 | MUI がパンくずを折りたたむ前の最大表示項目数 |
itemsBeforeCollapse | number | いいえ | 1 | 折りたたみの省略記号の前に表示する項目数 |
itemsAfterCollapse | number | いいえ | 1 | 折りたたみの省略記号の後に表示する項目数 |
コンテンツプロパティ
| コンポーネント | プロパティ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|---|
Item | href | string | いいえ | undefined | リンク先。現在の(リンクではない)セグメントでは省略します |
Item | children | ReactNode | はい | - | セグメントのラベル |
Item | component | React.ElementType | いいえ | 'a' | リンクのルート要素 |
Item | onClick | React.MouseEventHandler<HTMLAnchorElement> | いいえ | undefined | クリックハンドラ。href が文字列の場合は onNavigate も実行されます |
Breadcrumbs (root) | separator | ReactNode | いいえ | MUI ChevronRight アイコン | セグメント間の区切り記号 |
レイアウトと構成のプロパティ
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
children | BlocksOverride | ReactNode | いいえ | undefined | Breadcrumbs.Item 要素、または blocks と blockOrder を返す関数オーバーライド |
className | string | いいえ | undefined | ルートコンテナのクラス名(デフォルトで nbb-breadcrumb が適用されます) |
sx | SxProps | いいえ | undefined | ルートコンテナ用の MUI システムスタイル |
Breadcrumbs は MUI の BreadcrumbsProps(children を除く)を継承し、expandText と slotProps を含みます。オーバーライドなしのデフォルト blockOrder は ['item'](defaultBlockOrder)です。
デフォルト UI ブロック
| ブロック | 基盤 | 備考 |
|---|---|---|
Breadcrumbs (root) | Breadcrumbs | プライマリーバー(bgcolor: primary.main)。separator のデフォルトは ChevronRight |
Breadcrumbs.Item | Link | セグメントリンク(nbb-breadcrumb-item)。href を使い、設定されている場合は onNavigate を呼び出します |
TypeScript
import { Breadcrumbs } from '@nodeblocks/frontend-breadcrumb-block';
import type { MouseEventHandler, ReactNode } from 'react';
// Same shape as the package's BreadcrumbNavItem (not re-exported from the entry point).
type TrailItem = {
label: ReactNode;
url?: string;
onClick?: MouseEventHandler<HTMLAnchorElement>;
};
const trail: TrailItem[] = [
{ label: 'Home', url: '/home' },
{ label: 'Products', url: '/products' },
{ label: 'Shoes' },
];
<Breadcrumbs items={trail} onNavigate={(url) => router.push(url)} />;