{"id":23247149,"url":"https://github.com/evertras/bubble-table","last_synced_at":"2025-05-13T22:06:37.250Z","repository":{"id":38021893,"uuid":"458397184","full_name":"Evertras/bubble-table","owner":"Evertras","description":"A customizable, interactive table component for the Bubble Tea framework","archived":false,"fork":false,"pushed_at":"2024-10-31T13:58:13.000Z","size":681,"stargazers_count":488,"open_issues_count":15,"forks_count":29,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-11T10:00:57.487Z","etag":null,"topics":["bubble","bubble-tea","bubbles","go","golang","table","tui"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Evertras.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-02-12T02:14:17.000Z","updated_at":"2025-04-05T17:16:46.000Z","dependencies_parsed_at":"2022-07-09T17:46:57.309Z","dependency_job_id":"cc2ccf95-50f8-4ec3-90e3-04901e9954c9","html_url":"https://github.com/Evertras/bubble-table","commit_stats":null,"previous_names":[],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evertras%2Fbubble-table","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evertras%2Fbubble-table/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evertras%2Fbubble-table/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evertras%2Fbubble-table/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Evertras","download_url":"https://codeload.github.com/Evertras/bubble-table/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251341359,"owners_count":21574108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bubble","bubble-tea","bubbles","go","golang","table","tui"],"created_at":"2024-12-19T07:17:33.695Z","updated_at":"2025-04-28T15:44:19.698Z","avatar_url":"https://github.com/Evertras.png","language":"Go","readme":"# Bubble-table\n\n\u003cp\u003e\n  \u003ca href=\"https://github.com/Evertras/bubble-table/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/release/Evertras/bubble-table.svg\" alt=\"Latest Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/evertras/bubble-table/table?tab=doc\"\u003e\u003cimg src=\"https://godoc.org/github.com/golang/gddo?status.svg\" alt=\"GoDoc\"\u003e\u003c/a\u003e\n  \u003ca href='https://coveralls.io/github/Evertras/bubble-table?branch=main'\u003e\u003cimg src='https://coveralls.io/repos/github/Evertras/bubble-table/badge.svg?branch=main\u0026hash=abc' alt='Coverage Status'/\u003e\u003c/a\u003e\n  \u003ca href='https://goreportcard.com/report/github.com/evertras/bubble-table'\u003e\u003cimg src='https://goreportcard.com/badge/github.com/evertras/bubble-table' alt='Go Report Card' /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nA customizable, interactive table component for the\n[Bubble Tea framework](https://github.com/charmbracelet/bubbletea).\n\n![Styled table](https://user-images.githubusercontent.com/5923958/188168029-0de392c8-dbb0-47da-93a0-d2a6e3d46838.png)\n\n[View above sample source code](./examples/pokemon)\n\n## Contributing\n\nContributions welcome, please [check the contributions doc](./CONTRIBUTING.md)\nfor a few helpful tips!\n\n## Features\n\nFor a code reference of most available features, please see the [full feature example](./examples/features).\nIf you want to get started with a simple default table, [check the simplest example](./examples/simplest).\n\nDisplays a table with a header, rows, footer, and borders.  The header can be\nhidden, and the footer can be set to automatically show page information, use\ncustom text, or be hidden by default.\n\nColumns can be fixed-width [or flexible width](./examples/flex).  A maximum\nwidth can be specified which enables [horizontal scrolling](./examples/scrolling),\nand left-most columns can be frozen for easier reference.\n\nBorder shape is customizable with a basic thick square default.  The color can\nbe modified by applying a base style with `lipgloss.NewStyle().BorderForeground(...)`.\n\nStyles can be applied globally and to columns, rows, and individual cells.\nThe base style is applied first, then column, then row, then cell when\ndetermining overrides.  The default base style is a basic right-alignment.\n[See the main feature example](./examples/features) to see styles and\nhow they override each other.\n\nStyles can also be applied via a style function which can be used to apply\nzebra striping, data-specific formatting, etc.\n\nCan be focused to highlight a row and navigate with up/down (and j/k).  These\nkeys can be customized with a KeyMap.\n\nCan make rows selectable, and fetch the current selections.\n\nEvents can be checked for user interactions.\n\nPagination can be set with a given page size, which automatically generates a\nsimple footer to show the current page and total pages.\n\nBuilt-in filtering can be enabled by setting any columns as filterable, using\na text box in the footer and `/` (customizable by keybind) to start filtering.\n\nA missing indicator can be supplied to show missing data in rows.\n\nColumns can be sorted in either ascending or descending order.  Multiple columns\ncan be specified in a row.  If multiple columns are specified, first the table\nis sorted by the first specified column, then each group within that column is\nsorted in smaller and smaller groups.  [See the sorting example](examples/sorting)\nfor more information.  If a column contains numbers (either ints or floats),\nthe numbers will be sorted by numeric value.  Otherwise rendered string values\nwill be compared.\n\nIf a feature is confusing to use or could use a better example, please feel free\nto open an issue.\n\n## Defining table data\n\nA table is defined by a list of `Column` values that define the columns in the\ntable.  Each `Column` is associated with a unique string key.\n\nA table contains a list of `Row`s.  Each `Row` contains a `RowData` object which\nis simply a map of string column IDs to arbitrary `interface{}` data values.\nWhen the table is rendered, each `Row` is checked for each `Column` key.  If the\nkey exists in the `Row`'s `RowData`, it is rendered with `fmt.Sprintf(\"%v\")`.\nIf it does not exist, nothing is rendered.\n\nExtra data in the `RowData` object is ignored.  This can be helpful to simply\ndump data into `RowData` and create columns that select what is interesting to\nview, or to generate different columns based on view options on the fly (see the\n[metadata example](./examples/metadata) for an example of using this).\n\nAn example is given below.  For more detailed examples, see\n[the examples directory](./examples).\n\n```golang\n// This makes it easier/safer to match against values, but isn't necessary\nconst (\n  // This value isn't visible anywhere, so a simple lowercase is fine\n  columnKeyID = \"id\"\n\n  // It's just a string, so it can be whatever, really!  They only must be unique\n  columnKeyName = \"何?!\"\n)\n\n// Note that there's nothing special about \"ID\" or \"Name\", these are completely\n// arbitrary columns\ncolumns := []table.Column{\n  table.NewColumn(columnKeyID, \"ID\", 5),\n  table.NewColumn(columnKeyName, \"Name\", 10),\n}\n\nrows := []table.Row{\n  // This row contains both an ID and a name\n  table.NewRow(table.RowData{\n    columnKeyID:          \"abc\",\n    columnKeyName:        \"Hello\",\n  }),\n\n  table.NewRow(table.RowData{\n    columnKeyID:          \"123\",\n    columnKeyName:        \"Oh no\",\n    // This field exists in the row data but won't be visible\n    \"somethingelse\": \"Super bold!\",\n  }),\n\n  table.NewRow(table.RowData{\n    columnKeyID:          \"def\",\n    // This row is missing the Name column, so it will use the supplied missing\n    // indicator if supplied when creating the table using the following option:\n    // .WithMissingDataIndicator(\"\u003cない\u003e\") (or .WithMissingDataIndicatorStyled!)\n  }),\n\n  // We can also apply styling to the row or to individual cells\n\n  // This row has individual styling to make it bold\n  table.NewRow(table.RowData{\n    columnKeyID:          \"bold\",\n    columnKeyName:        \"Bolded\",\n  }).WithStyle(lipgloss.NewStyle().Bold(true).  ,\n\n  // This row also has individual styling to make it bold\n  table.NewRow(table.RowData{\n    columnKeyID:          \"alert\",\n    // This cell has styling applied on top of the bold\n    columnKeyName:        table.NewStyledCell(\"Alert\", lipgloss.NewStyle().Foreground(lipgloss.Color(\"#f88\"))),\n  }).WithStyle(lipgloss.NewStyle().Bold(true),\n}\n```\n\n### A note on 'metadata'\n\nThere may be cases where you wish to reference some kind of data object in the\ntable.  For example, a table of users may display a user name, ID, etc., and you\nmay wish to retrieve data about the user when the row is selected.  This can be\naccomplished by attaching hidden 'metadata' to the row in the same way as any\nother data.\n\n```golang\nconst (\n  columnKeyID = \"id\"\n  columnKeyName = \"名前\"\n  columnKeyUserData = \"userstuff\"\n)\n\n// Notice there is no \"userstuff\" column, so it won't be displayed\ncolumns := []table.Column{\n  table.NewColumn(columnKeyID, \"ID\", 5),\n  table.NewColumn(columnKeyName, \"Name\", 10),\n}\n\n// Just one user for this quick snippet, check the example for more\nuser := \u0026SomeUser{\n  ID:   3,\n  Name: \"Evertras\",\n}\n\nrows := []table.Row{\n  // This row contains both an ID and a name\n  table.NewRow(table.RowData{\n    columnKeyID:       user.ID,\n    columnKeyName:     user.Name,\n\n    // This isn't displayed, but it remains attached to the row\n    columnKeyUserData: user,\n  }),\n}\n```\n\nFor a more detailed demonstration of this idea in action, please see the\n[metadata example](./examples/metadata).\n\n## Demos\n\nCode examples are located in [the examples directory](./examples).  Run commands\nare added to the [Makefile](Makefile) for convenience but they should be as\nsimple as `go run ./examples/features/main.go`, etc.  You can also view what\nthey look like by checking the example's directory in each README here on\nGithub.\n\nTo run the examples, clone this repo and run:\n\n```bash\n# Run the pokemon demo for a general feel of common useful features\nmake\n\n# Run dimensions example to see multiple sizes of simple tables in action\nmake example-dimensions\n\n# Or run any of them directly\ngo run ./examples/pagination/main.go\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevertras%2Fbubble-table","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevertras%2Fbubble-table","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevertras%2Fbubble-table/lists"}