feat: centered footer + auth type toggle pills

- Status bar footer centered within terminal width using lipgloss.Width
- Auth Type field replaced with toggle pills (password/key)
  Space/Enter/←/→ cycle between options on the focused field
  Selected type shown with SelectedStyle/TagStyle (green),
  inactive type shown in muted SubtitleStyle
  Help hint 'Space/←/→ to toggle' shown when focused
- Added toggleAuthType() and cycleAuthType() helpers
This commit is contained in:
swanadiva
2026-06-23 15:59:54 +07:00
parent 5b456104e8
commit 2442920616
2 changed files with 68 additions and 9 deletions
+56 -7
View File
@@ -83,7 +83,6 @@ func newHostFormTab(mode formMode, host *models.Host, dataDir string) *HostFormT
inputs[fieldPort].Placeholder = "22"
inputs[fieldPort].SetValue("22")
inputs[fieldUsername].Placeholder = "root"
inputs[fieldAuthType].Placeholder = "password / key / both"
inputs[fieldAuthType].SetValue("password")
inputs[fieldPassword].EchoMode = textinput.EchoPassword
inputs[fieldPassword].Placeholder = "Enter password"
@@ -143,11 +142,22 @@ func (t *HostFormTab) Update(msg tea.Msg) (Tab, tea.Cmd) {
return t, func() tea.Msg { return closeFormMsg{} }
case "enter":
if t.focus == fieldAuthType {
t.toggleAuthType()
return t, nil
}
if t.focus == fieldCount-1 {
return t.submit()
}
t.nextField()
case " ", "left", "right":
if t.focus == fieldAuthType {
t.toggleAuthType()
return t, nil
}
fallthrough
case "tab", "down":
t.nextField()
@@ -158,6 +168,10 @@ func (t *HostFormTab) Update(msg tea.Msg) (Tab, tea.Cmd) {
return t.submit()
default:
if t.focus == fieldAuthType {
// ignore typing on auth type field
return t, nil
}
var cmd tea.Cmd
t.inputs[t.focus], cmd = t.inputs[t.focus].Update(msg)
return t, cmd
@@ -189,6 +203,22 @@ func (t *HostFormTab) prevField() {
t.inputs[t.focus].Prompt = "> "
}
func cycleAuthType(current string) string {
switch current {
case "password":
return "key"
case "key":
return "password"
default:
return "password"
}
}
func (t *HostFormTab) toggleAuthType() {
current := t.inputs[fieldAuthType].Value()
t.inputs[fieldAuthType].SetValue(cycleAuthType(current))
}
func (t *HostFormTab) submit() (Tab, tea.Cmd) {
name := t.inputs[fieldName].Value()
hostname := t.inputs[fieldHostname].Value()
@@ -278,16 +308,35 @@ func (t *HostFormTab) View() string {
b.WriteString(style.Render(label + ":"))
b.WriteString("\n")
renderedInput := input.View()
// Add parentheses showing auth options
if i == fieldAuthType && i != t.focus {
if i == fieldAuthType {
// Render auth type as toggle pills
current := input.Value()
pills := []string{"password", "key"}
var parts []string
for _, p := range pills {
if p == current {
if i == t.focus {
parts = append(parts, SelectedStyle.Render(" "+p+" "))
} else {
parts = append(parts, TagStyle.Render(" "+p+" "))
}
} else {
parts = append(parts, SubtitleStyle.Render(" "+p+" "))
}
}
b.WriteString(" ")
b.WriteString(strings.Join(parts, " "))
b.WriteString("\n")
if i == t.focus {
b.WriteString(InfoStyle.Render(" Space/←/→ to toggle"))
}
b.WriteString("\n")
} else {
renderedInput := input.View()
b.WriteString(" ")
b.WriteString(renderedInput)
b.WriteString("\n\n")
}
b.WriteString(renderedInput)
b.WriteString("\n\n")
}
// Help text