CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-williamcallahan--tui4j

Terminal User Interface framework for Java that ports the Charmbracelet ecosystem (Bubble Tea, Bubbles, Lipgloss, Harmonica) from Go, enabling developers to build interactive CLI applications using The Elm Architecture pattern.

Overview
Eval results
Files

lipgloss-styling.mddocs/

Lipgloss Styling

Lipgloss is TUI4J's comprehensive styling system for terminal text, providing colors, text attributes, borders, padding, margins, alignment, and layout capabilities. It uses a fluent, immutable API for building styled text.

Style

The Style class is the main entry point for creating styled text.

package com.williamcallahan.tui4j.compat.lipgloss;

class Style {
    // Creation
    static Style newStyle();
    Style(Renderer renderer);

    // Color methods
    Style foreground(TerminalColor color);
    Style foreground(String color);
    Style background(TerminalColor color);
    Style background(String color);

    // Text attribute methods (all require boolean parameter)
    Style bold(boolean enabled);
    Style italic(boolean enabled);
    Style underline(boolean enabled);
    Style blink(boolean enabled);
    Style faint(boolean enabled);
    Style reverse(boolean enabled);

    // Sizing methods
    Style width(int width);
    Style height(int height);
    Style maxWidth(int maxWidth);
    Style maxHeight(int maxHeight);
    Style inline();

    // Padding methods
    Style padding(int padding);
    Style padding(int vertical, int horizontal);
    Style padding(int top, int right, int bottom, int left);
    Style padTop(int padding);
    Style padRight(int padding);
    Style padBottom(int padding);
    Style padLeft(int padding);

    // Margin methods
    Style margin(int margin);
    Style margin(int vertical, int horizontal);
    Style margin(int top, int right, int bottom, int left);
    Style marginTop(int margin);
    Style marginRight(int margin);
    Style marginBottom(int margin);
    Style marginLeft(int margin);

    // Border methods
    Style border(Border border);
    Style border(Border border, boolean top, boolean right, boolean bottom, boolean left);
    Style borderTop();
    Style borderTop(boolean enabled);
    Style borderRight();
    Style borderRight(boolean enabled);
    Style borderBottom();
    Style borderBottom(boolean enabled);
    Style borderLeft();
    Style borderLeft(boolean enabled);
    Style borderForeground(TerminalColor color);
    Style borderForeground(String color);
    Style borderBackground(TerminalColor color);
    Style borderBackground(String color);
    Style borderTopForeground(TerminalColor color);
    Style borderRightForeground(TerminalColor color);
    Style borderBottomForeground(TerminalColor color);
    Style borderLeftForeground(TerminalColor color);
    Style borderTopBackground(TerminalColor color);
    Style borderRightBackground(TerminalColor color);
    Style borderBottomBackground(TerminalColor color);
    Style borderLeftBackground(TerminalColor color);

    // Margin styling
    Style marginBackground(TerminalColor color);

    // Alignment methods
    Style alignHorizontal(Position position);
    Style alignVertical(Position position);

    // Utility methods
    Style unsetMaxWidth();
    Style unsetMaxHeight();
    Style transform(Function<String, String> fn);
    Style copy();

    // Getters
    int getWidth();
    int getHeight();
    int getMaxWidth();
    int getMaxHeight();
    int leftPadding();
    int rightPadding();
    int topPadding();
    int bottomPadding();

    // Content and rendering
    Style setString(String... lines);
    String render();
    String render(String content);
}

Basic Usage:

// Create a styled string
Style style = Style.newStyle()
    .foreground("#FF5733")
    .background("#000000")
    .bold(true)
    .padding(1, 2);

String output = style.render("Hello, World!");

Chaining Methods:

Style titleStyle = Style.newStyle()
    .foreground("#FFFFFF")
    .background("#0066CC")
    .bold(true)
    .padding(1, 3)
    .margin(1, 0)
    .width(40)
    .alignHorizontal(Position.Center)
    .border(StandardBorder.RoundedBorder)
    .borderForeground("#0066CC");

String title = titleStyle.render("Application Title");

Colors

Color Factory

The Color class provides factory methods for creating colors.

package com.williamcallahan.tui4j.compat.lipgloss.color;

class Color {
    // RGB colors
    static TerminalColor color(String hex);
    static TerminalColor color(int r, int g, int b);

