Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
73f6f75
feat(bento-grid): add BentoGrid and BentoGridItem component implement…
carllosnc Nov 12, 2026
b421ac1
feat(bento-grid): add barrel export for BentoGrid
carllosnc Nov 12, 2026
007a5d5
test(bento-grid): add unit tests for BentoGrid and BentoGridItem
carllosnc Nov 12, 2026
41f146b
feat(dashkit): export BentoGrid in root barrel
carllosnc Nov 12, 2026
26a275e
feat(registry): register bento-grid component for CLI
carllosnc Nov 12, 2026
15e36eb
docs(llms): add BentoGrid to Layout & Containers category
carllosnc Nov 12, 2026
1e7d961
test(llms): update expected catalog component count to 56
carllosnc Nov 12, 2026
012e0fa
docs(bento-grid): add interactive MDX documentation page
carllosnc Nov 12, 2026
f61c0e4
feat(routes): add lazy route for BentoGridDocs
carllosnc Nov 12, 2026
d87748d
feat(router): register /docs/bento-grid route
carllosnc Nov 12, 2026
3bea9ce
docs(sidebar): add Bento Grid link to documentation sidebar
carllosnc Nov 12, 2026
010a710
docs(mdx): expose BentoGrid and BentoGridItem to MDX scope
carllosnc Nov 12, 2026
4a773ab
docs(components): add Bento Grid card to component overview grid
carllosnc Nov 12, 2026
97c93fe
docs(examples): add Bento Grid showcase to AllComponentsExample
carllosnc Nov 12, 2026
71251c1
chore(llms): update generated public/llms.txt
carllosnc Nov 12, 2026
0632e1f
chore(llms): update generated public/llms-full.txt
carllosnc Nov 12, 2026
a36a038
chore(registry): update generated public/registry.json
carllosnc Nov 12, 2026
e973c13
chore(cli): rebuild CLI bundle with bento-grid
carllosnc Nov 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion exec/cli.js

Large diffs are not rendered by default.

180 changes: 180 additions & 0 deletions public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,186 @@ Use the `type="multiple"` prop to allow more than one item to be expanded at the
| `className` | `string` | - | Custom styles for the container. |


## BentoGrid

- Category: Layout & Containers
- Slug: `bento-grid`
- Installation: `bunx carllosnc/dashkit add bento-grid`
- NPM Dependencies: `clsx`, `tailwind-merge`, `class-variance-authority`

A modular grid layout system for building regular and irregular Bento or Hairline grids while maintaining seamless `1px` shared border coherence across arbitrary column/row spans and responsive breakpoints.

### Installation

Add the BentoGrid component to your project using the Dashkit CLI:

```bash
bunx carllosnc/dashkit add bento-grid
```

### Import

```tsx
import { BentoGrid, BentoGridItem } from '@/dashkit/BentoGrid';
```

### Irregular Hairline Grid

By default, `BentoGrid` uses `gap="none"` to render a continuous `1px` hairline divider between cells without double borders—even when combining multi-row vertical spans (`rowSpan={2}`) and full-width spans (`colSpan="full"`).



01 / Ingestion

Edge Collector
Low-latency telemetry pipelines across 38 regions.




02 / Cache

99.98% Hit Rate
In-memory distributed read replicas.





03 / Architecture



1.42M req/s

Tall vertical cell spanning two rows alongside the 2x2 grid on the left, sharing a single 1px border on all sides.


cluster-us-east-primary



04 / Storage

Zero-Copy Snapshots
Instant branching for isolated preview environments.




05 / Security

mTLS Enforced
Automated certificate rotation every 24h.





06 / Full-Width Footer
Global Consensus Layer
Spans all 12 columns across the bottom while preserving a crisp 1px top divider.





```tsx
<BentoGrid cols={{ base: 1, sm: 2, lg: 12 }} autoRows="minmax(140px, auto)">
<BentoGridItem colSpan={{ base: 1, sm: 1, lg: 4 }}>Cell 1</BentoGridItem>
<BentoGridItem colSpan={{ base: 1, sm: 1, lg: 3 }}>Cell 2</BentoGridItem>
<BentoGridItem
colSpan={{ base: 1, sm: 2, lg: 5 }}
rowSpan={{ base: 1, lg: 2 }}
>
Cell 3 (Tall 2-Row Span)
</BentoGridItem>
<BentoGridItem colSpan={{ base: 1, sm: 1, lg: 4 }}>Cell 4</BentoGridItem>
<BentoGridItem colSpan={{ base: 1, sm: 1, lg: 3 }}>Cell 5</BentoGridItem>
<BentoGridItem colSpan="full">Cell 6 (Full Width)</BentoGridItem>
</BentoGrid>
```

