Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsLayout Blocks

Grid

A CSS-grid layout primitive with static and responsive column counts, gap presets, flow control, and per-cell placement via GridItem. Polymorphic render, RTL, and no hard-coded tokens.

Playground

Installation

pnpm add @tessinaui/ui

Usage

import { Grid, GridItem } from "@tessinaui/ui";
{/* Fixed 3-column grid */}
<Grid cols={3} gap="md">
  <Card>One</Card>
  <Card>Two</Card>
  <Card>Three</Card>
</Grid>

{/* Responsive columns */}
<Grid cols={{ base: 1, sm: 2, md: 3, lg: 4 }} gap="sm">
  {items.map((item) => <Card key={item.id}>{item.title}</Card>)}
</Grid>

{/* Cell placement with GridItem */}
<Grid cols={4} rows={3} gap="sm">
  <GridItem colSpan={2} rowSpan={2}>
    <Card>Featured</Card>
  </GridItem>
  <Card>1</Card>
  <Card>2</Card>
  <Card>3</Card>
  <Card>4</Card>
</Grid>

{/* Explicit line placement */}
<Grid cols={6}>
  <GridItem colStart={2} colEnd={5}>
    <Hero />
  </GridItem>
</Grid>

{/* Dense flow backfills gaps */}
<Grid cols={4} flow="dense" gap="sm">
  <GridItem colSpan={2}>Wide</GridItem>
  <Card>Auto</Card>
  <Card>Auto</Card>
</Grid>

Showcase

Columns

Pass a number for a fixed count, or a breakpoint object for responsive layouts.

<Grid cols={3}>…</Grid>
<Grid cols={{ base: 1, sm: 2, md: 3, lg: 4, xl: 6 }}>…</Grid>

Supported column counts: 1 through 12. Supported breakpoints: base, sm, md, lg, xl.

Rows

ValueCSS mapping
1–6grid-rows-1 – grid-rows-6

Explicit row counts are usually only needed when using rowSpan or rowStart/rowEnd.

Gap

Seven presets that map to Tailwind's spacing scale.

ValueTailwindpx
"none"gap-00
"xs"gap-14
"sm"gap-28
"md" (default)gap-416
"lg"gap-624
"xl"gap-832
"2xl"gap-1248

For independent axis control use rowGap and columnGap — they accept the same seven values and override gap on their respective axis.

Flow

Controls how auto-placed items fill the grid.

ValueCSS mapping
"row"grid-flow-row — fill row by row (default)
"col"grid-flow-col — fill column by column
"dense"grid-flow-dense — backfill gaps with smaller items
"row-dense"grid-flow-row-dense
"col-dense"grid-flow-col-dense

Alignment

PropCSSValues
alignItemsalign-itemsstart / center / end / stretch / baseline
justifyItemsjustify-itemsstart / center / end / stretch
alignContentalign-contentstart / center / end / stretch
justifyContentjustify-contentstart / center / end / stretch

Inline

inline={true} swaps grid for inline-grid so the container flows alongside surrounding inline content.

Polymorphic render

Clone a semantic element while keeping Grid styling.

<Grid render={<ul aria-label="Tiles" />} cols={3} gap="md">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</Grid>

GridItem

Per-cell placement and alignment helpers. GridItem is optional — you can always apply col-span-* / row-span-* directly with className.

colSpan / rowSpan

ValueCSS
"auto"col-auto / row-auto
"full"col-span-full / row-span-full
1–12col-span-n / row-span-n (row max 6)

colStart / colEnd / rowStart / rowEnd

Explicit grid-line placement. Start values accept "auto" or 1–13. End values accept "auto" or 1–13.

<GridItem colStart={2} colEnd={5}>…</GridItem>

alignSelf / justifySelf

Per-cell override of the parent's alignItems / justifyItems.

<GridItem alignSelf="end" justifySelf="center">…</GridItem>

RTL

dir="rtl" is forwarded to the DOM node. In RTL, columns are laid out right-to-left, mirroring the logical column order.

Accessibility

  • Grid is a structural primitive — it applies no ARIA roles.
  • Use render to mount semantic HTML (<ul>, <section>, <main>) when the grouping has meaning.
  • Reordering via colStart/rowStart separates visual order from DOM order. Keep DOM order logical — screen readers and keyboard navigation follow source order, not visual order.

When to use Grid vs. Flex

Use Grid when…Use Flex when…
You have a two-dimensional layoutYou have a one-dimensional layout
Items should align on both axesOnly the main axis matters
You need equal-width columns without basis mathItem widths vary by content
You want explicit cell placement (colStart, rowSpan)Items flow naturally

API Reference

Grid Props

PropTypeDefaultDescription
cols1..12 or { base, sm, md, lg, xl }—Column count (fixed or responsive)
rows1..6—Row count
gap"none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl""md"Both-axis gap
rowGapSame as gap—Vertical gap (overrides gap)
columnGapSame as gap—Horizontal gap (overrides gap)
flow"row" | "col" | "dense" | "row-dense" | "col-dense"—grid-auto-flow
alignItems"start" | "center" | "end" | "stretch" | "baseline"—align-items
justifyItems"start" | "center" | "end" | "stretch"—justify-items
alignContent"start" | "center" | "end" | "stretch"—align-content
justifyContent"start" | "center" | "end" | "stretch"—justify-content
inlinebooleanfalseUse inline-grid
renderReactElement—Polymorphic target
dir"ltr" | "rtl"—Text direction
classNamestring—Extra classes

GridItem Props

PropTypeDefaultDescription
colSpan"auto" | "full" | 1..12—grid-column: span n
rowSpan"auto" | "full" | 1..12—grid-row: span n
colStart"auto" | 1..13—grid-column-start
colEnd"auto" | 1..13—grid-column-end
rowStart"auto" | 1..13—grid-row-start
rowEnd"auto" | 1..13—grid-row-end
alignSelf"auto" | "start" | "center" | "end" | "stretch" | "baseline"—align-self
justifySelf"auto" | "start" | "center" | "end" | "stretch"—justify-self
renderReactElement—Polymorphic target
dir"ltr" | "rtl"—Text direction
classNamestring—Extra classes

Notes

  • No intrinsic padding. Grid only controls layout — add padding, borders, background via className.
  • No SSR caveats. Grid is a pure wrapper with no hooks; safe to render server-side.
  • Static class names. All CSS class names are resolved at compile time — Tailwind's JIT sees them.
  • Arbitrary values. If you need something outside the presets (e.g. cols={18}, gap="7"), drop to className="grid-cols-[18] gap-[28px]".

Flex

A low-level flexbox layout primitive that exposes the full flex API — four directions, three wrap modes, independent row and column gap, align-items, justify-content, align-content, inline mode, polymorphic render, and LTR/RTL. Ships with FlexItem for per-child grow, shrink, basis, order, and alignSelf control.

AspectRatio

Constrains content to a specific width/height ratio using CSS aspect-ratio. Seven named presets, arbitrary string or numeric ratios, eight corner-radius presets, automatic object-fit on single media children, and polymorphic render.

On this page

PlaygroundInstallationUsageShowcaseColumnsRowsGapFlowAlignmentInlinePolymorphic renderGridItemcolSpan / rowSpancolStart / colEnd / rowStart / rowEndalignSelf / justifySelfRTLAccessibilityWhen to use Grid vs. FlexAPI ReferenceGrid PropsGridItem PropsNotes