Selkie--Widget--RichText

NAME

Selkie::Widget::RichText - Styled text built from Span fragments

SYNOPSIS

use Selkie::Widget::RichText;
use Selkie::Widget::RichText::Span;
use Selkie::Style;
use Selkie::Sizing;

my $rich = Selkie::Widget::RichText.new(sizing => Sizing.flex);
$rich.set-content([
    Selkie::Widget::RichText::Span.new(
        text  => 'alice: ',
        style => Selkie::Style.new(fg => 0x7AA2F7, bold => True),
    ),
    Selkie::Widget::RichText::Span.new(
        text  => 'Hey, how are you?',
        style => Selkie::Style.new(fg => 0xEEEEEE),
    ),
]);

DESCRIPTION

Like Selkie::Widget::Text, but each fragment can have its own style. Word-wraps across span boundaries while preserving styles — if a span is split across two lines, both halves render with that span's style.

Supports partial rendering via render-region, so it composes correctly inside Selkie::Widget::ScrollView. The truncated-top and truncated-bottom flags insert "…" ellipsis lines when content would overflow — useful for showing a preview snippet.

EXAMPLES

Colour-coded message

my $red = Selkie::Style.new(fg => 0xFF5555, bold => True);
$rich.set-content([
    Selkie::Widget::RichText::Span.new(text => 'Error: ', style => $red),
    Selkie::Widget::RichText::Span.new(text => 'file not found'),
]);

Truncated preview

my $preview = Selkie::Widget::RichText.new(
    sizing           => Sizing.fixed(3),
    truncated-bottom => True,
);
# Content longer than 3 lines shows the first 2 lines + '…'

Pre-rendering line count

# Static wrap — lets variable-height container layouts size their
# slot to the exact rendered line count BEFORE the widget is
# attached to a plane. The same algorithm the live renderer uses,
# so card height matches render height to the row.
my @lines = Selkie::Widget::RichText.wrap-spans(@spans, 60);
say @lines.elems;   # exact wrapped-line count at width 60

SEE ALSO

has Bool $.truncated-bottom

When set to True, overflow at the bottom is shown as a "…" line in place of the last visible wrapped line.

has Bool $.truncated-top

When True, overflow at the top is shown as a "…" line in place of the first visible wrapped line (displays the most recent content).

method set-content

method set-content(
    @spans
) returns Mu

Replace the displayed content with the given list of Spans. The wrap cache is invalidated; the next render rebuilds it.

method spans

method spans() returns List

The current spans as a List.

method logical-height

method logical-height() returns UInt

Number of wrapped lines at the current width. Used by ScrollView.

method render-region

method render-region(
    Int :$offset where { ... },
    Int :$height where { ... }
) returns Mu

Render only a slice of the wrapped-line array, starting at #| :offset for :height rows. Used by ScrollView when #| RichText is the scrolled child — the parent decides which #| logical-line range is visible and asks the widget to paint that #| slice. Always rewraps before painting so the slice math sees the #| current wrap state.

method wrap-spans

method wrap-spans(
    @spans,
    Int $width where { ... }
) returns Array

Pure word-wrap: take a list of Spans and a target width, return the wrapped-line array (each element is an Array[Span]). Same algorithm the live renderer uses via !rewrap, exposed as a class method so consumers that need the exact line count without attaching a plane (e.g. variable-height card layouts) can size themselves accurately. Always returns at least one (possibly empty) line.

Selkie v0.10.0

High-level TUI framework built on Notcurses

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

Notcurses::Native:ver<0.4.0+>:auth<zef:apogee>

Test Dependencies

Provides

  • Selkie
  • Selkie::App
  • Selkie::App::Internal::Dispatch
  • Selkie::App::Internal::ErrorLog
  • Selkie::App::Internal::FocusTree
  • Selkie::App::Internal::HitTest
  • Selkie::App::Internal::IdleBudget
  • Selkie::App::Internal::OverlayTree
  • Selkie::App::Internal::RenderLoop
  • Selkie::App::Internal::ScreenModalLifecycle
  • Selkie::App::Internal::Terminal
  • Selkie::App::Internal::TerminalSequences
  • Selkie::Container
  • Selkie::EffectiveBounds
  • Selkie::Event
  • Selkie::Layout::Allocate
  • Selkie::Layout::HBox
  • Selkie::Layout::Split
  • Selkie::Layout::VBox
  • Selkie::Plot::Palette
  • Selkie::Plot::Scaler
  • Selkie::Plot::Ticks
  • Selkie::ScreenManager
  • Selkie::Sizing
  • Selkie::Store
  • Selkie::Style
  • Selkie::Test::Focus
  • Selkie::Test::Keys
  • Selkie::Test::Snapshot
  • Selkie::Test::Snapshot::Harness
  • Selkie::Test::Store
  • Selkie::Test::Supply
  • Selkie::Test::Tree
  • Selkie::Theme
  • Selkie::Trace
  • Selkie::Tree
  • Selkie::Widget
  • Selkie::Widget::Axis
  • Selkie::Widget::BarChart
  • Selkie::Widget::Border
  • Selkie::Widget::Button
  • Selkie::Widget::CardList
  • Selkie::Widget::Checkbox
  • Selkie::Widget::CommandPalette
  • Selkie::Widget::ConfirmModal
  • Selkie::Widget::FileBrowser
  • Selkie::Widget::FocusableByDefault
  • Selkie::Widget::Heatmap
  • Selkie::Widget::HelpOverlay
  • Selkie::Widget::Histogram
  • Selkie::Widget::Image
  • Selkie::Widget::Legend
  • Selkie::Widget::LineChart
  • Selkie::Widget::ListView
  • Selkie::Widget::Modal
  • Selkie::Widget::MultiLineInput
  • Selkie::Widget::PasswordStrength
  • Selkie::Widget::Plot
  • Selkie::Widget::ProgressBar
  • Selkie::Widget::RadioGroup
  • Selkie::Widget::RichText
  • Selkie::Widget::RichText::Span
  • Selkie::Widget::ScatterPlot
  • Selkie::Widget::ScrollView
  • Selkie::Widget::Select
  • Selkie::Widget::Sparkline
  • Selkie::Widget::Spinner
  • Selkie::Widget::TabBar
  • Selkie::Widget::Table
  • Selkie::Widget::Text
  • Selkie::Widget::TextInput
  • Selkie::Widget::TextInput::HighlightSpan
  • Selkie::Widget::TextStream
  • Selkie::Widget::Toast
  • Selkie::Widget::ViewportedCardList

Documentation

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.