Overview

RichText is a widget that displays text using multiple different styles. Inspired by Flutter’s RichText, it describes text using a tree of TextSpan objects, where each span has an associated style applied to that subtree.

All text in RichText must be explicitly styled. While the Text widget is simpler for single-style text, RichText is essential when you need complex text formatting, highlights, links, or mixed styles within a single text block.

See: https://api.flutter.dev/flutter/widgets/RichText-class.html

When to Use?

  • When you need multiple different styles within a single text
  • When highlighting or emphasizing parts of text
  • When creating links or clickable text areas
  • When complex text formatting (bold, italic, colors) is needed
  • When mixing various fonts or sizes within a paragraph

Basic Usage

import { RichText, TextSpan, TextStyle } from 'flitter';

// Basic rich text
const BasicRichText = RichText({
  text: new TextSpan({
    text: 'Hello, ',
    style: new TextStyle({
      fontSize: 16,
      color: 'black'
    }),
    children: [
      new TextSpan({
        text: 'bold text',
        style: new TextStyle({
          fontWeight: 'bold',
          color: '#e74c3c'
        })
      }),
      new TextSpan({
        text: '!'
      })
    ]
  })
});

Props

text (required)

Value: InlineSpan

The InlineSpan object (typically TextSpan) that describes the text to display. Defines both text content and styling.

text: new TextSpan({
  text: 'Main text',
  style: new TextStyle({ fontSize: 16 }),
  children: [
    new TextSpan({
      text: 'Child text',
      style: new TextStyle({ fontWeight: 'bold' })
    })
  ]
})

textAlign (optional)

Value: TextAlign (default: TextAlign.start)

Specifies how text should be aligned.

  • TextAlign.start: Start position based on text direction (default)
  • TextAlign.end: End position based on text direction
  • TextAlign.left: Left-aligned
  • TextAlign.right: Right-aligned
  • TextAlign.center: Center-aligned

overflow (optional)

Value: TextOverflow (default: TextOverflow.clip)

How to handle text that overflows its container.

  • TextOverflow.clip: Clip overflowing text
  • TextOverflow.ellipsis: Show ellipsis (…) for overflow
  • TextOverflow.visible: Display overflowing text outside container

softWrap (optional)

Value: boolean (default: true)

Whether text should wrap automatically when it runs out of space.

  • true: Automatically wrap to new lines
  • false: Keep text on a single line

maxLines (optional)

Value: number

Limits the maximum number of lines for the text. If exceeded, overflow settings determine handling.

textWidthBasis (optional)

Value: TextWidthBasis (default: TextWidthBasis.parent)

Determines how text width is calculated.

  • TextWidthBasis.parent: Calculate based on parent widget width
  • TextWidthBasis.longestLine: Calculate based on longest line length

textDirection (optional)

Value: TextDirection

Specifies the text direction.

  • TextDirection.ltr: Left-to-right (default)
  • TextDirection.rtl: Right-to-left

textScaleFactor (optional)

Value: number

Adjusts the scale factor for text size. 1.0 is default size, 2.0 is double size.

Real-World Examples

Example 1: Multi-styled Text

import { RichText, TextSpan, TextStyle } from 'flitter';

const StyledText = RichText({
  text: new TextSpan({
    text: 'This is ',
    style: new TextStyle({
      fontSize: 16,
      color: '#2c3e50'
    }),
    children: [
      new TextSpan({
        text: 'red ',
        style: new TextStyle({
          color: '#e74c3c',
          fontWeight: 'bold'
        })
      }),
      new TextSpan({
        text: 'and ',
        style: new TextStyle({
          fontSize: 14,
          fontStyle: 'italic'
        })
      }),
      new TextSpan({
        text: 'blue ',
        style: new TextStyle({
          color: '#3498db',
          fontSize: 20
        })
      }),
      new TextSpan({
        text: 'text.',
        style: new TextStyle({
          textDecoration: 'underline'
        })
      })
    ]
  })
});
import { RichText, TextSpan, TextStyle, GestureDetector } from 'flitter';

const LinkText = RichText({
  text: new TextSpan({
    text: 'For more information, ',
    style: new TextStyle({
      fontSize: 16,
      color: 'black'
    }),
    children: [
      new TextSpan({
        text: 'click here',
        style: new TextStyle({
          color: '#3498db',
          textDecoration: 'underline',
          fontWeight: 'bold'
        }),
        recognizer: new TapGestureRecognizer({
          onTap: () => {
            console.log('Link clicked!');
            // Handle link logic
          }
        })
      }),
      new TextSpan({
        text: '.'
      })
    ]
  })
});

