Merge branch 'devel' into 243-formdemo

This commit is contained in:
Jakub Sobon 2020-12-28 03:48:27 -05:00
commit db2fcdcffc
4 changed files with 100 additions and 2 deletions

View File

@ -65,6 +65,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- the `textinput` widget can now be configured to request keyboard events
exclusively when focused.
- the `textinput` widget can now be initialized with a default text in the
input box.
## [0.13.0] - 17-Nov-2020

View File

@ -17,6 +17,7 @@ package textinput
// options.go contains configurable options for TextInput.
import (
"errors"
"fmt"
"github.com/mum4k/termdash/align"
@ -58,6 +59,7 @@ type options struct {
placeHolder string
hideTextWith rune
defaultText string
filter FilterFn
onSubmit SubmitFn
@ -81,6 +83,16 @@ func (o *options) validate() error {
return fmt.Errorf("invalid HideTextWidth rune %c(%d), has rune width of %d cells, only runes with width of %d are accepted", r, r, got, want)
}
}
if o.defaultText != "" {
if err := wrap.ValidText(o.defaultText); err != nil {
return fmt.Errorf("invalid DefaultText: %v", err)
}
for _, r := range o.defaultText {
if r == '\n' {
return errors.New("invalid DefaultText: newline characters aren't allowed")
}
}
}
return nil
}
@ -272,3 +284,12 @@ func ExclusiveKeyboardOnFocus() Option {
opts.exclusiveKeyboardOnFocus = true
})
}
// DefaultText sets the text to be present in a newly created input field.
// The text must not contain any control or space characters other than ' '.
// The user can edit this text as normal.
func DefaultText(text string) Option {
return option(func(opts *options) {
opts.defaultText = text
})
}

View File

@ -69,10 +69,15 @@ func New(opts ...Option) (*TextInput, error) {
if err := opt.validate(); err != nil {
return nil, err
}
return &TextInput{
ti := &TextInput{
editor: newFieldEditor(),
opts: opt,
}, nil
}
for _, r := range ti.opts.defaultText {
ti.editor.insert(r)
}
return ti, nil
}
// Vars to be replaced from tests.

View File

@ -117,6 +117,20 @@ func TestTextInput(t *testing.T) {
},
wantNewErr: true,
},
{
desc: "fails on invalid DefaultText which has control characters",
opts: []Option{
DefaultText("\r"),
},
wantNewErr: true,
},
{
desc: "fails on invalid DefaultText which has newline",
opts: []Option{
DefaultText("\n"),
},
wantNewErr: true,
},
{
desc: "takes all space without label",
canvas: image.Rect(0, 0, 10, 1),
@ -559,6 +573,62 @@ func TestTextInput(t *testing.T) {
return ft
},
},
{
desc: "displays default text",
opts: []Option{
DefaultText("text"),
},
canvas: image.Rect(0, 0, 10, 1),
meta: &widgetapi.Meta{},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
cvs := testcanvas.MustNew(ft.Area())
testcanvas.MustSetAreaCells(
cvs,
image.Rect(0, 0, 10, 1),
textFieldRune,
cell.BgColor(cell.ColorNumber(DefaultFillColorNumber)),
)
testdraw.MustText(
cvs,
"text",
image.Point{0, 0},
)
testcanvas.MustApply(cvs, ft)
return ft
},
},
{
desc: "default text can be edited",
opts: []Option{
DefaultText("text"),
},
canvas: image.Rect(0, 0, 10, 1),
meta: &widgetapi.Meta{},
events: []terminalapi.Event{
&terminalapi.Keyboard{Key: keyboard.KeyBackspace},
&terminalapi.Keyboard{Key: 'a'},
},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
cvs := testcanvas.MustNew(ft.Area())
testcanvas.MustSetAreaCells(
cvs,
image.Rect(0, 0, 10, 1),
textFieldRune,
cell.BgColor(cell.ColorNumber(DefaultFillColorNumber)),
)
testdraw.MustText(
cvs,
"texa",
image.Point{0, 0},
)
testcanvas.MustApply(cvs, ft)
return ft
},
},
{
desc: "displays written text",
canvas: image.Rect(0, 0, 10, 1),