forked from toolshed/abra
chore: go mod tidy / vendor / make deps
This commit is contained in:
510
vendor/github.com/evertras/bubble-table/table/options.go
generated
vendored
Normal file
510
vendor/github.com/evertras/bubble-table/table/options.go
generated
vendored
Normal file
@ -0,0 +1,510 @@
|
||||
package table
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/bubbles/key"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
// RowStyleFuncInput is the input to the style function that can
|
||||
// be applied to each row. This is useful for things like zebra
|
||||
// striping or other data-based styles.
|
||||
//
|
||||
// Note that we use a struct here to allow for future expansion
|
||||
// while keeping backwards compatibility.
|
||||
type RowStyleFuncInput struct {
|
||||
// Index is the index of the row, starting at 0.
|
||||
Index int
|
||||
|
||||
// Row is the full row data.
|
||||
Row Row
|
||||
|
||||
// IsHighlighted is true if the row is currently highlighted.
|
||||
IsHighlighted bool
|
||||
}
|
||||
|
||||
// WithRowStyleFunc sets a function that can be used to apply a style to each row
|
||||
// based on the row data. This is useful for things like zebra striping or other
|
||||
// data-based styles. It can be safely set to nil to remove it later.
|
||||
// This style is applied after the base style and before individual row styles.
|
||||
// This will override any HighlightStyle settings.
|
||||
func (m Model) WithRowStyleFunc(f func(RowStyleFuncInput) lipgloss.Style) Model {
|
||||
m.rowStyleFunc = f
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithHighlightedRow sets the highlighted row to the given index.
|
||||
func (m Model) WithHighlightedRow(index int) Model {
|
||||
m.rowCursorIndex = index
|
||||
|
||||
if m.rowCursorIndex >= len(m.GetVisibleRows()) {
|
||||
m.rowCursorIndex = len(m.GetVisibleRows()) - 1
|
||||
}
|
||||
|
||||
if m.rowCursorIndex < 0 {
|
||||
m.rowCursorIndex = 0
|
||||
}
|
||||
|
||||
m.currentPage = m.expectedPageForRowIndex(m.rowCursorIndex)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// HeaderStyle sets the style to apply to the header text, such as color or bold.
|
||||
func (m Model) HeaderStyle(style lipgloss.Style) Model {
|
||||
m.headerStyle = style.Copy()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithRows sets the rows to show as data in the table.
|
||||
func (m Model) WithRows(rows []Row) Model {
|
||||
m.rows = rows
|
||||
m.visibleRowCacheUpdated = false
|
||||
|
||||
if m.rowCursorIndex >= len(m.rows) {
|
||||
m.rowCursorIndex = len(m.rows) - 1
|
||||
}
|
||||
|
||||
if m.rowCursorIndex < 0 {
|
||||
m.rowCursorIndex = 0
|
||||
}
|
||||
|
||||
if m.pageSize != 0 {
|
||||
maxPage := m.MaxPages()
|
||||
|
||||
// MaxPages is 1-index, currentPage is 0 index
|
||||
if maxPage <= m.currentPage {
|
||||
m.pageLast()
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithKeyMap sets the key map to use for controls when focused.
|
||||
func (m Model) WithKeyMap(keyMap KeyMap) Model {
|
||||
m.keyMap = keyMap
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// KeyMap returns a copy of the current key map in use.
|
||||
func (m Model) KeyMap() KeyMap {
|
||||
return m.keyMap
|
||||
}
|
||||
|
||||
// SelectableRows sets whether or not rows are selectable. If set, adds a column
|
||||
// in the front that acts as a checkbox and responds to controls if Focused.
|
||||
func (m Model) SelectableRows(selectable bool) Model {
|
||||
m.selectableRows = selectable
|
||||
|
||||
hasSelectColumn := len(m.columns) > 0 && m.columns[0].key == columnKeySelect
|
||||
|
||||
if hasSelectColumn != selectable {
|
||||
if selectable {
|
||||
m.columns = append([]Column{
|
||||
NewColumn(columnKeySelect, m.selectedText, len([]rune(m.selectedText))),
|
||||
}, m.columns...)
|
||||
} else {
|
||||
m.columns = m.columns[1:]
|
||||
}
|
||||
}
|
||||
|
||||
m.recalculateWidth()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// HighlightedRow returns the full Row that's currently highlighted by the user.
|
||||
func (m Model) HighlightedRow() Row {
|
||||
if len(m.GetVisibleRows()) > 0 {
|
||||
return m.GetVisibleRows()[m.rowCursorIndex]
|
||||
}
|
||||
|
||||
// TODO: Better way to do this without pointers/nil? Or should it be nil?
|
||||
return Row{}
|
||||
}
|
||||
|
||||
// SelectedRows returns all rows that have been set as selected by the user.
|
||||
func (m Model) SelectedRows() []Row {
|
||||
selectedRows := []Row{}
|
||||
|
||||
for _, row := range m.GetVisibleRows() {
|
||||
if row.selected {
|
||||
selectedRows = append(selectedRows, row)
|
||||
}
|
||||
}
|
||||
|
||||
return selectedRows
|
||||
}
|
||||
|
||||
// HighlightStyle sets a custom style to use when the row is being highlighted
|
||||
// by the cursor. This should not be used with WithRowStyleFunc. Instead, use
|
||||
// the IsHighlighted field in the style function.
|
||||
func (m Model) HighlightStyle(style lipgloss.Style) Model {
|
||||
m.highlightStyle = style
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Focused allows the table to show highlighted rows and take in controls of
|
||||
// up/down/space/etc to let the user navigate the table and interact with it.
|
||||
func (m Model) Focused(focused bool) Model {
|
||||
m.focused = focused
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Filtered allows the table to show rows that match the filter.
|
||||
func (m Model) Filtered(filtered bool) Model {
|
||||
m.filtered = filtered
|
||||
m.visibleRowCacheUpdated = false
|
||||
|
||||
if m.minimumHeight > 0 {
|
||||
m.recalculateHeight()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// StartFilterTyping focuses the text input to allow user typing to filter.
|
||||
func (m Model) StartFilterTyping() Model {
|
||||
m.filterTextInput.Focus()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithStaticFooter adds a footer that only displays the given text.
|
||||
func (m Model) WithStaticFooter(footer string) Model {
|
||||
m.staticFooter = footer
|
||||
|
||||
if m.minimumHeight > 0 {
|
||||
m.recalculateHeight()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithPageSize enables pagination using the given page size. This can be called
|
||||
// again at any point to resize the height of the table.
|
||||
func (m Model) WithPageSize(pageSize int) Model {
|
||||
m.pageSize = pageSize
|
||||
|
||||
maxPages := m.MaxPages()
|
||||
|
||||
if m.currentPage >= maxPages {
|
||||
m.currentPage = maxPages - 1
|
||||
}
|
||||
|
||||
if m.minimumHeight > 0 {
|
||||
m.recalculateHeight()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithNoPagination disables pagination in the table.
|
||||
func (m Model) WithNoPagination() Model {
|
||||
m.pageSize = 0
|
||||
|
||||
if m.minimumHeight > 0 {
|
||||
m.recalculateHeight()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithPaginationWrapping sets whether to wrap around from the beginning to the
|
||||
// end when navigating through pages. Defaults to true.
|
||||
func (m Model) WithPaginationWrapping(wrapping bool) Model {
|
||||
m.paginationWrapping = wrapping
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithSelectedText describes what text to show when selectable rows are enabled.
|
||||
// The selectable column header will use the selected text string.
|
||||
func (m Model) WithSelectedText(unselected, selected string) Model {
|
||||
m.selectedText = selected
|
||||
m.unselectedText = unselected
|
||||
|
||||
if len(m.columns) > 0 && m.columns[0].key == columnKeySelect {
|
||||
m.columns[0] = NewColumn(columnKeySelect, m.selectedText, len([]rune(m.selectedText)))
|
||||
m.recalculateWidth()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithBaseStyle applies a base style as the default for everything in the table.
|
||||
// This is useful for border colors, default alignment, default color, etc.
|
||||
func (m Model) WithBaseStyle(style lipgloss.Style) Model {
|
||||
m.baseStyle = style
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithTargetWidth sets the total target width of the table, including borders.
|
||||
// This only takes effect when using flex columns. When using flex columns,
|
||||
// columns will stretch to fill out to the total width given here.
|
||||
func (m Model) WithTargetWidth(totalWidth int) Model {
|
||||
m.targetTotalWidth = totalWidth
|
||||
|
||||
m.recalculateWidth()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithMinimumHeight sets the minimum total height of the table, including borders.
|
||||
func (m Model) WithMinimumHeight(minimumHeight int) Model {
|
||||
m.minimumHeight = minimumHeight
|
||||
|
||||
m.recalculateHeight()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// PageDown goes to the next page of a paginated table, wrapping to the first
|
||||
// page if the table is already on the last page.
|
||||
func (m Model) PageDown() Model {
|
||||
m.pageDown()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// PageUp goes to the previous page of a paginated table, wrapping to the
|
||||
// last page if the table is already on the first page.
|
||||
func (m Model) PageUp() Model {
|
||||
m.pageUp()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// PageLast goes to the last page of a paginated table.
|
||||
func (m Model) PageLast() Model {
|
||||
m.pageLast()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// PageFirst goes to the first page of a paginated table.
|
||||
func (m Model) PageFirst() Model {
|
||||
m.pageFirst()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithCurrentPage sets the current page (1 as the first page) of a paginated
|
||||
// table, bounded to the total number of pages. The current selected row will
|
||||
// be set to the top row of the page if the page changed.
|
||||
func (m Model) WithCurrentPage(currentPage int) Model {
|
||||
if m.pageSize == 0 || currentPage == m.CurrentPage() {
|
||||
return m
|
||||
}
|
||||
if currentPage < 1 {
|
||||
currentPage = 1
|
||||
} else {
|
||||
maxPages := m.MaxPages()
|
||||
|
||||
if currentPage > maxPages {
|
||||
currentPage = maxPages
|
||||
}
|
||||
}
|
||||
m.currentPage = currentPage - 1
|
||||
m.rowCursorIndex = m.currentPage * m.pageSize
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithColumns sets the visible columns for the table, so that columns can be
|
||||
// added/removed/resized or headers rewritten.
|
||||
func (m Model) WithColumns(columns []Column) Model {
|
||||
// Deep copy to avoid edits
|
||||
m.columns = make([]Column, len(columns))
|
||||
copy(m.columns, columns)
|
||||
|
||||
m.recalculateWidth()
|
||||
|
||||
if m.selectableRows {
|
||||
// Re-add the selectable column
|
||||
m = m.SelectableRows(true)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithFilterInput makes the table use the provided text input bubble for
|
||||
// filtering rather than using the built-in default. This allows for external
|
||||
// text input controls to be used.
|
||||
func (m Model) WithFilterInput(input textinput.Model) Model {
|
||||
if m.filterTextInput.Value() != input.Value() {
|
||||
m.pageFirst()
|
||||
}
|
||||
|
||||
m.filterTextInput = input
|
||||
m.visibleRowCacheUpdated = false
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithFilterInputValue sets the filter value to the given string, immediately
|
||||
// applying it as if the user had typed it in. Useful for external filter inputs
|
||||
// that are not necessarily a text input.
|
||||
func (m Model) WithFilterInputValue(value string) Model {
|
||||
if m.filterTextInput.Value() != value {
|
||||
m.pageFirst()
|
||||
}
|
||||
|
||||
m.filterTextInput.SetValue(value)
|
||||
m.filterTextInput.Blur()
|
||||
m.visibleRowCacheUpdated = false
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithFilterFunc adds a filter function to the model. If the function returns
|
||||
// true, the row will be included in the filtered results. If the function
|
||||
// is nil, the function won't be used and instead the default filtering will be applied,
|
||||
// if any.
|
||||
func (m Model) WithFilterFunc(shouldInclude FilterFunc) Model {
|
||||
m.filterFunc = shouldInclude
|
||||
|
||||
m.visibleRowCacheUpdated = false
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithFuzzyFilter enables fuzzy filtering for the table.
|
||||
func (m Model) WithFuzzyFilter() Model {
|
||||
return m.WithFilterFunc(filterFuncFuzzy)
|
||||
}
|
||||
|
||||
// WithFooterVisibility sets the visibility of the footer.
|
||||
func (m Model) WithFooterVisibility(visibility bool) Model {
|
||||
m.footerVisible = visibility
|
||||
|
||||
if m.minimumHeight > 0 {
|
||||
m.recalculateHeight()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithHeaderVisibility sets the visibility of the header.
|
||||
func (m Model) WithHeaderVisibility(visibility bool) Model {
|
||||
m.headerVisible = visibility
|
||||
|
||||
if m.minimumHeight > 0 {
|
||||
m.recalculateHeight()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithMaxTotalWidth sets the maximum total width that the table should render.
|
||||
// If this width is exceeded by either the target width or by the total width
|
||||
// of all the columns (including borders!), anything extra will be treated as
|
||||
// overflow and horizontal scrolling will be enabled to see the rest.
|
||||
func (m Model) WithMaxTotalWidth(maxTotalWidth int) Model {
|
||||
m.maxTotalWidth = maxTotalWidth
|
||||
|
||||
m.recalculateWidth()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithHorizontalFreezeColumnCount freezes the given number of columns to the
|
||||
// left side. This is useful for things like ID or Name columns that should
|
||||
// always be visible even when scrolling.
|
||||
func (m Model) WithHorizontalFreezeColumnCount(columnsToFreeze int) Model {
|
||||
m.horizontalScrollFreezeColumnsCount = columnsToFreeze
|
||||
|
||||
m.recalculateWidth()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// ScrollRight moves one column to the right. Use with WithMaxTotalWidth.
|
||||
func (m Model) ScrollRight() Model {
|
||||
m.scrollRight()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// ScrollLeft moves one column to the left. Use with WithMaxTotalWidth.
|
||||
func (m Model) ScrollLeft() Model {
|
||||
m.scrollLeft()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithMissingDataIndicator sets an indicator to use when data for a column is
|
||||
// not found in a given row. Note that this is for completely missing data,
|
||||
// an empty string or other zero value that is explicitly set is not considered
|
||||
// to be missing.
|
||||
func (m Model) WithMissingDataIndicator(str string) Model {
|
||||
m.missingDataIndicator = str
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithMissingDataIndicatorStyled sets a styled indicator to use when data for
|
||||
// a column is not found in a given row. Note that this is for completely
|
||||
// missing data, an empty string or other zero value that is explicitly set is
|
||||
// not considered to be missing.
|
||||
func (m Model) WithMissingDataIndicatorStyled(styled StyledCell) Model {
|
||||
m.missingDataIndicator = styled
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithAllRowsDeselected deselects any rows that are currently selected.
|
||||
func (m Model) WithAllRowsDeselected() Model {
|
||||
rows := m.GetVisibleRows()
|
||||
|
||||
for i, row := range rows {
|
||||
if row.selected {
|
||||
rows[i] = row.Selected(false)
|
||||
}
|
||||
}
|
||||
|
||||
m.rows = rows
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithMultiline sets whether or not to wrap text in cells to multiple lines.
|
||||
func (m Model) WithMultiline(multiline bool) Model {
|
||||
m.multiline = multiline
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithAdditionalShortHelpKeys enables you to add more keybindings to the 'short help' view.
|
||||
func (m Model) WithAdditionalShortHelpKeys(keys []key.Binding) Model {
|
||||
m.additionalShortHelpKeys = func() []key.Binding {
|
||||
return keys
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithAdditionalFullHelpKeys enables you to add more keybindings to the 'full help' view.
|
||||
func (m Model) WithAdditionalFullHelpKeys(keys []key.Binding) Model {
|
||||
m.additionalFullHelpKeys = func() []key.Binding {
|
||||
return keys
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// WithGlobalMetadata applies the given metadata to the table. This metadata is passed to
|
||||
// some functions in FilterFuncInput and StyleFuncInput to enable more advanced decisions,
|
||||
// such as setting some global theme variable to reference, etc. Has no effect otherwise.
|
||||
func (m Model) WithGlobalMetadata(metadata map[string]any) Model {
|
||||
m.metadata = metadata
|
||||
|
||||
return m
|
||||
}
|
Reference in New Issue
Block a user