    // ANSI colors
    static ANSIColor ansi(int code);

    // 256-color ANSI
    static ANSI256Color ansi256(int code);

    // Adaptive colors
    static AdaptiveColor adaptive(TerminalColor light, TerminalColor dark);
}

Usage:

// Hex color
TerminalColor red = Color.color("#FF0000");

// RGB values
TerminalColor blue = Color.color(0, 0, 255);

// ANSI color (0-15)
TerminalColor brightRed = Color.ansi(9);

// ANSI 256-color (0-255)
TerminalColor custom = Color.ansi256(203);

// Adaptive color (switches based on terminal background)
TerminalColor adaptive = Color.adaptive(
    Color.color("#000000"),  // Light background
    Color.color("#FFFFFF")   // Dark background
);

TerminalColor Interface

Base interface for all color types.

package com.williamcallahan.tui4j.compat.lipgloss.color;

interface TerminalColor {
    String sequence(boolean background);
}

RGBColor

True color (24-bit RGB).

package com.williamcallahan.tui4j.compat.lipgloss.color;

class RGBColor implements TerminalColor {
    RGBColor(int r, int g, int b);
    RGBColor(String hex);
}

ANSIColor

Standard 16-color ANSI.

package com.williamcallahan.tui4j.compat.lipgloss.color;

class ANSIColor implements TerminalColor {
    ANSIColor(int code);  // 0-15
}

Standard ANSI Colors:

  • 0: Black, 1: Red, 2: Green, 3: Yellow
  • 4: Blue, 5: Magenta, 6: Cyan, 7: White
  • 8-15: Bright variants

ANSI256Color

256-color ANSI palette.

package com.williamcallahan.tui4j.compat.lipgloss.color;

class ANSI256Color implements TerminalColor {
    ANSI256Color(int code);  // 0-255
}

AdaptiveColor

Color that adapts to terminal background.

package com.williamcallahan.tui4j.compat.lipgloss.color;

class AdaptiveColor implements TerminalColor {
    AdaptiveColor(TerminalColor light, TerminalColor dark);
}

NoColor

Represents absence of color.

package com.williamcallahan.tui4j.compat.lipgloss.color;

class NoColor implements TerminalColor {
    NoColor();
}

ColorProfile

Terminal color capability levels.

package com.williamcallahan.tui4j.compat.lipgloss.color;

enum ColorProfile {
    NoColor,      // No color support
    ANSI,         // 16 colors
    ANSI256,      // 256 colors
    TrueColor     // 24-bit RGB
}

RGB and HSL Records

package com.williamcallahan.tui4j.compat.lipgloss.color;

record RGB(int r, int g, int b) { }
record HSL(double h, double s, double l) { }

Borders

Border Record

Defines border characters for drawing boxes.

package com.williamcallahan.tui4j.compat.lipgloss.border;

record Border(
    String top,
    String bottom,
    String left,
    String right,
    String topLeft,
    String topRight,
    String bottomLeft,
    String bottomRight,
    String middleLeft,
    String middleRight,
    String middle,
    String middleTop,
    String middleBottom
) { }

StandardBorder

Pre-defined border styles.

package com.williamcallahan.tui4j.compat.lipgloss.border;

class StandardBorder {
    // Static final Border constants
    static final Border NoBorder;
    static final Border NormalBorder;
    static final Border RoundedBorder;
    static final Border BlockBorder;
    static final Border OuterHalfBlockBorder;
    static final Border InnerHalfBlockBorder;
    static final Border ThickBorder;
    static final Border DoubleBorder;
    static final Border HiddenBorder;
    static final Border MarkdownBorder;
    static final Border ASCIIBorder;
}

Usage:

// Normal box drawing characters
Style boxStyle = Style.newStyle()
    .border(StandardBorder.NormalBorder)
    .padding(1);

// Rounded corners
Style roundedStyle = Style.newStyle()
    .border(StandardBorder.RoundedBorder)
    .borderForeground("#00FF00");

// Thick borders
Style thickStyle = Style.newStyle()
    .border(StandardBorder.ThickBorder);

// Double-line borders
Style doubleStyle = Style.newStyle()
    .border(StandardBorder.DoubleBorder);

// Hidden border (for spacing without visible border)
Style spacedStyle = Style.newStyle()
    .border(StandardBorder.HiddenBorder)
    .padding(1);

