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 60SEE ALSO
Selkie::Widget::RichText::Span ā the fragment value class
Selkie::Widget::Text ā simpler, single-style variant
Selkie::Widget::ScrollView ā for scrolling long rich text
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 MuReplace the displayed content with the given list of Spans. The wrap cache is invalidated; the next render rebuilds it.
method spans
method spans() returns ListThe current spans as a List.
method logical-height
method logical-height() returns UIntNumber of wrapped lines at the current width. Used by ScrollView.
method render-region
method render-region(
Int :$offset where { ... },
Int :$height where { ... }
) returns MuRender 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 ArrayPure 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.