Search By Chips Block
SearchByChip is a chip-based quick-search block built on MUI with a title, subtitle, and one or more clickable chip sections.
Installation
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-search-by-chip-block
yarn add @nodeblocks/frontend-search-by-chip-block
pnpm add @nodeblocks/frontend-search-by-chip-block
bun add @nodeblocks/frontend-search-by-chip-block
What You Need
| Item | Why it matters |
|---|---|
searchByChipTitle | Main heading at the top of the block |
subtitle | Supporting text below the title |
chipSections | Defines each chip group, its label, chips, and onClickChip handler |
Each section supplies its own onClickChip callback. Use it to update search state, navigate, or trigger an API request.
Code Examples
- Quick Start
- Compound Components
- Block Override
function Example() { const searchChips = [ {value: 'electronics', label: 'Electronics'}, {value: 'clothing', label: 'Clothing'}, {value: 'books', label: 'Books'}, {value: 'home-garden', label: 'Home & Garden'}, {value: 'sports', label: 'Sports'}, ]; const [selectedValue, setSelectedValue] = React.useState(''); const handleChipClick = value => { setSelectedValue(value); }; const chipSections = [ { sectionTitle: 'Categories', chips: searchChips, onClickChip: handleChipClick, }, ]; return ( <> {selectedValue ? ( <Typography variant="body2" sx={{mb: 2, textAlign: 'center'}}> Selected: <strong>{selectedValue}</strong> </Typography> ) : null} <SearchByChip searchByChipTitle="Quick Search" subtitle="Find what you're looking for" chipSections={chipSections} /> </> ); }
Use child blocks to customize layout and styling.
function Example() { const searchChips = [ {value: 'electronics', label: 'Electronics'}, {value: 'clothing', label: 'Clothing'}, {value: 'books', label: 'Books'}, ]; const [selectedValue, setSelectedValue] = React.useState(''); const handleChipClick = value => { setSelectedValue(value); }; const chipSections = [ { sectionTitle: 'Categories', chips: searchChips, onClickChip: handleChipClick, }, ]; return ( <> {selectedValue ? ( <Typography variant="body2" sx={{mb: 2, textAlign: 'center'}}> Selected: <strong>{selectedValue}</strong> </Typography> ) : null} <SearchByChip searchByChipTitle="Quick Search" subtitle="Find what you're looking for" chipSections={chipSections} > <SearchByChip.Title sx={{color: 'primary.main'}} /> <SearchByChip.Subtitle sx={{mb: 1}} /> <SearchByChip.ChipSections sx={{mt: 3}} /> </SearchByChip> </> ); }
Use function children to override default blocks, change order, or inject custom blocks.
function Example() { const searchChips = [ {value: 'electronics', label: 'Electronics'}, {value: 'clothing', label: 'Clothing'}, {value: 'books', label: 'Books'}, {value: 'home-garden', label: 'Home & Garden'}, ]; const popularSearchChips = [ {value: 'new-arrivals', label: 'New arrivals'}, {value: 'sale', label: 'On sale'}, {value: 'best-sellers', label: 'Best sellers'}, ]; const [selectedValue, setSelectedValue] = React.useState(''); const handleChipClick = value => { setSelectedValue(value); }; const chipSections = [ { sectionTitle: 'Categories', chips: searchChips, onClickChip: handleChipClick, }, { sectionTitle: 'Popular searches', chips: popularSearchChips, onClickChip: handleChipClick, }, ]; return ( <> {selectedValue ? ( <Typography variant="body2" sx={{mb: 2, textAlign: 'center'}}> Selected: <strong>{selectedValue}</strong> </Typography> ) : null} <SearchByChip searchByChipTitle="Quick Search" subtitle="Find what you're looking for" chipSections={chipSections} > {({defaultBlocks}) => ({ blocks: { ...defaultBlocks, chipHint: ( <Box sx={{ position: 'relative', alignSelf: 'flex-start', width: 'fit-content', mr: {xs: 2, sm: 4}, mt: 3, px: 1.5, py: 1, bgcolor: 'info.light', borderRadius: 1, fontSize: 'body2.fontSize', color: 'info.dark', textAlign: 'center', whiteSpace: 'nowrap', '&::after': { content: '""', position: 'absolute', top: -10, left: 32, width: 0, height: 0, borderLeft: '10px solid transparent', borderRight: '10px solid transparent', borderBottom: '10px solid', borderBottomColor: 'info.light', }, }} > Click a chip to filter results </Box> ), }, blockOrder: ['subtitle', 'title', 'chipSections', 'chipHint'], })} </SearchByChip> </> ); }
When to use block overrides
Use overrides when you need to change block order, replace a default block, or add a custom block (like chipHint above) while keeping chip sections and click handlers on the root component.
Important Props
Core Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
searchByChipTitle | ReactNode | Yes | — | Main title rendered by SearchByChip.Title |
subtitle | ReactNode | Yes | — | Subtitle rendered by SearchByChip.Subtitle |
chipSections | ChipSection[] | Yes | — | Chip groups; each section has its own onClickChip handler |
ChipSection shape:
| Field | Type | Required | Description |
|---|---|---|---|
sectionTitle | ReactNode | Yes | Heading for the chip group |
chips | ChipOption[] | Yes | Chips shown in the section |
onClickChip | (value: string) => void | Yes | Called when a chip in this section is clicked |
ChipOption shape:
| Field | Type | Required | Description |
|---|---|---|---|
value | string | Yes | Identifier passed to onClickChip |
label | ReactNode | Yes | Chip button label |
icon | ReactNode | No | Optional startIcon on the chip button (defaults to SearchByChip.ChipIcon) |
Layout and Composition Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | BlocksOverride | ReactNode | No | undefined | Override default blocks or render compound children |
className | string | No | undefined | Class name on the root stack |
sx | SxProps | No | undefined | MUI system styles for the root stack |
spacing | StackProps['spacing'] | No | { xs: 0.5, sm: 1 } | Vertical spacing on the root stack |
SearchByChip inherits StackProps (except children). Default defaultBlockOrder: subtitle, title, sectionTitle, chipIcon, chipItem, chipSection, chipSections (root renders subtitle, title, chipSections only).
Sub-component props
Sub-components share context with the root. searchByChipTitle, subtitle, and chipSections apply by default; pass the same keys on a sub-component to override locally.
| Sub-component | Main Props | Inherits | Built on |
|---|---|---|---|
SearchByChip.Title | searchByChipTitle, children, variant (h1), component (h1), className, sx | TypographyProps | Typography |
SearchByChip.Subtitle | subtitle, children, variant (h6), component (h6), className, sx | TypographyProps | Typography |
SearchByChip.ChipSections | chipSections, children, className, sx | StackProps | Stack |
SearchByChip.ChipSection | sectionTitle, chips, onClickChip, children, className | StackProps | Stack + Divider + Box |
SearchByChip.SectionTitle | sectionTitle (required), children, variant (h5), component (h5), className, sx | TypographyProps | Typography |
SearchByChip.ChipItem | onClickChip (required), value (required), label (required), startIcon (default ChipIcon), className, sx | Button props except children | Button (variant="outlined", size="small") |
SearchByChip.ChipIcon | — | — | Check icon |
Default UI Blocks
| Block | Built on | Notes |
|---|---|---|
SearchByChip (root) | Stack | Centered container that provides title, subtitle, and chip section context |
SearchByChip.Title | Typography | variant="h1", responsive font size |
SearchByChip.Subtitle | Typography | Primary color, responsive typography |
SearchByChip.ChipSections | Stack | Maps chipSections to ChipSection blocks |
Default root render order: subtitle → title → chipSections.
chipSection, sectionTitle, chipItem, and chipIcon are composed inside ChipSections and are not rendered at the root block level.
Extra field primitives
| Primitive | Built on | Notes |
|---|---|---|
SearchByChip.SectionTitle | Typography | One chip-section heading; default variant="h5" and component="h5" |
SearchByChip.ChipSection | Stack + Divider + Box | Renders one section title and its chip buttons |
SearchByChip.ChipItem | Button | One outlined chip button; calls onClickChip(value) |
SearchByChip.ChipIcon | Check icon | Default start icon for ChipItem |
TypeScript
import * as React from 'react';
import {SearchByChip} from '@nodeblocks/frontend-search-by-chip-block';
import type {ReactNode} from 'react';
type ChipOption = {
value: string;
label: string;
icon?: ReactNode;
};
type ChipSection = {
sectionTitle: ReactNode;
chips: ChipOption[];
onClickChip: (value: string) => void;
};
const categoryChips: ChipOption[] = [
{value: 'electronics', label: 'Electronics'},
{value: 'clothing', label: 'Clothing'},
{value: 'books', label: 'Books'},
];
export function QuickSearchByChips() {
const [query, setQuery] = React.useState('');
const chipSections: ChipSection[] = [
{
sectionTitle: 'Categories',
chips: categoryChips,
onClickChip: value => setQuery(value),
},
];
return (
<SearchByChip
searchByChipTitle="Quick Search"
subtitle={query ? `Showing results for "${query}"` : "Find what you're looking for"}
chipSections={chipSections}
/>
);
}