Custom Borders:

Border customBorder = new Border(
    "-",  // top
    "-",  // bottom
    "|",  // left
    "|",  // right
    "+",  // topLeft
    "+",  // topRight
    "+",  // bottomLeft
    "+",  // bottomRight
    "+",  // middleLeft
    "+",  // middleRight
    "+",  // middle
    "+",  // middleTop
    "+"   // middleBottom
);

Style style = Style.newStyle().border(customBorder);

Partial Borders:

// Border only on top and bottom
Style style = Style.newStyle()
    .border(StandardBorder.NormalBorder, true, false, true, false);

// Border only on left
Style leftBorderStyle = Style.newStyle()
    .borderLeft(true)
    .borderForeground("#FF0000");

Layout and Alignment

Position Enum

Alignment positions.

package com.williamcallahan.tui4j.compat.lipgloss;

enum Position {
    Left, Center, Right,  // Horizontal
    Top, Bottom           // Vertical
}

Horizontal Alignment:

// Left-aligned (default)
Style leftStyle = Style.newStyle()
    .width(40)
    .alignHorizontal(Position.Left);

// Center-aligned
Style centerStyle = Style.newStyle()
    .width(40)
    .alignHorizontal(Position.Center);

// Right-aligned
Style rightStyle = Style.newStyle()
    .width(40)
    .alignHorizontal(Position.Right);

Vertical Alignment:

// Top-aligned (default)
Style topStyle = Style.newStyle()
    .height(10)
    .alignVertical(Position.Top);

// Center-aligned
Style middleStyle = Style.newStyle()
    .height(10)
    .alignVertical(Position.Center);

// Bottom-aligned
Style bottomStyle = Style.newStyle()
    .height(10)
    .alignVertical(Position.Bottom);

Dimensions

package com.williamcallahan.tui4j.compat.lipgloss;

record Dimensions(int width, int height) { }

Size

package com.williamcallahan.tui4j.compat.lipgloss;

record Size(int width, int height) { }

Layout Components

HorizontalJoinDecorator

Join multiple strings horizontally.

package com.williamcallahan.tui4j.compat.lipgloss.join;

class HorizontalJoinDecorator {
    static String join(Position position, String... strs);
}

Usage:

String left = Style.newStyle()
    .width(20)
    .background("#FF0000")
    .render("Left");

String right = Style.newStyle()
    .width(20)
    .background("#00FF00")
    .render("Right");

// Join at top
String joined = HorizontalJoinDecorator.join(Position.Top, left, right);

// Join centered
String centered = HorizontalJoinDecorator.join(Position.Center, left, right);

VerticalJoinDecorator

Join multiple strings vertically.

package com.williamcallahan.tui4j.compat.lipgloss.join;

class VerticalJoinDecorator {
    static String join(Position position, String... strs);
}

Usage:

String header = Style.newStyle()
    .width(40)
    .background("#0066CC")
    .render("Header");

String body = Style.newStyle()
    .width(40)
    .background("#FFFFFF")
    .foreground("#000000")
    .render("Body");

String footer = Style.newStyle()
    .width(40)
    .background("#666666")
    .render("Footer");

// Join vertically, left-aligned
String layout = VerticalJoinDecorator.join(Position.Left, header, body, footer);

List

Render lists with bullets or numbers.

package com.williamcallahan.tui4j.compat.lipgloss.list;

class List {
    List();

    List items(String... items);
    List enumerator(Enumerator enumerator);
    List enumeratorStyle(Style style);
    List itemStyle(Style style);

    String render();
}

Usage:

// Bulleted list
List bulletList = new List()
    .items("First item", "Second item", "Third item")
    .enumeratorStyle(Style.newStyle().foreground("#00FF00"))
    .itemStyle(Style.newStyle().foreground("#FFFFFF"));

String output = bulletList.render();

// Numbered list
List numberedList = new List()
    .items("Step 1", "Step 2", "Step 3")
    .enumerator(Enumerator.Arabic);

String numbered = numberedList.render();

Table

Render tables with borders and styling.

package com.williamcallahan.tui4j.compat.lipgloss.table;

class Table {
    Table();

    Table headers(String... headers);
    Table row(String... cells);
    Table rows(String[]... rows);
    Table border(Border border);
    Table borderStyle(Style style);
    Table styleFunc(BiFunction<Integer, Integer, Style> func);
    Table width(int width);

