Skip to main content

Responsive Layout Patterns

Dynamic UI provides powerful layout components and utilities for building responsive interfaces. The DLayout component wraps Bootstrap’s CSS Grid system with responsive gap utilities.

DLayout Component

The DLayout component is a wrapper around Bootstrap’s grid system with responsive gap support:
import { DLayout, DBox } from '@dynamic-framework/ui-react';

function ResponsiveGrid() {
  return (
    <DLayout gap={4}>
      <DLayout.Pane cols={12} colsLg={8}>
        <DBox>Main Content</DBox>
      </DLayout.Pane>
      <DLayout.Pane cols={12} colsLg={4}>
        <DBox>Sidebar</DBox>
      </DLayout.Pane>
    </DLayout>
  );
}

DLayout Props

  • gap - Spacing between grid items (0-30)
  • gapSm, gapMd, gapLg, gapXl, gapXxl - Responsive gap values
  • columns - Number of columns (overrides Bootstrap default of 12)

DLayout.Pane Props

  • cols - Number of columns to span (default breakpoint)
  • colsSm, colsMd, colsLg, colsXl, colsXxl - Responsive column spans

Dashboard Layout Pattern

Create a responsive dashboard with metric cards and charts:
import { DLayout, DBox, DIcon, DButton } from '@dynamic-framework/ui-react';

function Dashboard() {
  const metrics = [
    { title: 'Total Sales', value: '$12,000', icon: 'DollarSign', change: 5.2 },
    { title: 'Customers', value: '1,234', icon: 'UserRoundCheck', change: 4.2 },
    { title: 'Revenue', value: '$19,500', icon: 'TrendingUp', change: 8.1 },
    { title: 'Orders', value: '567', icon: 'ShoppingCart', change: -2.3 },
  ];
  
  return (
    <div className="p-8">
      <div className="d-flex justify-content-between align-items-end mb-8">
        <div>
          <h2 className="mb-0 fw-normal h4">
            Good morning, <strong>John</strong>
          </h2>
          <p className="text-muted mb-0">Today is May 12, 2023</p>
        </div>
        <DButton text="Refresh Data" iconStart="RotateCw" variant="link" />
      </div>
      
      {/* Metric Cards */}
      <DLayout gap={4} className="mb-4">
        {metrics.map((metric) => (
          <DLayout.Pane
            key={metric.title}
            cols={12}
            colsMd={6}
            colsLg={3}
            className="p-8 bg-primary-50 rounded-3"
          >
            <div className="d-flex gap-2 align-items-center mb-2">
              <DIcon hasCircle color="primary" icon={metric.icon} size="1rem" />
              <span className="text-muted">{metric.title}</span>
            </div>
            <div className="d-flex justify-content-between align-items-center">
              <div className="fs-4 fw-bold">{metric.value}</div>
              <p className={`mb-0 ${metric.change > 0 ? 'text-success' : 'text-danger'}`}>
                {metric.change}%
              </p>
            </div>
          </DLayout.Pane>
        ))}
      </DLayout>
      
      {/* Main Content Area */}
      <DLayout gap={4}>
        <DLayout.Pane cols={12} colsLg={8}>
          <DBox className="h-100">
            <h5 className="mb-4 d-flex align-items-center gap-2">
              <DIcon hasCircle icon="TrendingUp" size=".75rem" />
              Sales Performance
            </h5>
            {/* Chart component would go here */}
          </DBox>
        </DLayout.Pane>
        
        <DLayout.Pane cols={12} colsLg={4}>
          <DBox className="h-100">
            <h5 className="mb-4 d-flex align-items-center gap-2">
              <DIcon hasCircle icon="Users" size=".75rem" />
              Recent Activity
            </h5>
            {/* Activity list would go here */}
          </DBox>
        </DLayout.Pane>
      </DLayout>
    </div>
  );
}

Using Bootstrap Grid Utilities

For finer control, use Bootstrap’s grid classes directly:
import { DBox, DInput, DButton } from '@dynamic-framework/ui-react';

function TwoColumnForm() {
  return (
    <DBox className="p-8">
      <form>
        <fieldset>
          <legend className="fw-semibold">Personal Information</legend>
          
          <div className="grid gap-3">
            <div className="g-col-12 g-col-lg-6">
              <DInput
                id="firstName"
                label="First Name"
                placeholder="Enter your first name"
              />
            </div>
            
            <div className="g-col-12 g-col-lg-6">
              <DInput
                id="lastName"
                label="Last Name"
                placeholder="Enter your last name"
              />
            </div>
            
            <div className="g-col-12">
              <DInput
                id="email"
                type="email"
                label="Email"
                placeholder="Enter your email"
              />
            </div>
            
            <div className="g-col-12">
              <DButton type="submit" text="Submit" className="me-2" />
              <DButton type="reset" variant="outline" text="Reset" />
            </div>
          </div>
        </fieldset>
      </form>
    </DBox>
  );
}

Responsive Media Queries Hook

Use the useMediaQuery hook for conditional rendering:
1

Import the hook

import { useMediaQuery } from '@dynamic-framework/ui-react';
2

Use media query in component

function ResponsiveComponent() {
  // Listen for changes with second parameter set to true
  const isMobile = useMediaQuery('(max-width: 768px)', true);
  const isTablet = useMediaQuery('(min-width: 769px) and (max-width: 1024px)', true);
  const isDesktop = useMediaQuery('(min-width: 1025px)', true);
  
  return (
    <div>
      {isMobile && <MobileView />}
      {isTablet && <TabletView />}
      {isDesktop && <DesktopView />}
    </div>
  );
}
3

