Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProwlEngine/Prowl.Paper/llms.txt

Use this file to discover all available pages before exploring further.

Prowl.Paper handles text display and text input as first-class element capabilities. Static content is set directly on an element with Text, RichText, or Markdown; interactive editing is added with TextField or TextArea. All text styling properties (FontSize, TextColor, etc.) are inherited from StyleSetterBase<T> and interact correctly with state blocks and style templates.

Text Display

Text

public ElementBuilder Text(string text, FontFile font)
text
string
required
Plain text content to display. No markup is interpreted.
font
FontFile
required
Font asset used to render the text.
Renders static, unstyled text inside the element. Sizing, color, and alignment are controlled by the style properties described in Text Styling.
Paper.Element("heading")
    .Text("Welcome to Prowl", myFont)
    .FontSize(24f)
    .TextColor(Color32.FromArgb(255, 220, 220, 240));

Markdown

public ElementBuilder Markdown(
    string text,
    FontFile font,
    FontFile bold,
    FontFile italic,
    FontFile boldItalic,
    FontFile mono)
text
string
required
Markdown-formatted text.
font
FontFile
required
Default font for body text.
bold
FontFile
required
Font for **bold** spans.
italic
FontFile
required
Font for *italic* spans.
boldItalic
FontFile
required
Font for ***bold-italic*** spans.
mono
FontFile
required
Font for `code` spans.
Parses the text as Markdown and renders inline formatting. Block-level Markdown elements (headings, lists, code fences) are supported where the underlying Scribe renderer implements them.
Paper.Element("readme")
    .Width(UnitValue.StretchOne)
    .Markdown(
        "Hello **World** — visit `ProwlEngine` for more.",
        regularFont, boldFont, italicFont, boldItalicFont, monoFont)
    .FontSize(15f)
    .Wrap(TextWrapMode.Wrap);

RichText

public ElementBuilder RichText(
    string text,
    FontFile font,
    FontFile bold,
    FontFile italic,
    FontFile boldItalic,
    FontFile mono)
Renders tagged rich text. The laid-out result is cached across frames so that animation timers (typewriter reveal, wave, pulse) survive between frames. Call Paper.ResetRichText on the element’s handle to replay animations from the beginning. Supported inline tags:
CategoryTags
Style<b>, <i>, <u>, <s>, <color=…>, <size=…>, <font=mono>
Link<link=…>
Animation<shake>, <wave>, <rainbow>, <pulse>, <fade>, <jitter>, <typewriter>
Paper.Element("fancy-label")
    .RichText(
        "Score: <color=#FFD700><b><wave>9999</wave></b></color>",
        regularFont, boldFont, italicFont, boldItalicFont, monoFont)
    .FontSize(18f)
    .Alignment(TextAlignment.MiddleCenter);

Alignment

public ElementBuilder Alignment(TextAlignment mode)
mode
TextAlignment
required
Controls both the horizontal and vertical anchor of text within the element’s content box.
ValuePosition
LeftTop-left
CenterTop-center
RightTop-right
MiddleLeftVertically centered, left-aligned
MiddleCenterFully centered
MiddleRightVertically centered, right-aligned
BottomLeftBottom-left
BottomCenterBottom-center
BottomRightBottom-right
Paper.Element("badge")
    .Size(UnitValue.Pixels(64))
    .Text("OK", uiFont)
    .Alignment(TextAlignment.MiddleCenter);

Wrap

public ElementBuilder Wrap(TextWrapMode mode)
mode
TextWrapMode
required
TextWrapMode.NoWrap — text overflows horizontally (default).
TextWrapMode.Wrap — text wraps at the element’s content width.
Paper.Element("description")
    .Width(UnitValue.Pixels(400))
    .Text(longDescription, bodyFont)
    .Wrap(TextWrapMode.Wrap)
    .FontSize(14f);

Text Styling

These properties are set on the element and affect all text rendered inside it. They cascade to children via the style inheritance system.

TextColor

public ElementBuilder TextColor(Color color)
Sets the color of rendered glyphs. Applies to Text, Markdown, RichText, and uncolored spans inside tagged rich text.

FontSize

public ElementBuilder FontSize(float size)
size
float
required
Glyph size in logical pixels.

LetterSpacing

public ElementBuilder LetterSpacing(float spacing)
spacing
float
required
Extra horizontal space between glyphs in pixels. Can be negative to tighten tracking.

WordSpacing

public ElementBuilder WordSpacing(float spacing)
spacing
float
required
Extra space added between words.

LineHeight

public ElementBuilder LineHeight(float height)
height
float
required
Line height as a multiplier of FontSize. 1.0 = tight; 1.4 is a comfortable default for body copy.

TabSize

public ElementBuilder TabSize(int size)
size
int
required
Number of spaces a tab character expands to. Default is typically 4.

Text Input Controls

TextField

Creates a single-line editable text control. The element that calls TextField becomes the input container — apply sizing, background, border, and padding to it as normal. Overload 1 — full settings:
public ElementBuilder TextField(
    string value,
    TextInputSettings settings,
    Action<string> onChange = null)
value
string
required
Current text value. The field reads this every frame when unfocused; while focused, internal state is authoritative (see TextInputSettings.ForceValue to override).
settings
TextInputSettings
required
Struct controlling font, colors, placeholder, masking, filtering, and more (see below).
onChange
Action<string>
Callback invoked with the updated string each time the value changes.
Overload 2 — simple parameters:
public ElementBuilder TextField(
    string value,
    FontFile font,
    Action<string> onChange = null,
    Color? textColor = null,
    string placeholder = "",
    Color? placeholderColor = null)
Use the simple overload for quick prototyping; switch to the settings overload for production controls that need masking, filtering, or SelectAllOnFocus.
string name = "";