    String render();
}

Usage:

Table table = new Table()
    .headers("Name", "Age", "City")
    .row("Alice", "30", "New York")
    .row("Bob", "25", "San Francisco")
    .row("Charlie", "35", "Seattle")
    .border(StandardBorder.NormalBorder)
    .borderStyle(Style.newStyle().foreground("#00FF00"));

String output = table.render();

// Styled cells
Table styledTable = new Table()
    .headers("Col1", "Col2")
    .row("A", "B")
    .row("C", "D")
    .styleFunc((row, col) -> {
        if (row == 0) {
            // Header row
            return Style.newStyle().bold(true).foreground("#FFFF00");
        }
        if (col % 2 == 0) {
            return Style.newStyle().background("#333333");
        }
        return Style.newStyle();
    });

Table Data Interface and Filter:

package com.williamcallahan.tui4j.compat.lipgloss.table;

interface Data {
    String at(int row, int cell);
    int rows();
    int columns();
}

final class Filter implements Data {
    Filter(Data data);
    Filter filter(IntPredicate predicate);
    String at(int row, int cell);
    int rows();
    int columns();
}

Usage:

// Create a data source
Data myData = new Data() {
    String[][] data = {
        {"Alice", "30", "New York"},
        {"Bob", "25", "San Francisco"},
        {"Charlie", "35", "Seattle"},
        {"Diana", "28", "Boston"}
    };

    public String at(int row, int cell) {
        return data[row][cell];
    }

    public int rows() { return data.length; }
    public int columns() { return data[0].length; }
};

// Filter rows (e.g., only people over 28)
Filter filtered = new Filter(myData).filter(row -> {
    int age = Integer.parseInt(myData.at(row, 1));
    return age > 28;
});

// Use filtered data in table
Table table = new Table()
    .headers("Name", "Age", "City")
    .data(filtered);

Tree

Render tree structures.

package com.williamcallahan.tui4j.compat.lipgloss.tree;

class Tree {
    Tree();

    Tree root(Node root);
    Tree enumeratorStyle(Style style);
    Tree itemStyle(Style style);

    String render();
}

interface Node {
    String value();
    List<Node> children();
}

record Leaf(String value) implements Node {
    @Override
    default List<Node> children() {
        return List.of();
    }
}

Usage:

// Simple tree
class TreeNode implements Node {
    private final String value;
    private final List<Node> children;

    TreeNode(String value, Node... children) {
        this.value = value;
        this.children = List.of(children);
    }

    @Override
    public String value() { return value; }

    @Override
    public List<Node> children() { return children; }
}

Node root = new TreeNode("Root",
    new TreeNode("Child 1",
        new Leaf("Grandchild 1.1"),
        new Leaf("Grandchild 1.2")
    ),
    new TreeNode("Child 2",
        new Leaf("Grandchild 2.1")
    )
);

Tree tree = new Tree()
    .root(root)
    .enumeratorStyle(Style.newStyle().foreground("#00FF00"))
    .itemStyle(Style.newStyle().foreground("#FFFFFF"));

String output = tree.render();

Tree Helper Interfaces and Classes:

package com.williamcallahan.tui4j.compat.lipgloss.tree;

// TreeEnumerator - Generates node prefixes
interface TreeEnumerator {
    String enumerate(int index);
}

// TreeIndenter - Generates indentation
interface TreeIndenter {
    String indent(int level);
}

// TreeStyle - Style configuration for tree rendering
class TreeStyle {
    TreeStyle();

    TreeStyle withEnumerator(TreeEnumerator enumerator);
    TreeStyle withIndenter(TreeIndenter indenter);
    TreeStyle withEnumeratorStyle(Style style);
    TreeStyle withItemStyle(Style style);
}

// StyleFunction - Dynamic styling based on tree state
interface StyleFunction {
    Style apply(String value, boolean isLeaf, int depth);
}

// Filter - Filter nodes based on criteria
interface Filter {
    boolean test(Node node);
}

// Children - Provide children for a node
interface Children {
    List<Node> children(Node node);
}

// NodeChildren - Helper for managing node children
class NodeChildren {
    static NodeChildren of(Node... nodes);
    static NodeChildren of(List<Node> nodes);

    List<Node> nodes();
}

