or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

ai-advanced.mddata-display.mdform-components.mdindex.mdinput-selection.mdlayout-navigation.mdloading-progress.mdmodal-overlay.mdtheming-customization.mdtiles-layout.md
tile.json

tiles-layout.mddocs/

Tiles & Layout

Tile components for grouping content and layout utilities for maintaining consistent aspect ratios in responsive interfaces.

Capabilities

Tile Components

Basic container component for grouping related content with optional decorative elements.

/**
 * Base tile component for grouping content
 */
interface TileProps extends React.HTMLAttributes<HTMLDivElement> {
  /** Tile content */
  children?: React.ReactNode;
  /** CSS class name */
  className?: string;
  /** Experimental: Provide a decorator component to be rendered inside the Tile */
  decorator?: React.ReactNode;
  /** Deprecated: Use Layer component instead */
  light?: boolean;
  /** Experimental: Specify if the Tile should be rendered with rounded corners. Only valid when an AILabel is present */
  hasRoundedCorners?: boolean;
  /** Deprecated: Use decorator instead. Experimental: Provide a Slug component */
  slug?: React.ReactNode;
}

/**
 * Clickable tile component that can function as a link or button
 */
interface ClickableTileProps extends React.HTMLAttributes<HTMLAnchorElement> {
  /** Tile content */
  children?: React.ReactNode;
  /** CSS class name */
  className?: string;
  /** Experimental: Provide a decorator component or set to true for an AILabel icon */
  decorator?: boolean | React.ReactNode;
  /** Deprecated: Use Layer component instead */
  light?: boolean;
  /** Boolean for whether a tile has been clicked */
  clicked?: boolean;
  /** Specify whether the ClickableTile should be disabled */
  disabled?: boolean;
  /** Experimental: Specify if the ClickableTile should be rendered with rounded corners. Only valid when decorator is present */
  hasRoundedCorners?: boolean;
  /** The href for the link */
  href?: string;
  /** A component used to render an icon */
  renderIcon?: React.ElementType;
  /** Function to run when the ClickableTile is clicked */
  onClick?: (event: React.MouseEvent) => void;
  /** Function to run when the ClickableTile is interacted with via keyboard */
  onKeyDown?: (event: React.KeyboardEvent) => void;
  /** The rel property for the link */
  rel?: string;
  /** Deprecated: Use decorator instead. Experimental: Specify if a Slug icon should be rendered */
  slug?: boolean;
}

/**
 * Selectable tile component with checkbox-style interaction
 */
interface SelectableTileProps extends React.HTMLAttributes<HTMLDivElement> {
  /** Tile content */
  children?: React.ReactNode;
  /** CSS class name */
  className?: string;
  /** Experimental: Provide a decorator component to be rendered inside the SelectableTile */
  decorator?: React.ReactNode;
  /** Deprecated: Use Layer component instead */
  light?: boolean;
  /** Specify whether the SelectableTile should be disabled */
  disabled?: boolean;
  /** Experimental: Specify if the SelectableTile should be rendered with rounded corners. Only valid when decorator is present */
  hasRoundedCorners?: boolean;
  /** The ID of the input */
  id?: string;
  /** Deprecated: The name of the input */
  name?: string;
  /** The handler for the input change event */
  onChange?: (
    event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>,
    selected?: boolean,
    id?: string
  ) => void;
  /** Function to run when the SelectableTile is clicked */
  onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
  /** Function to run when the SelectableTile is interacted with via keyboard */
  onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
  /** True to select this tile */
  selected?: boolean;
  /** Deprecated: Use decorator instead. Experimental: Provide a Slug component */
  slug?: React.ReactNode;
  /** Specify the tab index of the wrapper element */
  tabIndex?: number;
  /** The title of the input */
  title?: string;
  /** Deprecated: The value of the input */
  value?: string | number;
}

/**
 * Expandable tile component with collapsible content sections
 */
