Layout and Text Primitives
This page covers the most foundational component group. They do not own business state or register keyboard events; they only turn the component tree into predictable terminal regions and text output.
If you know React, think of View as the most common layout container and Fragment as a wrapper that does not produce an extra layout node. The difference is that ratatui-kit layout eventually lands on ratatui Layout, Constraint, Rect, and Buffer, so sizes and region boundaries are more explicit than in Web UI.
Choosing a component
Section titled “Choosing a component”| What you want to do | Component | Notes |
|---|---|---|
| Organize children horizontally or vertically | View | Default container; supports flex_direction, gap, width, height, margin, and offset |
| Add a border, title, and padding around content | Border | Draws its own Block; child regions enter Block::inner |
| Center content inside a region | Center | Transparent wrapper implemented with three nested Views |
| Overlay content at absolute coordinates | Positioned | Does not participate in ordinary flex sizing; can render Clear |
| Return multiple child nodes without adding a layout layer | Fragment | Transparent layout; inherits the first child’s layout |
Render short text, Line, Text, or Paragraph | Text | Suitable for fixed-region text; use WrappedText for auto-height prose |
View is the ordinary layout container. It has no drawing content of its own; it passes children to the default flex layout algorithm to compute their regions.
View layout fields come from #[with_layout_style]:
| Field | Meaning |
|---|---|
flex_direction | Direction used to split child regions; defaults to ratatui Direction::Vertical |
justify_content | Maps to ratatui Flex |
gap | Spacing between child regions |
width / height | Constraint used by parent layout when computing the current component region |
margin / offset | Applied to the current region before drawing the component and subtree |
If you are unsure which container to use, start with View. It is the closest thing to a plain “layout node”.
Border
Section titled “Border”Border does two things: it participates in parent layout and renders a ratatui Block during draw. After rendering the border, children are drawn inside Block::inner(drawer.area).
Common props:
| Field | Meaning |
|---|---|
padding | Inner padding reserved before entering Block::inner |
border_style | Border style |
borders | Which edges to show; defaults to Borders::ALL |
border_set | Border character set |
style | Base style for the whole block |
top_title / bottom_title | Top and bottom titles; you can pass Line directly |
Border is a content-grouping component. It should not be used as decorative page-section chrome. In terminal UI, borders consume real character cells, and excessive nesting reduces content density.
Center
Section titled “Center”Center is a transparent layout helper. It has no draw behavior of its own; it puts children into internally nested Views and centers the specified width and height inside the parent region.
Center fits splash screens, empty states, small modal content, and focused example regions. For complex responsive layout, composing Views directly is usually clearer.
Positioned
Section titled “Positioned”Positioned draws a subtree at an absolute Rect:
Its layout size is set to Constraint::Length(0), so it does not occupy parent flex space. During draw, it changes drawer.area to Rect::new(x, y, width, height); when clear: true, it renders ratatui Clear first, which is useful for overlaying background content.
Use Positioned carefully. It bypasses the ordinary layout flow and is well suited to local floating layers, cursor-adjacent hints, or debug overlays, but not to the main page structure. Main structure should still be expressed with View, Border, ScrollView, or dedicated components.
Fragment
Section titled “Fragment”Fragment is a transparent container for returning multiple child nodes:
It calls set_transparent_layout(true), so it does not create its own independent layout node. At runtime, it inherits the first child component’s LayoutStyle; if there are no children in the current frame, it resets to the default layout.
This matches the transparent layout rule for function components: do not expect setting width / height on the outside of a transparent wrapper to make it occupy space by itself. Put layout properties on the root child component it returns.
Text is a thin wrapper around Paragraph. It can receive a string, Line, ratatui Text, or Paragraph directly:
Common props:
| Field | Meaning |
|---|---|
text | &str, String, Line, ratatui Text, or Paragraph |
style | Overall style applied to the Paragraph |
alignment | Text alignment |
scroll | Paragraph scroll offset, typed as Position |
wrap | Whether to enable Wrap { trim }; passing true trims whitespace |
Text.wrap only affects how the Paragraph wraps inside the current region; it does not feed the measured wrapped height back to parent layout. For “long prose that should compute its own height, then scroll inside ScrollView”, use WrappedText.
Native widget adapter
Section titled “Native widget adapter”You can also bridge ratatui widgets directly inside element!:
widget(...) is for stateless widgets; stateful(...) is for widgets like List and Table that need ratatui state. They are low-level escape hatches. Simple bridges can use them directly; if you need to wrap a complex widget as a reusable component, see Native Widget Bridging.
Boundaries with other components
Section titled “Boundaries with other components”- Use
View/Border/Centerfor layout structure. - Use
WrappedTextfor long prose andScrollViewfor scrollable regions. - Do not handwrite a full input-exclusivity stack for modals with
Positioned; prefer Modal or the packaged modal components. - Use
widget/statefulonly when a native widget needs to be bridged; write aComponentwhen you need state, events, layout, and reuse.
For more runtime-level explanation, see Component Model and Render Loop.