// Renderer - Advanced tree rendering
class Renderer {
    Renderer();

    String render(Node root);
    String render(Node root, TreeStyle style);
}

Advanced Tree Usage:

// Custom enumerator
TreeEnumerator romanEnumerator = index -> {
    String[] romans = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"};
    return index < romans.length ? romans[index] + ". " : (index + 1) + ". ";
};

// Custom indenter
TreeIndenter customIndenter = level -> "  ".repeat(level) + "├─ ";

// Create styled tree
TreeStyle customStyle = new TreeStyle()
    .withEnumerator(romanEnumerator)
    .withIndenter(customIndenter)
    .withEnumeratorStyle(Style.newStyle().foreground("#FFFF00").bold(true))
    .withItemStyle(Style.newStyle().foreground("#FFFFFF"));

Tree tree = new Tree()
    .root(root)
    .style(customStyle);

// Dynamic styling with StyleFunction
StyleFunction depthStyling = (value, isLeaf, depth) -> {
    String[] colors = {"#FF0000", "#00FF00", "#0000FF", "#FFFF00"};
    return Style.newStyle().foreground(colors[depth % colors.length]);
};

// Filtered tree (show only specific nodes)
Filter onlyFilesFilter = node -> {
    return node instanceof FileNode && ((FileNode) node).isFile();
};

Renderer

The Renderer provides rendering context for styles.

package com.williamcallahan.tui4j.compat.lipgloss;

class Renderer {
    // Factory
    static Renderer defaultRenderer();

    // Constructor
    Renderer(Output output);

    // Style creation
    Style newStyle();

    // Terminal information
    boolean hasDarkBackground();
    ColorProfile colorProfile();

    // Configuration
    void setColorProfile(ColorProfile profile);
    void setHasDarkBackground(boolean dark);
}

Usage:

// Use default renderer
Renderer renderer = Renderer.defaultRenderer();
Style style = renderer.newStyle()
    .foreground("#FF0000");

// Create custom renderer
Output output = new Output(/* configuration */);
Renderer customRenderer = new Renderer(output);

// Check terminal capabilities
if (renderer.hasDarkBackground()) {
    style = style.foreground("#FFFFFF");
} else {
    style = style.foreground("#000000");
}

// Force color profile
renderer.setColorProfile(ColorProfile.ANSI256);

Utility Classes

Join

The Join class provides utilities for joining styled strings horizontally or vertically.

package com.williamcallahan.tui4j.compat.lipgloss;

final class Join {
    static String joinHorizontal(Position position, String... strings);
    static String joinVertical(Position position, String... strings);
}

Usage:

// Join strings horizontally (side-by-side)
String left = Style.newStyle().width(20).render("Left panel");
String right = Style.newStyle().width(20).render("Right panel");
String horizontal = Join.joinHorizontal(Position.Top, left, right);

// Join strings vertically (stacked)
String header = Style.newStyle().width(40).render("Header");
String body = Style.newStyle().width(40).render("Body");
String footer = Style.newStyle().width(40).render("Footer");
String vertical = Join.joinVertical(Position.Left, header, body, footer);

Alignment

The Alignment class provides text alignment utilities for positioning content.

package com.williamcallahan.tui4j.compat.lipgloss;

final class Alignment {
    static String alignTextHorizontal(String input, Position position, int width);
    static String alignTextHorizontal(String input, Position position, int width, AttributedStyle attributedStyle);
    static String alignTextVertical(String input, Position position, int height);
}

Usage:

// Center text horizontally
String centered = Alignment.alignTextHorizontal("Hello", Position.Center, 40);

// Right-align text
String rightAligned = Alignment.alignTextHorizontal("Right", Position.Right, 40);

// Center text vertically
String verticallyCentered = Alignment.alignTextVertical("Middle", Position.Center, 10);

Borders

The Borders class provides factory methods for creating border styles.

package com.williamcallahan.tui4j.compat.lipgloss;

final class Borders {
    // Factory methods that return Border instances
    // These delegate to StandardBorder static final constants
    static Border noBorder();
    static Border normalBorder();
    static Border roundedBorder();
    static Border blockBorder();
    static Border outerHalfBlockBorder();
    static Border innerHalfBlockBorder();
    static Border thickBorder();
    static Border doubleBorder();
    static Border hiddenBorder();
    static Border markdownBorder();
    static Border asciiBorder();
}

