Skip to main content
paragraph() makes it possible to render rich text with different styles. It’s a more customizable API than label(), allowing you to compose text with multiple styled segments called spans.

Usage

use freya::prelude::*;

fn app() -> impl IntoElement {
    paragraph()
        .span(Span::new("Hello ").font_size(24.0).color(Color::RED))
        .span(Span::new("World").font_size(16.0).color(Color::BLUE))
}

Builder Methods

Content

span
impl Into<Span<'static>>
Add a styled text span to the paragraph.
paragraph()
    .span(Span::new("Bold").font_weight(FontWeight::BOLD))
    .span(Span::new(" Regular"))
spans_iter
impl Iterator<Item = Span<'static>>
Add multiple spans from an iterator.
let spans = vec![
    Span::new("First"),
    Span::new("Second"),
];
paragraph().spans_iter(spans.into_iter())

Text Layout

max_lines
impl Into<Option<usize>>
Set the maximum number of lines.
paragraph()
    .span(Span::new("Long text..."))
    .max_lines(3)
line_height
impl Into<Option<f32>>
Set the line height multiplier.
paragraph()
    .span(Span::new("Text with custom spacing"))
    .line_height(1.5)
vertical_align
VerticalAlign
Set vertical alignment of text within the paragraph area.
paragraph()
    .span(Span::new("Centered vertically"))
    .vertical_align(VerticalAlign::Center)

Cursor (for text editing)

cursor_index
impl Into<Option<usize>>
Set the cursor position for text editing.
paragraph()
    .span(Span::new("Editable text"))
    .cursor_index(5)
cursor_color
Color
Set the cursor color.
paragraph()
    .cursor_color(Color::BLACK)
cursor_style
CursorStyle
Set the cursor style (Line, Block, or Underline).
paragraph()
    .cursor_style(CursorStyle::Block)
cursor_mode
CursorMode
Set the cursor rendering mode.
  • CursorMode::Fit: cursor uses the paragraph’s visible area
  • CursorMode::Expanded: cursor uses the paragraph’s full area
paragraph()
    .cursor_mode(CursorMode::Expanded)

Highlighting (for text selection)

highlights
impl Into<Option<Vec<(usize, usize)>>>
Set text selection highlights as ranges.
paragraph()
    .span(Span::new("Selected text"))
    .highlights(vec![(0, 8)])
highlight_color
Color
Set the highlight/selection color.
paragraph()
    .highlight_color(Color::from_rgb(200, 200, 255))

Reference

holder
ParagraphHolder
Set a holder to access the underlying Skia paragraph for advanced operations.
let holder = ParagraphHolder::default();
paragraph()
    .span(Span::new("Text"))
    .holder(holder.clone())

Layout

width
Size
Set the width constraint.
paragraph()
    .span(Span::new("Fixed width"))
    .width(200.0)
height
Size
Set the height constraint.
paragraph()
    .span(Span::new("Fixed height"))
    .height(100.0)
padding
Gaps
Set padding around the paragraph.
paragraph()
    .span(Span::new("Padded"))
    .padding(10.0)

Text Style (default for spans)

color
Color
Set the default text color for spans.
paragraph()
    .color(Color::BLACK)
    .span(Span::new("Uses default color"))
font_size
FontSize
Set the default font size for spans.
paragraph()
    .font_size(16.0)
    .span(Span::new("Default size"))
font_family
impl Into<Cow<'static, str>>
Set the default font family for spans.
paragraph()
    .font_family("Inter")
    .span(Span::new("Text in Inter"))

Events

on_press
EventHandler
Handle press/click events.
paragraph()
    .span(Span::new("Clickable"))
    .on_press(|_| println!("Clicked!"))
on_mouse_move
EventHandler<MouseEventData>
Handle mouse move events.

Span Methods

A Span represents a styled segment of text within a paragraph.

Creating Spans

Span::new("text")           // From &str
Span::from("text")          // From &str
Span::from(String::new())   // From String

Span Text Styling

color
Color
Set the span’s text color.
Span::new("Red").color(Color::RED)
font_size
FontSize
Set the span’s font size.
Span::new("Large").font_size(24.0)
font_weight
FontWeight
Set the span’s font weight.
Span::new("Bold").font_weight(FontWeight::BOLD)
font_slant
FontSlant
Set the span’s font slant.
Span::new("Italic").font_slant(FontSlant::ITALIC)
font_family
impl Into<Cow<'static, str>>
Set the span’s font family.
Span::new("Mono").font_family("Fira Code")
text_shadow
TextShadow
Add a text shadow to the span.
Span::new("Shadowed").text_shadow(TextShadow::new(
    (2.0, 2.0),
    5.0,
    Color::BLACK
))

Examples

Basic Rich Text

paragraph()
    .span(Span::new("Welcome ").font_size(24.0).font_weight(FontWeight::BOLD))
    .span(Span::new("to Freya!").font_size(18.0))

Multi-colored Text

paragraph()
    .span(Span::new("Red ").color(Color::RED))
    .span(Span::new("Green ").color(Color::GREEN))
    .span(Span::new("Blue").color(Color::BLUE))

Mixed Font Styles

paragraph()
    .span(Span::new("This is "))
    .span(Span::new("bold").font_weight(FontWeight::BOLD))
    .span(Span::new(" and this is "))
    .span(Span::new("italic").font_slant(FontSlant::ITALIC))

Text Editor with Cursor

let cursor_pos = use_state(|| 0);
let text = "Editable text";

paragraph()
    .span(Span::new(text))
    .cursor_index(cursor_pos())
    .cursor_color(Color::BLACK)
    .cursor_style(CursorStyle::Line)
    .on_press(move |e| {
        // Update cursor position based on click
    })

Text with Selection

let selection = use_state(|| (0, 5));

paragraph()
    .span(Span::new("Selected text here"))
    .highlights(vec![selection()])
    .highlight_color(Color::from_rgb(200, 220, 255))

Vertically Centered Paragraph

paragraph()
    .span(Span::new("Centered"))
    .height(100.0)
    .vertical_align(VerticalAlign::Center)

Dynamic Spans from Data

let words = vec!["One", "Two", "Three"];
let colors = vec![Color::RED, Color::GREEN, Color::BLUE];

paragraph()
    .spans_iter(
        words.iter()
            .zip(colors.iter())
            .map(|(word, color)| {
                Span::new(*word)
                    .color(*color)
                    .font_size(20.0)
            })
    )

Notes

  • Use label() for simple single-style text
  • Use paragraph() for rich text with multiple styles
  • Each span can have its own color, size, weight, and other text properties
  • Paragraph supports text editing features like cursor and selection
  • Text measurement and layout are handled automatically

Build docs developers (and LLMs) love