チップ検索ブロック
SearchByChipコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルなチップ検索インターフェースです。モダンなデザインパターン、クリック可能なチップセクション、フィルタリングと検索機能のための柔軟なカスタマイズオプションを備えた完全なチップベースの検索体験を提供します。
🚀 インストール
npm install @nodeblocks/frontend-search-by-chip-block@0.1.3
📖 使用法
import {SearchByChip} from '@nodeblocks/frontend-search-by-chip-block';
- 基本的な使用法
- 高度な使用法
function BasicSearchByChips() {
const handleChipClick = (value: string) => {
console.log('チップがクリックされました:', value);
// ここで検索ロジックを処理
};
const searchChips = [
{ value: 'electronics', label: '電子機器' },
{ value: 'clothing', label: '衣類' },
{ value: 'books', label: '書籍' },
{ value: 'home-garden', label: 'ホーム・ガーデン' },
{ value: 'sports', label: 'スポーツ' }
];
return (
<SearchByChip
searchByChipTitle="クイック検索"
subtitle="お探しのものを見つけてください"
sectionTitle="カテゴリ"
onClickChip={handleChipClick}
chips={searchChips}>
<SearchByChip.Title />
<SearchByChip.Subtitle />
<SearchByChip.ChipSection />
</SearchByChip>
);
}
function AdvancedSearchByChips() {
const handleChipClick = (value: string) => {
console.log('チップがクリックされました:', value);
// ここで検索ロジックを処理
};
const searchChips = [
{ value: 'electronics', label: '電子機器' },
{ value: 'clothing', label: '衣類' },
{ value: 'books', label: '書籍' },
{ value: 'home-garden', label: 'ホーム・ガーデン' },
{ value: 'sports', label: 'スポーツ' }
];
return (
<SearchByChip
searchByChipTitle="クイック検索"
subtitle="お探しのものを見つけてください"
sectionTitle="カテゴリ"
onClickChip={handleChipClick}
chips={searchChips}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
// 📋 プロパティオーバーライド付きカスタムタイトル
title: {
...defaultBlocks.title,
props: {
...defaultBlocks.title.props,
className: "custom-search-title",
style: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
fontSize: '2.5rem',
fontWeight: 'bold',
textAlign: 'center',
marginBottom: '10px'
},
children: "🔍 スマート検索体験"
},
},
// 📝 プロパティオーバーライド付きカスタムサブタイトル
subtitle: {
...defaultBlocks.subtitle,
props: {
...defaultBlocks.subtitle.props,
className: "custom-search-subtitle",
style: {
color: '#6c757d',
fontSize: '1.1rem',
textAlign: 'center',
marginBottom: '40px',
fontWeight: '400'
},
children: "インテリジェントなカテゴリフィルターで必要なものを正確に発見しましょう"
},
},
// 🏷️ 完全なコンポーネントオーバーライド付きリッチチップセクション
chipSection: (
<div style={{
padding: '30px',
backgroundColor: '#f8f9fa',
borderRadius: '16px',
border: '1px solid #e9ecef'
}}>
<h3 style={{
color: '#495057',
fontSize: '1.3rem',
fontWeight: '600',
marginBottom: '20px',
textAlign: 'center'
}}>
✨ 人気のカテゴリ
</h3>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
gap: '15px',
marginBottom: '25px'
}}>
{[
{ value: 'tech', label: '💻 テクノロジー', color: '#007bff', bgColor: '#e3f2fd' },
{ value: 'fashion', label: '👗 ファッション', color: '#e91e63', bgColor: '#fce4ec' },
{ value: 'books', label: '📚 書籍', color: '#ff9800', bgColor: '#fff3e0' },
{ value: 'home', label: '🏠 ホーム・ガーデン', color: '#4caf50', bgColor: '#e8f5e8' },
{ value: 'sports', label: '⚽ スポーツ', color: '#9c27b0', bgColor: '#f3e5f5' },
{ value: 'health', label: '💊 健康', color: '#00bcd4', bgColor: '#e0f2f1' }
].map((chip, index) => (
<button
key={index}
onClick={() => handleChipClick(chip.value)}
style={{
backgroundColor: chip.bgColor,
border: `2px solid ${chip.color}`,
borderRadius: '12px',
padding: '15px 20px',
fontSize: '0.95rem',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.3s ease',
textAlign: 'center',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
gap: '8px',
color: chip.color
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = chip.color;
e.currentTarget.style.color = 'white';
e.currentTarget.style.transform = 'translateY(-3px)';
e.currentTarget.style.boxShadow = `0 8px 25px ${chip.color}30`;
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = chip.bgColor;
e.currentTarget.style.color = chip.color;
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = 'none';
}}
>
{chip.label}
</button>
))}
</div>
{/* トレンドタグ */}
<div style={{ marginTop: '30px' }}>
<h4 style={{
color: '#6c757d',
fontSize: '1rem',
fontWeight: '600',
marginBottom: '15px',
textAlign: 'center'
}}>
🔥 今話題
</h4>
<div style={{
display: 'flex',
flexWrap: 'wrap',
gap: '10px',
justifyContent: 'center'
}}>
{['AIツール', '持続可能な生活', '在宅勤務', 'フィットネス', '料理'].map((tag, index) => (
<span
key={index}
style={{
backgroundColor: '#fff',
border: '1px solid #dee2e6',
borderRadius: '20px',
padding: '6px 14px',
fontSize: '0.85rem',
color: '#6c757d',
cursor: 'pointer',
transition: 'all 0.2s ease'
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = '#007bff';
e.currentTarget.style.color = 'white';
e.currentTarget.style.borderColor = '#007bff';
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = '#fff';
e.currentTarget.style.color = '#6c757d';
e.currentTarget.style.borderColor = '#dee2e6';
}}
>
{tag}
</span>
))}
</div>
</div>
</div>
),
},
blockOrder: defaultBlockOrder,
})}
</SearchByChip>
);
}
🔧 プロパティリファレンス
メインコンポーネントプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
searchByChipTitle | ReactNode | 必須 | チップ検索セクションのメインタイトル |
sectionTitle | ReactNode | 必須 | チップセクションのタイトル |
subtitle | ReactNode | 必須 | メインタイトルの下に表示されるサブタイトルテキスト |
onClickChip | (value: string) => void | 必須 | チップがクリックされたときにトリガーされるコールバック関数 |
chips | { value: string; label: string }[] | 必須 | 表示するチップオブジェクトの配列 |
className | string | undefined | コンテナのスタイリング用の追加CSSクラス名 |
children | BlocksOverride | undefined | デフォルトブロックをオーバーライドするか、カスタムチップコンポーネントを追加する関数 |
注意: メインコンポーネントはすべてのHTML div要素プロパティを継承します。
サブコンポーネント
SearchByChipコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
SearchByChip.Title
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | コンテキストのsearchByChipTitle | デフォルトタイトルレンダリングをオーバーライドするカスタムコンテンツ |
注意: このコンポーネントはすべてのHTML h4要素プロパティを継承します。
SearchByChip.Subtitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | コンテキストのsubtitle | デフォルトサブタイトルレンダリングをオーバーライドするカスタムコンテンツ |
注意: このコンポーネントはすべてのHTML h6要素プロパティを継承します。
SearchByChip.SectionTitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | コンテキストのsectionTitle | デフォルトセクションタイトルレンダリングをオーバーライドするカスタムコンテンツ |
注意: このコンポーネントはすべてのHTML h6要素プロパティを継承します。
SearchByChip.ChipItem
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
onClickChip | (value: string) => void | 必須 | チップクリックイベントのコールバック関数 |
value | string | 必須 | チップの一意の値識別子 |
label | ReactNode | 必須 | チップの表示テキスト |
注意: このコンポーネントはすべてのHTML button要素プロパティを継承します。
SearchByChip.ChipIcon
このコンポーネントはプロパティを受け取らず、チェックマークSVGアイコンをレンダリングします。
SearchByChip.ChipSection
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | デフォルトチップレンダリング | デフォルトチップセクションレンダリングをオーバーライドするカスタムコンテンツ |
chips | { value: string; label: string }[] | コンテキストから | 表示するチップオブジェクトの配列 |
sectionTitle | ReactNode | コンテキストから | チップセクションのタイトル |
注意: このコンポーネントはすべてのHTML div要素プロパティを継承します。
🔧 TypeScriptサポート
包括的な型定義による完全なTypeScriptサポート:
import {SearchByChip} from '@nodeblocks/frontend-search-by-chip-block';
import {ComponentProps, ReactNode} from 'react';
interface Chip {
value: string;
label: string;
}
// メインコンポーネントインターフェース
interface SearchByChipProps extends Omit<ComponentProps<'div'>, 'children'> {
searchByChipTitle: ReactNode;
sectionTitle: ReactNode;
subtitle: ReactNode;
onClickChip: (value: string) => void;
chips: Chip[];
className?: string;
}
// サブコンポーネントインターフェース
interface ChipItemProps extends ComponentProps<'button'> {
onClickChip: (value: string) => void;
value: string;
label: ReactNode;
}
interface ChipSectionProps
extends Partial<
ComponentProps<'div'> & {
chips: Chip[];
sectionTitle: ReactNode;
}
> {
children?: ReactNode;
}
// 包括的な型付けでの使用例
interface CustomSearchData {
categories: Chip[];
onSearch: (searchValue: string) => void;
title: string;
description: string;
}
const SearchComponent = ({categories, onSearch, title, description}: CustomSearchData) => {
const handleChipSelection = (value: string) => {
onSearch(value);
// 追加の検索ロジック
};
return (
<SearchByChip
searchByChipTitle={title}
sectionTitle="カテゴリ"
subtitle={description}
onClickChip={handleChipSelection}
chips={categories}
onClick={e => console.log('コンテナがクリックされました')}>
<SearchByChip.Title />
<SearchByChip.Subtitle />
<SearchByChip.ChipSection />
</SearchByChip>
);
};
React、TypeScript、モダンWebスタンダードを使用して❤️で構築されました。