Skip to main content

Crate sectioned_picker

Crate sectioned_picker 

Source
Expand description

Interactive terminal multi-select picker with non-selectable section headers.

This crate provides a full-screen ratatui-based picker widget that groups selectable items under bold section headers. It’s designed for CLI tools that need users to choose from categorized options.

§Features

  • Sectioned layout — items grouped under bold, non-selectable headers
  • Selection modes — checkbox sections ([x]/[ ], any number selected) or radio sections (/, at most one selected)
  • Keyboard navigation — arrow keys, j/k, Space to toggle, Enter to confirm
  • Section togglea checks/unchecks all items in a checkbox section
  • Collapsing — Left/Right arrows collapse/expand a section
  • Item descriptions — optional per-item explanatory text shown inline
  • Smart scrolling — keeps cursor visible; snaps to section header when near top
  • Custom actions — bind arbitrary keys to caller-defined handlers that can take over the terminal (e.g., for previews)

§Example

use sectioned_picker::{Section, SectionItem, PickerOutcome, run_picker};

let sections = vec![
    Section::new(
        "Features:",
        vec![
            SectionItem::new("logging", true),
            SectionItem::new("metrics", false),
        ],
    ),
    Section::new(
        "Dependencies:",
        vec![SectionItem::new("tokio (1.38)", true)],
    ),
];

match run_picker("my-app v1.0", sections, Vec::new()).unwrap() {
    PickerOutcome::Confirmed(results) => {
        // results[0] = [true, false] — features section
        // results[1] = [true]        — dependencies section
    }
    PickerOutcome::Cancelled => {}
}

§Scrolling behavior

When the list exceeds the viewport height, the view scrolls to keep the cursor visible:

  • Near section top: scrolling up snaps to the section header when it fits in the viewport alongside the cursor.
  • Tall sections: does NOT snap to a distant header on every up-movement; only snaps when the cursor is close enough to the top of its section.

§Enter behavior

If no items are checked when the user presses Enter, the item under the cursor is checked before submitting. This makes single-item selection a one-key operation (navigate + Enter). The convenience is skipped when the cursor is in a radio section, where an empty selection is a valid choice.

Confirming is rejected when any radio section has more than one item checked; an inline error is shown and the picker stays open.

Structs§

ActionContext
Context passed to action handlers when a custom key is pressed.
PickerAction
A caller-defined action bound to a key.
PickerState
The internal state of the picker widget.
Section
A section of items in the picker.
SectionItem
A selectable item within a section.

Enums§

PickerOutcome
The outcome of a picker interaction.
SelectionMode
How many items a section allows to be selected at once.

Functions§

render_picker
Render the picker into the given frame.
run_picker
Run an interactive sectioned multi-select picker.

Type Aliases§

ActionHandler
Handler type for picker actions.