Article Layout
Long-form article layout for blog posts, case studies, and docs
Overview
A compound component for rendering a complete blog article page. Each sub-component can be used independently within the root ArticleLayout wrapper.
Usage
import { ArticleLayout } from '@leanicon/web-builder-library'Default (overlay hero)
The "overlay" variant (default) renders the title over a gradient overlay on the hero image.
How to Build a Design System from Scratch
Building a design system is one of the most impactful investments a product team can make. It creates a shared language between designers and developers, accelerates feature development, and ensures consistency across your product.
Why You Need a Design System
As products grow in complexity, maintaining visual consistency becomes increasingly difficult. A design system solves this by providing reusable components and clear guidelines.
Getting Started
Start with a thorough audit of your existing UI. Identify patterns that repeat across your product and document them. These become the foundation of your component library.
Clean hero
The "clean" variant places the title above the image with a back link, author name, share icons, and category badge in a single row.
Today we are excited to announce Tiny Aya, a new family of lightweight multilingual models that make AI accessible to more languages and communities worldwide.
Why Multilingual AI Matters
The vast majority of the world communicates in languages other than English, yet most AI models are predominantly trained on English data. Tiny Aya bridges this gap.
LeanIcon Labs Team
Research Division at LeanIcon
LeanIcon Labs is dedicated to advancing multilingual AI research for the benefit of all communities.
Clean hero — minimal
Clean variant with only title, date, and image — no back link, author, share icons, or category.
A Brief Update on Our Research Roadmap
We are sharing our updated research roadmap for the coming year, focusing on efficiency, safety, and multilingual capabilities.
With table of contents
Place ArticleLayout.TableOfContents before the Body to render a collapsible TOC on mobile and a sticky sidebar on desktop (xl+). Items are passed as props — heading IDs must match. Best suited for long-form articles with many sections.
Building a design system is one of the most impactful investments a product team can make. It creates a shared language between designers and developers, accelerates feature development, and ensures visual consistency across every surface of your product. Yet many teams struggle with where to begin, how to structure their system, and how to drive adoption across the organization.
This guide walks through the full lifecycle of building a design system from scratch — from the initial audit through governance and measuring success.
The Case for Design Systems
Before diving into implementation, it is worth understanding why design systems matter. The benefits extend far beyond aesthetics — they touch engineering velocity, product quality, accessibility, and brand coherence.
Consistency at Scale
As products grow from a handful of screens to hundreds, maintaining visual consistency becomes exponentially harder. Without a shared component library, teams inevitably drift — one squad uses 14px body text while another uses 16px, buttons come in subtly different border radii, and spacing becomes a game of guesswork.
A design system provides a single source of truth. Every component, token, and pattern is defined once and consumed everywhere. When you need to update the primary brand color, you change it in one place and every surface updates automatically.
Developer Velocity
Engineers spend a surprising amount of time recreating UI patterns from scratch. A modal dialog that took three days to build on the settings page gets rebuilt from zero on the billing page because no one knew the first implementation existed.
Teams that adopt mature design systems report 30-50% faster feature development for UI-heavy work. Instead of debating pixel values in pull requests, developers compose pre-built, pre-tested primitives and focus on business logic.
Laying the Foundation
Every successful design system starts with a thorough understanding of the current state. Resist the temptation to jump straight into building components — the discovery phase is where you build the mental model that will guide every decision downstream.
Auditing Your Existing UI
Take screenshots of every unique screen in your product and print them out. Group similar patterns together — buttons, form fields, cards, navigation elements. This visual inventory reveals where inconsistencies live and which patterns are most commonly repeated.
Pay special attention to near-duplicates: components that look almost identical but differ in subtle ways. A typical audit reveals 5-15 button variants when 3-4 would suffice, and dozens of spacing values when a disciplined scale of 8-12 would cover every use case.
Defining Design Tokens
Design tokens are the atomic values that form the foundation of your visual language: colors, spacing, typography scales, border radii, shadows, and animation curves. They are the lowest layer of your system and the most important to get right.
Structure your tokens in three tiers. Global tokens define the raw palette.Semantic tokens assign meaning. Component tokens scope values to specific components. This three-tier model makes theming straightforward — swap the semantic layer and every component updates.
Building Core Components
With your tokens defined and your audit complete, it is time to start building. The key is to work from the bottom up, starting with the simplest primitives and composing them into increasingly complex patterns. Start with Button, Input, Select, Checkbox, Radio, Badge, Avatar, and Typography.
Each primitive should accept a variant prop powered by a library like Class Variance Authority (CVA). This gives consumers a type-safe API for switching between visual treatments while keeping the underlying DOM and behavior identical.
Documentation and Governance
A design system without documentation is just a component library that nobody uses. Tools like Storybook let you create interactive documentation that stays in sync with your code. Every component should have stories that cover its full API surface.
Define a clear process for proposing, reviewing, and shipping new components. At minimum, you need: a request template, a design review checkpoint, an engineering review with accessibility and performance checks, and a documentation requirement before merge.
Adoption Strategy
Building a design system is only half the battle — the other half is getting people to use it. Start by integrating the system into the project scaffolding. When someone spins up a new feature, the design system should already be there — imported, configured, and ready.
For existing code, adopt a "strangler fig" approach: don't rewrite everything at once. Instead, replace one-off implementations with system components as you touch those areas for feature work. Over time, the old patterns shrink and the system becomes the default.
Measuring Success
Define metrics that matter to your organization. Common design system KPIs include: component adoption rate, time-to-ship for new features, visual regression counts, accessibility audit scores, and developer satisfaction measured via periodic surveys.
Track these metrics over time, not as one-off snapshots. A healthy design system shows increasing adoption, decreasing visual bugs, and stable or improving developer sentiment.
Conclusion
A design system is a living product, not a one-time project. It requires ongoing investment in maintenance, documentation, and community engagement. Start small, stay disciplined, and optimize for adoption over completeness. A system with ten well-documented, widely-used components is infinitely more valuable than one with a hundred components that nobody trusts.
With table of contents — dark
Building a design system is one of the most impactful investments a product team can make. It creates a shared language between designers and developers, accelerates feature development, and ensures visual consistency across every surface of your product.
This guide walks through the full lifecycle of building a design system from scratch — from the initial audit through governance and measuring success.
The Case for Design Systems
Before diving into implementation, it is worth understanding why design systems matter. The benefits extend far beyond aesthetics — they touch engineering velocity, product quality, accessibility, and brand coherence.
Consistency at Scale
As products grow from a handful of screens to hundreds, maintaining visual consistency becomes exponentially harder. A design system provides a single source of truth. Every component, token, and pattern is defined once and consumed everywhere.
Developer Velocity
Teams that adopt mature design systems report 30-50% faster feature development for UI-heavy work. Instead of debating pixel values in pull requests, developers compose pre-built, pre-tested primitives and focus on business logic.
Laying the Foundation
Every successful design system starts with a thorough understanding of the current state. Resist the temptation to jump straight into building components — the discovery phase is where you build the mental model that will guide every decision downstream.
Take screenshots of every unique screen in your product. Group similar patterns together. Pay special attention to near-duplicates: components that look almost identical but differ in subtle ways. A typical audit reveals 5-15 button variants when 3-4 would suffice.
Building Core Components
With your tokens defined and your audit complete, it is time to start building. The key is to work from the bottom up, starting with the simplest primitives — Button, Input, Select, Checkbox, Radio, Badge, Avatar — and composing them into increasingly complex patterns.
Documentation and Governance
A design system without documentation is just a component library that nobody uses. Tools like Storybook let you create interactive documentation that stays in sync with your code. Define a clear process for proposing, reviewing, and shipping new components.
Adoption Strategy
Building a design system is only half the battle — the other half is getting people to use it. For existing code, adopt a "strangler fig" approach: replace one-off implementations with system components as you touch those areas for feature work.
Measuring Success
Define metrics that matter to your organization. Common design system KPIs include: component adoption rate, time-to-ship for new features, visual regression counts, accessibility audit scores, and developer satisfaction.
Conclusion
A design system is a living product, not a one-time project. Start small, stay disciplined, and optimize for adoption over completeness. A system with ten well-documented, widely-used components is infinitely more valuable than one with a hundred that nobody trusts.
Minimal article
Just hero and body — no meta, author card, or related posts.
A Short Note on CSS Custom Properties
CSS custom properties (also known as CSS variables) are entities defined by CSS authors that contain specific values to be reused throughout a document.
They are set using custom property notation and are accessed using the var() function.
Without author avatar
When avatar is omitted, the AvatarFallback renders initials derived from the author name.
Getting Started with React Server Components
React Server Components are changing how we think about rendering in React applications. They allow us to run components on the server, reducing the JavaScript sent to the client.
Alex Rivera
UI Engineer at LeanIcon
Alex specializes in frontend performance and React architecture.
Related posts with images
The RelatedPosts sub-component renders a 3-column grid. Posts with image show a thumbnail; without it, only title and date are shown.
Building Accessible Components
Accessibility should be built into every component from the start, not added as an afterthought. This guide covers the key patterns every component library should implement.
Dark mode — overlay hero
Dark Mode Design Considerations
Dark mode has become a standard expectation for modern applications. This article covers best practices for implementing dark mode in your design system.
Dark mode — clean hero
Today we are excited to announce Tiny Aya, a new family of lightweight multilingual models that make AI accessible to more languages and communities worldwide.
Why Multilingual AI Matters
The vast majority of the world communicates in languages other than English, yet most AI models are predominantly trained on English data. Tiny Aya bridges this gap.
Sub-components
ArticleLayout.Hero
Prop | Type | Default | Description |
|---|---|---|---|
|
| — | Article title (required) |
|
| — | Publication date (required) |
|
|
|
|
|
| — | Hero image |
|
| — | Badge label |
|
| — | Back navigation link (clean variant) |
|
| — | Author name shown in meta row (clean variant) |
|
| — | Social share icons (clean variant) |
ArticleLayout.Meta
Prop | Type | Default | Description |
|---|---|---|---|
|
| — | Author info with avatar |
|
| — | Estimated read time label |
ArticleLayout.Body
Prop | Type | Default | Description |
|---|---|---|---|
|
| — | Legacy JSX content — rendered inside a |
|
| — | Structured content blocks (takes precedence over |
|
| — | Override map to replace default renderers for specific block types |
|
| — | Additional CSS classes merged into the prose container |
ArticleLayout.Author
Prop | Type | Default | Description |
|---|---|---|---|
|
| — | Author name (required) |
|
| — | Author avatar |
|
| — | Role / job title |
|
| — | Short biography |
|
| — | Links displayed below the bio |
ArticleLayout.RelatedPosts
Prop | Type | Description |
|---|---|---|
|
| Array of related post cards |
RelatedPost: { title: string; href: string; image?: ImageProps; date: string }
ArticleLayout.TableOfContents
Prop | Type | Default | Description |
|---|---|---|---|
|
| — | CMS-provided heading list (required) |
|
|
| Nav heading text |
|
|
| Pixels from viewport top for active heading calc |
|
| — | Additional CSS classes |
TocItem: { id: string; text: string; level: number }
ArticleLayout (root)
Prop | Type | Default | Description |
|---|---|---|---|
|
| — | Force light or dark mode |
|
| — | Additional CSS classes on root |
|
| — | Sub-components |
Structured content blocks
When blog content comes from a CMS as structured blocks, use the blocks prop instead of children. The library provides default renderers for all block types. Override specific renderers via the components prop.
With structured blocks
Building a design system is one of the most impactful investments a product team can make. It creates a shared language between designers and developers.
Why You Need a Design System
As products grow in complexity, maintaining visual consistency becomes increasingly difficult. A design system solves this by providing reusable components and clear guidelines.
A design system is not a project. It is a product, serving products.
export const colors = {
primary: "hsl(222.2 47.4% 11.2%)",
"primary-foreground": "hsl(210 40% 98%)",
muted: "hsl(210 40% 96.1%)",
} as const;Conclusion
A design system is a living product, not a one-time project. Start small, stay disciplined, and optimize for adoption over completeness.
With structured blocks — dark
Building a design system is one of the most impactful investments a product team can make. It creates a shared language between designers and developers.
Why You Need a Design System
As products grow in complexity, maintaining visual consistency becomes increasingly difficult.
A design system is not a project. It is a product, serving products.
export const colors = {
primary: "hsl(222.2 47.4% 11.2%)",
muted: "hsl(210 40% 96.1%)",
} as const;Conclusion
Start small, stay disciplined, and optimize for adoption over completeness.
Block types
Block type | Properties | Default renderer |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All blocks share type: string and key: string fields. Unknown block types log a dev warning and render nothing.
Overriding block renderers
import Image from 'next/image'
;<ArticleLayout.Body
blocks={post.blocks}
components={{
// Override the image renderer with next/image
image: ({ block }) => (
<figure className="my-8">
<Image
src={block.src}
alt={block.alt}
width={block.width ?? 1200}
height={block.height ?? 630}
className="w-full "
/>
{block.caption && (
<figcaption className="mt-2 text-center text-sm text-muted-foreground">
{block.caption}
</figcaption>
)}
</figure>
),
// Override the code renderer with Shiki
code: ({ block }) => <ShikiCodeBlock code={block.code} lang={block.language} />,
}}
/>Notes
ArticleLayout.Bodyappliesprose prose-neutral dark:prose-invert— ensure Tailwind Typography is installed.- The overlay hero renders a gradient overlay (
from-overlay/60 to-transparent) when an image is present; without an image it falls back to a plain header. - The clean hero only shows
backLink,author, andshareLinkswhen those props are provided. - Author initials are derived from the first letter of each word in the name (max 2 characters).
shareLinkssupports"twitter"/"x"and"linkedin"platforms with built-in icons.- Dark mode: pass
colorScheme="dark"to the root or place inside a.darkancestor.
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
colorScheme | enum | — | No | |
className | string | — | No | |
title | string | — | Yes | |
image | ImageProps | — | No | |
category | string | — | No | |
date | string | — | Yes | |
dateTime | string | — | No | ISO 8601 value for the rendered `<time>` element (e.g. raw `publishedAt`). |
variant | enum | overlay | No | |
backLink | { label: string; href: string; } | — | No | |
author | { name: string; avatar?: ImageProps; } | — | No | |
shareLinks | SocialLink[] | — | No | |
headingLevel | enum | h1 | No | h1 when the layout IS the page surface (default); h2 when embedded under a page h1 (spec 007 D7). |
priority | boolean | true | No | The hero image is the LCP candidate when the layout IS the page surface (default). Pass false when embedded below other media. |
readTime | string | — | No | |
blocks | BlogContentBlock[] | — | No | |
components | BlogContentBlockComponents | — | No | |
name | string | — | Yes | |
avatar | ImageProps | — | No | |
bio | string | — | No | |
socialLinks | SocialLink[] | — | No | |
posts | ArticleLayoutRelatedPost[] | — | Yes | |
items | TocItem[] | — | Yes | |
label | string | On this page | No | |
topOffset | number | 96 | No |