Nesting Containers Guide

A comprehensive guide to understanding and implementing the container nesting system in our design system.

Overview

Our design system uses a systematic approach to nesting containers that provides consistent spacing, layout, and content hierarchy. This system ensures predictable layouts while maintaining flexibility for different content types.

The container architecture follows a clear hierarchy from root layout to individual content examples, with each level having specific responsibilities and styling patterns.

Container Architecture

The layout of the CircuitDS documentation pages follows a consistent structure, from the overall application frame down to individual component examples.

Visual Container Hierarchy

Simplified visual representation of how containers typically nest within each other on a documentation page.

See code block below for the hierarchy structure.

// Your App's Main Layout (e.g., app/(circuitds)/circuitds/layout.tsx)
<div className="circuitds-layout-container">
  <AppNavigation /> {/* Sidebar Navigation */}
  <main className="circuitds-main-content">
    {/* PageLayout will be rendered here by Next.js for each page */}
    <PageLayout title="Page Title" description="Page description.">
      <ContentSection title="Section Title">
        <ExampleShowcase
          title="Example Title"
          description="Example description."
          preview={"<p>Preview Area Content</p>"} 
          code={"<YourComponent />"} 
        />
        {/* More ExampleShowcases */}
      </ContentSection>
      {/* More ContentSections */}
    </PageLayout>
  </main>
</div>

Core Layout Components

These are the primary components responsible for page structure and content organization.

AppNavigation & Main Layout Structure

The root layout for CircuitDS pages, providing the sidebar and the main content area that hosts individual page layouts. This is primarily defined in app/(circuitds)/circuitds/layout.tsx and its associated CSS.

// Simplified from app/(circuitds)/circuitds/layout.tsx
export default function CircuitDSLayout({ children }) {
  return (
    <div className="circuitds-layout-container">
      <AppNavigation
        navTitle="CircuitDS"
        items={...} // your nav items
        // ... other props
      />
      <main className="circuitds-main-content">
        {children}
      </main>
    </div>
  );
}

/* Relevant CSS (app/styles/circuitds-layout.css) */
.circuitds-layout-container {
  display: flex;
  height: calc(100vh - var(--header-height, 0px));
  /* ... */
}
.circuitds-sidebar { /* Class used by AppNavigation's wrapper if baseNavClass is set */
  width: 260px;
  padding: var(--sds-size-space-600);
  /* ... */
}
.circuitds-main-content {
  flex: 1;
  padding: var(--sds-size-space-800); /* Overall content padding */
  overflow-y: auto;
  /* ... */
}

PageLayout Component

Wraps the entire content of a single documentation page, providing the main title, description, and a container for content sections. (components/layout/PageLayout.tsx)

// From components/layout/PageLayout.tsx
export default function PageLayout({ title, description, children }) {
  return (
    <article className="page-layout">
      <header className="page-layout-header">
        <h1 className="page-title">{title}</h1>
        {description && <p className="page-description">{description}</p>}
      </header>
      <div className="page-layout-content">
        {children}
      </div>
    </article>
  );
}

/* Relevant CSS (app/styles/page-layout.css) */
.page-layout-header {
  margin-bottom: var(--sds-size-space-600); /* Space after header */
  padding-bottom: var(--sds-size-space-400); /* Space before border */
  border-bottom: var(--sds-size-stroke-border) solid var(--border-subtle);
}
/* .page-layout-content has no specific padding/margin by default,
   it relies on .circuitds-main-content for outer padding
   and ContentSection for inner structure. */

ContentSection Component

Groups related content or examples under a common heading within a page. These are visually distinct bordered sections. (components/layout/ContentSection.tsx)

// From components/layout/ContentSection.tsx
export default function ContentSection({ title, children, headingLevel = 2 }) {
  // ... heading render logic ...
  return (
    <section className="content-section">
      {renderHeading()}
      <div className="content-section-body">
        {children}
      </div>
    </section>
  );
}

