Container

Layout wrapper with consistent max-width and responsive padding. Supports full-bleed backgrounds with theme control.

API Reference

PropTypeDefault
as"div" | "section" | "header" | "footer""div"
bg"root" | "root-contrast" | "root-100" | "root-100-contrast" | "root-200" | "root-200-contrast"
themeTheme

Backgrounds

root

bg-root

root-100

bg-root-100

root-200

bg-root-200

root-contrast

bg-root-contrast

<Container bg="root">...</Container>
<Container bg="root-100">...</Container>
<Container bg="root-200">...</Container>
<Container bg="root-contrast">...</Container>

Theme

Pass a theme class (e.g. "dark") to apply it to the wrapper element. Combine with bg for full-bleed themed sections.

<Container theme="dark" bg="root">
  <Heading>Dark section</Heading>
</Container>

Structure

Without bg or theme, renders a single element. With either, renders an outer wrapper for the background and an inner div for the constrained content.

// Single element
<Container>...</Container>
// → <div class="container mx-auto px-6 lg:px-8">...</div>

// Two elements (full-bleed background)
<Container bg="root-100">...</Container>
// → <div class="bg-root-100">
//     <div class="container mx-auto px-6 lg:px-8">...</div>
//   </div>

Basic Usage

import { Container } from "@/ui";

<Container>
  Content
</Container>

Source

src/ui/Container.tsx
import { cn } from "@/utils";
import type { Theme } from "@/types";

interface ContainerProps {
  as?: "div" | "section" | "header" | "footer";
  theme?: Theme;
  bg?:
    | "root"
    | "root-contrast"
    | "root-100"
    | "root-100-contrast"
    | "root-200"
    | "root-200-contrast";
  className?: string;
  children: React.ReactNode;
}

const bgClass = {
  root: "bg-root",
  "root-contrast": "bg-root-contrast",
  "root-100": "bg-root-100",
  "root-100-contrast": "bg-root-100-contrast",
  "root-200": "bg-root-200",
  "root-200-contrast": "bg-root-200-contrast",
} as const;

const containerClasses = "container mx-auto px-6 lg:px-8";

export function Container({
  as: Tag = "div",
  theme,
  bg,
  className,
  children,
}: ContainerProps) {
  const needsWrapper = theme || bg;

  if (!needsWrapper) {
    return (
      <Tag className={cn(containerClasses, className)}>
        {children}
      </Tag>
    );
  }

  return (
    <Tag className={cn(theme, bg && bgClass[bg])}>
      <div className={cn(containerClasses, className)}>
        {children}
      </div>
    </Tag>
  );
}