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.1.3
π Usageβ
import {Merits} from '@nodeblocks/frontend-merits-block';
- Basic Usage
- Advanced Usage
function BasicMerits() {
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}
style={{backgroundColor: 'white', padding: '16px'}}>
<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}
style={{backgroundColor: 'white', padding: '16px'}}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
// π Custom Header with props override
header: {
...defaultBlocks.header,
props: {
...defaultBlocks.header.props,
className: "custom-merits-header",
style: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
padding: '60px 40px',
borderRadius: '20px',
color: 'white',
textAlign: 'center',
marginBottom: '50px'
},
children: (
<div>
<h3 style={{
fontSize: '1.2rem',
fontWeight: '500',
marginBottom: '15px',
color: 'black'
}}>
β¨ Discover Excellence
</h3>
<h1 style={{
fontSize: '3rem',
fontWeight: 'bold',
margin: '0',
color: 'black'
}}>
π Unmatched Benefits
</h1>
</div>
)
},
},
// π Rich Content with full component override
content: (
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
gap: '30px',
padding: '40px 20px'
}}>
{[
{
icon: 'β‘',
title: 'Lightning Fast',
description: 'Experience blazing-fast performance with our optimized infrastructure',
color: '#ff6b6b',
bgColor: '#fff5f5'
},
{
icon: 'π',
title: 'Bank-Grade Security',
description: 'Your data is protected with enterprise-level security measures',
color: '#4ecdc4',
bgColor: '#f0fdfc'
},
{
icon: 'π―',
title: 'Precision Analytics',
description: 'Make data-driven decisions with our advanced analytics platform',
color: '#45b7d1',
bgColor: '#f0f9ff'
}
].map((merit, index) => (
<div key={index} style={{
backgroundColor: merit.bgColor,
padding: '40px',
borderRadius: '20px',
textAlign: 'center',
border: `2px solid ${merit.color}20`,
transition: 'all 0.3s ease',
cursor: 'pointer'
}}
onMouseEnter={(e) => {
e.currentTarget.style.transform = 'translateY(-10px)';
e.currentTarget.style.boxShadow = `0 20px 40px ${merit.color}20`;
}}
onMouseLeave={(e) => {
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = 'none';
}}>
<div style={{
fontSize: '4rem',
marginBottom: '20px',
filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.1))'
}}>
{merit.icon}
</div>
<h3 style={{
color: merit.color,
fontSize: '1.5rem',
fontWeight: 'bold',
marginBottom: '15px'
}}>
{merit.title}
</h3>
<p style={{
color: '#666',
fontSize: '1rem',
lineHeight: '1.6',
margin: '0'
}}>
{merit.description}
</p>
</div>
))}
</div>
),
// π Custom Action Bar with props override
actionBar: {
...defaultBlocks.actionBar,
props: {
...defaultBlocks.actionBar.props,
className: "custom-action-bar",
style: {
background: 'linear-gradient(45deg, #ff6b6b, #feca57)',
padding: '40px',
borderRadius: '20px',
textAlign: 'center',
marginTop: '50px'
},
children: (
<div>
<h3 style={{
color: 'black',
fontSize: '1.5rem',
fontWeight: 'bold',
marginBottom: '20px',
}}>
π― Ready to Experience Excellence?
</h3>
<button style={{
background: 'white',
color: '#ff6b6b',
border: 'none',
padding: '15px 40px',
fontSize: '1.1rem',
fontWeight: 'bold',
borderRadius: '50px',
cursor: 'pointer',
boxShadow: '0 8px 20px rgba(0,0,0,0.2)',
transition: 'all 0.3s ease'
}}
onMouseEnter={(e) => {
e.currentTarget.style.transform = 'translateY(-2px)';
e.currentTarget.style.boxShadow = '0 12px 30px rgba(0,0,0,0.3)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = '0 8px 20px rgba(0,0,0,0.2)';
}}>
π Start Your Journey Today
</button>
</div>
)
},
},
},
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 |
className | string | undefined | Additional CSS class name for styling the container |
children | BlocksOverride | undefined | Custom block components to override default rendering |
Note: The main component inherits all HTML div element 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β
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Default header content | Custom content to override default header rendering |
subtitle | ReactNode | From context | Subtitle text to display (overrides context subtitle) |
meritsTitle | ReactNode | From context | Main title text to display (overrides context meritsTitle) |
Note: This component inherits all HTML div element props.
Merits.Contentβ
| 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) |
Note: This component inherits all HTML div element props.
Merits.Content.MeritImageβ
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | undefined | URL for the image |
alt | string | undefined | Alt text for the image |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML img element props.
Merits.Content.MeritTextβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | From context | Title content - overrides errorTitle from context |
size | enum | "2XL" | Typography size for the title |
type | enum | "heading" | Typography type |
color | enum | "low-emphasis" | Color theme for the title |
weight | enum | "bold" | Weight of the title |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML span element props.
Merits.Content.MeritSubtextβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | From context | Title content - overrides errorTitle from context |
size | enum | "S" | Typography size for the title |
type | enum | "heading" | Typography type |
color | enum | "low-emphasis" | Color theme for the title |
weight | enum | "regular" | Weight of the title |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML span element props.
Merits.ActionBarβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Default button | Custom content to override default action bar rendering |
Note: This component inherits all HTML div element props. Renders a Merits.ActionBar.Button component.
Merits.ActionBar.Buttonβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Required | Text to place inside the button |
className | string | undefined | Additional CSS class name for styling |
fill | enum | "fill" | Button fill style |
icon | enum | undefined | Optional icon for the left-hand side of the button |
iconColor | enum | undefined | Color for the left-hand side icon. When not provided, a default color for the fill type will be used. |
isDisabled | boolean | false | Whether the button is disabled and cannot be used |
onClick | function | undefined | Function to handle button click |
size | enum | "M" | Button vertical size |
textAlign | enum | "center" | Button icon and text positioning within the button |
textColor | enum | "default" | Button text color |
textEmphasis | boolean | false | Button text weight |
textSize | enum | "M" | Button text size |
type | enum | "button" | Button purpose (affects html type) |
π§ TypeScript Supportβ
Full TypeScript support with comprehensive type definitions:
import {Merits} from '@nodeblocks/frontend-merits-block';
import {ComponentProps, ReactNode} from 'react';
// Merit item interface
interface MeritProps {
imageUrl: string;
text: ReactNode;
subtext: ReactNode;
}
// Main component interface
interface MeritsProps extends Omit<ComponentProps<'div'>, 'children'> {
subtitle: ReactNode;
meritsTitle: ReactNode;
buttonText: string;
buttonHref: string;
items: MeritProps[];
}
// Example with comprehensive merits configuration
function CustomMeritsSection() {
const meritsData: MeritProps[] = [
{
imageUrl: '/icons/speed.svg',
text: 'Lightning Fast',
subtext: 'Optimized performance for the best user experience',
},
{
imageUrl: '/icons/security.svg',
text: 'Secure & Reliable',
subtext: 'Enterprise-grade security with 99.9% uptime guarantee',
},
{
imageUrl: '/icons/support.svg',
text: '24/7 Expert Support',
subtext: 'Get help from our team of experts anytime, anywhere',
},
];
return (
<Merits
subtitle="Why Choose Our Platform"
meritsTitle="Built for Modern Businesses"
buttonText="Start Free Trial"
buttonHref="#signup"
items={meritsData}
className="custom-merits-section"
style={{backgroundColor: '#f8f9fa', padding: '4rem 2rem'}}
id="benefits-section">
<Merits.Header className="custom-header" style={{marginBottom: '3rem'}} />
<Merits.Content
className="custom-content"
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
gap: '2rem',
}}
/>
<Merits.ActionBar className="custom-action-bar" style={{marginTop: '3rem'}}>
<Merits.ActionBar.Button href="#get-started" className="premium-cta">
π Get Started Today
</Merits.ActionBar.Button>
</Merits.ActionBar>
</Merits>
);
}
Built with β€οΈ using React, TypeScript, and modern web standards.