Skip to content

Commit

Permalink
doc(credit-card-form): add example with credit card inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
maaslalani committed Jun 7, 2022
1 parent 958dc20 commit d667a2d
Showing 1 changed file with 149 additions and 0 deletions.
149 changes: 149 additions & 0 deletions examples/credit-card-form/main.go
@@ -0,0 +1,149 @@
package main

import (
"fmt"
"log"

"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)

func main() {
p := tea.NewProgram(initialModel())

if err := p.Start(); err != nil {
log.Fatal(err)
}
}

type tickMsg struct{}
type errMsg error

const (
ccn = iota
exp
cvv
)

const (
hotPink = lipgloss.Color("#FF06B7")
darkGray = lipgloss.Color("#767676")
)

var (
inputStyle = lipgloss.NewStyle().Foreground(hotPink)
continueStyle = lipgloss.NewStyle().Foreground(darkGray)
)

type model struct {
inputs []textinput.Model
focused int
err error
}

func initialModel() model {
var inputs []textinput.Model = make([]textinput.Model, 3)
inputs[ccn] = textinput.New()
inputs[ccn].Placeholder = "4505 **** **** 1234"
inputs[ccn].Focus()
inputs[ccn].CharLimit = 20
inputs[ccn].Width = 30
inputs[ccn].Prompt = ""

inputs[exp] = textinput.New()
inputs[exp].Placeholder = "MM/YY "
inputs[exp].CharLimit = 5
inputs[exp].Width = 5
inputs[exp].Prompt = ""

inputs[cvv] = textinput.New()
inputs[cvv].Placeholder = "XXX"
inputs[cvv].CharLimit = 3
inputs[cvv].Width = 5
inputs[cvv].Prompt = ""

return model{
inputs: inputs,
focused: 0,
err: nil,
}
}

func (m model) Init() tea.Cmd {
return textinput.Blink
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var (
cmds []tea.Cmd = make([]tea.Cmd, len(m.inputs))
)

switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.Type {
case tea.KeyEnter:
if m.focused == len(m.inputs)-1 {
return m, tea.Quit
} else {
m.nextInput()
}
case tea.KeyCtrlC, tea.KeyEsc:
return m, tea.Quit
case tea.KeyShiftTab, tea.KeyCtrlP:
m.prevInput()
case tea.KeyTab, tea.KeyCtrlN:
m.nextInput()
}
for i := range m.inputs {
m.inputs[i].Blur()
}
m.inputs[m.focused].Focus()

// We handle errors just like any other message
case errMsg:
m.err = msg
return m, nil
}

for i := range m.inputs {
m.inputs[i], cmds[i] = m.inputs[i].Update(msg)
}
return m, tea.Batch(cmds...)
}

func (m model) View() string {
return fmt.Sprintf(
` Total: $21.50:
%s
%s
%s %s
%s %s
%s
`,
inputStyle.Width(30).Render("Card Number"),
m.inputs[ccn].View(),
inputStyle.Width(6).Render("EXP"),
inputStyle.Width(6).Render("CVV"),
m.inputs[exp].View(),
m.inputs[cvv].View(),
continueStyle.Render("Continue ->"),
) + "\n"
}

// nextInput focuses the next input field
func (m *model) nextInput() {
m.focused = (m.focused + 1) % len(m.inputs)
}

// prevInput focuses the previous input field
func (m *model) prevInput() {
m.focused--
// Wrap around
if m.focused < 0 {
m.focused = len(m.inputs) - 1
}
}

0 comments on commit d667a2d

Please sign in to comment.