gridland
Theming

Breakpoints

Responsive layout utilities for adapting to different terminal widths.

Overview

Gridland apps run in terminals of varying widths, from narrow mobile screens to wide desktop terminals. The useBreakpoints hook provides reactive boolean flags for common width thresholds, making it easy to adapt your layout.

Usage

import { useBreakpoints } from "@/components/ui/breakpoints"

function MyApp() {
  const { isMobile, isNarrow, isTiny, isDesktop, width, height } = useBreakpoints()

  return (
    <box flexDirection="column">
      {isDesktop ? (
        <box flexDirection="row">
          <Sidebar />
          <MainContent />
        </box>
      ) : (
        <MainContent />
      )}
    </box>
  )
}

Breakpoint Values

FlagConditionUse case
isTinywidth < 40Extremely narrow. Hide decorative elements, use compact text
isNarrowwidth < 60Narrow. Stack layouts vertically, use abbreviated labels
isMobilewidth < 70Mobile. Simplify layouts, merge text blocks
isDesktopwidth >= 70Desktop. Full layouts with sidebars and multi-column content

The raw width and height values are also returned for custom thresholds.

Constants

The breakpoint thresholds are exported as BREAKPOINTS for use outside of React components:

import { BREAKPOINTS } from "@/components/ui/breakpoints"

// BREAKPOINTS.tiny   = 40
// BREAKPOINTS.narrow = 60
// BREAKPOINTS.mobile = 70

API

useBreakpoints()

Returns a Breakpoints object:

interface Breakpoints {
  isTiny: boolean
  isNarrow: boolean
  isMobile: boolean
  isDesktop: boolean
  width: number
  height: number
}

Examples

Responsive text

function Subtitle() {
  const { isMobile } = useBreakpoints()

  return (
    <text wrapMode="word" textAlign="center" width="100%">
      {isMobile
        ? "Short description for mobile."
        : "A longer, more detailed description for desktop terminals."}
    </text>
  )
}

Responsive layout direction

function ActionBar() {
  const { isNarrow } = useBreakpoints()

  return (
    <box flexDirection={isNarrow ? "column" : "row"} gap={1}>
      <InstallBox />
      <LinksBox />
    </box>
  )
}