### Sharp Architectural Wireframe (`rounded="none"`)

Set `rounded="none"` for a sharp editorial or architectural blueprint layout where every outer corner and inner intersection meets at 90 degrees.



col-span-4


col-span-3


col-span-5 / row-span-2


col-span-4


col-span-3


col-span-full



```tsx
<BentoGrid cols={{ base: 1, md: 12 }} rounded="none" autoRows="minmax(120px, auto)">
<BentoGridItem colSpan={{ base: 1, md: 4 }}>col-span-4</BentoGridItem>
<BentoGridItem colSpan={{ base: 1, md: 3 }}>col-span-3</BentoGridItem>
<BentoGridItem colSpan={{ base: 1, md: 5 }} rowSpan={{ base: 1, md: 2 }}>
col-span-5 / row-span-2
</BentoGridItem>
<BentoGridItem colSpan={{ base: 1, md: 4 }}>col-span-4</BentoGridItem>
<BentoGridItem colSpan={{ base: 1, md: 3 }}>col-span-3</BentoGridItem>
<BentoGridItem colSpan="full">col-span-full</BentoGridItem>
</BentoGrid>
```

### Spaced Bento Cards

Pass `gap="sm" | "md" | "lg"` when you want detached Bento cards instead of shared hairline borders.



Detached Bento Card (2 cols)
Automatically switches to individual card borders when gap is enabled.


Side Card (1 col)
Muted surface variant.



```tsx
<BentoGrid cols={3} gap="md">
<BentoGridItem colSpan={2}>Detached Bento Card</BentoGridItem>
<BentoGridItem colSpan={1} surface="muted">Side Card</BentoGridItem>
</BentoGrid>
```

### BentoGrid Props

| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `cols` | `BentoResponsiveValue` | `3` | Number of grid columns. Accepts a direct number (stacks on mobile, applies at md+) or a responsive breakpoint object ({ base, sm, md, lg, xl }). |
| `gap` | `'none' \| 'sm' \| 'md' \| 'lg'` | `'none'` | 'none' enables the seamless 1px hairline border mode. Other values separate items into individual bordered cards. |
| `bordered` | `boolean` | `true` | Whether to render the outer 1px perimeter border in hairline mode. |
| `rounded` | `'none' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'xl'` | Controls the outer corner radius of the grid container. |
| `autoRows` | `string` | - | Sets the CSS grid-auto-rows property (e.g., 'minmax(140px, auto)'). |

### BentoGridItem Props

| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `colSpan` | `BentoResponsiveValue<1..12 \| 'full'>` | `1` | Number of columns the cell spans. Accepts a direct value or a responsive breakpoint object. |
| `rowSpan` | `BentoResponsiveValue` | `1` | Number of rows the cell spans. Accepts a direct value or a responsive breakpoint object. |
| `surface` | `'card' \| 'background' \| 'muted' \| 'transparent'` | `'card'` | Semantic background surface color of the cell. |
| `padding` | `'none' \| 'sm' \| 'md' \| 'lg'` | `'md'` | Internal cell padding ('none' for full-bleed visuals, 'sm' = p-4, 'md' = p-6, 'lg' = p-8). |


## Card

- Category: Layout & Containers
Expand Down
1 change: 1 addition & 0 deletions public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Complete list of 55 production-ready components. For full API signatures, props
### Layout & Containers