Use breakpoint helper hooks

import {
  useMediaBreakpointUpSm,
  useMediaBreakpointUpMd,
  useMediaBreakpointUpLg,
  useMediaBreakpointUpXl,
} from '@dynamic-framework/ui-react';

function AdaptiveLayout() {
  const isSmUp = useMediaBreakpointUpSm(true);
  const isMdUp = useMediaBreakpointUpMd(true);
  const isLgUp = useMediaBreakpointUpLg(true);
  
  return (
    <DLayout gap={isLgUp ? 4 : isMdUp ? 3 : 2}>
      <DLayout.Pane
        cols={12}
        colsMd={isMdUp ? 6 : 12}
        colsLg={isLgUp ? 4 : 6}
      >
        <DBox>Responsive Pane</DBox>
      </DLayout.Pane>
    </DLayout>
  );
}

Responsive Form with Cover Image

Create a split-screen layout that adapts to mobile:
import { DBox, DInput, DButton, DIcon } from '@dynamic-framework/ui-react';

function FormWithCover() {
  return (
    <DBox className="grid gap-0 p-0 overflow-hidden">
      {/* Cover image - hidden on mobile, shown on desktop */}
      <div className="g-col-12 g-col-lg-4">
        <div
          className="bg-primary text-white h-100 position-relative"
          style={{
            backgroundImage: 'url(https://images.unsplash.com/photo-1486406146926-c627a92ad1ab)',
            backgroundSize: 'cover',
          }}
        >
          <div className="bottom-0 end-0 p-8 text-end position-lg-absolute">
            <h5>Welcome Back</h5>
            <p className="mb-0 opacity-50">Join thousands of users</p>
          </div>
        </div>
      </div>
      
      {/* Form - full width on mobile, 8 columns on desktop */}
      <form className="p-8 g-col-12 g-col-lg-8">
        <fieldset className="mb-8">
          <legend className="d-flex fw-bold">
            <DIcon icon="User" size="1rem" className="me-2 text-muted" />
            Personal Information
          </legend>
          
          <div className="grid gap-3">
            <div className="g-col-12 g-col-lg-6">
              <DInput id="firstName" label="First Name" placeholder="John" />
            </div>
            <div className="g-col-12 g-col-lg-6">
              <DInput id="lastName" label="Last Name" placeholder="Doe" />
            </div>
            <div className="g-col-12">
              <DInput
                id="email"
                type="email"
                label="Email"
                placeholder="[email protected]"
              />
            </div>
          </div>
        </fieldset>
        
        <DButton type="submit" text="Save Information" className="me-2" />
        <DButton type="reset" variant="outline" text="Clear Form" />
      </form>
    </DBox>
  );
}

Responsive Navigation Pattern

Adapt content based on screen size:
import { useMediaQuery } from '@dynamic-framework/ui-react';
import { DButton, DButtonIcon } from '@dynamic-framework/ui-react';

function ResponsiveNav() {
  const isDesktop = useMediaQuery('(min-width: 992px)', true);
  
  return (
    <nav className="d-flex align-items-center justify-content-between p-4">
      <div className="brand">Logo</div>
      
      {isDesktop ? (
        <div className="d-flex gap-3">
          <DButton text="Dashboard" variant="link" />
          <DButton text="Reports" variant="link" />
          <DButton text="Settings" variant="link" />
        </div>
      ) : (
        <DButtonIcon icon="Menu" aria-label="Open menu" />
      )}
    </nav>
  );
}

Three-Column Layout

Create a flexible three-column layout:
import { DLayout, DBox } from '@dynamic-framework/ui-react';

function ThreeColumnLayout() {
  return (
    <DLayout gap={4}>
      {/* Left sidebar - full width on mobile, 3 cols on desktop */}
      <DLayout.Pane cols={12} colsLg={3}>
        <DBox className="h-100">
          <h5>Navigation</h5>
          <ul className="list-unstyled">
            <li>Dashboard</li>
            <li>Reports</li>
            <li>Settings</li>
          </ul>
        </DBox>
      </DLayout.Pane>
      
      {/* Main content - full width on mobile, 6 cols on desktop */}
      <DLayout.Pane cols={12} colsLg={6}>
        <DBox className="h-100">
          <h3>Main Content</h3>
          <p>Your primary content goes here</p>
        </DBox>
      </DLayout.Pane>
      
      {/* Right sidebar - full width on mobile, 3 cols on desktop */}
      <DLayout.Pane cols={12} colsLg={3}>
        <DBox className="h-100">
          <h5>Activity</h5>
          <p className="text-muted">Recent updates</p>
        </DBox>
      </DLayout.Pane>
    </DLayout>
  );
}

Responsive Gap Utilities

Adjust spacing based on viewport:
import { DLayout, DBox } from '@dynamic-framework/ui-react';

function ResponsiveGaps() {
  return (
    <DLayout
      gap={2}      // Small gap on mobile
      gapMd={3}    // Medium gap on tablets
      gapLg={4}    // Large gap on desktop
    >
      <DLayout.Pane cols={12} colsMd={6} colsLg={4}>
        <DBox>Card 1</DBox>
      </DLayout.Pane>
      <DLayout.Pane cols={12} colsMd={6} colsLg={4}>
        <DBox>Card 2</DBox>
      </DLayout.Pane>
      <DLayout.Pane cols={12} colsMd={6} colsLg={4}>
        <DBox>Card 3</DBox>
      </DLayout.Pane>
    </DLayout>
  );
}

Build docs developers (and LLMs) love