@banja-labs/react-jedi
v1.5.6
Published
A Server-Driven UI (SDUI) component library for React
Downloads
512
Maintainers
Readme
Table of Contents
- Installation
- Quick Start
- Node.js Usage
- Core Concepts
- Development
- Error Handling
- Use Cases
- TypeScript Support
- Components
- Blocks
- Features
- JSX-Lite Transpilation
- API Reference
- Examples
- License
Installation
npm install @banja-au/react-jediQuick Start
import { render, ComponentConfig } from '@banja-au/react-jedi';
import { Suspense } from 'react';
// JSON configuration (typically from your API)
const config: ComponentConfig = {
type: "Button",
props: { onClick: () => alert("Hello SDUI!") },
children: "Click Me"
};
// Render to React elements (async with Suspense)
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<DynamicContent config={config} />
</Suspense>
);
}
function DynamicContent({ config }: { config: ComponentConfig }) {
const [element, setElement] = React.useState<React.ReactElement | null>(null);
React.useEffect(() => {
render(config).then(setElement);
}, [config]);
return element;
}Node.js Usage (MCP Servers, CLI Tools, API Routes)
For Node.js environments (servers, CLI tools, build scripts, MCP servers), use the /node export - a complete Node.js API with zero React dependencies:
// Safe for any Node.js environment - NO React, NO browser APIs
import {
// Component Registry (27 components)
COMPONENT_REGISTRY,
COMPONENT_NAMES,
hasComponent,
getComponentMetadata,
// Validation
validateComponentConfig,
validateRenderOptions,
// Zod Schemas
ButtonPropsSchema,
HeroPropsSchema,
// Logger
log,
setLogLevel,
// Types
type ComponentConfig,
type ComponentMetadata,
type ValidationResult,
} from '@banja-au/react-jedi/node';1. Component Registry
Check component existence and access metadata without loading React components:
import { COMPONENT_REGISTRY, COMPONENT_NAMES, hasComponent } from '@banja-au/react-jedi/node';
// Check if component exists
if (hasComponent('Button')) {
console.log('Button component is available');
}
// Get all component names
console.log(COMPONENT_NAMES);
// ['Accordion', 'Badge', 'Button', 'Card', ... (27 total)]
// Access component metadata
const buttonMeta = COMPONENT_REGISTRY['Button'];
console.log(buttonMeta.name); // "Button"
console.log(buttonMeta.category); // "component"
console.log(buttonMeta.description); // "A customizable button..."
console.log(buttonMeta.examples); // Usage examples in ComponentConfig format2. Validation (Next.js API Routes, Servers)
Validate ComponentConfig JSON in server environments:
import { validateComponentConfig } from '@banja-au/react-jedi/node';
// Next.js API route
export async function POST(request: Request) {
const body = await request.json();
// Validate configuration
const result = validateComponentConfig(body.config);
if (!result.valid) {
return Response.json({
errors: result.errors.map(err => ({
message: err.message,
path: err.path,
suggestion: err.suggestion,
}))
}, { status: 400 });
}
// Process valid config...
return Response.json({ success: true });
}3. Zod Schema Validation
Runtime validation with detailed error messages:
import { ButtonPropsSchema, HeroPropsSchema } from '@banja-au/react-jedi/node';
// Validate button props
const result = ButtonPropsSchema.safeParse({
children: "Click me",
variant: "primary",
size: "lg"
});
if (!result.success) {
console.error("Invalid props:", result.error.errors);
// Detailed Zod error messages with paths
}
// Use validated data
const validProps = result.data;4. Pattern Interpreters & MCP Servers
Build tools that transform patterns into ComponentConfig:
import {
COMPONENT_REGISTRY,
validateComponentConfig,
hasComponent,
type ComponentConfig,
} from '@banja-au/react-jedi/node';
class PatternInterpreter {
interpret(pattern: any): ComponentConfig {
// Check component exists (metadata lookup - no React)
if (!hasComponent(pattern.type)) {
throw new Error(`Unknown component: ${pattern.type}`);
}
// Get metadata for validation
const metadata = COMPONENT_REGISTRY[pattern.type];
// Transform pattern
const config = this.transformPattern(pattern);
// Validate result
const result = validateComponentConfig(config);
if (!result.valid) {
throw new Error(`Invalid config: ${result.errors[0].message}`);
}
return config;
}
}5. CLI Tools & Build Scripts
import {
COMPONENT_NAMES,
getComponentsByCategory,
log,
setLogLevel,
} from '@banja-au/react-jedi/node';
// Configure logging
setLogLevel('info');
// List all components
log.info('system', `Found ${COMPONENT_NAMES.length} components`);
// Filter by category
const blocks = getComponentsByCategory('block');
const components = getComponentsByCategory('component');
console.log('Blocks:', blocks.map(m => m.name).join(', '));
console.log('Components:', components.map(m => m.name).join(', '));Available Exports from /node
Component Registry:
COMPONENT_REGISTRY- Map of component name → metadataCOMPONENT_NAMES- Array of all component names (27 total)hasComponent(name)- Check if component existsgetComponentMetadata(name)- Get component metadatagetComponentsByCategory(category)- Filter by 'component' or 'block'
Validation:
validateComponentConfig- Validate ComponentConfig JSONvalidateRenderOptions- Validate RenderOptionsvalidateJSON- Validate JSON syntaxvalidateSpec- Validate complete SDUI spec
Zod Schemas (all 27 components):
- Block schemas:
CallToActionPropsSchema,HeaderPropsSchema,HeroPropsSchema, etc. - Component schemas:
ButtonPropsSchema,BadgePropsSchema,CardPropsSchema, etc.
Logger:
log- Structured logger (debug, info, warn, error)setLogLevel- Set verbosity levelgetLogBuffer- Get logged entriesclearLogBuffer- Reset log bufferLOG_CATEGORIES- All log categories
Types:
ComponentConfig,RenderOptions,ThemeConfigComponentMetadata,ComponentExample,PropMetadataValidationResult,ValidationError,LogLevel
Benefits of /node Export
- ✅ Zero React dependencies - No React, react-icons, or JSX
- ✅ Zero browser APIs - No DOM manipulation, no window/document
- ✅ 97% smaller bundle - Only metadata and validators (~5KB vs ~500KB)
- ✅ Works everywhere - MCP servers, CLI tools, Next.js API routes, build scripts
- ✅ Complete functionality - Registry, validation, schemas, logging, types
- ✅ TypeScript support - Full type definitions and auto-completion
Client-Side Rendering
For browser environments with React components, use the main import:
import { render, ComponentMap, cn } from '@banja-au/react-jedi';
import { Suspense } from 'react';
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
{render(pageConfig)}
</Suspense>
);
}Core Concepts
ComponentMap
The ComponentMap is the registry that maps string identifiers to React components:
import { ComponentMap } from '@banja-au/react-jedi';
// Built-in components
console.log(Object.keys(ComponentMap));
// Output: ["Accordion", "Badge", "Button", "Card", "Carousel", "Container", ...]render() Function
The render() function transforms JSON configuration into React elements. Note: render() is async and returns a Promise.
import { render, type ComponentConfig, type RenderOptions } from '@banja-au/react-jedi';
// Single component (async)
const element = await render(config);
// Array of components (async)
const elements = await render([config1, config2, config3]);
// With custom options (async)
const element = await render(config, {
componentMap: customMap, // Use custom component registry
maxDepth: 50, // Set recursion depth limit
theme: { colors: { ... } } // Dynamic theming
});
// Or use with .then() for Promise handling
render(config).then(element => {
// Use element here
});Server-Driven UI Pattern
SDUI enables backend-controlled interfaces:
- Server sends JSON - Backend API returns ComponentConfig objects
- Client renders dynamically -
render()transforms JSON to React components - No frontend deployments - Update UI by changing server responses
- A/B testing & feature flags - Serve different UIs to different users
Development
Prerequisites
- Node.js 16+ (recommended: 18+)
- npm or yarn
- React 18 or 19 (peer dependency)
Setup
# Clone the repository
git clone https://github.com/yourusername/react-jedi.git
cd react-jedi
# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
# Type check
npm run type-check
# Lint and format (Biome)
npm run check # Check for issues
npm run fix # Auto-fix issues
npm run format # Format code
# Build
npm run build
# Development mode (watch + rebuild)
npm run dev
# Run all checks (lint + type-check + tests + build)
npm run check-allProject Structure
src/
├── index.ts # Main entry - exports ComponentMap + all components
├── ComponentMap.ts # Core SDUI mapping (string → React component)
├── core/
│ ├── render.tsx # render() function implementation
│ ├── theme.ts # cn() utility and theme management
│ ├── types.ts # Core type definitions
│ └── validation/ # Validation utilities
├── components/ # SDUI components
│ ├── index.ts # Barrel export for all components
│ ├── button/
│ │ ├── Button.tsx
│ │ ├── Button.stories.tsx
│ │ ├── Button.component-config.ts
│ │ └── index.ts
│ └── ... # Other components follow same pattern
├── blocks/ # Page-level SDUI blocks
│ └── ... # Same pattern as components
├── transpile/ # JSX-Lite transpiler
│ ├── transformer.ts # Core JSX → ComponentConfig logic
│ ├── validator.ts # JSX-Lite syntax validation
│ ├── stringify.ts # ComponentConfig → JSX converter
│ └── types.ts # Transpiler type definitions
└── llm/ # LLM integration utilities
├── schema-generator.ts # Compact schema generation
├── reference-generator.ts # Markdown documentation
├── prompts.ts # Prompt engineering templates
└── types.ts # LLM utility types
packages/
└── mcp/ # MCP server package (@banja-labs/react-jedi-mcp)
├── src/
│ ├── server.ts # MCP server implementation
│ ├── tools.ts # Tool handlers
│ └── resources.ts # Resource handlers
└── bin/
└── react-jedi-mcp.js # CLI entry pointAdding New Components
Create component directory (lowercase):
mkdir src/components/mycomponentCreate component file (
MyComponent.tsx):import React from "react"; import { cn } from "@/core/theme"; export interface MyComponentProps { title: string; className?: string; id?: string; // For blocks/containers } export const MyComponent: React.FC<MyComponentProps> = ({ title, className, id }) => { return ( <div id={id} className={cn("p-4 rounded-lg", className)}> <h2>{title}</h2> </div> ); }; export default MyComponent;Create barrel export (
index.ts):export { MyComponent, type MyComponentProps, default } from "./MyComponent";Add to components index (
src/components/index.ts):export * from "./mycomponent";Register in ComponentMap (
src/ComponentMap.ts):import { MyComponent } from "./components/mycomponent"; export const ComponentMap = { // ... existing components MyComponent, };Validate architecture:
npm run validate:componentsBuild and verify:
npm run build npm test
Component Validation
This project enforces SDUI architectural standards through automated validation. Run npm run validate:components to check all components against the rules below.
Validation Rules:
File Structure - Required files must exist:
ComponentName.tsx(implementation)ComponentName.stories.tsx(Storybook stories)ComponentName.component-config.ts(metadata)index.ts(barrel export)
className Prop - All components must accept
className?: stringfor SDUI styling flexibilitycn() Utility - Components should use
cn()from@/core/themefor className mergingNo Hardcoded Backgrounds - Components must NOT have hardcoded
bg-*classes (use className prop instead)ComponentMap Registration - All components must be registered in
src/ComponentMap.tsMetadata Structure - Config files must use
defineComponentConfig()helperrender() Import - Block components should import
render()from@/core/renderDirectory Naming - Component directories must be lowercase only
Usage:
# Validate all components
npm run validate:components
# Stop on first error
npm run validate:components -- --fail-fast
# Output JSON format
npm run validate:components -- --json
# Run all checks including validation
npm run check-allCommon Fixes:
export interface ButtonProps {
children: React.ReactNode;
+ className?: string;
}- className="bg-white rounded-lg"
+ className={cn("rounded-lg", className)}// src/ComponentMap.ts
+import { NewComponent } from "@/components/newcomponent";
export const ComponentMap = {
Button,
Link,
+ NewComponent,
};SDUI Configuration Validation
Validate SDUI JSON configurations and render options before runtime to catch errors early. The validate:sdui CLI tool provides comprehensive validation with detailed error reporting.
Features:
- ✅ Validates ComponentConfig JSON (single or array)
- ✅ Validates RenderOptions JSON (theme, pageFeatures, etc.)
- ✅ File input, stdin input, or both
- ✅ Colored terminal output with error details
- ✅ JSON output mode for CI/CD integration
- ✅ Verbose mode for debugging
Basic Usage:
# Validate a component configuration file
npm run validate:sdui -- --config=page.json
# Validate render options
npm run validate:sdui -- --options=theme.json
# Validate both config and options together
npm run validate:sdui -- --config=page.json --options=theme.json
# Validate from stdin
echo '{"type":"Button","props":{"children":"Click me"}}' | npm run validate:sdui
# Show help
npm run validate:sdui:helpAdvanced Usage:
# JSON output for CI/CD pipelines
npm run validate:sdui -- --config=page.json --json
# Verbose mode for detailed progress
npm run validate:sdui -- --config=page.json --verbose
# Combine flags
npm run validate:sdui -- --config=page.json --options=theme.json --verboseExit Codes:
0- Validation passed1- Validation errors found2- Script error (file not found, invalid JSON syntax, etc.)
Example Output:
📋 SDUI Configuration Validator
✓ All validations passed!📋 SDUI Configuration Validator
❌ Validation Errors:
● :12 at type [UNKNOWN_COMPONENT] Unknown component type: "Buton"
→ Did you mean "Button"?
● :25 at props [MISSING_REQUIRED_PROP] Required prop "children" is missing
→ Add "children" to the props object
━━━ Validation Summary ━━━
Errors: 2
Validation failed. Fix errors above.{
"valid": false,
"summary": {
"errors": 1
},
"errors": [
{
"code": "UNKNOWN_COMPONENT",
"message": "Unknown component type: \"Buton\"",
"path": "type",
"line": 12,
"suggestion": "Did you mean \"Button\"?",
"invalidValue": "Buton",
"expectedType": "string (valid component name)"
}
]
}Common Validation Errors:
| Error Code | Description | Fix |
|------------|-------------|-----|
| INVALID_JSON | JSON syntax error | Check for missing commas, brackets, or quotes |
| UNKNOWN_COMPONENT | Component type not in ComponentMap | Check spelling and capitalization |
| MISSING_REQUIRED_PROP | Required prop missing | Add the required prop to props object |
| INVALID_PROP_TYPE | Prop type mismatch | Check prop value matches expected type |
| INVALID_THEME_CONFIG | Invalid theme structure | Ensure theme.colors is an object |
Integration with CI/CD:
# GitHub Actions example
- name: Validate SDUI Configs
run: |
npm run validate:sdui -- --config=config/page.json --jsonRunning Tests
# Run all tests (watch mode)
npm test
# Run tests once (CI mode)
npm test -- --run
# Run with coverage
npm run test:coverage
# Watch mode
npm run test:watch
# UI mode
npm run test:ui
# Storybook tests
npm run test:storybookError Handling
The library provides robust error handling with two modes: graceful degradation (enabled by default) and strict mode (opt-in for development).
Graceful Error Handling (Default)
By default, error boundaries are enabled to prevent a single invalid component from breaking the entire page:
import { render } from '@banja-au/react-jedi';
// Default behavior - graceful error handling with silent fallback
const element = await render(config);
// Failed components render as empty space, rest of page works
// Customize fallback mode
const element = await render(config, {
errorHandling: {
fallback: "placeholder", // Show error box for debugging
logErrors: true // Log errors to console (default: true)
}
});Fallback Modes:
// 1. Silent (default) - failed components render nothing
errorHandling: { fallback: "silent" }
// 2. Placeholder - shows error box for debugging
errorHandling: { fallback: "placeholder" }
// 3. Dev - detailed error with stack trace
errorHandling: { fallback: "dev" }Custom Error Handling
// Custom error handler callback
const element = await render(config, {
errorHandling: {
fallback: "silent",
onError: (error, componentType) => {
// Send to error tracking service
console.error(`Component ${componentType} failed:`, error);
trackError({ component: componentType, error: error.message });
}
}
});Strict Mode (Opt-In)
To disable error boundaries and fail fast on invalid components (useful for development):
// Enable strict mode - entire page fails on single invalid component
const element = await render(config, {
errorHandling: {
mode: "throw" // Disable error boundaries
}
});
// Examples of errors in strict mode:
render({ type: "NonExistent", props: {} }, { errorHandling: { mode: "throw" } });
// ❌ Error: Unknown component type: "NonExistent". Available types: Button, Link, Card, ...
render(deeplyNestedConfig, { maxDepth: 5, errorHandling: { mode: "throw" } });
// ❌ Error: Max render depth (5) exceededWhen to use strict mode:
- ✅ Development and testing
- ✅ When all components are known and validated
- ✅ When you want to catch errors early
When to use graceful error handling (default):
- ✅ Production environments
- ✅ Untrusted server JSON
- ✅ Progressive rendering (partial content better than blank page)
- ✅ User-facing applications
Common Issues
- Component not found: Ensure component is registered in
ComponentMap - Recursion limit: Increase
maxDepthinRenderOptionsor simplify nesting - Invalid config: Validate API responses match
ComponentConfiginterface
Use Cases
Real-world scenarios where React Jedi excels:
- 🏢 Multi-tenant SaaS - Customize UI per tenant/organization from backend configuration
- 🚩 Feature Flags - Gradually roll out features to specific users or segments
- 🧪 A/B Testing - Serve different UI variations for experimentation and optimization
- 📝 CMS-driven pages - Build dynamic pages from headless CMS content
- 📋 Dynamic forms - Generate complex forms from backend schemas and validation rules
- 🎯 Promotional banners - Update marketing content and CTAs instantly without deployments
- 🚀 Onboarding flows - Customize user onboarding experiences per segment or cohort
- 🎨 Whitelabel products - Support multiple brands with different themes and components
- 📊 Admin dashboards - Build configurable dashboards with drag-and-drop layouts
- 📱 Mobile app backends - Drive native mobile UIs from the same backend configs
TypeScript Support
Full TypeScript support with strict type checking and IntelliSense:
import type { ComponentConfig, RenderOptions } from '@banja-au/react-jedi';
// Fully typed component config
const config: ComponentConfig = {
type: "Button",
props: {
variant: "primary",
onClick: () => console.log("Clicked")
},
children: "Click me"
};
// Fully typed render options
const options: RenderOptions = {
maxDepth: 100,
theme: {
colors: {
primary: "#4f46e5"
}
},
logLevel: "debug"
};
const element = render(config, options);Components
Props
export interface AccordionItem {
id: string;
title: string;
content: React.ReactNode;
icon?: React.ReactNode;
}
export interface AccordionProps {
items: AccordionItem[];
allowMultiple?: boolean;
defaultOpenItems?: string[];
className?: string;
variant?: "default" | "bordered" | "separated" | "minimal";
id?: string; // Optional ID for anchor linking and scroll targets
}Description
An interactive accordion component with smooth animations powered by Framer Motion. Perfect for FAQs, collapsible sections, and organizing content into expandable panels.
Example
{
type: "Accordion",
props: {
items: [
{
id: "item-1",
title: "What is Server-Driven UI?",
content: "Server-Driven UI is an architectural pattern..."
}
],
variant: "default"
}
}Props
export interface AnnouncementBarProps {
/** Main announcement text */
text: string;
/** Optional link configuration (using ComponentConfig for SDUI) */
link?: ComponentConfig;
/** Optional icon to display before the text (using ComponentConfig for SDUI) */
icon?: ComponentConfig;
/** Whether the bar can be dismissed by the user */
dismissible?: boolean;
/** Callback when the bar is dismissed */
onDismiss?: () => void;
/** Text alignment */
align?: "left" | "center" | "right";
/** Whether to use sticky positioning at the top */
sticky?: boolean;
/** Additional CSS classes */
className?: string;
/** Optional ID for anchor linking and scroll targets */
id?: string;
}Description
A full-width announcement bar component designed to appear at the top of web pages. Perfect for promoting sales, announcing new features, displaying important notices, or showing maintenance alerts. Supports optional icons, links, dismissibility, and sticky positioning.
Example
{
type: "AnnouncementBar",
props: {
text: "Plan Smarter. Grow Stronger. Don't miss our latest financial strategies.",
link: {
type: "Link",
props: {
href: "/learn-more",
className: "text-current font-semibold no-underline hover:underline inline-flex items-center gap-1"
},
children: [
"Learn More",
{
type: "Icon",
props: { name: "arrow-right", size: 16 }
}
]
},
className: "bg-amber-400 text-gray-900"
}
}Props
export interface EdgeBlurConfig {
/** Intensity of the edge fade (0-1, default: 0.6) */
intensity?: number;
/** Shape of the gradient (default: ellipse) */
shape?: "circle" | "ellipse";
}
export interface ParallaxConfig {
/** Strength of parallax effect (default: 0.1). Higher = more movement */
strength?: number;
/** Enable parallax on touch devices (default: true) */
enableOnTouchDevice?: boolean;
/** Easing for smooth interpolation (default: 0.1). Lower = smoother */
lerpEase?: number;
/** Horizontal parallax instead of vertical (default: false) */
isHorizontal?: boolean;
}
export interface ResponsiveBackgroundStyles {
size?: "cover" | "contain" | "auto";
position?: string;
margin?: string;
transform?: string;
transformOrigin?: string;
left?: string;
opacity?: number;
}
export interface BackgroundImageProps {
url: string;
alt?: string;
size?: "cover" | "contain" | "auto";
position?: string;
attachment?: "fixed" | "scroll" | "local";
overlay?: string;
edgeBlur?: boolean | number | EdgeBlurConfig;
parallax?: boolean | ParallaxConfig;
opacity?: number;
blendMode?: React.CSSProperties["mixBlendMode"];
zIndex?: number;
margin?: string;
transform?: string;
transformOrigin?: string;
left?: string;
mobile?: ResponsiveBackgroundStyles;
desktop?: ResponsiveBackgroundStyles;
className?: string;
id?: string;
}Description
A powerful background image component for creating rich visual layers. Supports parallax scrolling, edge blur/vignette effects, responsive breakpoints, and CSS transforms. Perfect for hero backgrounds, decorative elements, and layered compositions.
Example
{
type: "BackgroundImage",
props: {
url: "/hero-bg.jpg",
alt: "Hero background",
parallax: { strength: 0.15 },
edgeBlur: 0.4,
overlay: "rgba(0,0,0,0.3)",
mobile: { position: "center top" },
desktop: { position: "center center" }
}
}Props
export interface BadgeProps {
text: string;
icon?: ComponentConfig;
className?: string;
}Description
A simple, clean badge component for labels, tags, and status indicators. Features optional icons and customizable styling.
Example
{
type: "Badge",
props: {
text: "New",
className: "bg-gradient-to-r from-purple-500 to-pink-600"
}
}Props
export interface BlogCardAuthor {
/** Author's name */
name: string;
/** Author's avatar image (ComponentConfig for Image component) */
avatar?: ComponentConfig;
/** Author's role or title */
role?: string;
}
export interface BlogCardProps {
/** Optional ID for anchor linking and scroll targets */
id?: string;
/** Blog post title */
title: string;
/** Brief excerpt or description */
excerpt?: string;
/** Publication date (formatted string) */
date?: string;
/** Category or tag label */
category?: string;
/** Reading time estimate (e.g., "5 min read") */
readTime?: string;
/** Featured image (ComponentConfig for Image component) */
image?: ComponentConfig;
/** Link to the full blog post */
href?: string;
/** Author information */
author?: BlogCardAuthor;
/** Layout variant */
variant?: "default" | "horizontal" | "minimal" | "featured";
/** Image aspect ratio */
imageAspectRatio?: "auto" | "square" | "video" | "portrait" | "wide";
/** Show/hide category badge */
showCategory?: boolean;
/** Show/hide date */
showDate?: boolean;
/** Show/hide read time */
showReadTime?: boolean;
/** Show/hide author info */
showAuthor?: boolean;
/** Show/hide excerpt */
showExcerpt?: boolean;
/** Additional CSS classes */
className?: string;
/** Custom className for the image container */
imageClassName?: string;
/** Custom className for the content section */
contentClassName?: string;
/** Custom className for the title */
titleClassName?: string;
/** Custom className for the excerpt */
excerptClassName?: string;
/** Custom className for the date */
dateClassName?: string;
/** Custom className for the category badge */
categoryClassName?: string;
}Description
A versatile blog post card component with multiple layout variants (default, horizontal, minimal, featured). Displays post title, excerpt, date, category, read time, featured image, and author information. Perfect for blog listings, news feeds, and content showcases.
Variants
- default: Standard vertical card with image on top
- horizontal: Side-by-side image and content layout
- minimal: Clean, text-focused card without prominent image
- featured: Large hero-style card for featured content
Example
{
type: "BlogCard",
props: {
title: "The Power of Compound Interest Explained",
excerpt: "Discover how compound interest can accelerate your wealth building journey.",
date: "May 21, 2025",
category: "Finance",
readTime: "5 min read",
variant: "default",
href: "/blog/compound-interest",
image: {
type: "Image",
props: {
src: "https://example.com/blog-image.jpg",
alt: "Blog post image",
className: "w-full h-full object-cover"
}
},
author: {
name: "Sarah Chen",
role: "Financial Advisor",
avatar: {
type: "Image",
props: {
src: "https://example.com/avatar.jpg",
alt: "Sarah Chen"
}
}
}
}
}Props
export interface ButtonProps {
children: React.ReactNode;
onClick?: () => void;
href?: string;
type?: "button" | "submit" | "reset";
disabled?: boolean;
variant?: "primary" | "secondary" | "ghost" | "outline";
size?: "sm" | "md" | "lg";
className?: string;
}Description
A flexible button component with full HTML button support. Supports click handlers, links (href), variants, sizes, and custom styling.
Example
{
type: "Button",
props: {
onClick: () => console.log("Clicked!"),
variant: "primary",
size: "lg"
},
children: "Get Started"
}Props
export interface CardProps {
children: ComponentConfig | ComponentConfig[] | React.ReactNode;
title?: string;
subtitle?: string;
className?: string;
variant?: "default" | "elevated" | "outlined";
id?: string; // Optional ID for anchor linking and scroll targets
}Description
A versatile card component with optional title/subtitle and multiple style variants (default with border, elevated with shadow, outlined with thicker border).
Example
{
type: "Card",
props: {
title: "Feature Card",
subtitle: "Supporting text",
variant: "elevated",
className: "p-6"
},
children: "Card content here"
}Props
export interface CarouselItem {
id: string;
content: ComponentConfig;
}
export interface CarouselProps {
items: CarouselItem[];
variant?: "default" | "cards" | "fade" | "scale" | "slide-3d";
autoPlay?: number;
showArrows?: boolean;
showIndicators?: boolean;
loop?: boolean;
animationDuration?: number;
enableSwipe?: boolean;
pauseOnHover?: boolean;
itemsPerView?: 1 | 2 | 3;
gap?: "none" | "sm" | "md" | "lg";
arrowVariant?: "default" | "minimal" | "rounded" | "pill";
className?: string;
itemClassName?: string;
id?: string; // Optional ID for anchor linking and scroll targets
}Description
An interactive carousel component with multiple animation styles (default slide, fade, scale, 3D, multi-item cards), auto-play, and swipe gestures. Perfect for image galleries, testimonials, and product showcases.
Example
{
type: "Carousel",
props: {
items: [
{ id: "1", content: { type: "Image", props: { src: "https://placehold.co/800x400", alt: "Image 1" } } }
],
variant: "fade",
autoPlay: 5000,
showArrows: true
}
}Props
export interface ContainerProps {
children: ComponentConfig | ComponentConfig[] | React.ReactNode;
direction?: "row" | "column";
gap?: number;
className?: string;
backgroundImage?: BackgroundImageConfig | BackgroundImageConfig[];
style?: React.CSSProperties;
id?: string;
}Description
A flexible container component for organizing layouts with flexbox. Supports row/column direction, customizable gap spacing, and optional background images.
Example
{
type: "Container",
props: {
direction: "column",
gap: 6,
className: "p-8"
},
children: [
{ type: "Text", props: { variant: "h2" }, children: "Title" },
{ type: "Text", props: { variant: "p" }, children: "Description" }
]
}Props
export interface FloatingPanelProps {
isOpen: boolean;
onToggle: () => void;
buttonIcon?: React.ReactNode;
buttonPosition?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
panelPosition?: "bottom-right" | "left" | "right" | "top";
panelWidth?: string;
panelMaxHeight?: string;
title?: string;
children: React.ReactNode;
className?: string;
buttonClassName?: string;
zIndex?: number;
id?: string;
}Description
A floating action button that expands to reveal a panel overlay. Supports multiple positioning options, keyboard navigation (Escape to close), and click-outside-to-close behavior. Perfect for debug tools, settings panels, chat widgets, or contextual controls.
Example
{
type: "FloatingPanel",
props: {
isOpen: true,
onToggle: () => {},
title: "Settings",
buttonPosition: "bottom-right",
panelPosition: "left",
panelWidth: "w-full max-w-md"
},
children: "Panel content here"
}Props
export interface GradientProps {
color: string;
direction?: "vertical" | "horizontal";
height: string;
width?: string;
absolute?: boolean;
className?: string;
}Description
A gradient overlay component that fades from transparent to a specified color. Perfect for creating visual fade effects over images, backgrounds, or content sections.
Example
{
type: "Gradient",
props: {
color: "white",
direction: "vertical",
height: "h-24",
absolute: true
}
}Props
export interface IconProps {
library: "fa" | "fi" | "ai" | "bs" | "md" | "io" | "hi" | "ri";
name: string;
size?: number | string;
color?: string;
className?: string;
}Description
Flexible icon component supporting multiple icon libraries from react-icons (Font Awesome, Feather, Ant Design, Bootstrap, Material Design, Ionicons, Hero Icons, Remix Icon).
Example
{
type: "Icon",
props: {
library: "hi",
name: "HiRocketLaunch",
size: 32,
color: "#8b5cf6"
}
}Props
export interface ImageProps {
src: string;
alt: string;
width?: number | string;
height?: number | string;
loading?: "lazy" | "eager";
className?: string;
}Description
An image component with built-in lazy loading support and responsive sizing. Automatically applies object-cover and rounded corners.
Note: For placeholder images, use https://placehold.co/{width}x{height} (e.g., https://placehold.co/800x600).
Example
{
type: "Image",
props: {
src: "https://placehold.co/800x600",
alt: "Example image",
width: 800,
height: 600,
loading: "lazy"
}
}Props
export interface InputProps {
type?: "text" | "email" | "password" | "number" | "tel" | "url";
placeholder?: string;
value?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
disabled?: boolean;
required?: boolean;
className?: string;
id?: string; // Optional ID for anchor linking and scroll targets
}Description
A standard form input component with support for various input types (text, email, password, etc.), validation states, and custom styling.
Example
{
type: "Input",
props: {
type: "email",
placeholder: "Enter your email",
required: true
}
}Props
export interface LinkProps {
children: React.ReactNode;
href: string;
target?: "_blank" | "_self" | "_parent" | "_top";
rel?: string;
className?: string;
}Description
An anchor component for navigation with support for external links (target="_blank"), custom rel attributes, and styling.
Example
{
type: "Link",
props: {
href: "/about",
target: "_self"
},
children: "Learn More"
}Props
export interface ResizableProps {
children: React.ReactNode;
className?: string;
id?: string;
direction?: "horizontal" | "vertical";
}
export interface ResizableHandleProps {
withHandle?: boolean;
className?: string;
}Description
A resizable panel container built on react-resizable-panels. Create split-pane layouts with draggable resize handles. Supports horizontal and vertical directions. Use with ResizablePanel and ResizableHandle sub-components.
Example
{
type: "Resizable",
props: {
direction: "horizontal",
className: "min-h-[200px]"
},
children: [
{ type: "ResizablePanel", props: { defaultSize: 50 }, children: "Left panel" },
{ type: "ResizableHandle", props: { withHandle: true } },
{ type: "ResizablePanel", props: { defaultSize: 50 }, children: "Right panel" }
]
}Props
export interface StatBoxProps {
/** The numeric value to display (e.g., 150, 99.9, 1000000) */
value: number;
/** Optional prefix before the value (e.g., "$", "€") */
prefix?: string;
/** Optional suffix after the value (e.g., "+", "%", "K", "M") */
suffix?: string;
/** Label text describing the stat (e.g., "Projects Completed") */
label: string;
/** Optional description or subtitle text */
description?: string;
/** Optional icon to display */
icon?: ComponentConfig<IconProps>;
/** Layout variant */
layout?: "vertical" | "horizontal" | "centered";
/** Size variant affecting typography scale */
size?: "sm" | "md" | "lg" | "xl";
/** Whether to animate the number counting up */
animate?: boolean;
/** Animation duration in milliseconds */
animationDuration?: number;
/** Animation easing function */
animationEasing?: "linear" | "easeOut" | "easeInOut" | "spring" | "bounce";
/** Start animation when element enters viewport (requires animate=true) */
animateOnScroll?: boolean;
/** Decimal places to show (auto-detected from value if not specified) */
decimals?: number;
/** Format large numbers with separators (e.g., 1,000,000) */
formatNumber?: boolean;
/** Locale for number formatting (e.g., "en-US", "de-DE") */
locale?: string;
/** Additional CSS classes */
className?: string;
/** CSS classes for the value text */
valueClassName?: string;
/** CSS classes for the label text */
labelClassName?: string;
/** CSS classes for the description text */
descriptionClassName?: string;
/** CSS classes for the icon container */
iconClassName?: string;
/** Optional ID for anchor linking and scroll targets */
id?: string;
}Description
A stat box component for displaying numeric statistics with optional counting animation, icons, and multiple layout options. Features smooth easing animations (linear, easeOut, easeInOut, spring, bounce) that can trigger on scroll. Perfect for dashboards, landing pages, and data visualizations.
Example
{
type: "StatBox",
props: {
value: 150,
suffix: "+",
label: "Projects Completed",
animate: true,
animationDuration: 2000,
animationEasing: "easeOut",
layout: "centered",
className: "text-gray-900"
}
}Props
export interface TextProps {
variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "label";
children: React.ReactNode;
className?: string;
}Description
A flexible typography component that renders semantic HTML elements (h1-h6, p, span, label) with consistent styling based on variant.
Example
{
type: "Text",
props: {
variant: "h2",
className: "text-gray-900"
},
children: "Welcome to our site"
}Blocks
Props
export interface BlogPost {
/** Unique key for the post */
key?: string;
/** Blog post title */
title: string;
/** Brief excerpt or description */
excerpt?: string;
/** Publication date (formatted string) */
date?: string;
/** Category or tag label */
category?: string;
/** Reading time estimate */
readTime?: string;
/** Featured image (ComponentConfig for Image component) */
image?: ComponentConfig;
/** Link to the full blog post */
href?: string;
/** Author information */
author?: BlogCardAuthor;
}
export interface BlogGridProps {
/** Optional ID for anchor linking and scroll targets */
id?: string;
/** Section heading */
heading?: string;
/** Section subheading or description */
subheading?: string;
/** Array of blog posts to display */
posts: BlogPost[];
/** Grid layout style */
layout?: "grid" | "list" | "masonry" | "featured" | "magazine" | "cards" | "minimal" | "hero-grid";
/** Number of columns (for grid layout) */
columns?: 1 | 2 | 3 | 4;
/** Gap size between items */
gap?: "sm" | "md" | "lg" | "xl";
/** BlogCard variant to use */
cardVariant?: "default" | "horizontal" | "minimal" | "featured";
/** Image aspect ratio for cards */
imageAspectRatio?: "auto" | "square" | "video" | "portrait" | "wide";
/** Show category on cards */
showCategory?: boolean;
/** Show date on cards */
showDate?: boolean;
/** Show read time on cards */
showReadTime?: boolean;
/** Show author on cards */
showAuthor?: boolean;
/** Show excerpt on cards */
showExcerpt?: boolean;
/** Heading alignment */
align?: "left" | "center" | "right";
/** CTA button/link (ComponentConfig) */
cta?: ComponentConfig;
/** Additional CSS classes */
className?: string;
/** Custom className for the heading section */
headingClassName?: string;
/** Custom className for the grid container */
gridClassName?: string;
/** Custom className for individual cards */
cardClassName?: string;
}Description
A flexible blog grid section that displays multiple blog posts in various layouts. Supports grid, list, featured, magazine, masonry, cards, minimal, and hero-grid layouts. Perfect for blog listing pages, news sections, and content hubs.
Layouts
- grid: Standard responsive grid (default)
- list: Vertical list with horizontal cards
- featured: One large featured post with smaller posts alongside
- magazine: Hero article with grid below
- masonry: Pinterest-style masonry layout
- cards: Elevated card style with shadows
- minimal: Text-focused minimal design
- hero-grid: Large hero post + grid below
Example
{
type: "BlogGrid",
props: {
heading: "Latest Articles",
subheading: "Stay informed with our latest insights and updates",
layout: "grid",
columns: 3,
posts: [
{
title: "The Power of Compound Interest",
excerpt: "Discover how compound interest can accelerate wealth building.",
date: "May 21, 2025",
category: "Finance",
readTime: "5 min read",
href: "/blog/compound-interest",
image: {
type: "Image",
props: {
src: "https://example.com/image.jpg",
alt: "Blog image",
className: "w-full h-full object-cover"
}
}
},
{
title: "5 Smart Ways to Save More",
excerpt: "Learn practical strategies to increase your savings.",
date: "May 20, 2025",
category: "Savings",
readTime: "4 min read",
href: "/blog/save-more"
}
],
cta: {
type: "Button",
props: { variant: "secondary", href: "/blog" },
children: "View All Articles"
}
}
}Props
export interface CallToActionProps {
icon?: ComponentConfig;
title: string;
description?: string;
button?: ComponentConfig;
className?: string;
titleClassName?: string;
descriptionClassName?: string;
id?: string;
}Description
A full-width call-to-action section with decorative grid background and glowing dots. Perfect for conversion sections, newsletter signups, and promotional content.
Example
{
type: "CallToAction",
props: {
title: "Ready to get started?",
description: "Join thousands of users who have already transformed their workflow",
button: {
type: "Button",
props: { variant: "primary", size: "lg" },
children: "Get Started Free"
}
}
}Props
export interface CaseStudyItem {
key?: string;
media: ComponentConfig;
logo?: ComponentConfig;
logoPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
headline: string;
headlineTag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
headlineClassName?: string;
description?: string;
descriptionClassName?: string;
badge?: ComponentConfig;
companyName?: string;
companyNameClassName?: string;
metrics?: Array<{ value: string; label: string }>;
metricsClassName?: string;
cta?: ComponentConfig;
mediaPosition?: "left" | "right";
contentClassName?: string;
mediaClassName?: string;
logoClassName?: string;
mediaAspectRatio?: "auto" | "square" | "video" | "portrait";
className?: string;
}
export interface CaseStudySummariesProps {
id?: string;
heading?: string;
headingClassName?: string;
subheading?: string;
subheadingClassName?: string;
items: CaseStudyItem[];
layout?: "stacked" | "alternating";
gap?: "sm" | "md" | "lg" | "xl" | "none";
align?: "left" | "center" | "right";
showDividers?: boolean;
dividerClassName?: string;
cta?: ComponentConfig;
className?: string;
headerClassName?: string;
itemsClassName?: string;
}Description
A container block for displaying multiple case study summaries in a consistent layout. Supports stacked and alternating layouts, configurable spacing, optional dividers, and section-level heading/CTA. Each item renders as a CaseStudySummary component.
Example
{
type: "CaseStudySummaries",
props: {
heading: "Customer Success Stories",
subheading: "See how our clients achieved remarkable results",
layout: "alternating",
gap: "lg",
items: [
{
media: { type: "Image", props: { src: "/case1.jpg", alt: "Case study 1" } },
headline: "40% Increase in Revenue",
description: "How Company X transformed their business",
companyName: "Company X",
cta: { type: "Link", props: { href: "/case-studies/company-x" }, children: "Read more" }
}
]
}
}Props
export interface CaseStudyMetric {
/** Metric value (e.g., "40%", "3x", "$2M") */
value: string;
/** Metric label (e.g., "Growth", "ROI", "Savings") */
label: string;
}
export interface CaseStudySummaryProps {
/** Optional ID for anchor linking and scroll targets */
id?: string;
/** Media content (typically Image with logo overlay) */
media: ComponentConfig;
/** Logo overlay on the media (positioned bottom-left by default) */
logo?: ComponentConfig;
/** Position of logo overlay on media */
logoPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
/** Main headline/result statement */
headline: string;
/** HTML tag for headline (default: h3) */
headlineTag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
/** Custom className for headline */
headlineClassName?: string;
/** Optional description/subtext */
description?: string;
/** Custom className for description */
descriptionClassName?: string;
/** Optional badge above headline (e.g., "Case Study", "Success Story") */
badge?: ComponentConfig<BadgeProps>;
/** Optional company name text */
companyName?: string;
/** Custom className for company name */
companyNameClassName?: string;
/** Optional key metrics to highlight */
metrics?: CaseStudyMetric[];
/** Custom className for metrics container */
metricsClassName?: string;
/** CTA link configuration */
cta?: ComponentConfig<LinkProps>;
/** Position of media content (default: left) */
mediaPosition?: "left" | "right";
/** Custom className for content section */
contentClassName?: string;
/** Custom className for media section */
mediaClassName?: string;
/** Custom className for logo container */
logoClassName?: string;
/** Aspect ratio for media container (default: auto) */
mediaAspectRatio?: "auto" | "square" | "video" | "portrait";
/** Additional CSS classes for the block */
className?: string;
}Description
A versatile case study/testimonial block that displays customer success stories with media, logo overlay, headline, optional metrics, and CTA. Supports multiple layouts (image left/right), logo positioning, and aspect ratio control. Perfect for showcasing customer results, testimonials, and success stories.
Example
{
type: "CaseStudySummary",
props: {
media: {
type: "Image",
props: {
src: "https://images.unsplash.com/photo-1600880292203-757bb62b4baf",
alt: "Team collaboration",
className: "w-full h-auto rounded-lg"
}
},
logo: {
type: "Container",
props: {
className: "bg-black/70 backdrop-blur-sm px-4 py-2 rounded-md flex items-center gap-2"
},
children: [
{ type: "Icon", props: { name: "Zap", size: 20, className: "text-white" } },
{ type: "Text", props: { className: "text-white font-semibold" }, children: "ZenZap" }
]
},
headline: "Achieved 40% net portfolio growth in 3 years through disciplined wealth management.",
metrics: [
{ value: "40%", label: "Growth" },
{ value: "3 years", label: "Timeline" }
],
cta: {
type: "Link",
props: {
href: "/case-studies/zenzap",
className: "text-blue-600 hover:text-blue-700 font-medium inline-flex items-center"
},
children: [
{ type: "Text", children: "Read Case Study" },
{ type: "Icon", props: { name: "ArrowRight", size: 16, className: "ml-2" } }
]
}
}
}Props
export interface CustomerLogo {
name: string;
image: string;
alt?: string;
href?: string;
}
export interface CustomerLogosProps {
logos: CustomerLogo[];
title?: string;
className?: string;
variant?: "default" | "compact" | "large";
scrolling?: boolean;
scrollSpeed?: number;
mobileScrollSpeedMultiplier?: number;
fade?: boolean;
fadeColor?: string;
pauseOnHover?: boolean;
id?: string;
}Description
A customer/partner logo showcase with optional infinite scrolling animation. Perfect for social proof sections and partner displays.
Example
{
type: "CustomerLogos",
props: {
title: "Trusted by leading companies",
logos: [
{ name: "Company 1", image: "/logos/company1.png" },
{ name: "Company 2", image: "/logos/company2.png" }
],
scrolling: true,
fade: true,
variant: "default"
}
}Props
export interface Feature {
id?: string;
title: string;
description: string;
icon?: React.ReactNode;
iconColor?: string;
iconTextColor?: string;
onClick?: () => void;
href?: string;
}
export interface FeatureGridProps {
heading?: React.ReactNode;
subheading?: React.ReactNode;
features: Feature[];
columns?: 1 | 2 | 3 | 4 | 5 | 6;
gap?: "sm" | "md" | "lg" | "xl";
variant?: "default" | "bordered" | "elevated" | "minimal";
className?: string;
headingClassName?: string;
gridClassName?: string;
align?: "left" | "center" | "right";
id?: string;
}Description
A flexible grid layout for showcasing features with optional icons, multiple column configurations, and style variants.
Example
{
type: "FeatureGrid",
props: {
heading: "Powerful Features",
subheading: "Everything you need to build amazing products",
features: [
{
title: "Fast Performance",
description: "Lightning-fast load times",
icon: { type: "Icon", props: { library: "hi", name: "HiBolt", size: 24 } }
}
],
columns: 3,
variant: "elevated"
}
}Props
export interface FeatureStepItem {
id: string;
image: ComponentConfig;
badge: ComponentConfig;
title: string;
description: string;
cardClassName?: string;
imageClassName?: string;
contentClassName?: string;
badgeClassName?: string;
titleClassName?: string;
descriptionClassName?: string;
imageBlur?: number | string;
imageBlurColor?: string;
}
export interface FeatureStepGridProps {
id?: string;
items: FeatureStepItem[];
className?: string;
gridClassName?: string;
columns?: 1 | 2 | 3 | 4;
}Description
A grid layout for step-by-step features with images, badges, and blur effects. Perfect for onboarding flows and product tours.
Example
{
type: "FeatureStepGrid",
props: {
items: [
{
id: "step-1",
badge: { type: "Badge", props: { text: "STEP 1" } },
image: { type: "Image", props: { src: "https://placehold.co/400x300", alt: "Step 1" } },
title: "Create Account",
description: "Sign up in seconds",
imageBlur: 80
}
],
columns: 3
}
}Props
export interface FooterColumn {
header: string;
links: Array<{ text: string; href: string }>;
}
export interface FooterProps {
logo?: ComponentConfig;
brandText?: string;
brandClassName?: string;
columns?: FooterColumn[];
columnHeaderClassName?: string;
columnClassName?: string;
copyright: string;
bottomBadge?: ComponentConfig;
bottomClassName?: string;
links?: Array<{ text: string; href: string }>;
className?: string;
innerClassName?: string;
id?: string;
}Description
A comprehensive footer component with logo, brand description, link columns, and copyright section. Supports both enhanced layout and simple centered layout.
Example
{
type: "Footer",
props: {
logo: { type: "Image", props: { src: "https://placehold.co/120x40", alt: "Logo", width: 120 } },
brandText: "Building the future of web development",
columns: [
{
header: "Product",
links: [
{ text: "Features", href: "/features" },
{ text: "Pricing", href: "/pricing" }
]
}
],
copyright: "© 2025 YourCompany. All rights reserved."
}
}Props
export interface HeaderProps {
layout?: "default" | "logo-nav-cta" | "centered" | "minimal";
logo?: {
src: string;
alt: string;
href?: string;
width?: number;
height?: number;
className?: string;
};
links?: Array<{
text: string;
href: string;
active?: boolean;
children?: Array<{
text: string;
href: string;
active?: boolean;
}>;
}>;
ctas?: Array<{
text: string;
href?: string;
onClick?: () => void;
variant?: "primary" | "secondary" | "ghost" | "outline";
size?: "sm" | "md" | "lg";
}>;
title?: string;
maxWidth?: "sm" | "md" | "lg" | "xl" | "full";
sticky?: boolean;
className?: string;
containerClassName?: string;
linkClassName?: string;
activeLinkClassName?: string;
navClassName?: string;
mobileMenuIconClassName?: string;
mobileMenuClassName?: string;
id?: string;
}Description
A flexible navigation header with multiple layouts, dropdown support, mobile menu, and sticky positioning. Includes accessibility features and smooth animations.
Example
{
type: "Header",
props: {
layout: "logo-nav-cta",
logo: { src: "/logo.png", alt: "Logo", href: "/" },
links: [
{ text: "Features", href: "/features" },
{ text: "Pricing", href: "/pricing" }
],
ctas: [
{ text: "Sign In", variant: "ghost" },
{ text: "Get Started", variant: "primary" }
],
sticky: true
}
}Props
export interface HeroProps {
title: string | ComponentConfig[];
subtitle?: React.ReactNode;
ctaText?: string;
ctaOnClick?: () => void;
ctaHref?: string;
align?: "left" | "center" | "right";
size?: "sm" | "md" | "lg" | "xl";
layout?: "default" | "split" | "centered";
logo?: {
src: string;
alt: string;
width?: number;
height?: number;
href?: string;
className?: string;
};
badge?: {
text: string;
icon?: ComponentConfig;
className?: string;
};
image?: {
src: string;
alt: string;
width?: number;
height?: number;
className?: string;
containerClassName?: string;
};
className?: string;
titleClassName?: string;
subtitleClassName?: string;
ctaClassName?: string;
background?: string;
backgroundImage?: BackgroundImageConfig | BackgroundImageConfig[];
innerBackgroundImage?: BackgroundImageConfig | BackgroundImageConfig[];
maxWidth?: "sm" | "md" | "lg" | "xl" | "full";
blur?: number;
blurColor?: string;
id?: string;
}Description
A powerful hero section with multiple layouts (default stacked, split two-column, centered), size variants, optional logo/badge, and background image support.
Example
{
type: "Hero",
props: {
title: "Build Better Products Faster",
subtitle: "The complete platform for modern development teams",
ctaText: "Get Started Free",
ctaHref: "/signup",
layout: "centered",
size: "lg",
badge: { text: "New Release", className: "bg-purple-600 text-white" }
}
}Props
export interface MediaContentBoxStat {
icon: ComponentConfig;
label: string;
value: string;
}
export interface MediaContentBoxProps {
badge?: ComponentConfig;
title: string;
titleTag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
description: string;
media: ComponentConfig;
mediaPosition?: "left" | "right";
stats?: MediaContentBoxStat[];
className?: string;
id?: string; // Optional ID for anchor linking and scroll targets
}Description
A flexible content section displaying media (image/video) alongside text with optional statistics. Perfect for feature showcases and product highlights.
Example
{
type: "MediaContentBox",
props: {
title: "Powerful Analytics",
description: "Track your performance with real-time insights",
media: { type: "Image", props: { src: "https://plac