Date & Time: review r3 fixes
This commit is contained in:
8 files changed
+70
-7
No files matched your search
+3
-2
@@ -102,11 +102,12 @@ func DatePicker(c *ui.Context, value *Date, opts DatePickerOptions) DateTimeResu
|
|||||||
if placeholder == "" {
|
if placeholder == "" {
|
||||||
placeholder = msg(c, "date_picker.placeholder")
|
placeholder = msg(c, "date_picker.placeholder")
|
||||||
}
|
}
|
||||||
var field *ui.Element
|
var field, input *ui.Element
|
||||||
col.Children(func() {
|
col.Children(func() {
|
||||||
field = datetimeField(c, ui.Row(c), *problem != "", opts.ReadOnly)
|
field = datetimeField(c, ui.Row(c), *problem != "", opts.ReadOnly)
|
||||||
field.Children(func() {
|
field.Children(func() {
|
||||||
in := textInputEditor(c, field, text, opts.ReadOnly, ui.TextInputBase).Grow(1).Shrink(1).Placeholder(placeholder).FontFeatures("tnum")
|
in := textInputEditor(c, field, text, opts.ReadOnly, ui.TextInputBase).Grow(1).Shrink(1).Placeholder(placeholder).FontFeatures("tnum")
|
||||||
|
input = in
|
||||||
label := opts.Label
|
label := opts.Label
|
||||||
if label == "" {
|
if label == "" {
|
||||||
label = placeholder
|
label = placeholder
|
||||||
@@ -149,7 +150,7 @@ func DatePicker(c *ui.Context, value *Date, opts DatePickerOptions) DateTimeResu
|
|||||||
})
|
})
|
||||||
datetimeError(c, *problem)
|
datetimeError(c, *problem)
|
||||||
})
|
})
|
||||||
return DateTimeResult{Element: col, changed: changed}
|
return DateTimeResult{Element: col, Input: input, changed: changed}
|
||||||
}
|
}
|
||||||
|
|
||||||
// datePickerProblem explains why an existing day d cannot be chosen, or returns "".
|
// datePickerProblem explains why an existing day d cannot be chosen, or returns "".
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ func (d Date) within(lo, hi Date) bool {
|
|||||||
// DateTimeResult is a date or time component and what happened to it this frame.
|
// DateTimeResult is a date or time component and what happened to it this frame.
|
||||||
type DateTimeResult struct {
|
type DateTimeResult struct {
|
||||||
*ui.Element
|
*ui.Element
|
||||||
|
// Input is the text field inside, for labels and focus; nil without one.
|
||||||
|
Input *ui.Element
|
||||||
changed bool
|
changed bool
|
||||||
cancelled bool
|
cancelled bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/egoist/mygo/ui"
|
"github.com/egoist/mygo/ui"
|
||||||
|
|
||||||
|
"mujicaui/theme"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTimePickerDisabledIgnoresSegmentKeys(t *testing.T) {
|
func TestTimePickerDisabledIgnoresSegmentKeys(t *testing.T) {
|
||||||
@@ -159,3 +161,61 @@ func TestTimePickerPopupPickClearsSegmentError(t *testing.T) {
|
|||||||
t.Fatalf("popup pick: value %v, %d changes, %v", v, n, tt.Texts())
|
t.Fatalf("popup pick: value %v, %d changes, %v", v, n, tt.Texts())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFormFocusesDatePickerInput(t *testing.T) {
|
||||||
|
var st FormState
|
||||||
|
day := Date{}
|
||||||
|
var input *ui.Element
|
||||||
|
tt := ui.NewTester(func(c *ui.Context) {
|
||||||
|
Use(c, Settings{})
|
||||||
|
Form(c, &st, FormOptions{}, func(f *FormScope) {
|
||||||
|
FormItem(f, "debut", &day, FormItemOptions[Date]{Label: "Debut date", Required: true}, func() *ui.Element {
|
||||||
|
r := DatePicker(c, &day, DatePickerOptions{Today: calendarToday})
|
||||||
|
input = r.Input
|
||||||
|
return r.Input
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, 600, 500)
|
||||||
|
if err := tt.Click("Submit"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if input == nil || !input.Focused() || !tt.Focused("Debut date") {
|
||||||
|
t.Fatal("a failed submit should focus the DatePicker's text box")
|
||||||
|
}
|
||||||
|
tt.Type("2026-10-12")
|
||||||
|
tt.Key(0, ui.KeyEnter)
|
||||||
|
if day != oct(12) {
|
||||||
|
t.Fatalf("typing after the focus jump gave %v", day)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSelectedCellsHaveTheirOwnMark(t *testing.T) {
|
||||||
|
k := theme.Light()
|
||||||
|
check := func(name string, tt *ui.Tester, label string, shift int) {
|
||||||
|
t.Helper()
|
||||||
|
r, ok := tt.Find(label)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("%s: no cell %q", name, label)
|
||||||
|
}
|
||||||
|
r.X += float32(shift) * r.W
|
||||||
|
img := tt.Image()
|
||||||
|
y := int(r.Y + r.H/2)
|
||||||
|
frame, fill := img.RGBAAt(int(r.X)+2, y), img.RGBAAt(int(r.X)+5, y)
|
||||||
|
if !datetimeNear(frame, k.OnAccent) || !datetimeNear(fill, k.Accent) {
|
||||||
|
t.Fatalf("%s: selected cell frame %v fill %v", name, frame, fill)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v := oct(14)
|
||||||
|
tt := ui.NewTester(func(c *ui.Context) {
|
||||||
|
Use(c, Settings{Mode: Light})
|
||||||
|
Calendar(c, &v, CalendarOptions{Today: calendarToday})
|
||||||
|
}, 400, 400)
|
||||||
|
tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1})
|
||||||
|
check("calendar", tt, datetimeTestLabel(oct(14)), 0)
|
||||||
|
y := 2024
|
||||||
|
ty := yearPickerTester(&y, YearPickerOptions{}, new(int))
|
||||||
|
ty.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1})
|
||||||
|
_ = ty.Click("Vintage")
|
||||||
|
// The field also shows "2024", so locate the cell beside 2023.
|
||||||
|
check("year", ty, "2023", 1)
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ ui.Render(view, 400, 300, 1)
|
|||||||
|
|
||||||
## 状态
|
## 状态
|
||||||
|
|
||||||
默认、悬停、按下、聚焦(键盘焦点环)、选中(酒红填充 + 单选语义)、今日(加粗 + 菱形)、不可选(删除线并由 MyGo 置灰)、非本月(弱化文字)、禁用。
|
默认、悬停、按下、聚焦(键盘焦点环)、选中(酒红填充 + 内嵌细框 + 单选语义)、今日(加粗 + 菱形)、不可选(删除线并由 MyGo 置灰)、非本月(弱化文字)、禁用。
|
||||||
|
|
||||||
## 事件
|
## 事件
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ ui.Render(view, 400, 300, 1)
|
|||||||
|
|
||||||
## 状态
|
## 状态
|
||||||
|
|
||||||
默认、悬停、聚焦、选中(酒红填充)、当前月(加粗 + 菱形)、不可选(删除线)、禁用。
|
默认、悬停、聚焦、选中(酒红填充 + 内嵌细框)、当前月(加粗 + 菱形)、不可选(删除线)、禁用。
|
||||||
|
|
||||||
## 事件
|
## 事件
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ ui.Render(view, 400, 300, 1)
|
|||||||
|
|
||||||
## 状态
|
## 状态
|
||||||
|
|
||||||
默认、悬停、聚焦、选中、当前年、不可选、相邻十年(弱化)、禁用。
|
默认、悬停、聚焦、选中(酒红填充 + 内嵌细框)、当前年(加粗 + 菱形)、不可选、相邻十年(弱化)、禁用。
|
||||||
|
|
||||||
## 事件
|
## 事件
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ func (g *gallery) formFields(c *ui.Context, f *mujica.FormScope, log func(string
|
|||||||
if r.Changed() {
|
if r.Changed() {
|
||||||
log("debut " + s.debut.Format("2006-01-02"))
|
log("debut " + s.debut.Format("2006-01-02"))
|
||||||
}
|
}
|
||||||
return r.Element
|
return r.Input
|
||||||
})
|
})
|
||||||
mujica.FormItem(f, "roles", &s.tags, mujica.FormItemOptions[[]string]{Label: g.t("Roles", "担当"), Required: true,
|
mujica.FormItem(f, "roles", &s.tags, mujica.FormItemOptions[[]string]{Label: g.t("Roles", "担当"), Required: true,
|
||||||
Description: g.t("Up to 4; press Enter after each.", "最多 4 个;每个后按 Enter。")}, func() *ui.Element {
|
Description: g.t("Up to 4; press Enter after each.", "最多 4 个;每个后按 Enter。")}, func() *ui.Element {
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ func TestCompositeFormInvalidThenValid(t *testing.T) {
|
|||||||
tt.Type("Mortis")
|
tt.Type("Mortis")
|
||||||
click(t, tt, "Password")
|
click(t, tt, "Password")
|
||||||
tt.Type("hunter22secret")
|
tt.Type("hunter22secret")
|
||||||
click(t, tt, "Select date") // the date field itself; its FormItem label focuses the picker's column
|
click(t, tt, "Debut date") // the FormItem label now reaches the picker's text box
|
||||||
tt.Type("2026-12-24")
|
tt.Type("2026-12-24")
|
||||||
tt.Key(0, ui.KeyEnter)
|
tt.Key(0, ui.KeyEnter)
|
||||||
click(t, tt, "Roles")
|
click(t, tt, "Roles")
|
||||||
|
|||||||
Reference in new issue
Block a user