Usage:

// Recommended: Use StandardBorder constants directly
Style normalStyle = Style.newStyle().border(StandardBorder.NormalBorder);
Style roundedStyle = Style.newStyle().border(StandardBorder.RoundedBorder);
Style thickStyle = Style.newStyle().border(StandardBorder.ThickBorder);
Style markdownStyle = Style.newStyle().border(StandardBorder.MarkdownBorder);
Style asciiStyle = Style.newStyle().border(StandardBorder.ASCIIBorder);

// Alternative: Use Borders utility class (delegates to StandardBorder)
Style normalStyle2 = Style.newStyle().border(Borders.normalBorder());

Runes

The Runes class provides utilities for styling specific characters within a string.

package com.williamcallahan.tui4j.compat.lipgloss;

class Runes {
    static String styleRunes(String input, int[] indices, Style matched, Style unmatched);
}

Usage:

// Highlight specific characters in a string
Style highlighted = Style.newStyle().foreground("#FFFF00").bold(true);
Style normal = Style.newStyle().foreground("#FFFFFF");
int[] indices = {0, 5, 10}; // Highlight characters at these positions
String styled = Runes.styleRunes("Hello World Example", indices, highlighted, normal);

Whitespace

The Whitespace class provides utilities for rendering styled whitespace.

package com.williamcallahan.tui4j.compat.lipgloss;

final class Whitespace {
    Whitespace(Style style);
    String render(int width);

    // Options
    interface WhitespaceOption {
        void apply(Whitespace whitespace);
    }

    static WhitespaceOption WithWhitespaceForeground(TerminalColor color);
    static WhitespaceOption WithWhitespaceBackground(TerminalColor color);
    static WhitespaceOption WithWhitespaceChars(String chars);
    static Whitespace newWhiteSpace(Renderer renderer, WhitespaceOption... options);
}

Usage:

// Create styled whitespace
Renderer renderer = Renderer.defaultRenderer();
Whitespace ws = Whitespace.newWhiteSpace(
    renderer,
    Whitespace.WithWhitespaceBackground(Color.color("#333333")),
    Whitespace.WithWhitespaceChars(".")
);
String spacer = ws.render(40); // 40 characters of styled whitespace

// Simple whitespace with style
Style bgStyle = Style.newStyle().background("#222222");
Whitespace simple = new Whitespace(bgStyle);
String space = simple.render(20);

TextLines

The TextLines class provides utilities for analyzing multi-line text.

package com.williamcallahan.tui4j.compat.lipgloss;

class TextLines {
    static TextLines fromText(String text);
    int widestLineLength();
    String[] lines();
}

Usage:

// Analyze text dimensions
String multilineText = "Line 1\nLine 2 is longer\nLine 3";
TextLines textLines = TextLines.fromText(multilineText);
int maxWidth = textLines.widestLineLength();
String[] lines = textLines.lines();

// Use for dynamic width calculation
Style dynamicStyle = Style.newStyle().width(maxWidth + 4);

ListEnumerator

The ListEnumerator interface provides enumerators for list rendering in trees and lists.

package com.williamcallahan.tui4j.compat.lipgloss;

interface ListEnumerator extends TreeEnumerator {
    int abcLen = 26;

    static TreeEnumerator alphabet();
    static TreeEnumerator arabic();
    static TreeEnumerator roman();
    static TreeEnumerator bullet();
    static TreeEnumerator asterisk();
    static TreeEnumerator dash();
}

Usage:

// Use with Tree component
Tree tree = new Tree()
    .enumerator(ListEnumerator.arabic());  // 1., 2., 3., ...

Tree bulletTree = new Tree()
    .enumerator(ListEnumerator.bullet());  // •, •, •, ...

Tree alphaTree = new Tree()
    .enumerator(ListEnumerator.alphabet());  // a., b., c., ...

Output

The Output class provides terminal output configuration and color profile detection.

package com.williamcallahan.tui4j.compat.lipgloss;

class Output {
    Output();
    static Output defaultOutput();
    ColorProfile envColorProfile();
    boolean hasDarkBackground();
    TerminalColor backgroundColor();
}

Usage:

// Get default terminal output
Output output = Output.defaultOutput();

// Check color capabilities
ColorProfile profile = output.envColorProfile();
boolean darkMode = output.hasDarkBackground();
TerminalColor bgColor = output.backgroundColor();