Example 3: Code Highlighting

import { RichText, TextSpan, TextStyle } from 'flitter';

const CodeHighlight = RichText({
  text: new TextSpan({
    text: 'To define a function, use the ',
    style: new TextStyle({
      fontSize: 14,
      fontFamily: 'Arial'
    }),
    children: [
      new TextSpan({
        text: 'function',
        style: new TextStyle({
          fontFamily: 'Monaco, monospace',
          backgroundColor: '#f1f2f6',
          color: '#8e44ad',
          fontWeight: 'bold'
        })
      }),
      new TextSpan({
        text: ' keyword and write code inside ',
      }),
      new TextSpan({
        text: '{ }',
        style: new TextStyle({
          fontFamily: 'Monaco, monospace',
          backgroundColor: '#f1f2f6',
          color: '#e67e22'
        })
      }),
      new TextSpan({
        text: ' blocks.'
      })
    ]
  })
});

Example 4: Text Truncation with Ellipsis

import { RichText, TextSpan, TextStyle } from 'flitter';

const TruncatedText = RichText({
  maxLines: 2,
  overflow: TextOverflow.ellipsis,
  text: new TextSpan({
    text: 'This is very long text. ',
    style: new TextStyle({
      fontSize: 16
    }),
    children: [
      new TextSpan({
        text: 'This text will be truncated with ellipsis if it exceeds two lines. ',
        style: new TextStyle({
          fontWeight: 'bold'
        })
      }),
      new TextSpan({
        text: 'Additional text that may not be visible.'
      })
    ]
  })
});

Example 5: Multi-language Text Direction

import { RichText, TextSpan, TextStyle } from 'flitter';

const MultiLanguageText = Column({
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    // Left-to-right (English/Korean)
    RichText({
      textDirection: TextDirection.ltr,
      text: new TextSpan({
        text: 'Hello ',
        style: new TextStyle({ fontSize: 16 }),
        children: [
          new TextSpan({
            text: '안녕하세요',
            style: new TextStyle({
              color: '#e74c3c',
              fontWeight: 'bold'
            })
          })
        ]
      })
    }),
    
    SizedBox({ height: 10 }),
    
    // Right-to-left (Arabic, etc.)
    RichText({
      textDirection: TextDirection.rtl,
      text: new TextSpan({
        text: 'مرحبا ',
        style: new TextStyle({ fontSize: 16 }),
        children: [
          new TextSpan({
            text: 'World',
            style: new TextStyle({
              color: '#3498db',
              fontWeight: 'bold'
            })
          })
        ]
      })
    })
  ]
});

Example 6: Dynamic Style Changes

import { RichText, TextSpan, TextStyle } from 'flitter';

class DynamicRichText extends StatefulWidget {
  createState() {
    return new DynamicRichTextState();
  }
}

class DynamicRichTextState extends State {
  isHighlighted = false;
  
  build() {
    return GestureDetector({
      onTap: () => this.setState(() => {
        this.isHighlighted = !this.isHighlighted;
      }),
      child: RichText({
        text: new TextSpan({
          text: 'Click to change ',
          style: new TextStyle({
            fontSize: 16
          }),
          children: [
            new TextSpan({
              text: 'this part',
              style: new TextStyle({
                color: this.isHighlighted ? '#e74c3c' : '#3498db',
                fontWeight: this.isHighlighted ? 'bold' : 'normal',
                backgroundColor: this.isHighlighted ? '#f8f9fa' : 'transparent'
              })
            }),
            new TextSpan({
              text: ' dynamically.'
            })
          ]
        })
      })
    });
  }
}

Best Practices

  • Explicit Styling: All text in RichText must be explicitly styled
  • Performance: Complex TextSpan trees can impact rendering performance
  • Style Inheritance: Child TextSpans inherit parent styles (can be disabled with inherit: false)
  • Gesture Recognition: Add recognizers to TextSpans to handle touch events
  • Accessibility: Consider screen readers and create meaningful text structure
  • Text: When you need single-style text
  • SelectableText: When you need selectable text
  • TextField: When you need editable text input
  • Container: When you need text background or padding