Paper.Element("name-field")
    .Size(UnitValue.Pixels(240), UnitValue.Pixels(32))
    .BackgroundColor(darkBg)
    .Rounded(4f)
    .Padding(UnitValue.Pixels(6))
    .TextField(name, uiFont,
        onChange: v => name = v,
        placeholder: "Enter name…");

TextArea

Creates a multi-line editable text control with vertical scrolling and optional word wrap. Overload 1 — full settings:
public ElementBuilder TextArea(
    string value,
    TextInputSettings settings,
    Action<string> onChange = null)
Overload 2 — simple parameters:
public ElementBuilder TextArea(
    string value,
    FontFile font,
    Action<string> onChange = null,
    string placeholder = "",
    Color? textColor = null,
    Color? placeholderColor = null)
TextArea automatically enables ContentSizer for the inner text content so the element’s height grows with its content when unconstrained. Give the element a fixed height and call Clip() to produce a scrollable box.
string notes = "";

Paper.Element("notes-area")
    .Size(UnitValue.Pixels(400), UnitValue.Pixels(200))
    .BackgroundColor(darkBg)
    .Rounded(4f)
    .Padding(UnitValue.Pixels(8))
    .Clip()
    .TextArea(notes, uiFont, v => notes = v, placeholder: "Write here…");

TextInputSettings

TextInputSettings is a plain value struct. All fields have defaults provided by the static Default property.
var settings = TextInputSettings.Default;
FieldTypeDefaultDescription
FontFontFilenullFont used to render and measure text inside the field.
TextColorColorNear-whiteColor of input text.
Placeholderstring""Hint text shown when the field is empty and unfocused.
PlaceholderColorColorMuted greyColor of placeholder text.
ReadOnlyboolfalseWhen true, the field displays text but rejects all edits.
MaxLengthint0Maximum character count. 0 means no limit.
DoWrapbooltrueMulti-line only — true to wrap lines at the field width; false to scroll horizontally.
CharFilterFunc<char, string, bool>nullReturn true to accept a character, false to reject it. Receives the incoming character and the current full value.
SelectAllOnFocusboolfalseSelects all text when the field gains focus.
MaskCharchar?nullWhen set, every visible character is replaced with this glyph for display. The underlying value is unchanged. Clipboard copy/cut is suppressed while masking.
ForceValuestringnullWhen non-null, overrides the internal value for the current frame regardless of focus state. Reset to null on subsequent frames.
ForceSelectAllboolfalseCompanion to ForceValue: selects all text after a forced update, if the field is focused.

Examples

Password field

Use MaskChar to hide characters and MaxLength to cap input:
string password = "";

var pwSettings = TextInputSettings.Default;
pwSettings.Font       = uiFont;
pwSettings.MaskChar   = '●';
pwSettings.MaxLength  = 128;
pwSettings.Placeholder = "Password";

Paper.Element("pw-field")
    .Size(UnitValue.Pixels(240), UnitValue.Pixels(32))
    .BackgroundColor(darkBg)
    .BorderColor(accentColor).BorderWidth(1f)
    .Rounded(4f)
    .Padding(UnitValue.Pixels(6))
    .TextField(password, pwSettings, v => password = v);
Clipboard copy and cut (Ctrl+C / Ctrl+X) are automatically suppressed when MaskChar is set, so masked content cannot leave the field via the clipboard.

Numeric-only field

Use CharFilter to accept only digits and an optional decimal point:
string numericValue = "0";

var numSettings = TextInputSettings.Default;
numSettings.Font = uiFont;
numSettings.CharFilter = (ch, currentValue) =>
    char.IsDigit(ch) || (ch == '.' && !currentValue.Contains('.'));

Paper.Element("numeric-field")
    .Size(UnitValue.Pixels(120), UnitValue.Pixels(32))
    .BackgroundColor(darkBg)
    .Rounded(4f)
    .Padding(UnitValue.Pixels(6))
    .TextField(numericValue, numSettings, v => numericValue = v);

Programmatic value override with ForceValue

When you need to push a new value into a focused field from outside (e.g. an autocomplete suggestion), set ForceValue for exactly one frame:
string query = "";
bool applyAutocomplete = false;
string autocompleteResult = "";

var searchSettings = TextInputSettings.Default;
searchSettings.Font = uiFont;
searchSettings.Placeholder = "Search…";
searchSettings.SelectAllOnFocus = true;

if (applyAutocomplete)
{
    searchSettings.ForceValue     = autocompleteResult;
    searchSettings.ForceSelectAll = false;  // place cursor at end, don't select
    applyAutocomplete = false;              // clear flag — only force for one frame
}

Paper.Element("search-field")
    .Size(UnitValue.Pixels(300), UnitValue.Pixels(32))
    .BackgroundColor(darkBg)
    .Rounded(4f)
    .Padding(UnitValue.Pixels(6))
    .TextField(query, searchSettings, v => query = v);
Set ForceValue only on the frame you want to apply the change. On subsequent frames, leave it as null; otherwise the field’s internal editing state is replaced every frame, breaking normal typing.

Read-only display field

var roSettings = TextInputSettings.Default;
roSettings.Font     = uiFont;
roSettings.ReadOnly = true;
roSettings.TextColor = Color32.FromArgb(200, 200, 200, 200);

Paper.Element("status-display")
    .Size(UnitValue.Pixels(200), UnitValue.Pixels(32))
    .BackgroundColor(Color32.FromArgb(40, 255, 255, 255))
    .Rounded(4f)
    .Padding(UnitValue.Pixels(6))
    .TextField(currentStatusText, roSettings);

Build docs developers (and LLMs) love