// Use for adaptive styling
Style adaptiveStyle;
if (output.hasDarkBackground()) {
    adaptiveStyle = Style.newStyle().foreground("#FFFFFF");
} else {
    adaptiveStyle = Style.newStyle().foreground("#000000");
}

ANSIColors

The ANSIColors class provides the 256-color ANSI palette as hex values.

package com.williamcallahan.tui4j.compat.lipgloss.color;

final class ANSIColors {
    static final String[] ANSI_HEX;  // 256-element hex color palette
}

Usage:

// Access ANSI color palette
String color42 = ANSIColors.ANSI_HEX[42]; // Get hex value for ANSI color 42
TerminalColor termColor = Color.color(color42);

// Use in styles
Style ansiStyle = Style.newStyle().foreground(ANSIColors.ANSI_HEX[196]); // Bright red

Advanced Styling Patterns

Conditional Styling

Style createStyle(boolean isActive) {
    Style style = Style.newStyle()
        .padding(1, 2)
        .border(StandardBorder.RoundedBorder);

    if (isActive) {
        style = style
            .foreground("#00FF00")
            .bold(true)
            .borderForeground("#00FF00");
    } else {
        style = style
            .foreground("#666666")
            .borderForeground("#666666");
    }

    return style;
}

Style Composition

// Base style
Style baseStyle = Style.newStyle()
    .padding(1)
    .border(StandardBorder.NormalBorder);

// Derive variants
Style successStyle = baseStyle
    .foreground("#00FF00")
    .borderForeground("#00FF00");

Style errorStyle = baseStyle
    .foreground("#FF0000")
    .borderForeground("#FF0000");

Style warningStyle = baseStyle
    .foreground("#FFFF00")
    .borderForeground("#FFFF00");

Responsive Width

Style createResponsiveStyle(int terminalWidth) {
    int contentWidth = Math.max(40, Math.min(80, terminalWidth - 4));

    return Style.newStyle()
        .width(contentWidth)
        .padding(1, 2)
        .alignHorizontal(Position.Center);
}

Theme System

class Theme {
    Style primaryStyle = Style.newStyle()
        .foreground("#FFFFFF")
        .background("#0066CC")
        .bold(true);

    Style secondaryStyle = Style.newStyle()
        .foreground("#FFFFFF")
        .background("#666666");

    Style errorStyle = Style.newStyle()
        .foreground("#FFFFFF")
        .background("#FF0000")
        .bold(true);

    Style successStyle = Style.newStyle()
        .foreground("#FFFFFF")
        .background("#00AA00")
        .bold(true);
}

Complex Layouts

// Header-Body-Footer layout
Style headerStyle = Style.newStyle()
    .width(80)
    .padding(1, 2)
    .background("#0066CC")
    .foreground("#FFFFFF")
    .bold(true);

Style bodyStyle = Style.newStyle()
    .width(80)
    .height(20)
    .padding(1, 2)
    .border(StandardBorder.NormalBorder)
    .alignVertical(Position.Top);

Style footerStyle = Style.newStyle()
    .width(80)
    .padding(0, 2)
    .foreground("#666666");

String header = headerStyle.render("Application Title");
String body = bodyStyle.render("Content goes here...");
String footer = footerStyle.render("Press 'q' to quit");

String layout = VerticalJoinDecorator.join(
    Position.Left,
    header,
    body,
    footer
);

Two-Column Layout

Style leftColumnStyle = Style.newStyle()
    .width(40)
    .height(20)
    .padding(1)
    .border(StandardBorder.NormalBorder)
    .borderForeground("#00FF00");

Style rightColumnStyle = Style.newStyle()
    .width(40)
    .height(20)
    .padding(1)
    .border(StandardBorder.NormalBorder)
    .borderForeground("#FF00FF");

String leftColumn = leftColumnStyle.render("Left content");
String rightColumn = rightColumnStyle.render("Right content");

String layout = HorizontalJoinDecorator.join(
    Position.Top,
    leftColumn,
    rightColumn
);

Install with Tessl CLI

npx tessl i tessl/maven-com-williamcallahan--tui4j

docs

animation.md

bubbles-components.md

bubbletea-core.md

index.md

input-handling.md

lipgloss-styling.md

utilities.md

tile.json