/* Relevant CSS (app/styles/content-section.css) */
.content-section {
  margin-bottom: var(--sds-size-space-800); /* Space after each section */
  padding: var(--sds-size-space-600); /* Internal padding */
  border: var(--sds-size-stroke-border) solid var(--border-default);
  border-radius: var(--sds-size-radius-200);
  background-color: var(--surface-background);
  overflow: hidden;
}
.content-section-title {
  margin-bottom: var(--sds-size-space-400); /* Space after title, before content body */
}
.content-section-body {
  display: flex;
  flex-direction: column;
  gap: var(--sds-size-space-600); /* Handles spacing between direct children */
}

/* List styling within content sections */
.content-section .list-disc {
  list-style-type: disc;
  padding-left: var(--sds-size-space-800); /* 32px - Standard indentation for lists */
  margin: 0;
}
.content-section .list-circle {
  list-style-type: circle;
  padding-left: var(--sds-size-space-800); /* 32px - Consistent with list-disc */
  margin: 0;
}

/* Example usage:
<ul className="list-disc">
  <li>First level bullet point</li>
  <ul className="list-circle">
    <li>Second level bullet point</li>
  </ul>
</ul>
*/

ExampleShowcase Component

Displays individual examples, typically including a title, description, a live preview area, and a code snippet. (components/layout/ExampleShowcase.tsx)

// From components/layout/ExampleShowcase.tsx
export default function ExampleShowcase({ title, description, preview, code, ...rest }) {
  // ...
  return (
    <div className="example-showcase" {...rest}>
      {/* Header (title, description) */}
      {/* Preview */}
      {/* Code block */}
    </div>
  );
}

/* Relevant CSS (app/styles/example-showcase.css) */
.example-showcase {
  /* margin-bottom: var(--sds-size-space-600); */ /* Removed: Spacing now typically handled by parent ContentSection's gap */
  border: var(--sds-size-stroke-border) solid var(--border-default);
  border-radius: var(--sds-size-radius-200);
  background-color: var(--surface-container-level-1, var(--surface-background-subtle));
  overflow: hidden;
}
.example-showcase-header {
  padding: var(--sds-size-space-500);
  /* ... */
}
.example-showcase-preview {
  padding: var(--sds-size-space-600);
  /* ... */
}
.example-showcase-code-block {
  padding: var(--sds-size-space-500);
  border-top: var(--sds-size-stroke-border) solid var(--border-default);
  /* ... */
}

Spacing & Sizing System

Design Token Usage

Our containers use a system of CSS custom properties (design tokens) for consistent spacing. Key tokens include: - `--sds-size-space-200`: 8px (Tight spacing, e.g., gap within a header) - `--sds-size-space-400`: 16px (Element spacing, e.g., section title margin) - `--sds-size-space-500`: 20px (Component internal padding) - `--sds-size-space-600`: 24px (Content spacing, e.g., padding within sections, example margins) - `--sds-size-space-800`: 32px (Container spacing, e.g., main content padding, section margins) Radii: - `--sds-size-radius-200`: 8px (Standard border radius for containers)

/* Example CSS rules from various layout stylesheets */

.circuitds-main-content {
  padding: var(--sds-size-space-800); /* 32px */
}

.content-section {
  margin-bottom: var(--sds-size-space-800); /* 32px */
  padding: var(--sds-size-space-600); /* 24px */
  border-radius: var(--sds-size-radius-200); /* 8px */
  /* Direct children within .content-section-body are spaced using: */
  /* .content-section-body { gap: var(--sds-size-space-600); } */
}

.example-showcase {
  /* margin-bottom: var(--sds-size-space-600); */ /* Now handled by parent ContentSection's gap */
  padding: /* Varies by sub-element, e.g. header/preview/code */;
  border-radius: var(--sds-size-radius-200); /* 8px */
}

.example-showcase-header {
  gap: var(--sds-size-space-200); /* 8px */
}

