# Chapter 2: Layout System Ink uses [Yoga](https://yogalayout.com/) (Facebook's cross-platform layout engine) to implement CSS Flexbox in the terminal. Every layout is flexbox-based -- there is no CSS Grid or flow layout. ## Box Component `Box` is the fundamental layout primitive. It is the terminal equivalent of `
`. ```tsx import { Box, Text } from '@anthropic/ink' Left Right ``` ### Box Props (Styles) All layout props are passed directly as JSX props (no `style={}` wrapper needed): #### Flex Direction Controls the main axis direction. ```tsx ... // Left to right (default) ... // Top to bottom ... // Right to left ... // Bottom to top ``` #### Flex Grow / Shrink / Basis ```tsx ... // Grow to fill available space ... // Don't shrink below intrinsic size ... // Initial size before flex distribution ... // Percentage basis ``` Default values: `flexGrow={0}`, `flexShrink={1}`, `flexBasis=auto`. #### Flex Wrap ```tsx ... // Single line (default) ... // Multiple lines ... // Reverse cross-axis stacking ``` #### Alignment ```tsx ... // Cross-axis start ... // Cross-axis center ... // Cross-axis end ... // Stretch to fill (default) ... // Override parent's alignItems ... ... ... // Inherit from parent ``` #### Justify Content ```tsx ... // Main-axis start (default) ... // Main-axis end ... // Center ... // Equal gaps, no edges ... // Equal gaps with edges ... // Evenly distributed ``` #### Gap Spacing between children (only accepts integers): ```tsx ... // Both row and column gap ... // Gap between columns only ... // Gap between rows only ``` #### Padding Inner spacing (only accepts integers): ```tsx ... // All sides ... // Left and right ... // Top and bottom ... // Left only ... // Right only ... // Top only ... // Bottom only ``` #### Margin Outer spacing (only accepts integers): ```tsx ... // All sides ... // Left and right ... // Top and bottom ... // Left only ... // Right only ... // Top only ... // Bottom only ``` > **Note:** Fractional values for padding, margin, and gap are not supported. Ink will emit warnings if non-integer values are used. #### Width & Height ```tsx ... // Fixed 40 characters wide ... // Fixed 10 rows tall ... // 50% of parent's width ... // Full parent width ``` #### Min/Max Dimensions ```tsx ... ... ... ... ``` Percentage values are supported: `minWidth="30%"`. #### Position ```tsx ... ... ... // Default ``` Position `absolute` removes the element from normal flow and positions it relative to its nearest positioned ancestor. Useful for overlays. #### Display ```tsx ... // Visible (default) ... // Hidden (removed from layout) ``` #### Border ```tsx ... // Thin border ... // Double-line border ... // Rounded corners ... // Bold border ... // Mixed ... // Mixed ... // ASCII art border ``` Control individual sides and colors: ```tsx ... ``` Per-side colors: ```tsx ``` Border text (labels in the border): ```tsx ``` #### Background ```tsx ... ``` #### Overflow ```tsx ... // Content expands container (default) ... // Clip without scrolling ... // Enable scrolling (use ScrollBox) ``` `overflowX` and `overflowY` control each axis independently. #### Opaque ```tsx ... ``` Fills the box interior with spaces (using terminal's default background) before rendering children. Useful for absolute-positioned overlays where gaps would otherwise be transparent. #### NoSelect ```tsx ... // Exclude from text selection ... // Exclude from column 0 to box edge ``` Only affects alt-screen text selection. Useful for gutters (line numbers, diff markers). ## Spacer `Spacer` fills all available space along the main axis (equivalent to `flexGrow: 1`). ```tsx Left Right ``` ## Newline Inserts line breaks. ```tsx Line 1 Line 2 Line 4 (after double break) ``` ## Layout Examples ### Two-column layout ```tsx Left column Right column ``` ### Centered content ```tsx Centered! ``` ### Sticky footer ```tsx Scrollable content area Status bar at bottom ``` ### Bordered panel with title ```tsx Panel Title Panel content goes here. ``` ## NoSelect Wraps a region to exclude it from text selection in alt-screen mode. A convenience wrapper around `Box` with `noSelect` set. ```tsx import { NoSelect } from '@anthropic/ink' 1 │ selectable code here ``` ### Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `ReactNode` | - | Content | | `fromLeftEdge` | `boolean` | `false` | Extend exclusion from column 0 to box's right edge | Accepts all `BoxProps` except `noSelect`. ## BaseBox vs ThemedBox Two versions of Box are exported: - **`BaseBox`** (imported as `BaseBox`) -- Raw box, color props accept only raw `Color` values - **`Box`** (themed, imported as `Box`) -- Theme-aware, color props accept `keyof Theme | Color` ```tsx // Raw // Theme-aware (resolves 'permission' to the current theme's blue) ```