bubble-table

repository·main·Indexed 20 days ago

https://github.com/evertras/bubble-table

A customizable, interactive table component for the Bubble Tea framework. It supports complex terminal UI requirements including pagination, sorting, filtering, scrolling, and advanced styling. Key features include flexible-width columns, multiline content, OSC 8 hyperlinks, and the ability to attach hidden metadata to rows for data retrieval.

Tokens
2.3K
Snippets
4
Records
20
Agent score
69%

What's inside bubble-table

  1. Define table columns and rows

    main

    A table is constructed using a slice of table.Column values and a slice of table.Row values.

    • Columns: Each column is defined with a unique string key, a display name, and an optional width.
    • Rows: Each row contains RowData, which is a map[string]any mapping column keys to data values.
    • Rendering: The table renders data using fmt.Sprintf("%v"). If a key exists in RowData but has no corresponding Column, it is ignored (useful for attaching hidden metadata). If a key exists in a Column but is missing from the RowData, the table can display a missing data indicator.
    • Styling: You can apply styles to entire rows or to individual cells using table.NewStyledCell.
    const (
      columnKeyID = "id"
      columnKeyName = "Name"
    )
    
    columns := []table.Column{
      table.NewColumn(columnKeyID, "ID", 5),
      table.NewColumn(columnKeyName, "Name", 10),
    }
    
    rows := []table.Row{
      table.NewRow(table.RowData{
        columnKeyID:   "abc",
        columnKeyName: "Hello",
      }),
      // Row with individual cell styling
      table.NewRow(table.RowData{
        columnKeyID:   "alert",
        columnKeyName: table.NewStyledCell("Alert", lipgloss.NewStyle().Foreground(lipgloss.Color("#f88")),
      }).WithStyle(lipgloss.NewStyle().Bold(true)),
    }
  2. Attach hidden metadata to rows

    main

    You can attach arbitrary data to a row by including keys in the RowData map that do not have a corresponding table.Column definition. This data remains attached to the row and can be retrieved when the row is selected, even though it is not rendered in the table UI. This is useful for mapping table rows back to complex domain objects.

    const (
      columnKeyID = "id"
      columnKeyName = "Name"
      columnKeyUserData = "userstuff" // This key has no Column, so it stays hidden
    )
    
    columns := []table.Column{
      table.NewColumn(columnKeyID, "ID", 5),
      table.NewColumn(columnKeyName, "Name", 10),
    }
    
    user := &SomeUser{ID: 3, Name: "Evertras"}
    
    rows := []table.Row{
      table.NewRow(table.RowData{
        columnKeyID:       user.ID,
        columnKeyName:     user.Name,
        columnKeyUserData: user, // Hidden metadata attached to the row
      }),
    }
  3. Use row metadata for data retrieval in bubble-table

    main
    Instead of retrieving data directly from the row values, you can attach metadata to rows. This allows you to use the metadata as a lookup key or a reference to retrieve the actual data you want to display. This technique is useful for performing more natural or complex data transformations where the row itself might only contain identifiers rather than the full displayable content.
  4. Use scrolling to navigate large tables

    main
    For tables that are too large to fit on a single screen, bubble-table provides scrolling capabilities. This allows users to navigate through extensive datasets within a constrained viewport. You can find implementation details for scrolling in the examples/scrolling directory of the repository.
  5. Run bubble-table examples

    main

    To explore the features of bubble-table, you can run the provided examples. After cloning the repository, use the following commands:

    # Run the pokemon demo for a general feel of common useful features
    make
    
    # Run dimensions example to see multiple sizes of simple tables in action
    make example-dimensions
    
    # Or run any of them directly
    go run ./examples/pagination/main.go
    make
    make example-dimensions
    go run ./examples/pagination/main.go
  6. Use external text controls for filtering in bubble-table

    main
    While bubble-table provides built-in filtering, you can implement more flexible UIs by using external text box controls to drive the filtering logic. This is achieved by manually interacting with the table's Filter API rather than relying on the default internal filter widgets. This pattern allows you to integrate the table into custom layouts where the search input is located outside the table component itself.
  7. Implement multiline content in bubble-table rows

    main
    The multiline feature in bubble-table allows users to input and display content that spans multiple lines within a single row. This is useful for displaying long descriptions, notes, or any data that cannot be contained in a single line without breaking the table layout. You can integrate this by following the patterns demonstrated in the multiline example code.
  8. Use OSC 8 hyperlinks in bubble-table

    main
    You can include clickable hyperlinks within a bubble-table by using OSC 8 escape sequences. In terminals that support OSC 8 (such as iTerm2, Ghostty, WezTerm, and kitty), text containing these sequences will be rendered as clickable links that open the specified URL in a browser.