Skip to content

Commit

Permalink
feat(confirm): add accept/reject/tab keybindings to Confirm (#308)
Browse files Browse the repository at this point in the history
* Added Accept and Reject key bindings to Confirm field in Keymap.
ref: charmbracelet/gum#568

* with Accept and Reject key help text that matches the negative and affirmative text. Optionally disable Reject key if negative is unset.

* fix(confirm): fix a bug where Yes and No buttons were not centered.

ref: charmbracelet/gum#566.

* fix(confirm): fix a linter error, variable names were using underscores

* fix(confirm): tab / shift+tab to toggle between buttons
  • Loading branch information
csandeep authored Jul 12, 2024
1 parent dbf5a5a commit ccca06d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
26 changes: 24 additions & 2 deletions field_confirm.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (c *Confirm) Blur() tea.Cmd {

// KeyBinds returns the help message for the confirm field.
func (c *Confirm) KeyBinds() []key.Binding {
return []key.Binding{c.keymap.Toggle, c.keymap.Prev, c.keymap.Submit, c.keymap.Next}
return []key.Binding{c.keymap.Toggle, c.keymap.Prev, c.keymap.Submit, c.keymap.Next, c.keymap.Accept, c.keymap.Reject}
}

// Init initializes the confirm field.
Expand Down Expand Up @@ -205,6 +205,12 @@ func (c *Confirm) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, PrevField)
case key.Matches(msg, c.keymap.Next, c.keymap.Submit):
cmds = append(cmds, NextField)
case key.Matches(msg, c.keymap.Accept):
c.accessor.Set(true)
cmds = append(cmds, NextField)
case key.Matches(msg, c.keymap.Reject):
c.accessor.Set(false)
cmds = append(cmds, NextField)
}
}

Expand Down Expand Up @@ -254,11 +260,27 @@ func (c *Confirm) View() string {
affirmative = styles.BlurredButton.Render(c.affirmative)
negative = styles.FocusedButton.Render(c.negative)
}
c.keymap.Reject.SetHelp("n", c.negative)
} else {
affirmative = styles.FocusedButton.Render(c.affirmative)
c.keymap.Reject.SetEnabled(false)
}

c.keymap.Accept.SetHelp("y", c.affirmative)

buttonsRow := lipgloss.JoinHorizontal(lipgloss.Center, affirmative, negative)

promptWidth := lipgloss.Width(sb.String())
buttonsWidth := lipgloss.Width(buttonsRow)

renderWidth := promptWidth
if buttonsWidth > renderWidth {
renderWidth = buttonsWidth
}

sb.WriteString(lipgloss.JoinHorizontal(lipgloss.Center, affirmative, negative))
style := lipgloss.NewStyle().Width(renderWidth).Align(lipgloss.Center)

sb.WriteString(style.Render(buttonsRow))
return styles.Base.Render(sb.String())
}

Expand Down
6 changes: 5 additions & 1 deletion keymap.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ type ConfirmKeyMap struct {
Prev key.Binding
Toggle key.Binding
Submit key.Binding
Accept key.Binding
Reject key.Binding
}

// NewDefaultKeyMap returns a new default keymap.
Expand Down Expand Up @@ -172,7 +174,9 @@ func NewDefaultKeyMap() *KeyMap {
Prev: key.NewBinding(key.WithKeys("shift+tab"), key.WithHelp("shift+tab", "back")),
Next: key.NewBinding(key.WithKeys("enter", "tab"), key.WithHelp("enter", "next")),
Submit: key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "submit")),
Toggle: key.NewBinding(key.WithKeys("h", "l", "right", "left"), key.WithHelp("←/→", "toggle")),
Toggle: key.NewBinding(key.WithKeys("h", "l", "right", "left", "tab", "shift+tab"), key.WithHelp("←/→", "toggle")),
Accept: key.NewBinding(key.WithKeys("y", "Y"), key.WithHelp("y", "Yes")),
Reject: key.NewBinding(key.WithKeys("n", "N"), key.WithHelp("n", "No")),
},
}
}

1 comment on commit ccca06d

@farzadmf
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@csandeep tab and shift+tab don't seem to work in confirm; any idea why?

Please sign in to comment.