interface ExpandableTileProps extends React.HTMLAttributes<HTMLDivElement> {
  /** Tile content - expects two children for above and below fold content */
  children?: React.ReactNode;
  /** CSS class name */
  className?: string;
  /** Experimental: Provide a decorator component to be rendered inside the ExpandableTile */
  decorator?: React.ReactNode;
  /** Deprecated: Use Layer component instead */
  light?: boolean;
  /** True if the tile is expanded */
  expanded?: boolean;
  /** Experimental: Specify if the ExpandableTile should be rendered with rounded corners. Only valid when decorator is present */
  hasRoundedCorners?: boolean;
  /** An ID that can be provided to aria-labelledby */
  id?: string;
  /** Function to run when the ExpandableTile is clicked */
  onClick?: (event: React.MouseEvent) => void;
  /** Optional handler to trigger a function when a key is pressed */
  onKeyUp?: (event: React.KeyboardEvent) => void;
  /** Deprecated: Use decorator instead. Experimental: Provide a Slug component */
  slug?: React.ReactNode;
  /** The tabindex attribute */
  tabIndex?: number;
  /** The description of the "collapsed" icon that can be read by screen readers */
  tileCollapsedIconText?: string;
  /** When "collapsed", a label to appear next to the chevron (e.g., "View more") */
  tileCollapsedLabel?: string;
  /** The description of the "expanded" icon that can be read by screen readers */
  tileExpandedIconText?: string;
  /** When "expanded", a label to appear next to the chevron (e.g., "View less") */
  tileExpandedLabel?: string;
  /** Maximum height of the tile */
  tileMaxHeight?: number;
  /** Tile padding */
  tilePadding?: number;
}

/**
 * Content wrapper for the visible portion of an expandable tile
 */
interface TileAboveTheFoldContentProps {
  /** The child nodes */
  children?: React.ReactNode;
}

/**
 * Content wrapper for the collapsible portion of an expandable tile
 */
interface TileBelowTheFoldContentProps {
  /** The child nodes */
  children?: React.ReactNode;
}

/**
 * Group container for RadioTile components with form-like behavior
 */
interface TileGroupProps<T = string | number>
  extends Omit<React.HTMLAttributes<HTMLFieldSetElement>, "onChange"> {
  /** Collection of RadioTile components to render in the group */
  children?: React.ReactNode;
  /** Optional className to be applied to the container node */
  className?: string;
  /** The value of RadioTile to be selected by default */
  defaultSelected?: T;
  /** Specify whether the group is disabled */
  disabled?: boolean;
  /** Optional legend for this group */
  legend?: string;
  /** Specify the name of the underlying input nodes (required) */
  name: string;
  /** Optional onChange hook that is called whenever the value of the group changes */
  onChange?: (selection: T, name: string, evt: unknown) => void;
  /** Specify the value that is currently selected in the group */
  valueSelected?: T;
  /** True to specify if input selection in group is required */
  required?: boolean;
}

Usage Examples:

import {
  Tile,
  ClickableTile,
  SelectableTile,
  ExpandableTile,
  TileAboveTheFoldContent,
  TileBelowTheFoldContent,
  TileGroup
} from "@carbon/react";
import { ArrowRight, Add } from "@carbon/react/icons";

// Basic tile for grouping content
<Tile>
  <h3>Product Overview</h3>
  <p>This product offers comprehensive features for your business needs.</p>
</Tile>

// Clickable tile as a link
<ClickableTile href="/product-details" renderIcon={ArrowRight}>
  <h4>Learn More</h4>
  <p>Discover all the features and benefits.</p>
</ClickableTile>

// Clickable tile as a button
<ClickableTile 
  onClick={() => console.log('Tile clicked')}
  renderIcon={Add}
>
  <h4>Add New Item</h4>
  <p>Click to create a new item.</p>
</ClickableTile>

// Selectable tile with checkbox behavior
<SelectableTile
  id="option-1"
  selected={isSelected}
  onChange={(event, selected, id) => {
    setIsSelected(selected);
  }}
>
  <h4>Premium Plan</h4>
  <p>Advanced features for enterprise customers.</p>
</SelectableTile>

// Expandable tile with collapsible content
<ExpandableTile
  expanded={isExpanded}
  tileCollapsedIconText="Expand to see more details"
  tileExpandedIconText="Collapse details"
  tileCollapsedLabel="Show more"
  tileExpandedLabel="Show less"
>
  <TileAboveTheFoldContent>
    <h4>Service Details</h4>
    <p>Basic information about our service offering.</p>
  </TileAboveTheFoldContent>
  <TileBelowTheFoldContent>
    <p>Additional details about pricing, features, and implementation process.</p>
    <ul>
      <li>24/7 Support</li>
      <li>Custom Integration</li>
      <li>Advanced Analytics</li>
    </ul>
  </TileBelowTheFoldContent>
</ExpandableTile>

// Tile group for radio button-like selection (requires RadioTile components)
<TileGroup
  name="plan-selection"
  legend="Choose your plan"
  valueSelected={selectedPlan}
  onChange={(selection, name, event) => {
    setSelectedPlan(selection);
  }}
>
  <RadioTile value="basic" id="basic-plan">
    <h4>Basic Plan</h4>
    <p>Essential features for small teams</p>
  </RadioTile>
  <RadioTile value="premium" id="premium-plan">
    <h4>Premium Plan</h4>
    <p>Advanced features for growing businesses</p>
  </RadioTile>
</TileGroup>

