Merits Block
The Merits Component is a fully customizable and accessible merits/benefits display block built with React and TypeScript. It provides a complete interface for showcasing company merits, benefits, or features with modern design patterns, flexible customization options, and responsive layout.
π Installationβ
npm install @nodeblocks/frontend-merits-block@0.2.0
π Usageβ
import {Merits} from '@nodeblocks/frontend-merits-block';
- Basic Usage
- Advanced Usage
function SimpleMerits() { const meritsData = [ { imageUrl: '/img/undraw_docusaurus_mountain.svg', text: 'Fast Delivery', subtext: 'Get your orders delivered quickly and efficiently', }, { imageUrl: '/img/undraw_docusaurus_react.svg', text: 'Quality Guarantee', subtext: 'We ensure the highest quality for all our products', }, { imageUrl: '/img/undraw_docusaurus_tree.svg', text: '24/7 Support', subtext: 'Round-the-clock customer support for all your needs', }, ]; return ( <Merits subtitle="Why Choose Us" meritsTitle="Our Key Benefits" buttonText="Learn More" buttonHref="#about" items={meritsData} sx={{backgroundColor: 'white', padding: 2}} > <Merits.Header /> <Merits.Content /> <Merits.ActionBar /> </Merits> ); }
function AdvancedMerits() { const meritsData = [ { imageUrl: '/img/undraw_docusaurus_mountain.svg', text: 'Fast Delivery', subtext: 'Get your orders delivered quickly and efficiently', }, { imageUrl: '/img/undraw_docusaurus_react.svg', text: 'Quality Guarantee', subtext: 'We ensure the highest quality for all our products', }, { imageUrl: '/img/undraw_docusaurus_tree.svg', text: '24/7 Support', subtext: 'Round-the-clock customer support for all your needs', }, ]; return ( <Merits subtitle="Why Choose Us" meritsTitle="Our Key Benefits" buttonText="Learn More" buttonHref="#about" items={meritsData} sx={{ background: 'linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%)', padding: {xs: 3, md: 6}, borderRadius: 4, }} > {({defaultBlocks, defaultBlockOrder}) => ({ blocks: { ...defaultBlocks, header: { ...defaultBlocks.header, props: { ...defaultBlocks.header.props, spacing: 2, sx: { textAlign: 'center', mb: 4, '& .nbb-merits-merit-subtitle': { color: '#6366f1', fontWeight: 800, textTransform: 'uppercase', letterSpacing: 2, fontSize: '0.875rem', }, '& .nbb-merits-merit-title': { fontSize: {xs: 32, md: 48}, fontWeight: 700, background: 'linear-gradient(135deg, #1e293b 0%, #475569 100%)', backgroundClip: 'text', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', }, }, }, }, content: { ...defaultBlocks.content, props: { ...defaultBlocks.content.props, direction: {xs: 'column', md: 'row'}, spacing: 4, sx: { '& .nbb-merits-merit-item': { backgroundColor: 'white', borderRadius: 3, padding: 4, boxShadow: '0 4px 20px rgba(0,0,0,0.08)', transition: 'all 0.3s ease', '&:hover': { transform: 'translateY(-8px)', boxShadow: '0 12px 40px rgba(99,102,241,0.15)', }, }, '& .nbb-merits-merit-image': { height: 160, objectFit: 'contain', }, '& .nbb-merits-merit-text': { color: '#1e293b', fontWeight: 700, }, '& .nbb-merits-merit-subtext': { color: '#64748b', textAlign: 'center', }, }, }, }, actionBar: { ...defaultBlocks.actionBar, props: { ...defaultBlocks.actionBar.props, sx: { mt: 4, '& .nbb-merits-merit-button': { background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', borderRadius: 3, px: 5, py: 1.5, fontSize: 18, fontWeight: 600, textTransform: 'none', boxShadow: '0 4px 20px rgba(99,102,241,0.4)', '&:hover': { background: 'linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%)', boxShadow: '0 8px 30px rgba(99,102,241,0.5)', }, }, }, }, }, }, blockOrder: defaultBlockOrder, })} </Merits> ); }
π§ Props Referenceβ
Main Component Propsβ
| Prop | Type | Default | Description |
|---|---|---|---|
subtitle | ReactNode | Required | Subtitle text displayed above the main title |
meritsTitle | ReactNode | Required | Main title for the merits section |
buttonText | string | Required | Text content for the action button |
buttonHref | string | Required | URL or path for the action button link |
items | MeritProps[] | Required | Array of merit items to display |
spacing | number | ResponsiveValue | 6 | Spacing between child elements |
direction | StackDirection | 'column' | Layout direction of child elements |
className | string | undefined | Additional CSS class name for styling the container |
sx | SxProps<Theme> | undefined | MUI System prop for custom styling |
children | BlocksOverride | undefined | Custom block components to override default rendering |
Note: The main component inherits all MUI Stack props.
Sub-Componentsβ
The Merits component provides several sub-components. All sub-components receive their default values from the main component's context and can override these values through props.
Merits.Headerβ
Renders the header section with subtitle and main title.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Default header content | Custom content to override default header rendering |
spacing | number | ResponsiveValue | 1 | Spacing between subtitle and title |
alignItems | string | 'stretch' | Alignment of child elements |
sx | SxProps<Theme> | { textAlign: 'center' } | MUI System prop for custom styling |
Note: This component inherits all MUI Stack props. When children is not provided, it renders MeritSubtitle and MeritTitle internally.
Merits.Contentβ
Renders the merit items in a row layout.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Default merit items | Custom content to override default merit items rendering |
items | MeritProps[] | From context | Array of merit items to display (overrides context items) |
direction | StackDirection | 'row' | Layout direction of merit items |
spacing | number | ResponsiveValue | 5 | Spacing between merit items |
sx | SxProps<Theme> | undefined | MUI System prop for custom styling |
Note: This component inherits all MUI Stack props. Each merit item is rendered as a MeritItem containing MeritImage, MeritText, and MeritSubtext.
Merits.Content.MeritImageβ
Renders the image for a merit item.
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | undefined | URL for the image |
alt | string | 'merit image' | Alt text for the image |
component | string | 'img' | The component used for the root node (fixed) |
sx | SxProps<Theme> | { maxWidth: '100%', height: 225 } | MUI System prop for custom styling |
Note: This component inherits all MUI Box<'img'> props.
Merits.Content.MeritTextβ
Renders the main text for a merit item.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | From item data | Text content for the merit |
variant | string | 'h4' | Typography variant |
sx | SxProps<Theme> | See below | MUI System prop for custom styling |
Default sx:
{
fontWeight: 600,
textAlign: 'center',
fontSize: 25,
lineHeight: 1.5
}
Note: This component inherits all MUI Typography props.
MeritSubtext (Internal)β
Renders the secondary text/description for a merit item.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | From item data | Subtext content for the merit |
variant | string | 'body1' | Typography variant |
sx | SxProps<Theme> | See below | MUI System prop for custom styling |
Default sx:
{
lineHeight: 1.72,
alignSelf: 'center',
fontWeight: 300
}
Note: This component inherits all MUI Typography props. This is an internal component used when rendering merit items.
MeritItem (Internal)β
Container component for each individual merit.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Required | Content for the merit item |
spacing | number | ResponsiveValue | 2 | Spacing between image, text, and subtext |
alignItems | string | 'stretch' | Alignment of child elements |
sx | SxProps<Theme> | See below | MUI System prop for custom styling |
Default sx:
{
minWidth: 0,
flex: 1,
paddingBottom: 4
}
Note: This component inherits all MUI Stack props. This is an internal component used when rendering merit items.
Merits.ActionBarβ
Renders the action bar with the call-to-action button.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Default button | Custom content to override default action bar rendering |
buttonHref | string | From context | URL for the button (overrides context buttonHref) |
buttonText | string | From context | Text for the button (overrides context buttonText) |
spacing | number | ResponsiveValue | 1 | Spacing between child elements |
alignItems | string | 'stretch' | Alignment of child elements |
sx | SxProps<Theme> | { textAlign: 'center' } | MUI System prop for custom styling |
Note: This component inherits all MUI Stack props. Renders a Merits.ActionBar.Button component by default.
Merits.ActionBar.Buttonβ
Renders the call-to-action button.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | From context | Text to display inside the button |
href | string | From context | URL for the button link |
variant | string | 'contained' | Button variant |
size | string | 'large' | Button size |
color | string | 'primary' | Button color |
disabled | boolean | false | Whether the button is disabled |
onClick | function | undefined | Click handler function |
sx | SxProps<Theme> | See below | MUI System prop for custom styling |
Default sx:
{
fontSize: 22,
alignSelf: 'center',
fontWeight: 600,
lineHeight: 1.5
}
Note: This component inherits all MUI Button props.
π¨ Configuration examplesβ
Custom Header Stylingβ
<Merits.Header sx={{mb: 4, textAlign: 'center'}} />
Custom Content Layoutβ
<Merits.Content direction={{xs: 'column', md: 'row'}} spacing={4} />
Custom Action Buttonβ
<Merits.ActionBar sx={{mt: 4}}>
<Merits.ActionBar.Button href="#get-started" sx={{px: 6, py: 2}}>
π Get Started Today
</Merits.ActionBar.Button>
</Merits.ActionBar>
Custom Styling Exampleβ
<Merits
subtitle="Why Choose Our Platform"
meritsTitle="Built for Modern Businesses"
buttonText="Start Free Trial"
buttonHref="#signup"
items={meritsData}
spacing={8}
sx={{backgroundColor: '#f8f9fa', padding: 4}}
>
<Merits.Header sx={{mb: 4}} />
<Merits.Content direction={{xs: 'column', md: 'row'}} spacing={4} />
<Merits.ActionBar sx={{mt: 4}}>
<Merits.ActionBar.Button href="#get-started" sx={{px: 6, py: 2}}>
π Get Started Today
</Merits.ActionBar.Button>
</Merits.ActionBar>
</Merits>
Block Override Patternβ
<Merits {...props}>
{({defaultBlocks, defaultBlockOrder}) => ({
blocks: {
...defaultBlocks,
header: {
...defaultBlocks.header,
props: {
...defaultBlocks.header.props,
spacing: 2,
sx: {
textAlign: 'center',
mb: 4,
},
},
},
},
blockOrder: defaultBlockOrder,
})}
</Merits>
π§ TypeScript Supportβ
Full TypeScript support with comprehensive type definitions:
import {Merits} from '@nodeblocks/frontend-merits-block';
import {ReactNode} from 'react';
interface MeritProps {
imageUrl: string;
text: ReactNode;
subtext: ReactNode;
}
function TypedMerits() {
const meritsData: MeritProps[] = [
{
imageUrl: '/icons/analytics.svg',
text: 'Powerful Analytics',
subtext: 'Get detailed insights into your business performance',
},
{
imageUrl: '/icons/automation.svg',
text: 'Smart Automation',
subtext: 'Automate repetitive tasks and focus on what matters',
},
{
imageUrl: '/icons/integration.svg',
text: 'Seamless Integration',
subtext: 'Connect with 200+ popular tools and services',
},
];
return (
<Merits
subtitle="Platform Benefits"
meritsTitle="Everything You Need to Succeed"
buttonText="Explore Features"
buttonHref="#features"
items={meritsData}
spacing={6}
direction="column"
sx={{
backgroundColor: 'background.paper',
borderRadius: 3,
boxShadow: 2,
p: 4,
maxWidth: 1200,
mx: 'auto',
}}
>
<Merits.Header sx={{textAlign: 'center'}} />
<Merits.Content />
<Merits.ActionBar>
<Merits.ActionBar.Button
variant="contained"
href="#pricing"
sx={{
fontSize: 22,
alignSelf: 'center',
fontWeight: 600,
lineHeight: 1.5,
}}
>
View Pricing Plans
</Merits.ActionBar.Button>
</Merits.ActionBar>
</Merits>
);
}
π Notesβ
- The main component uses MUI
Stackwithdirection="column"andspacing={6}by default. - All sub-components inherit MUI component props and support the
sxprop for styling. - The Header component internally renders
MeritSubtitle(Typography h4) andMeritTitle(Typography h1) unlesschildrenis provided. - The Content component renders items in a horizontal row by default. Use
direction={{ xs: 'column', md: 'row' }}for responsive layouts. - Each merit item is wrapped in a
MeritItemStack container withspacing={2}andflex: 1. - The ActionBar.Button uses MUI Button with
variant="contained"andsize="large"by default. - Context values (
subtitle,meritsTitle,buttonText,buttonHref,items) are shared via React Context and can be overridden at the sub-component level.
Built with β€οΈ using React, TypeScript, and MUI.