BentoGrid Component
Relevant source files
The following files were used as context for generating this wiki page:The BentoGrid component system is a shared UI module designed to create responsive, bento-style grid layouts. It consists of a container component, BentoGrid, and an item component, BentoCard. This system is architected to be highly reusable and customizable, separating the generic layout and interaction logic from the specific content and styling, which are provided at the implementation level.
A primary example of its use is the HomeBentoSection widget, which populates the grid with various content cards on the application's home page. The component features rich micro-interactions, including a mouse-aware spotlight effect, conditional rendering of CTAs based on device capabilities, and dynamic backgrounds.
Sources: src/shared/ui/BentoGrid/BentoGrid.tsx, src/widgets/HomeBentoSection/HomeBentoSection.tsx, src/pages/Home.tsx:13-15
Architecture and Components
The system is composed of two main React components: BentoGrid and BentoCard. They are designed to be used together to create a complete bento layout.
Sources: src/shared/ui/BentoGrid/BentoGrid.tsx:13-49
Component Hierarchy
The following diagram illustrates how the BentoGrid components are nested within a page structure.
This diagram shows that the Home page renders the HomeBentoSection widget, which in turn uses BentoGrid to lay out multiple BentoCard instances.
Sources: src/pages/Home.tsx:13-15, src/widgets/HomeBentoSection/HomeBentoSection.tsx:159-162
BentoGrid
The BentoGrid component is the main container. It is a simple div wrapper that applies foundational grid styling. It accepts a className prop to allow for customization of the grid's columns, rows, and gaps from the parent component.
Sources: src/shared/ui/BentoGrid/BentoGrid.tsx:13-25
Props
| Prop | Type | Description |
|---|---|---|
children | ReactNode | The BentoCard components to be rendered inside the grid. |
className | string | Additional CSS classes to be merged with the default styles, used for defining grid layout (cols, rows). |
Sources: src/shared/ui/BentoGrid/BentoGrid.tsx:9-11
BentoCard
The BentoCard is the core interactive element of the grid. It functions as a navigational link, rendering as either a react-router-dom <Link> for internal routes or a standard <a> tag for external URLs (detected if href starts with http or ends with .pdf). It is highly configurable through its props, supporting custom icons, backgrounds, and interaction behaviors.
Sources: src/shared/ui/BentoGrid/BentoGrid.tsx:51-52, src/shared/ui/BentoGrid/BentoGrid.tsx:210-233
Props
| Prop | Type | Default Value | Description |
|---|---|---|---|
name | string | - | The main title of the card. |
className | string | - | Additional CSS classes for custom styling and grid placement (e.g., col-span-2). |
background | ReactNode | - | A React node to be rendered as the card's background. Can be an <img>, a div with gradients, or another component. |
Icon | ElementType | - | The component or element type for the icon displayed on the card. |
description | string | - | The descriptive text content of the card. |
href | string | - | The URL for navigation. Determines if the card is an internal <Link> or external <a>. |
cta | string | - | The text for the call-to-action button. |
minimalCTA | boolean | false | If true, renders a smaller, icon-only CTA button. |
ctaIcon | ReactNode | - | A custom icon for the CTA button, overriding the default arrow. |
spotlightColor | string | rgba(255, 255, 255, 0.15) | The color of the radial gradient for the mouse-follow spotlight effect. |
ctaLayout | "bottom" | "side" | "bottom" | Defines the layout of the CTA on larger screens. "bottom" places it below the text, while "side" places it to the right. |
Sources: src/shared/ui/BentoGrid/BentoGrid.tsx:27-49
Interactive Features
The BentoCard includes several interactive features designed to enhance user experience.
Spotlight Effect
On mouse-enabled devices, a "spotlight" effect follows the cursor within the card's bounds. This is achieved by tracking the mouse position and applying a radial-gradient background overlay. The effect's opacity is animated on mouseEnter and mouseLeave.
The following diagram shows the sequence of events for the spotlight effect.
Responsive CTA Handling
The BentoCard intelligently displays its call-to-action (CTA) based on the user's device.
- Touch Devices (
pointer-coarse): A permanent, visible icon-only CTA is shown in the bottom-right corner. - Mouse Devices (
pointer-fine): The CTA is hidden by default and revealed on hover (group-hover). The reveal animation depends on thectaLayoutprop:bottom: The CTA fades and expands into view below the text content.side: The CTA fades and slides in from the right.
Sources: src/shared/ui/BentoGrid/BentoGrid.tsx:143-165, src/shared/ui/BentoGrid/BentoGrid.tsx:189-195
Implementation Example: HomeBentoSection
The HomeBentoSection widget provides a concrete implementation of the BentoGrid system. It defines a features array, where each object contains the props for a single BentoCard.
Sources: src/widgets/HomeBentoSection/HomeBentoSection.tsx:13-158
Data and Content Configuration
The content for the bento cards (titles, descriptions, CTAs) is sourced from a centralized content configuration file, promoting separation of content from presentation.
// src/shared/config/content.ts
export const homeContent = {
// ...
bento: {
profile: {
title: "Profile",
description: "Creative Full-stack Developer.",
cta: "About Me",
},
// ... other bento items
},
// ...
};
Sources: src/shared/config/content.ts:33-65
Grid and Card Instantiation
The widget instantiates the BentoGrid and provides responsive grid layout classes. It then maps over the features array to render each BentoCard, passing the configured props.
// src/widgets/HomeBentoSection/HomeBentoSection.tsx
export function HomeBentoSection() {
const features = [
{
Icon: User,
name: homeContent.bento.profile.title,
description: homeContent.bento.profile.description,
href: "/about",
cta: homeContent.bento.profile.cta,
className: "row-span-2 md:col-span-2 md:row-span-2",
background: (
<img /* ... */ />
),
},
// ... more feature objects
];
return (
<BentoGrid className="grid-cols-1 grid-rows-10 md:grid-cols-6 md:grid-rows-4 ...">
{features.map((feature, idx) => (
<BentoCard key={idx} {...feature} />
))}
</BentoGrid>
);
}
This example shows how className is used on BentoGrid to define the main grid structure and on each BentoCard to specify its individual span across rows and columns. The background prop is used to pass complex JSX, including images and other components like LogoLoop and DottedMap.
Sources: src/widgets/HomeBentoSection/HomeBentoSection.tsx:13-25, src/widgets/HomeBentoSection/HomeBentoSection.tsx:159-164
Conclusion
The BentoGrid component system is a flexible and interactive module for creating visually engaging grid layouts. Its architecture effectively separates the concerns of layout, interaction, and content. The BentoCard component is particularly powerful, offering a rich set of props for customization and featuring sophisticated micro-interactions like the spotlight effect and responsive CTA handling. The HomeBentoSection serves as a clear blueprint for how to consume and configure this system to build complex, content-rich UI sections.