Layout Utilities

Aspect ratio container for maintaining consistent proportions across different screen sizes.

/**
 * Aspect ratio container component for maintaining consistent content proportions
 */
interface AspectRatioProps {
  /** Provide a custom component or string to be rendered as the outermost node */
  as?: React.ElementType;
  /** Specify a class name for the outermost node of the component */
  className?: string;
  /** Specify the ratio to be used by the aspect ratio container */
  ratio?: 
    | "1x1"
    | "2x3" 
    | "3x2"
    | "3x4"
    | "4x3"
    | "1x2"
    | "2x1"
    | "9x16"
    | "16x9";
  /** Content to be displayed within the aspect ratio container */
  children?: React.ReactNode;
}

Usage Examples:

import { AspectRatio } from "@carbon/react";

// Square aspect ratio for profile images
<AspectRatio ratio="1x1">
  <img src="profile.jpg" alt="User profile" />
</AspectRatio>

// Video aspect ratio
<AspectRatio ratio="16x9">
  <video controls>
    <source src="presentation.mp4" type="video/mp4" />
  </video>
</AspectRatio>

// Portrait aspect ratio for mobile mockups
<AspectRatio ratio="9x16">
  <div className="mobile-mockup">
    <h3>Mobile App Preview</h3>
    <p>App interface content</p>
  </div>
</AspectRatio>

// Custom element type
<AspectRatio as="section" ratio="3x2" className="hero-banner">
  <div className="hero-content">
    <h1>Welcome to our platform</h1>
    <p>Discover amazing features</p>
  </div>
</AspectRatio>

// Grid layout with consistent aspect ratios
<Grid>
  <Row>
    <Column lg={4}>
      <AspectRatio ratio="4x3">
        <Tile>
          <h3>Feature 1</h3>
          <p>Description of feature 1</p>
        </Tile>
      </AspectRatio>
    </Column>
    <Column lg={4}>
      <AspectRatio ratio="4x3">
        <Tile>
          <h3>Feature 2</h3>
          <p>Description of feature 2</p>
        </Tile>
      </AspectRatio>
    </Column>
  </Row>
</Grid>

Integration Patterns

Common patterns for combining tiles with other Carbon components.

// Tiles in a grid layout for dashboard cards
<Grid>
  <Row>
    <Column lg={4}>
      <ClickableTile href="/analytics" renderIcon={ArrowRight}>
        <h4>Analytics Dashboard</h4>
        <p>View detailed analytics and reports</p>
        <Tag type="green">Active</Tag>
      </ClickableTile>
    </Column>
    <Column lg={4}>
      <ClickableTile href="/settings" renderIcon={ArrowRight}>
        <h4>Account Settings</h4>
        <p>Manage your account preferences</p>
      </ClickableTile>
    </Column>
  </Row>
</Grid>

// Selectable tiles for configuration options
<FormGroup legendText="Select deployment options">
  <SelectableTile
    id="auto-deploy"
    selected={options.autoDeploy}
    onChange={(event, selected) => setOptions({...options, autoDeploy: selected})}
  >
    <h4>Automatic Deployment</h4>
    <p>Deploy changes automatically on push</p>
  </SelectableTile>
  
  <SelectableTile
    id="manual-deploy"
    selected={options.manualDeploy}
    onChange={(event, selected) => setOptions({...options, manualDeploy: selected})}
  >
    <h4>Manual Deployment</h4>
    <p>Require manual approval for deployments</p>
  </SelectableTile>
</FormGroup>

// Expandable tiles for FAQ or help content
<Stack gap={4}>
  <ExpandableTile
    tileCollapsedLabel="Show answer"
    tileExpandedLabel="Hide answer"
  >
    <TileAboveTheFoldContent>
      <h4>How do I reset my password?</h4>
    </TileAboveTheFoldContent>
    <TileBelowTheFoldContent>
      <p>You can reset your password by clicking the "Forgot Password" link on the login page...</p>
      <Button kind="ghost" size="sm">Reset Password</Button>
    </TileBelowTheFoldContent>
  </ExpandableTile>
  
  <ExpandableTile
    tileCollapsedLabel="Show answer"  
    tileExpandedLabel="Hide answer"
  >
    <TileAboveTheFoldContent>
      <h4>How do I contact support?</h4>
    </TileAboveTheFoldContent>
    <TileBelowTheFoldContent>
      <p>Our support team is available 24/7 through multiple channels...</p>
      <ButtonSet>
        <Button kind="secondary" size="sm">Email Support</Button>
        <Button kind="primary" size="sm">Live Chat</Button>
      </ButtonSet>
    </TileBelowTheFoldContent>
  </ExpandableTile>
</Stack>