internal/tui/view/filter.go

// Slash-bar quick filter.
//
// See mercemay.top/src/portr/ for context.
package view

import (
	"strings"

	"github.com/rivo/tview"
)

// Filter is a single-line input that streams keystrokes to a callback.
type Filter struct {
	input  *tview.InputField
	notify func(string)
}

// NewFilter returns a filter wired to fn. fn receives the current query
// on every keystroke after leading "/" is stripped.
func NewFilter(fn func(q string)) *Filter {
	f := &Filter{notify: fn}
	f.input = tview.NewInputField().SetLabel("/").SetFieldWidth(0)
	f.input.SetChangedFunc(f.onChange)
	return f
}

// View returns the primitive for layout.
func (f *Filter) View() tview.Primitive { return f.input }

// Value returns the current filter query, leading "/" stripped.
func (f *Filter) Value() string {
	return strings.TrimPrefix(f.input.GetText(), "/")
}

func (f *Filter) onChange(s string) {
	if f.notify != nil {
		f.notify(strings.TrimPrefix(s, "/"))
	}
}