- [Accordion](llms-full.txt#accordion): A vertically stacked list of headers that reveal associated content areas when clicked.
- [BentoGrid](llms-full.txt#bentogrid): A modular grid layout system for building regular and irregular Bento or Hairline grids while maintaining seamless `1px` shared border coherence across arbitrary column/row spans and responsive breakpoints.
- [Card](llms-full.txt#card): Dashkit's Card is designed as a **composed wrapper**, providing total layout control through granular sub-components.
- [Surface](llms-full.txt#surface): A lightweight, foundational component for creating containers with consistent background variants based on design system states. It provides a clean, borderless surface with no internal padding or margin, serving as a pure visual block.
- [Divider](llms-full.txt#divider): A versatile component used to separate sections of content with horizontal or vertical lines.
Expand Down
27 changes: 26 additions & 1 deletion public/registry.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Dashkit UI Registry",
"totalComponents": 55,
"totalComponents": 56,
"components": {
"accordion": {
"slug": "accordion",
Expand Down Expand Up @@ -188,6 +188,31 @@
"export interface BarChartProps {\r\n data: Record<string, string | number>[];\r\n series: BarChartSeries[];\r\n height?: number | string;\r\n className?: string;\r\n showGrid?: boolean;\r\n showLabels?: boolean;\r\n showTooltip?: boolean;\r\n animate?: boolean;\r\n barGap?: number;\r\n maxBarWidth?: number;\r\n rounded?: boolean;\r\n texture?: BarChartTexture;\r\n showTrack?: boolean;\r\n}"
]
},
"bento-grid": {
"slug": "bento-grid",
"name": "BentoGrid",
"category": "Layout & Containers",
"description": "A modular grid layout system for building regular and irregular Bento or Hairline grids while maintaining seamless `1px` shared border coherence across arbitrary column/row spans and responsive breakpoints.",
"installCommand": "bunx carllosnc/dashkit add bento-grid",
"files": [
"src/dashkit/BentoGrid/BentoGrid.tsx",
"src/dashkit/BentoGrid/index.ts"
],
"dependencies": [
"clsx",
"tailwind-merge",
"class-variance-authority"
],
"registryDependencies": [],
"exports": [
"BentoGrid",
"BentoGridItem"
],
"propsDefinitions": [
"export interface BentoGridProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof bentoGridVariants> {\n cols?: BentoResponsiveValue<BentoCols>;\n autoRows?: string;\n}",
"export interface BentoGridItemProps\n extends React.HTMLAttributes<HTMLDivElement>,\n Omit<VariantProps<typeof bentoGridItemVariants>, 'divided'> {\n colSpan?: BentoResponsiveValue<BentoColSpan>;\n rowSpan?: BentoResponsiveValue<BentoRowSpan>;\n}"
]
},
"breadcrumb": {
"slug": "breadcrumb",
"name": "Breadcrumb",
Expand Down
1 change: 1 addition & 0 deletions scripts/generate-llms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const CATEGORIES: ComponentCategory[] = [
name: 'Layout & Containers',
components: [
{ name: 'Accordion', slug: 'accordion', mdxFile: 'accordion.mdx' },
{ name: 'BentoGrid', slug: 'bento-grid', mdxFile: 'bento-grid.mdx' },
{ name: 'Card', slug: 'card', mdxFile: 'card.mdx' },
{ name: 'Surface', slug: 'surface', mdxFile: 'surface.mdx' },
{ name: 'Divider', slug: 'divider', mdxFile: 'divider.mdx' },
Expand Down
9 changes: 9 additions & 0 deletions scripts/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ export const registry: Record<string, ComponentConfig> = {
dependencies: ['clsx', 'tailwind-merge'],
registryDependencies: ['badge'],
},
'bento-grid': {
name: 'BentoGrid',
files: [
'src/dashkit/BentoGrid/BentoGrid.tsx',
'src/dashkit/BentoGrid/BentoGrid.test.tsx',
'src/dashkit/BentoGrid/index.ts'
],
dependencies: ['clsx', 'tailwind-merge', 'class-variance-authority'],
},
button: {
name: 'Button',
files: [
Expand Down
6 changes: 3 additions & 3 deletions scripts/tests/llms.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('LLMs Documentation Generator', () => {

expect(llmsContent.length).toBeGreaterThan(1000);
expect(llmsFullContent.length).toBeGreaterThan(10000);
expect(registryJson.totalComponents).toBeGreaterThanOrEqual(55);
expect(registryJson.totalComponents).toBeGreaterThanOrEqual(56);
expect(registryJson.components.button.name).toBe('Button');
expect(Array.isArray(registryJson.components.button.exports)).toBe(true);
});
Expand Down Expand Up @@ -57,7 +57,7 @@ describe('LLMs Documentation Generator', () => {
}
}

expect(totalCatalogComponents).toBe(55);
expect(totalCatalogComponents).toBe(56);
});

it('should resolve every catalog link anchor in llms.txt to an existing heading in llms-full.txt', () => {
Expand All @@ -70,7 +70,7 @@ describe('LLMs Documentation Generator', () => {
}

const linkAnchors = [...llmsContent.matchAll(/\(llms-full\.txt#([^)]+)\)/g)].map((m) => m[1]);
expect(linkAnchors.length).toBe(55);
expect(linkAnchors.length).toBe(56);

for (const anchor of linkAnchors) {
expect(fullHeadingAnchors.has(anchor), `Broken anchor link: #${anchor}`).toBe(true);
Expand Down
109 changes: 109 additions & 0 deletions src/dashkit/BentoGrid/BentoGrid.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import * as React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { BentoGrid, BentoGridItem } from './index';

describe('BentoGrid', () => {
it('renders grid and items with default hairline border coherence classes', () => {
render(
<BentoGrid data-testid="grid">
<BentoGridItem>Cell 1</BentoGridItem>
<BentoGridItem>Cell 2</BentoGridItem>
</BentoGrid>
);

const grid = screen.getByTestId('grid');
const cell1 = screen.getByText('Cell 1');

expect(grid).toHaveAttribute('data-slot', 'bento-grid');
expect(grid).toHaveClass('grid', 'gap-px', 'bg-border', 'border', 'border-border', 'rounded-xl');
expect(grid).toHaveClass('grid-cols-1', 'md:grid-cols-3');

expect(cell1).toHaveAttribute('data-slot', 'bento-grid-item');
expect(cell1).toHaveClass('bg-card', 'p-6', 'ring-1', 'ring-border', 'col-span-1', 'row-span-1');
});

it('supports numeric cols, colSpan, and rowSpan with mobile-first responsive defaults', () => {
render(
<BentoGrid data-testid="grid" cols={12}>
<BentoGridItem colSpan={4} rowSpan={2}>
Irregular Cell
</BentoGridItem>
<BentoGridItem colSpan="full">
Footer Cell
</BentoGridItem>
</BentoGrid>
);

const grid = screen.getByTestId('grid');
const irregular = screen.getByText('Irregular Cell');
const footer = screen.getByText('Footer Cell');

expect(grid).toHaveClass('grid-cols-1', 'md:grid-cols-12');
expect(irregular).toHaveClass('col-span-full', 'md:col-span-4', 'row-span-1', 'md:row-span-2');
expect(footer).toHaveClass('col-span-full');
});

it('supports responsive breakpoint objects for cols, colSpan, and rowSpan', () => {
render(
<BentoGrid data-testid="grid" cols={{ base: 1, sm: 2, md: 4, lg: 12 }}>
<BentoGridItem
colSpan={{ base: 1, sm: 2, md: 2, lg: 5 }}
rowSpan={{ base: 1, lg: 2 }}
>
Responsive Cell
</BentoGridItem>
</BentoGrid>
);

const grid = screen.getByTestId('grid');
const cell = screen.getByText('Responsive Cell');

expect(grid).toHaveClass('grid-cols-1', 'sm:grid-cols-2', 'md:grid-cols-4', 'lg:grid-cols-12');
expect(cell).toHaveClass(
'col-span-1',
'sm:col-span-2',
'md:col-span-2',
'lg:col-span-5',
'row-span-1',
'lg:row-span-2'
);
});

it('applies rounded, bordered, gap, and autoRows props correctly', () => {
render(
<BentoGrid
data-testid="grid"
rounded="none"
bordered={false}
gap="md"
autoRows="minmax(180px, auto)"
>
<BentoGridItem surface="muted" padding="sm">
Spaced Cell
</BentoGridItem>
</BentoGrid>
);

const grid = screen.getByTestId('grid');
const cell = screen.getByText('Spaced Cell');

expect(grid).toHaveClass('rounded-none', 'border-0', 'gap-4');
expect(grid).toHaveStyle({ gridAutoRows: 'minmax(180px, auto)' });
expect(cell).toHaveClass('bg-muted/60', 'p-4', 'border', 'border-border', 'rounded-xl');
});

it('forwards refs to BentoGrid and BentoGridItem', () => {
const gridRef = React.createRef<HTMLDivElement>();
const itemRef = React.createRef<HTMLDivElement>();

render(
<BentoGrid ref={gridRef}>
<BentoGridItem ref={itemRef}>Ref Cell</BentoGridItem>
</BentoGrid>
);

expect(gridRef.current).toBeInstanceOf(HTMLDivElement);
expect(itemRef.current).toBeInstanceOf(HTMLDivElement);
});
});
Loading
Loading