Key Principles:

  • Utilize the predefined \`--sds-size-space-*\` tokens for all margins and paddings.
  • Use \`--sds-size-radius-*\` tokens for border radii.
  • Ensure responsive adjustments are made where necessary, often reducing padding on smaller screens while maintaining a consistent rhythmic scale.

List Styling

ContentSection components provide automatic list styling for better readability and hierarchy:

  • Default Styling: All lists within ContentSection get proper indentation and styling automatically
  • Indentation: Lists are indented by 32px (var(--sds-size-space-800)) by default
  • Typography: Lists inherit body-medium font styling
  • List Types:
    • Unordered lists use disc bullets by default
    • Ordered lists use decimal numbering
    • Nested lists automatically use circle bullets
    • Third-level lists use square bullets
  • Override Classes: Use .list-disc and .list-circle classes when you need explicit styling control
  • Responsive: Indentation reduces to 24px on mobile screens

List Styling Example

Lists are automatically styled within ContentSection components.

<ContentSection title="Example Section">
  {/* Lists get proper styling automatically */}
  <ul>
    <li>First level item</li>
    <ul>
      <li>Second level item</li>
      <ul>
        <li>Third level item</li>
      </ul>
    </ul>
  </ul>
  
  {/* Use override classes when needed */}
  <ul className="list-disc pl-6 body-medium">
    <li>Explicitly styled list</li>
  </ul>
</ContentSection>

Implementation Patterns

Standard Documentation Page Structure

The recommended JSX structure for creating new documentation pages using the established layout components.

import PageLayout from '@/components/layout/PageLayout';
import ContentSection from '@/components/layout/ContentSection';
import ExampleShowcase from '@/components/layout/ExampleShowcase';
// import YourActualComponent from '@/components/YourComponent'; // Example import

export default function MyNewDocumentationPage() {
  return (
    <PageLayout
      title="My Component Name"
      description="A brief description of what this component does."
    >
      <ContentSection title="Overview">
        <p>Detailed explanation of the component's purpose and usage context.</p>
        <ExampleShowcase
          title="Basic Usage"
          description="This is how to use the component in its simplest form."
          preview={<div>YourActualComponent Preview Placeholder</div>}
          code={ `// Note: Using YourActualComponent would require it to be defined and imported.
<YourActualComponent
  prop1="value"
  prop2={true} // booleans are fine in JSX like contexts
/>` }
        />
      </ContentSection>

      <ContentSection title="Props & API">
        <ExampleShowcase
          title="Available Props"
          description="Details about each prop, its type, default value, and effect."
          code={ `interface YourComponentProps {
  prop1?: string; // Description of prop1
  prop2?: boolean; // Description of prop2
}` }
        />
      </ContentSection>
      
      {/* Further sections for different variants, states, accessibility notes etc. */}
    </PageLayout>
  );
}

Best Practices

Semantic HTML

Use appropriate HTML elements for better accessibility and SEO.

Recommended Element Usage

<div className="circuitds-layout-container"> {/* Overall app container */}
  <AppNavigation /> {/* Contains <nav> internally */}
  <main className="circuitds-main-content"> {/* Main content area of a page */}
    <PageLayout title="Page Title" description="Page Description"> {/* Added missing props */}
      <ContentSection title="Section Title"> {/* Added missing prop */}
        <ExampleShowcase title="Example" description="Desc."> {/* Added missing props */}
          {/* ... */}
        </ExampleShowcase>
      </ContentSection>
    </PageLayout>
  </main>
</div>

Content Hierarchy (Headings)

Follow established heading level patterns for consistent content organization and accessibility.

Typical Heading Structure

{/* PageLayout title (typically h1 generated by the component) */}
<PageLayout title="Page Title (h1)">

  {/* ContentSection title (h2 by default, configurable) */}
  <ContentSection title="Section Title (h2)">

    {/* ExampleShowcase title (h3 by default, configurable) */}
    <ExampleShowcase title="Example Title (h3)">
      {/* ... */}
    </ExampleShowcase>

  </ContentSection>
</PageLayout>

Ensure heading levels are sequential and do not skip levels to maintain a logical document outline.