From 1b025b5fadae06dc4a8a74100bc2b48c35b01186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 5 Oct 2026 12:17:01 -0400 Subject: [PATCH] Inputs: components 021-030 --- button_group.go | 124 ++++++ button_group_test.go | 84 +++++ button_test.go | 57 ++- checkbox.go | 134 +++++++ checkbox_test.go | 104 +++++ docs/components/021-button.md | 43 +++ docs/components/022-icon-button.md | 42 +++ docs/components/023-button-group.md | 53 +++ docs/components/024-text-input.md | 49 +++ docs/components/025-text-area.md | 49 +++ docs/components/026-number-input.md | 49 +++ docs/components/027-password-input.md | 42 +++ docs/components/028-search-input.md | 51 +++ docs/components/029-checkbox.md | 51 +++ docs/components/030-radio-group.md | 52 +++ example_input_test.go | 130 +++++++ examples/gallery/pages_input.go | 357 +++++++++++++++++- icon_button.go | 33 ++ icon_button_test.go | 78 ++++ messages_input.go | 22 ++ number_input.go | 227 +++++++++++ number_input_test.go | 141 +++++++ password_input.go | 75 ++++ password_input_test.go | 101 +++++ radio_group.go | 90 +++++ radio_group_test.go | 99 +++++ search_input.go | 140 +++++++ search_input_test.go | 129 +++++++ .../darwin/button-comfortable-dark.png | Bin 0 -> 11237 bytes .../darwin/button-comfortable-light.png | Bin 0 -> 10937 bytes .../snapshots/darwin/button-compact-dark.png | Bin 0 -> 11338 bytes .../snapshots/darwin/button-compact-light.png | Bin 0 -> 11075 bytes testdata/snapshots/darwin/button-dark.png | Bin 10309 -> 11165 bytes testdata/snapshots/darwin/button-light.png | Bin 9932 -> 10867 bytes .../snapshots/darwin/button_group-dark.png | Bin 0 -> 5061 bytes .../snapshots/darwin/button_group-light.png | Bin 0 -> 4956 bytes .../darwin/checkbox-comfortable-dark.png | Bin 0 -> 12926 bytes .../darwin/checkbox-comfortable-light.png | Bin 0 -> 12125 bytes .../darwin/checkbox-compact-dark.png | Bin 0 -> 12557 bytes .../darwin/checkbox-compact-light.png | Bin 0 -> 11910 bytes testdata/snapshots/darwin/checkbox-dark.png | Bin 0 -> 12385 bytes testdata/snapshots/darwin/checkbox-light.png | Bin 0 -> 11756 bytes .../snapshots/darwin/icon_button-dark.png | Bin 0 -> 3561 bytes .../snapshots/darwin/icon_button-light.png | Bin 0 -> 3551 bytes .../snapshots/darwin/number_input-dark.png | Bin 0 -> 7139 bytes .../snapshots/darwin/number_input-light.png | Bin 0 -> 6878 bytes .../snapshots/darwin/password_input-dark.png | Bin 0 -> 7652 bytes .../snapshots/darwin/password_input-light.png | Bin 0 -> 7542 bytes .../snapshots/darwin/radio_group-dark.png | Bin 0 -> 10665 bytes .../snapshots/darwin/radio_group-light.png | Bin 0 -> 10032 bytes .../snapshots/darwin/search_input-dark.png | Bin 0 -> 7926 bytes .../snapshots/darwin/search_input-light.png | Bin 0 -> 7847 bytes testdata/snapshots/darwin/text_area-dark.png | Bin 0 -> 16547 bytes testdata/snapshots/darwin/text_area-light.png | Bin 0 -> 15926 bytes .../darwin/text_input-comfortable-dark.png | Bin 0 -> 13287 bytes .../darwin/text_input-comfortable-light.png | Bin 0 -> 12823 bytes .../darwin/text_input-compact-dark.png | Bin 0 -> 13079 bytes .../darwin/text_input-compact-light.png | Bin 0 -> 12710 bytes testdata/snapshots/darwin/text_input-dark.png | Bin 0 -> 12964 bytes .../snapshots/darwin/text_input-light.png | Bin 0 -> 12498 bytes text_area.go | 88 +++++ text_area_test.go | 94 +++++ text_input.go | 172 +++++++++ text_input_test.go | 141 +++++++ 64 files changed, 3090 insertions(+), 11 deletions(-) create mode 100644 button_group.go create mode 100644 button_group_test.go create mode 100644 checkbox.go create mode 100644 checkbox_test.go create mode 100644 docs/components/021-button.md create mode 100644 docs/components/022-icon-button.md create mode 100644 docs/components/023-button-group.md create mode 100644 docs/components/024-text-input.md create mode 100644 docs/components/025-text-area.md create mode 100644 docs/components/026-number-input.md create mode 100644 docs/components/027-password-input.md create mode 100644 docs/components/028-search-input.md create mode 100644 docs/components/029-checkbox.md create mode 100644 docs/components/030-radio-group.md create mode 100644 example_input_test.go create mode 100644 icon_button.go create mode 100644 icon_button_test.go create mode 100644 messages_input.go create mode 100644 number_input.go create mode 100644 number_input_test.go create mode 100644 password_input.go create mode 100644 password_input_test.go create mode 100644 radio_group.go create mode 100644 radio_group_test.go create mode 100644 search_input.go create mode 100644 search_input_test.go create mode 100644 testdata/snapshots/darwin/button-comfortable-dark.png create mode 100644 testdata/snapshots/darwin/button-comfortable-light.png create mode 100644 testdata/snapshots/darwin/button-compact-dark.png create mode 100644 testdata/snapshots/darwin/button-compact-light.png create mode 100644 testdata/snapshots/darwin/button_group-dark.png create mode 100644 testdata/snapshots/darwin/button_group-light.png create mode 100644 testdata/snapshots/darwin/checkbox-comfortable-dark.png create mode 100644 testdata/snapshots/darwin/checkbox-comfortable-light.png create mode 100644 testdata/snapshots/darwin/checkbox-compact-dark.png create mode 100644 testdata/snapshots/darwin/checkbox-compact-light.png create mode 100644 testdata/snapshots/darwin/checkbox-dark.png create mode 100644 testdata/snapshots/darwin/checkbox-light.png create mode 100644 testdata/snapshots/darwin/icon_button-dark.png create mode 100644 testdata/snapshots/darwin/icon_button-light.png create mode 100644 testdata/snapshots/darwin/number_input-dark.png create mode 100644 testdata/snapshots/darwin/number_input-light.png create mode 100644 testdata/snapshots/darwin/password_input-dark.png create mode 100644 testdata/snapshots/darwin/password_input-light.png create mode 100644 testdata/snapshots/darwin/radio_group-dark.png create mode 100644 testdata/snapshots/darwin/radio_group-light.png create mode 100644 testdata/snapshots/darwin/search_input-dark.png create mode 100644 testdata/snapshots/darwin/search_input-light.png create mode 100644 testdata/snapshots/darwin/text_area-dark.png create mode 100644 testdata/snapshots/darwin/text_area-light.png create mode 100644 testdata/snapshots/darwin/text_input-comfortable-dark.png create mode 100644 testdata/snapshots/darwin/text_input-comfortable-light.png create mode 100644 testdata/snapshots/darwin/text_input-compact-dark.png create mode 100644 testdata/snapshots/darwin/text_input-compact-light.png create mode 100644 testdata/snapshots/darwin/text_input-dark.png create mode 100644 testdata/snapshots/darwin/text_input-light.png create mode 100644 text_area.go create mode 100644 text_area_test.go create mode 100644 text_input.go create mode 100644 text_input_test.go diff --git a/button_group.go b/button_group.go new file mode 100644 index 0000000..b3de134 --- /dev/null +++ b/button_group.go @@ -0,0 +1,124 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// ButtonGroupItem is one button of a ButtonGroup. Give Label, Icon or both. +type ButtonGroupItem struct { + Label string + Icon *ui.SVG + // Name names an icon-only item for assistive technology. + Name string + Disabled bool +} + +// ButtonGroupOptions configure a ButtonGroup. +type ButtonGroupOptions struct { + Vertical bool + // Label names the group for assistive technology. + Label string + Disabled bool +} + +// ButtonGroupResult is the group element and the item clicked this frame. +type ButtonGroupResult struct { + *ui.Element + clicked int +} + +// ClickedItem returns the index of the item clicked this frame, or -1. +func (r ButtonGroupResult) ClickedItem() int { return r.clicked } + +// ButtonGroup joins buttons in one bordered strip; arrows move between them. +func ButtonGroup(c *ui.Context, items []ButtonGroupItem, opts ButtonGroupOptions) ButtonGroupResult { + if len(items) == 0 { + panic("mujica: ButtonGroup needs items") + } + k := Tokens(c) + d := Density(c) + orient, last := ui.Horizontal, len(items)-1 + g := ui.Row(c).AlignItems(ui.Stretch).Shrink(0) + if opts.Vertical { + orient = ui.Vertical + g.Column() + } + g.FocusGroup(orient).Role(ui.RoleToolbar).Label(opts.Label).Disabled(opts.Disabled) + r := ButtonGroupResult{Element: g, clicked: -1} + g.Children(func() { + for i, it := range items { + if it.Label == "" && it.Icon == nil { + panic("mujica: ButtonGroupItem needs a Label or an Icon") + } + b := ui.ButtonBase(c).Key(i).MinHeight(d.ControlHeight()).MinWidth(d.ControlHeight()). + Padding(0, d.Unit()*3).Gap(d.Unit() * 2).Disabled(it.Disabled) + internal.Ring(b, k.Focus, theme.ControlRadius) + if it.Name != "" { + b.Label(it.Name) + } + bg := k.Surface + if b.Pressed() { + bg = k.Selection + } else if b.Hovered() { + bg = k.SurfaceHover + } + b.Background(bg).TextColor(k.Text).Transition(textInputFade) + b.Radius(buttonGroupCorners(i, last, opts.Vertical)...) + b.Border(theme.BorderWidth, k.ControlBorder).BorderWidth(buttonGroupEdges(i, opts.Vertical)...) + b.Children(func() { + if it.Icon != nil { + ui.Icon(c, it.Icon).Size(16, 16) + } + if it.Label != "" { + ui.Text(c, it.Label).SingleLine() + } + }) + if b.Clicked() { + r.clicked = i + slog.Debug("mujica: button_group click", "item", i) + } + } + }) + return r +} + +// buttonGroupCorners rounds only the outer corners of item i of 0..last. +func buttonGroupCorners(i, last int, vertical bool) []float32 { + var tl, tr, br, bl float32 + r := theme.ControlRadius + first, end := i == 0, i == last + if vertical { + if first { + tl, tr = r, r + } + if end { + br, bl = r, r + } + } else { + if first { + tl, bl = r, r + } + if end { + tr, br = r, r + } + } + return []float32{tl, tr, br, bl} +} + +// buttonGroupEdges draws each shared edge once: items after the first skip the leading one. +func buttonGroupEdges(i int, vertical bool) []float32 { + w := theme.BorderWidth + switch { + case i == 0: + return []float32{w} + case vertical: + return []float32{0, w, w, w} + default: + return []float32{w, w, w, 0} + } +} diff --git a/button_group_test.go b/button_group_test.go new file mode 100644 index 0000000..ead0aa7 --- /dev/null +++ b/button_group_test.go @@ -0,0 +1,84 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" +) + +var buttonGroupTestItems = []ButtonGroupItem{{Label: "Left"}, {Label: "Center", Disabled: true}, {Label: "Right"}} + +func TestButtonGroupClickAndArrows(t *testing.T) { + var got []int + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if i := ButtonGroup(c, buttonGroupTestItems, ButtonGroupOptions{Label: "Align"}).ClickedItem(); i >= 0 { + got = append(got, i) + } + }, 400, 200) + _ = tt.Click("Center") + _ = tt.Click("Left") + tt.Key(0, ui.KeyRight) + if !tt.Focused("Right") { + t.Fatal("Right arrow did not skip the disabled item to Right") + } + tt.Key(0, ui.KeyEnter) + tt.Key(0, ui.KeyRight) + if !tt.Focused("Left") { + t.Fatal("arrows do not wrap round") + } + if len(got) != 2 || got[0] != 0 || got[1] != 2 { + t.Fatalf("clicked %v, want [0 2]", got) + } +} + +func TestButtonGroupOneTabStop(t *testing.T) { + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ButtonGroup(c, buttonGroupTestItems, ButtonGroupOptions{Vertical: true}) + Button(c, "After", ButtonOptions{}) + }, 400, 300) + tt.Key(0, ui.KeyTab) + if !tt.Focused("Left") { + t.Fatal("Tab did not enter the group") + } + tt.Key(0, ui.KeyDown) + if !tt.Focused("Right") { + t.Fatal("Down did not move in a vertical group") + } + tt.Key(0, ui.KeyTab) + if !tt.Focused("After") { + t.Fatal("Tab did not leave the group") + } +} + +func TestButtonGroupDisabledGroup(t *testing.T) { + n := 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if ButtonGroup(c, buttonGroupTestItems, ButtonGroupOptions{Disabled: true}).ClickedItem() >= 0 { + n++ + } + }, 400, 200) + _ = tt.Click("Left") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if n != 0 { + t.Fatalf("disabled group clicked %d", n) + } +} + +func TestButtonGroupSnapshot(t *testing.T) { + snapshot(t, "button_group", 420, 200, func(c *ui.Context) { + ui.Row(c).Padding(24).Gap(24).AlignItems(ui.Start).Children(func() { + ButtonGroup(c, []ButtonGroupItem{{Label: "Day"}, {Label: "Week"}, {Label: "Month", Disabled: true}}, ButtonGroupOptions{}) + ButtonGroup(c, []ButtonGroupItem{ + {Icon: icons.Must("bold"), Name: "Bold"}, + {Icon: icons.Must("italic"), Name: "Italic"}, + {Icon: icons.Must("underline"), Name: "Underline"}, + }, ButtonGroupOptions{Vertical: true}) + }) + }) +} diff --git a/button_test.go b/button_test.go index de99f0d..8a1bc96 100644 --- a/button_test.go +++ b/button_test.go @@ -1,10 +1,12 @@ package mujica import ( + "strings" "testing" "github.com/egoist/mygo/ui" + "mujicaui/icons" "mujicaui/theme" ) @@ -80,16 +82,51 @@ func TestButtonMinHeight(t *testing.T) { } } -func TestButtonSnapshot(t *testing.T) { - snapshot(t, "button", 640, 140, func(c *ui.Context) { - ui.Row(c).Padding(24).Gap(12).Wrap().Children(func() { - Button(c, "Primary", ButtonOptions{}) - Button(c, "Secondary", ButtonOptions{Variant: Secondary}) - Button(c, "Outline", ButtonOptions{Variant: Outline}) - Button(c, "Ghost", ButtonOptions{Variant: Ghost}) - Button(c, "Delete", ButtonOptions{Variant: Danger}) - Button(c, "Saving", ButtonOptions{Loading: true}) - Button(c, "Disabled", ButtonOptions{Disabled: true}) +func TestButtonIconAndDanger(t *testing.T) { + n := 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if Button(c, "", ButtonOptions{Variant: Danger, Icon: icons.Must("trash-2"), Label: "Delete"}).Clicked() { + n++ + } + }, 300, 200) + if err := tt.Click("Delete"); err != nil { + t.Fatal(err) + } + if n != 1 { + t.Fatalf("icon button clicked %d times", n) + } +} + +// buttonDensitySnapshots snapshots view at Compact and Comfortable as name-. +func buttonDensitySnapshots(t *testing.T, name string, w, h int, view func(c *ui.Context)) { + t.Helper() + for _, d := range []theme.Density{theme.Compact, theme.Comfortable} { + snapshot(t, name+"-"+strings.ToLower(d.String()), w, h, func(c *ui.Context) { + m := Light + if Tokens(c).Dark { + m = Dark + } + Use(c, Settings{Mode: m, Density: d}) + view(c) }) + } +} + +func TestButtonSnapshot(t *testing.T) { + snapshot(t, "button", 640, 140, buttonSnapshotView) + buttonDensitySnapshots(t, "button", 640, 160, buttonSnapshotView) +} + +func buttonSnapshotView(c *ui.Context) { + ui.Row(c).Padding(24).Gap(12).Wrap().Children(func() { + Button(c, "Primary", ButtonOptions{}) + Button(c, "Secondary", ButtonOptions{Variant: Secondary}) + Button(c, "Outline", ButtonOptions{Variant: Outline}) + Button(c, "Ghost", ButtonOptions{Variant: Ghost}) + Button(c, "Delete", ButtonOptions{Variant: Danger}) + Button(c, "Saving", ButtonOptions{Loading: true}) + Button(c, "Disabled", ButtonOptions{Disabled: true}) + Button(c, "Add", ButtonOptions{Variant: Secondary, Icon: icons.Must("plus")}) }) } diff --git a/checkbox.go b/checkbox.go new file mode 100644 index 0000000..de9b5a4 --- /dev/null +++ b/checkbox.go @@ -0,0 +1,134 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// CheckboxOptions configure a Checkbox. +type CheckboxOptions struct { + // Indeterminate shows the mixed mark; a click then checks the box. + Indeterminate bool + Disabled bool +} + +// checkboxSize is the box edge in DIPs. +const checkboxSize float32 = 16 + +// Checkbox toggles *value; a click on the box or its label toggles, as does Space. +func Checkbox(c *ui.Context, value *bool, label string, opts CheckboxOptions) *ui.Element { + if value == nil { + panic("mujica: Checkbox needs a value") + } + k := Tokens(c) + d := Density(c) + row := ui.CheckboxBase(c, value).Gap(d.Unit() * 2).MinHeight(d.ControlHeight()).FocusRing(false).Disabled(opts.Disabled) + if row.Changed() && opts.Indeterminate && !*value { + // From mixed, a click always checks. + *value = true + } + if opts.Indeterminate { + row.Description(msg(c, "checkbox.mixed")) + } + on, mixed := *value, opts.Indeterminate + hover, pressed := row.Hovered(), row.Pressed() + row.Children(func() { + box := ui.Box(c).Size(checkboxSize, checkboxSize).Shrink(0).Radius(theme.ControlRadius) + switch { + case on || mixed: + box.Background(k.Accent).Border(theme.BorderWidth, k.AccentText) + case pressed: + box.Background(k.Selection).Border(theme.BorderWidth, k.AccentText) + case hover: + box.Background(k.SurfaceHover).Border(theme.BorderWidth, k.AccentText) + default: + box.Background(k.Surface).Border(theme.BorderWidth, k.ControlBorder) + } + box.Transition(textInputFade) + box.DrawOver(func(p *ui.Painter, r ui.Rect) { + switch { + case mixed: + p.Fill(ui.Rect{X: r.X + r.W*0.25, Y: r.Y + r.H/2 - 1, W: r.W * 0.5, H: 2}, k.OnAccent, 1) + case on: + var path ui.Path + path.MoveTo(r.X+r.W*0.24, r.Y+r.H*0.52).LineTo(r.X+r.W*0.42, r.Y+r.H*0.7).LineTo(r.X+r.W*0.77, r.Y+r.H*0.3) + p.StrokePath(&path, 2, k.OnAccent) + } + if row.FocusVisible() { + internal.FocusRing(p, r, theme.ControlRadius, k.Focus) + } + }) + if label != "" { + ui.Text(c, label) + } + }) + if row.Changed() { + slog.Debug("mujica: checkbox toggle", "label", label, "checked", *value) + } + return row +} + +// CheckboxItem is one box of a CheckboxGroup. +type CheckboxItem struct { + Label string + Value *bool + Disabled bool +} + +// CheckboxGroupOptions configure a CheckboxGroup. +type CheckboxGroupOptions struct { + Disabled bool +} + +// CheckboxGroup shows a select-all box over items: checked, mixed or clear. +func CheckboxGroup(c *ui.Context, label string, items []CheckboxItem, opts CheckboxGroupOptions) InputResult { + if len(items) == 0 { + panic("mujica: CheckboxGroup needs items") + } + d := Density(c) + on, enabled, enabledOn := 0, 0, 0 + for _, it := range items { + if it.Value == nil { + panic("mujica: CheckboxItem needs a Value") + } + if *it.Value { + on++ + } + if !it.Disabled { + enabled++ + if *it.Value { + enabledOn++ + } + } + } + var r InputResult + r.Element = ui.Column(c).Shrink(0).Disabled(opts.Disabled || enabled == 0) + r.Element.Children(func() { + all := on == len(items) + head := Checkbox(c, &all, label, CheckboxOptions{Indeterminate: on > 0 && !all}) + r.Input = head + if head.Changed() { + // Select-all leaves disabled items alone. + target := enabledOn < enabled + for _, it := range items { + if !it.Disabled { + *it.Value = target + } + } + r.changed = true + slog.Debug("mujica: checkbox_group select_all", "label", label, "checked", target) + } + ui.Column(c).Padding(0, 0, 0, checkboxSize+d.Unit()*2).Role(ui.RoleGroup).Label(label).Children(func() { + for _, it := range items { + if Checkbox(c, it.Value, it.Label, CheckboxOptions{Disabled: it.Disabled}).Changed() { + r.changed = true + } + } + }) + }) + return r +} diff --git a/checkbox_test.go b/checkbox_test.go new file mode 100644 index 0000000..d8befba --- /dev/null +++ b/checkbox_test.go @@ -0,0 +1,104 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +func TestCheckboxLabelClickAndSpace(t *testing.T) { + on, changes := false, 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if Checkbox(c, &on, "Remember me", CheckboxOptions{}).Changed() { + changes++ + } + }, 300, 200) + _ = tt.Click("Remember me") + if !on || changes != 1 { + t.Fatalf("label click: %v changes %d", on, changes) + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + if on || changes != 2 { + t.Fatalf("Space: %v changes %d", on, changes) + } +} + +func TestCheckboxIndeterminateChecks(t *testing.T) { + for _, start := range []bool{false, true} { + on := start + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + Checkbox(c, &on, "Some", CheckboxOptions{Indeterminate: true}) + }, 300, 200) + _ = tt.Click("Some") + if !on { + t.Fatalf("from mixed with %v, click left the box clear", start) + } + } +} + +func TestCheckboxDisabled(t *testing.T) { + on := false + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + Checkbox(c, &on, "Off", CheckboxOptions{Disabled: true}) + }, 300, 200) + _ = tt.Click("Off") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + if on || tt.Focused("Off") { + t.Fatalf("disabled box changed %v or took focus", on) + } +} + +func TestCheckboxGroupSelectAll(t *testing.T) { + mail, cal, locked := true, false, false + changes := 0 + items := []CheckboxItem{{Label: "Mail", Value: &mail}, {Label: "Calendar", Value: &cal}, {Label: "Admin", Value: &locked, Disabled: true}} + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if CheckboxGroup(c, "Notifications", items, CheckboxGroupOptions{}).Changed() { + changes++ + } + }, 300, 300) + _ = tt.Click("Notifications") + if !mail || !cal || locked || changes != 1 { + t.Fatalf("select all: mail %v cal %v admin %v changes %d", mail, cal, locked, changes) + } + _ = tt.Click("Notifications") + if mail || cal || locked { + t.Fatalf("clear all: mail %v cal %v admin %v", mail, cal, locked) + } + _ = tt.Click("Calendar") + if !cal || changes != 3 { + t.Fatalf("item click: cal %v changes %d", cal, changes) + } + tt.Key(0, ui.KeyTab) + if !tt.Focused("Notifications") { + t.Fatal("Tab did not reach the select-all box") + } + tt.Key(0, ui.KeySpace) + if !mail || !cal { + t.Fatalf("Space on select-all: mail %v cal %v", mail, cal) + } +} + +func checkboxSnapshotView(c *ui.Context) { + a, b, m, x, y := false, true, false, true, false + ui.Row(c).Padding(24).Gap(32).AlignItems(ui.Start).Children(func() { + ui.Column(c).Children(func() { + Checkbox(c, &a, "Unchecked", CheckboxOptions{}) + Checkbox(c, &b, "Checked", CheckboxOptions{}) + Checkbox(c, &m, "Indeterminate", CheckboxOptions{Indeterminate: true}) + Checkbox(c, &b, "Disabled", CheckboxOptions{Disabled: true}) + }) + CheckboxGroup(c, "Notifications", []CheckboxItem{{Label: "Mail", Value: &x}, {Label: "Calendar", Value: &y}}, CheckboxGroupOptions{}) + }) +} + +func TestCheckboxSnapshot(t *testing.T) { + snapshot(t, "checkbox", 420, 220, checkboxSnapshotView) + buttonDensitySnapshots(t, "checkbox", 420, 260, checkboxSnapshotView) +} diff --git a/docs/components/021-button.md b/docs/components/021-button.md new file mode 100644 index 0000000..02824ad --- /dev/null +++ b/docs/components/021-button.md @@ -0,0 +1,43 @@ +# 021 Button 按钮 + +## 用途 + +触发一个操作。提供主按钮、次按钮、描边、无底色和危险五种变体,可带图标,可显示加载与禁用。基于 MyGo `ui.ButtonBase`。 + +## 最小示例 + +```go +if mujica.Button(c, "Save", mujica.ButtonOptions{Icon: icons.Must("check")}).Clicked() { + fmt.Println("saved") +} +``` + +签名:`func Button(c *ui.Context, label string, opts ButtonOptions) *ui.Element` + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `label` | `string` | 必填(仅图标时可为空) | 按钮文字。 | +| `Variant` | `ButtonVariant` | `Primary` | `Primary`、`Secondary`、`Outline`、`Ghost`、`Danger`。 | +| `Icon` | `*ui.SVG` | `nil` | 文字前的 16 DIP 图标。 | +| `Loading` | `bool` | `false` | 以菱形加载标记替换图标,保留尺寸与文字,阻止点击。 | +| `Disabled` | `bool` | `false` | 不可点击、不进入 Tab 序列。 | +| `Label` | `string` | `""` | 无文字按钮的无障碍名称。 | + +## 状态 + +默认、悬停(底色加深或出现浅底)、按下、键盘聚焦(2 DIP 酒红焦点环,外留 2 DIP)、加载、禁用(MyGo 统一减淡)。高度不低于当前密度的控件高度(28/36/44 DIP)。 + +## 事件 + +`Clicked()`:鼠标在按钮内释放、Enter 或 Space 时为真,一次操作只报告一次。加载与禁用时始终为假。 + +## 键盘操作 + +Tab / Shift+Tab 聚焦;Enter 或 Space 触发。 + +## 限制 + +- 加载标记在减少动画模式下静止显示。 +- 危险变体的悬停与按下色由 `DangerFill` 混合黑色得到,未单独定义变量。 diff --git a/docs/components/022-icon-button.md b/docs/components/022-icon-button.md new file mode 100644 index 0000000..9efa694 --- /dev/null +++ b/docs/components/022-icon-button.md @@ -0,0 +1,42 @@ +# 022 IconButton 图标按钮 + +## 用途 + +只显示图标的方形按钮,用于工具栏与紧凑操作。操作名称必填,供辅助技术朗读,并作为默认提示文字。建立在 Button 之上。 + +## 最小示例 + +```go +if mujica.IconButton(c, icons.Must("settings"), "Settings", mujica.IconButtonOptions{Variant: mujica.Ghost}).Clicked() { + fmt.Println("open settings") +} +``` + +签名:`func IconButton(c *ui.Context, icon *ui.SVG, label string, opts IconButtonOptions) *ui.Element` + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `icon` | `*ui.SVG` | 必填 | 图标;为 nil 时 panic。 | +| `label` | `string` | 必填 | 操作名称;为空时 panic。 | +| `Variant` | `ButtonVariant` | `Primary` | 与 Button 相同的五种变体;工具栏通常用 `Ghost`。 | +| `Tooltip` | `string` | 操作名称 | 悬停约 600 毫秒后显示的提示。 | +| `Loading` | `bool` | `false` | 显示加载标记并阻止点击。 | +| `Disabled` | `bool` | `false` | 禁用。 | + +## 状态 + +同 Button:悬停、按下、聚焦、加载、禁用。边长等于当前密度的控件高度,不小于 28 DIP。 + +## 事件 + +`Clicked()`,一次操作一次。 + +## 键盘操作 + +Tab 聚焦;Enter 或 Space 触发。 + +## 限制 + +- 禁用时不显示提示:MyGo 的 `Hovered` 对禁用元素返回 false,提示随之不出现;名称仍作为无障碍描述保留。 diff --git a/docs/components/023-button-group.md b/docs/components/023-button-group.md new file mode 100644 index 0000000..c394325 --- /dev/null +++ b/docs/components/023-button-group.md @@ -0,0 +1,53 @@ +# 023 ButtonGroup 按钮组 + +## 用途 + +把若干按钮拼成一条,共用边框与尺寸,只有外侧圆角。整个组是一个 Tab 停靠点,组内用方向键移动。基于 `ui.ButtonBase` 与 MyGo 焦点组 `FocusGroup`。 + +## 最小示例 + +```go +items := []mujica.ButtonGroupItem{{Label: "Day"}, {Label: "Week"}, {Label: "Month"}} +if i := mujica.ButtonGroup(c, items, mujica.ButtonGroupOptions{Label: "Range"}).ClickedItem(); i >= 0 { + fmt.Println("chose", items[i].Label) +} +``` + +签名:`func ButtonGroup(c *ui.Context, items []ButtonGroupItem, opts ButtonGroupOptions) ButtonGroupResult` + +## 参数 + +`ButtonGroupItem` + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Label` | `string` | `""` | 文字;与 `Icon` 至少给一个,否则 panic。 | +| `Icon` | `*ui.SVG` | `nil` | 图标。 | +| `Name` | `string` | `""` | 仅图标项的无障碍名称。 | +| `Disabled` | `bool` | `false` | 单项禁用;方向键跳过该项。 | + +`ButtonGroupOptions` + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Vertical` | `bool` | `false` | 纵向排列,使用上下方向键。 | +| `Label` | `string` | `""` | 组的无障碍名称(工具栏角色)。 | +| `Disabled` | `bool` | `false` | 禁用整组。 | + +`items` 为空时 panic。 + +## 状态 + +每项有悬停、按下、聚焦、禁用;相邻项共用一条 1 DIP 分隔边。 + +## 事件 + +`ClickedItem()` 返回本帧被点击项的下标,无点击时为 -1。 + +## 键盘操作 + +Tab 进入组(回到上次聚焦项);横向组 Left/Right、纵向组 Up/Down 移动并循环;Home、End 到首末项;Enter 或 Space 触发。 + +## 限制 + +- 组内没有选中概念;需要保持选中请使用 ToggleGroup(033)。 diff --git a/docs/components/024-text-input.md b/docs/components/024-text-input.md new file mode 100644 index 0000000..88649a9 --- /dev/null +++ b/docs/components/024-text-input.md @@ -0,0 +1,49 @@ +# 024 TextInput 文本输入框 + +## 用途 + +单行文本编辑。支持占位、前后插槽、清空、只读与错误。编辑核心是 MyGo `ui.TextInputBase`,因此保留选择、撤销重做、剪贴板、右键菜单与输入法组合。 + +## 最小示例 + +```go +r := mujica.TextInput(c, &name, mujica.TextInputOptions{Label: "Name", Placeholder: "Your name", Clearable: true}) +if r.Submitted() { + fmt.Println("hello", name) +} +``` + +签名:`func TextInput(c *ui.Context, value *string, opts TextInputOptions) InputResult` + +`InputResult` 内嵌外层 `*ui.Element`,`Input` 字段是内部编辑元素,`Changed()`、`Submitted()` 报告事件。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `value` | `*string` | 必填 | 编辑的字符串;nil 时 panic。 | +| `Placeholder` | `string` | `""` | 空值时的占位文字(TextMuted 色)。 | +| `Label` | `string` | `""` | 无障碍名称,也供测试查找。 | +| `Leading` / `Trailing` | `func()` | `nil` | 在框内左侧、右侧构建内容,如图标或单位。 | +| `Clearable` | `bool` | `false` | 有内容时显示清空按钮;Escape 也会清空。 | +| `Disabled` | `bool` | `false` | 禁用,不可聚焦。 | +| `ReadOnly` | `bool` | `false` | 可聚焦、选择、复制,不可修改。 | +| `Error` | `string` | `""` | 非空时边框变为 Danger,并在下方显示该文字;辅助技术同时朗读。 | + +## 状态 + +默认(Surface 底、ControlBorder 边)、悬停(边框加深)、聚焦(边框 Focus 色;键盘聚焦另加焦点环)、只读(Background 底、Border 边)、错误、禁用。颜色变化 120 毫秒过渡,减少动画时直接切换。 + +## 事件 + +- `Changed()`:输入、粘贴、撤销或清空改变了值。只读时不会报告。 +- `Submitted()`:在框内按 Enter。 + +## 键盘操作 + +Tab 聚焦(全选内容);Enter 提交;Escape 清空(仅 `Clearable` 且有内容时,否则交给外层);Cmd/Ctrl+Z、Shift+Cmd+Z 撤销重做;Cmd/Ctrl+A/C/X/V;输入法组合期间不提交。 + +## 限制 + +- MyGo 没有公开的只读输入接口(只读模式仅用于 `Text.Selectable`,`editor.go:77`)。`ReadOnly` 通过让编辑器编辑一个副本并在同帧还原实现,撤销栈里可能出现被还原的步骤。 +- 清空按钮不进入 Tab 序列(与 MyGo SearchField 相同),键盘用 Escape 清空。 diff --git a/docs/components/025-text-area.md b/docs/components/025-text-area.md new file mode 100644 index 0000000..32205d8 --- /dev/null +++ b/docs/components/025-text-area.md @@ -0,0 +1,49 @@ +# 025 TextArea 多行文本框 + +## 用途 + +多行文本编辑,可设最小与最大高度,超出最大高度后在框内滚动;可显示字数;提交快捷键可配置。编辑核心是 MyGo `ui.TextAreaBase`,只排版可见段落,适合长文本。 + +## 最小示例 + +```go +r := mujica.TextArea(c, ¬es, mujica.TextAreaOptions{Label: "Notes", MaxHeight: 160, MaxLength: 200}) +if r.Submitted() { + fmt.Println("send", notes) +} +``` + +签名:`func TextArea(c *ui.Context, value *string, opts TextAreaOptions) InputResult` + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `value` | `*string` | 必填 | 编辑的字符串。 | +| `Placeholder` | `string` | `""` | 占位文字。 | +| `Label` | `string` | `""` | 无障碍名称。 | +| `MinHeight` | `float32` | `0`(三行) | 编辑区最小高度,DIP。 | +| `MaxHeight` | `float32` | `0`(随内容增长) | 编辑区最大高度,超出后滚动;小于 `MinHeight` 时 panic。 | +| `MaxLength` | `int` | `0`(不显示) | 显示“当前 / 上限”字数(按 Unicode 字符计);超出时变红并提示超出数量。 | +| `SubmitKey` / `SubmitMods` | `ui.Key` / `ui.Modifiers` | Cmd+Enter(非 macOS 为 Ctrl+Enter) | 提交快捷键;`SubmitKey` 为零时使用默认值。 | +| `Disabled` | `bool` | `false` | 禁用。 | +| `ReadOnly` | `bool` | `false` | 只读,可选择复制。 | +| `Error` | `string` | `""` | 错误文字;为空且超出 `MaxLength` 时自动显示超出提示。 | + +## 状态 + +默认、悬停、聚焦、只读、错误、禁用,表现同 TextInput。 + +## 事件 + +`Changed()`:内容被用户改变。`Submitted()`:按下提交快捷键。 + +## 键盘操作 + +Enter 与 Shift+Enter 换行;提交快捷键提交;方向键、PageUp/PageDown 移动光标并滚动;撤销、剪贴板与输入法同 TextInput。 + +## 限制 + +- `MaxLength` 只提示,不截断输入,以免打断输入法组合与粘贴。 +- 提交快捷键不能是不带修饰键的 Enter:MyGo 编辑器先接收 Enter 并插入换行(`editor.go:161`)。 +- 只读实现方式同 TextInput。 diff --git a/docs/components/026-number-input.md b/docs/components/026-number-input.md new file mode 100644 index 0000000..82865f7 --- /dev/null +++ b/docs/components/026-number-input.md @@ -0,0 +1,49 @@ +# 026 NumberInput 数字输入框 + +## 用途 + +输入与步进数值,支持范围、步长、精度与空值。合并 MyGo 的 Number input(输入模式)与 Stepper(`StepperOnly` 仅步进模式)。 + +## 最小示例 + +```go +if mujica.NumberInput(c, &copies, mujica.NumberInputOptions{Min: 1, Max: 99, Label: "Copies"}).Changed() { + fmt.Println("copies", copies) +} +``` + +签名:`func NumberInput(c *ui.Context, value *float64, opts NumberInputOptions) InputResult` + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `value` | `*float64` | 必填 | 数值;空值用 `math.NaN()` 表示,仅在 `AllowEmpty` 时允许。 | +| `Min` / `Max` | `float64` | 都为 0 | 范围;相等(含零值)表示不限范围;`Min > Max` 时 panic。 | +| `Step` | `float64` | `1` | 方向键与按钮的步长;负数 panic。 | +| `Precision` | `int` | 取 `Step` 的小数位 | 保留与显示的小数位。 | +| `AllowEmpty` | `bool` | `false` | 允许清空,值变为 NaN;从空值步进时从 0(夹在范围内)开始。 | +| `StepperOnly` | `bool` | `false` | 只显示数值与上下箭头,不可输入;必须给出 `Min < Max`,且不能与 `AllowEmpty` 同用。 | +| `Placeholder` | `string` | `""` | 空值时的占位。 | +| `Label` | `string` | `""` | 无障碍名称。 | +| `Disabled` | `bool` | `false` | 禁用。 | +| `Error` | `string` | `""` | 调用方给出的错误。 | + +## 状态 + +输入模式同 TextInput;输入非数字或超出范围时显示内置错误(“请输入数字”“请输入 a 到 b 之间的数字”),值保持上一次有效值;失去焦点后文本恢复为当前值并清除该错误。到达边界时对应按钮禁用。 + +## 事件 + +`Changed()`:值因输入、方向键、按钮或步进器改变。 + +## 键盘操作 + +输入模式:Up/Down 按步长增减。仅步进模式:Up/Right 增加、Down/Left 减少、Home 到最小、End 到最大;按住箭头持续步进。 + +## 限制 + +- 输入模式下的加减按钮不进入 Tab 序列,键盘用 Up/Down。 +- 仅步进模式复用 MyGo `ui.Stepper`,箭头高度来自主题间距,不随密度的控件高度变化。 +- MyGo `ui.Stepper` 的箭头不检查禁用(`indicators.go:216`),禁用时组件向它传入副本,保证值不被修改。 +- MyGo 的步进器吸附依赖有限边界(`widgets.go` 中 `snap`),所以仅步进模式要求有界。 diff --git a/docs/components/027-password-input.md b/docs/components/027-password-input.md new file mode 100644 index 0000000..20d4cab --- /dev/null +++ b/docs/components/027-password-input.md @@ -0,0 +1,42 @@ +# 027 PasswordInput 密码输入框 + +## 用途 + +遮蔽显示的密码输入,带显示/隐藏切换。允许粘贴;遮蔽时不允许复制与剪切。基于 `ui.TextInputBase(...).Password()`,辅助技术读不到遮蔽中的值。组件从不记录密码内容。 + +## 最小示例 + +```go +if mujica.PasswordInput(c, &password, mujica.PasswordInputOptions{Label: "Password"}).Submitted() { + fmt.Println("signing in") +} +``` + +签名:`func PasswordInput(c *ui.Context, value *string, opts PasswordInputOptions) InputResult` + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `value` | `*string` | 必填 | 密码。 | +| `Placeholder` | `string` | `""` | 占位文字。 | +| `Label` | `string` | `""` | 无障碍名称。 | +| `Disabled` | `bool` | `false` | 禁用(切换按钮同时禁用)。 | +| `Error` | `string` | `""` | 错误文字。 | + +## 状态 + +默认、悬停、聚焦、错误、禁用;遮蔽 / 显示两种模式,切换按钮的图标与名称(“显示密码”“隐藏密码”)随之变化。 + +## 事件 + +`Changed()`:内容改变。`Submitted()`:Enter。日志只写切换事件(`mujica: password_input reveal`,含是否显示),不写内容。 + +## 键盘操作 + +Tab 依次到输入框、切换按钮;切换按钮上 Space 或 Enter 切换;输入框中 Enter 提交,Cmd/Ctrl+V 粘贴。 + +## 限制 + +- MyGo 的 `Password()` 一旦设置无法撤销(`editor.go:791`),因此遮蔽与显示两种模式各用一个编辑器,切换时撤销历史和光标位置不保留,焦点留在切换按钮上。 +- 显示模式下内容是普通文本,可复制,辅助技术可朗读——这是用户主动选择的结果。 diff --git a/docs/components/028-search-input.md b/docs/components/028-search-input.md new file mode 100644 index 0000000..8d074bc --- /dev/null +++ b/docs/components/028-search-input.md @@ -0,0 +1,51 @@ +# 028 SearchInput 搜索框 + +## 用途 + +搜索模式:放大镜、输入、清空与提交。查找栏模式(`Find`):在此基础上显示匹配数量、上一项与下一项,对应 MyGo 的 Search field 与 Find bar。匹配由调用方计算。 + +## 最小示例 + +```go +matches := 0 +if query != "" { + matches = strings.Count(text, query) +} +r := mujica.SearchInput(c, &query, mujica.SearchInputOptions{Find: true, Matches: matches, Current: ¤t}) +if r.Moved() { + fmt.Println("show match", current) +} +``` + +签名:`func SearchInput(c *ui.Context, query *string, opts SearchInputOptions) SearchInputResult` + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `query` | `*string` | 必填 | 查询文字。 | +| `Placeholder` | `string` | “搜索”或“查找” | 占位文字。 | +| `Label` | `string` | 占位文字 | 无障碍名称。 | +| `Disabled` | `bool` | `false` | 禁用(查找快捷键也停用)。 | +| `Find` | `bool` | `false` | 开启查找栏模式。 | +| `Matches` | `int` | `0` | 匹配数量;负数 panic。 | +| `Current` | `*int` | `nil` | 当前匹配下标;`Find` 时必填,组件会把它夹在有效范围内。 | + +## 状态 + +同 TextInput;查找栏模式下显示“第 n 项,共 m 项”或“无匹配”(状态角色,变化时可被朗读),无匹配时上一项/下一项禁用。 + +## 事件 + +- `Changed()`:查询改变(含清空)。 +- `Submitted()`:搜索模式下 Enter。 +- `Moved()`:查找栏模式下当前匹配改变。 + +## 键盘操作 + +搜索模式:Enter 提交,Escape 清空。查找栏模式:Enter 下一项,Shift+Enter 上一项,macOS 上 Cmd+G / Shift+Cmd+G、其他平台 F3 / Shift+F3(窗口级),循环到首尾;Escape 清空。 + +## 限制 + +- MyGo 单行编辑器把 Shift+Enter 当作普通提交且不公开修饰键(`editor.go:489`,`submitMods` 未导出),组件用 `HandleInput` 先截获 Shift+Enter。 +- 没有“完成/关闭”按钮;是否显示查找栏由调用方决定。 diff --git a/docs/components/029-checkbox.md b/docs/components/029-checkbox.md new file mode 100644 index 0000000..2e88b84 --- /dev/null +++ b/docs/components/029-checkbox.md @@ -0,0 +1,51 @@ +# 029 Checkbox 复选框 + +## 用途 + +切换布尔值,支持选中、未选、半选;点击方框或标签都会切换。`CheckboxGroup` 提供组内全选(对应 MyGo CheckboxGroup)。基于 `ui.CheckboxBase`。 + +## 最小示例 + +```go +mujica.CheckboxGroup(c, "Notifications", []mujica.CheckboxItem{ + {Label: "Mail", Value: &mail}, + {Label: "Calendar", Value: &calendar}, +}, mujica.CheckboxGroupOptions{}) +``` + +签名: + +```go +func Checkbox(c *ui.Context, value *bool, label string, opts CheckboxOptions) *ui.Element +func CheckboxGroup(c *ui.Context, label string, items []CheckboxItem, opts CheckboxGroupOptions) InputResult +``` + +## 参数 + +`CheckboxOptions` + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Indeterminate` | `bool` | `false` | 显示半选横线;此时点击总是变为选中。是否半选由调用方决定。 | +| `Disabled` | `bool` | `false` | 禁用。 | + +`CheckboxItem`:`Label string`、`Value *bool`(必填)、`Disabled bool`。`CheckboxGroupOptions`:`Disabled bool`。`items` 为空时 panic。 + +## 状态 + +未选(Surface 底、ControlBorder 边)、悬停与按下(AccentText 边)、选中(酒红底、象牙白勾)、半选(酒红底、象牙白横线)、键盘聚焦(方框外焦点环)、禁用。行高不低于密度控件高度。 + +全选框:全部选中为选中,部分选中为半选,全不选为未选。点击时若可用项未全选则全部勾选,否则全部清除;禁用项保持不变。 + +## 事件 + +- `Checkbox(...).Changed()`:用户切换了值。 +- `CheckboxGroup(...).Changed()`:全选或任一项被切换。 + +## 键盘操作 + +Tab 聚焦(每个复选框一个停靠点);Space 切换。 + +## 限制 + +- MyGo 只有内部字段能把复选框报告为“mixed”(`access.go:307`,`checked` 未导出)。半选时组件在无障碍描述中加入“部分选中”,但角色状态仍报告为未选中。 diff --git a/docs/components/030-radio-group.md b/docs/components/030-radio-group.md new file mode 100644 index 0000000..f421a8e --- /dev/null +++ b/docs/components/030-radio-group.md @@ -0,0 +1,52 @@ +# 030 RadioGroup 单选组 + +## 用途 + +在一组选项中选一个,横向或纵向排列;选项值是任意可比较类型,作为稳定标识。基于 `ui.RadioGroup` 与 `ui.RadioBase`,整组是一个 Tab 停靠点。 + +## 最小示例 + +```go +items := []mujica.RadioItem[string]{{Value: "s", Label: "Small"}, {Value: "m", Label: "Medium"}, {Value: "l", Label: "Large"}} +if mujica.RadioGroup(c, &size, items, mujica.RadioGroupOptions{Label: "Size"}).Changed() { + fmt.Println("size", size) +} +``` + +签名:`func RadioGroup[T comparable](c *ui.Context, value *T, items []RadioItem[T], opts RadioGroupOptions) InputResult` + +## 参数 + +`RadioItem[T]` + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Value` | `T` | 必填 | 稳定选项值;重复时 panic。 | +| `Label` | `string` | `""` | 标签,点击标签也会选择。 | +| `Disabled` | `bool` | `false` | 单项禁用,方向键跳过。 | + +`RadioGroupOptions` + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Horizontal` | `bool` | `false` | 横向排列。 | +| `Label` | `string` | `""` | 组的无障碍名称。 | +| `Disabled` | `bool` | `false` | 禁用整组。 | + +`value` 为 nil 或 `items` 为空时 panic。`*value` 不在选项中时没有选中项。 + +## 状态 + +未选(空心圆)、悬停与按下(AccentText 边)、选中(酒红实心圆与象牙白圆点)、键盘聚焦、禁用。 + +## 事件 + +`Changed()`:用户选择了另一个值(点击、Space 或方向键)。 + +## 键盘操作 + +Tab 进入组并落在已选项;Up/Down/Left/Right 移动并直接选择,循环,跳过禁用项;Home、End 选择首末可用项。 + +## 限制 + +- 方向键对横向与纵向组都同时响应上下左右(MyGo `RadioGroup` 固定使用 `Horizontal|Vertical`)。 diff --git a/example_input_test.go b/example_input_test.go new file mode 100644 index 0000000..9828a07 --- /dev/null +++ b/example_input_test.go @@ -0,0 +1,130 @@ +package mujica_test + +import ( + "fmt" + "strings" + + "github.com/egoist/mygo/ui" + + mujica "mujicaui" + "mujicaui/icons" +) + +func ExampleButton() { + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Save", mujica.ButtonOptions{Icon: icons.Must("check")}).Clicked() { + fmt.Println("saved") + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleIconButton() { + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.IconButton(c, icons.Must("settings"), "Settings", mujica.IconButtonOptions{Variant: mujica.Ghost}).Clicked() { + fmt.Println("open settings") + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleButtonGroup() { + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + items := []mujica.ButtonGroupItem{{Label: "Day"}, {Label: "Week"}, {Label: "Month"}} + if i := mujica.ButtonGroup(c, items, mujica.ButtonGroupOptions{Label: "Range"}).ClickedItem(); i >= 0 { + fmt.Println("chose", items[i].Label) + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleTextInput() { + var name string + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TextInput(c, &name, mujica.TextInputOptions{Label: "Name", Placeholder: "Your name", Clearable: true}) + if r.Submitted() { + fmt.Println("hello", name) + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleTextArea() { + var notes string + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + r := mujica.TextArea(c, ¬es, mujica.TextAreaOptions{Label: "Notes", MaxHeight: 160, MaxLength: 200}) + if r.Submitted() { + fmt.Println("send", notes) + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleNumberInput() { + copies := 1.0 + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.NumberInput(c, &copies, mujica.NumberInputOptions{Min: 1, Max: 99, Label: "Copies"}).Changed() { + fmt.Println("copies", copies) + } + } + ui.Render(view, 400, 300, 1) +} + +func ExamplePasswordInput() { + var password string + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.PasswordInput(c, &password, mujica.PasswordInputOptions{Label: "Password"}).Submitted() { + fmt.Println("signing in") + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleSearchInput() { + var query string + current := 0 + text := "rose lys rose crown rose" + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + matches := 0 + if query != "" { + matches = strings.Count(text, query) + } + r := mujica.SearchInput(c, &query, mujica.SearchInputOptions{Find: true, Matches: matches, Current: ¤t}) + if r.Moved() { + fmt.Println("show match", current) + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleCheckbox() { + var mail, calendar bool + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.CheckboxGroup(c, "Notifications", []mujica.CheckboxItem{ + {Label: "Mail", Value: &mail}, + {Label: "Calendar", Value: &calendar}, + }, mujica.CheckboxGroupOptions{}) + } + ui.Render(view, 400, 300, 1) +} + +func ExampleRadioGroup() { + size := "m" + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + items := []mujica.RadioItem[string]{{Value: "s", Label: "Small"}, {Value: "m", Label: "Medium"}, {Value: "l", Label: "Large"}} + if mujica.RadioGroup(c, &size, items, mujica.RadioGroupOptions{Label: "Size"}).Changed() { + fmt.Println("size", size) + } + } + ui.Render(view, 400, 300, 1) +} diff --git a/examples/gallery/pages_input.go b/examples/gallery/pages_input.go index 72bd7b6..f1db221 100644 --- a/examples/gallery/pages_input.go +++ b/examples/gallery/pages_input.go @@ -1,3 +1,358 @@ package main -var inputPages = []page{} +import ( + "fmt" + "math" + "strings" + + "github.com/egoist/mygo/ui" + + mujica "mujicaui" + "mujicaui/icons" +) + +const inputCategory = "Inputs" + +// inputVariants lists the button variants for variant pickers. +var inputVariants = []mujica.RadioItem[mujica.ButtonVariant]{ + {Value: mujica.Primary, Label: "Primary"}, {Value: mujica.Secondary, Label: "Secondary"}, + {Value: mujica.Outline, Label: "Outline"}, {Value: mujica.Ghost, Label: "Ghost"}, {Value: mujica.Danger, Label: "Danger"}, +} + +// inputSection titles one part of a demo. +func inputSection(c *ui.Context, title string, fn func()) { + ui.Column(c).Gap(8).Children(func() { + ui.Text(c, title).FontWeight(600).TextColor(mujica.Tokens(c).TextMuted) + fn() + }) +} + +// inputFlags builds one checkbox per named flag, logging each toggle. +func inputFlags(c *ui.Context, log func(string), flags map[string]*bool, order ...string) { + ui.Row(c).Gap(16).Wrap().Children(func() { + for _, name := range order { + if mujica.Checkbox(c, flags[name], name, mujica.CheckboxOptions{}).Changed() { + log(fmt.Sprintf("option %s = %v", name, *flags[name])) + } + } + }) +} + +type inputButtonDemo struct { + variant mujica.ButtonVariant + icon, loading, disabled bool +} + +type inputTextDemo struct { + value, err string + clearable, readOnly, disabled, sl, fail bool +} + +type inputAreaDemo struct { + value string + max float64 + readOnly, disabled bool +} + +type inputNumberDemo struct { + value, step float64 + empty, stepper, disabled, fail bool +} + +type inputSearchDemo struct { + query, find string + current int + disabled bool +} + +type inputCheckDemo struct { + single, mixed, disabled bool + items [4]bool +} + +type inputGroupDemo struct { + vertical, disabled bool +} + +type inputRadioDemo struct { + value string + horizontal, disabledAll bool +} + +var inputPages = []page{ + {ID: "021", Name: "Button", ZhName: "按钮", Category: inputCategory, Keys: "Tab 聚焦;Enter 或 Space 触发。", + Code: `if mujica.Button(c, "Save", mujica.ButtonOptions{Icon: icons.Must("check")}).Clicked() { + fmt.Println("saved") +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "021", func() inputButtonDemo { return inputButtonDemo{} }) + inputSection(c, "Parameters", func() { + mujica.RadioGroup(c, &s.variant, inputVariants, mujica.RadioGroupOptions{Horizontal: true, Label: "Variant"}) + inputFlags(c, log, map[string]*bool{"Icon": &s.icon, "Loading": &s.loading, "Disabled": &s.disabled}, "Icon", "Loading", "Disabled") + }) + inputSection(c, "Live", func() { + opts := mujica.ButtonOptions{Variant: s.variant, Loading: s.loading, Disabled: s.disabled} + if s.icon { + opts.Icon = icons.Must("check") + } + ui.Row(c).Children(func() { + if mujica.Button(c, "Save changes", opts).Clicked() { + log("Button clicked") + } + }) + }) + inputSection(c, "Variants", func() { + ui.Row(c).Gap(12).Wrap().Children(func() { + for _, v := range inputVariants { + if mujica.Button(c, v.Label, mujica.ButtonOptions{Variant: v.Value}).Clicked() { + log(v.Label + " clicked") + } + } + mujica.Button(c, "Loading", mujica.ButtonOptions{Loading: true}) + mujica.Button(c, "Disabled", mujica.ButtonOptions{Disabled: true}) + }) + }) + }}, + {ID: "022", Name: "IconButton", ZhName: "图标按钮", Category: inputCategory, Keys: "Tab 聚焦;Enter 或 Space 触发;悬停显示提示。", + Code: `if mujica.IconButton(c, icons.Must("settings"), "Settings", mujica.IconButtonOptions{Variant: mujica.Ghost}).Clicked() { + fmt.Println("open settings") +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "022", func() inputButtonDemo { return inputButtonDemo{variant: mujica.Ghost} }) + inputSection(c, "Parameters", func() { + mujica.RadioGroup(c, &s.variant, inputVariants, mujica.RadioGroupOptions{Horizontal: true, Label: "Variant"}) + inputFlags(c, log, map[string]*bool{"Loading": &s.loading, "Disabled": &s.disabled}, "Loading", "Disabled") + }) + inputSection(c, "Live", func() { + ui.Row(c).Gap(8).Children(func() { + for _, n := range []string{"bold", "italic", "underline", "copy", "trash-2"} { + opts := mujica.IconButtonOptions{Variant: s.variant, Loading: s.loading, Disabled: s.disabled} + if mujica.IconButton(c, icons.Must(n), n, opts).Clicked() { + log("IconButton " + n + " clicked") + } + } + }) + }) + }}, + {ID: "023", Name: "ButtonGroup", ZhName: "按钮组", Category: inputCategory, Keys: "Tab 进入组;方向键在组内移动并跳过禁用项;Enter 或 Space 触发。", + Code: `items := []mujica.ButtonGroupItem{{Label: "Day"}, {Label: "Week"}, {Label: "Month"}} +if i := mujica.ButtonGroup(c, items, mujica.ButtonGroupOptions{Label: "Range"}).ClickedItem(); i >= 0 { + fmt.Println("chose", items[i].Label) +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "023", func() inputGroupDemo { return inputGroupDemo{} }) + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"Vertical": &s.vertical, "Disable group": &s.disabled}, "Vertical", "Disable group") + }) + inputSection(c, "Live", func() { + items := []mujica.ButtonGroupItem{{Label: "Day"}, {Label: "Week", Disabled: true}, {Label: "Month"}, {Icon: icons.Must("calendar"), Name: "Pick a date"}} + r := mujica.ButtonGroup(c, items, mujica.ButtonGroupOptions{Vertical: s.vertical, Disabled: s.disabled, Label: "Range"}) + if i := r.ClickedItem(); i >= 0 { + log(fmt.Sprintf("ButtonGroup item %d clicked", i)) + } + }) + }}, + {ID: "024", Name: "TextInput", ZhName: "文本输入框", Category: inputCategory, Keys: "Tab 聚焦;Enter 提交;Escape 清空(可清空时);Cmd/Ctrl+Z 撤销、+C/X/V 剪贴板;支持输入法组合。", + Code: `r := mujica.TextInput(c, &name, mujica.TextInputOptions{Label: "Name", Placeholder: "Your name", Clearable: true}) +if r.Submitted() { + fmt.Println("hello", name) +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "024", func() inputTextDemo { return inputTextDemo{clearable: true, sl: true} }) + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"Clearable": &s.clearable, "Slots": &s.sl, "ReadOnly": &s.readOnly, "Disabled": &s.disabled}, "Clearable", "Slots", "ReadOnly", "Disabled") + mujica.TextInput(c, &s.err, mujica.TextInputOptions{Label: "Error message", Placeholder: "Error message (empty for none)"}) + }) + inputSection(c, "Live", func() { + opts := mujica.TextInputOptions{Label: "Name", Placeholder: "Your name", Clearable: s.clearable, ReadOnly: s.readOnly, Disabled: s.disabled, Error: s.err} + if s.sl { + opts.Leading = func() { ui.Icon(c, icons.Must("user")).Size(16, 16).TextColor(mujica.Tokens(c).TextMuted) } + opts.Trailing = func() { ui.Text(c, fmt.Sprintf("%d", len([]rune(s.value)))).TextColor(mujica.Tokens(c).TextMuted) } + } + r := mujica.TextInput(c, &s.value, opts) + if r.Changed() { + log(fmt.Sprintf("TextInput changed: %q", s.value)) + } + if r.Submitted() { + log(fmt.Sprintf("TextInput submitted: %q", s.value)) + } + }) + inputSection(c, "States", func() { + ui.Row(c).Gap(12).Children(func() { + e, ro, off := "1789-13-01", "Read only", "Disabled" + mujica.TextInput(c, &e, mujica.TextInputOptions{Label: "Error state", Error: "No such date"}).Grow(1) + mujica.TextInput(c, &ro, mujica.TextInputOptions{Label: "Read-only state", ReadOnly: true}).Grow(1) + mujica.TextInput(c, &off, mujica.TextInputOptions{Label: "Disabled state", Disabled: true}).Grow(1) + }) + }) + }}, + {ID: "025", Name: "TextArea", ZhName: "多行文本框", Category: inputCategory, Keys: "Enter 换行;Cmd/Ctrl+Enter 提交(可配置);滚轮与方向键滚动;撤销、剪贴板与输入法同 TextInput。", + Code: `r := mujica.TextArea(c, ¬es, mujica.TextAreaOptions{Label: "Notes", MaxHeight: 160, MaxLength: 200}) +if r.Submitted() { + fmt.Println("send", notes) +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "025", func() inputAreaDemo { return inputAreaDemo{max: 120} }) + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"ReadOnly": &s.readOnly, "Disabled": &s.disabled}, "ReadOnly", "Disabled") + if mujica.NumberInput(c, &s.max, mujica.NumberInputOptions{Min: 0, Max: 1000, Step: 10, Label: "MaxLength"}).Changed() { + log(fmt.Sprintf("option MaxLength = %v", s.max)) + } + }) + inputSection(c, "Live", func() { + r := mujica.TextArea(c, &s.value, mujica.TextAreaOptions{Label: "Notes", Placeholder: "Write a dedication…", MinHeight: 80, MaxHeight: 160, + MaxLength: int(s.max), ReadOnly: s.readOnly, Disabled: s.disabled}) + if r.Changed() { + log(fmt.Sprintf("TextArea changed: %d characters", len([]rune(s.value)))) + } + if r.Submitted() { + log("TextArea submitted") + } + }) + }}, + {ID: "026", Name: "NumberInput", ZhName: "数字输入框", Category: inputCategory, Keys: "Up/Down 按步长增减;步进模式下 Up/Down/Left/Right、Home、End。", + Code: `if mujica.NumberInput(c, &copies, mujica.NumberInputOptions{Min: 1, Max: 99, Label: "Copies"}).Changed() { + fmt.Println("copies", copies) +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "026", func() inputNumberDemo { return inputNumberDemo{value: 3, step: 1} }) + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"AllowEmpty": &s.empty, "StepperOnly": &s.stepper, "Disabled": &s.disabled, "Error": &s.fail}, "AllowEmpty", "StepperOnly", "Disabled", "Error") + steps := []mujica.RadioItem[float64]{{Value: 1, Label: "Step 1"}, {Value: 0.5, Label: "Step 0.5"}, {Value: 0.01, Label: "Step 0.01"}} + if mujica.RadioGroup(c, &s.step, steps, mujica.RadioGroupOptions{Horizontal: true, Label: "Step"}).Changed() { + log(fmt.Sprintf("option Step = %v", s.step)) + } + }) + if s.stepper { + s.empty = false + } + if !s.empty && math.IsNaN(s.value) { + s.value = 0 + } + inputSection(c, "Live", func() { + opts := mujica.NumberInputOptions{Min: 0, Max: 10, Step: s.step, AllowEmpty: s.empty, StepperOnly: s.stepper, Disabled: s.disabled, Label: "Quantity", Placeholder: "Empty"} + if s.fail { + opts.Error = "Not in stock" + } + ui.Box(c).Width(240).Children(func() { + if mujica.NumberInput(c, &s.value, opts).Changed() { + log(fmt.Sprintf("NumberInput changed: %v", s.value)) + } + }) + }) + inputSection(c, "States", func() { + ui.Row(c).Gap(12).AlignItems(ui.Start).Children(func() { + a, b, e := 4.0, 2.0, 7.5 + mujica.NumberInput(c, &a, mujica.NumberInputOptions{Min: 1, Max: 8, StepperOnly: true, Label: "Stepper state"}) + mujica.NumberInput(c, &b, mujica.NumberInputOptions{Label: "Disabled state", Disabled: true}).Width(160) + mujica.NumberInput(c, &e, mujica.NumberInputOptions{Step: 0.5, Label: "Error state", Error: "Must be whole"}).Width(160) + }) + }) + }}, + {ID: "027", Name: "PasswordInput", ZhName: "密码输入框", Category: inputCategory, Keys: "Tab 依次聚焦输入框与显隐按钮;Space 或 Enter 切换显隐;Enter 在输入框中提交;粘贴可用,遮蔽时不可复制。", + Code: `if mujica.PasswordInput(c, &password, mujica.PasswordInputOptions{Label: "Password"}).Submitted() { + fmt.Println("signing in") +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "027", func() inputTextDemo { return inputTextDemo{} }) + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"Disabled": &s.disabled, "Error": &s.fail}, "Disabled", "Error") + }) + inputSection(c, "Live", func() { + opts := mujica.PasswordInputOptions{Label: "Password", Placeholder: "Password", Disabled: s.disabled} + if s.fail { + opts.Error = "At least 8 characters" + } + r := mujica.PasswordInput(c, &s.value, opts) + if r.Changed() { + // The contents never reach the log. + log(fmt.Sprintf("PasswordInput changed: %d characters", len([]rune(s.value)))) + } + if r.Submitted() { + log("PasswordInput submitted") + } + }) + }}, + {ID: "028", Name: "SearchInput", ZhName: "搜索框", Category: inputCategory, Keys: "Enter 提交(搜索模式)或下一项(查找栏);Shift+Enter 上一项;Cmd+G / F3 下一项,Shift 加上为上一项;Escape 清空。", + Code: `matches := 0 +if query != "" { + matches = strings.Count(text, query) +} +r := mujica.SearchInput(c, &query, mujica.SearchInputOptions{Find: true, Matches: matches, Current: ¤t}) +if r.Moved() { + fmt.Println("show match", current) +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "028", func() inputSearchDemo { return inputSearchDemo{} }) + const text = "The rose of the court, the rose of the chapel, and the rose of the garden all bloom in May." + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"Disabled": &s.disabled}, "Disabled") + }) + inputSection(c, "Search mode", func() { + r := mujica.SearchInput(c, &s.query, mujica.SearchInputOptions{Disabled: s.disabled}) + if r.Changed() { + log(fmt.Sprintf("SearchInput changed: %q", s.query)) + } + if r.Submitted() { + log(fmt.Sprintf("SearchInput submitted: %q", s.query)) + } + }) + inputSection(c, "Find bar mode", func() { + n := 0 + if s.find != "" { + n = strings.Count(text, s.find) + } + r := mujica.SearchInput(c, &s.find, mujica.SearchInputOptions{Find: true, Matches: n, Current: &s.current, Disabled: s.disabled}) + if r.Changed() { + log(fmt.Sprintf("find query: %q, %d matches", s.find, n)) + } + if r.Moved() { + log(fmt.Sprintf("find moved to match %d", s.current+1)) + } + ui.Text(c, text).TextColor(mujica.Tokens(c).TextMuted) + }) + }}, + {ID: "029", Name: "Checkbox", ZhName: "复选框", Category: inputCategory, Keys: "Tab 聚焦;Space 切换;点击标签同样切换;全选框在组内勾选全部或清空。", + Code: `mujica.CheckboxGroup(c, "Notifications", []mujica.CheckboxItem{ + {Label: "Mail", Value: &mail}, + {Label: "Calendar", Value: &calendar}, +}, mujica.CheckboxGroupOptions{})`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "029", func() inputCheckDemo { return inputCheckDemo{items: [4]bool{true, false, false, true}} }) + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"Indeterminate": &s.mixed, "Disabled": &s.disabled}, "Indeterminate", "Disabled") + }) + inputSection(c, "Live", func() { + if mujica.Checkbox(c, &s.single, "Accept the terms", mujica.CheckboxOptions{Indeterminate: s.mixed, Disabled: s.disabled}).Changed() { + s.mixed = false + log(fmt.Sprintf("Checkbox changed: %v", s.single)) + } + }) + inputSection(c, "Group with select all", func() { + items := []mujica.CheckboxItem{ + {Label: "Mail", Value: &s.items[0]}, {Label: "Calendar", Value: &s.items[1]}, + {Label: "Messages", Value: &s.items[2]}, {Label: "Security alerts (required)", Value: &s.items[3], Disabled: true}, + } + if mujica.CheckboxGroup(c, "Notifications", items, mujica.CheckboxGroupOptions{Disabled: s.disabled}).Changed() { + log(fmt.Sprintf("CheckboxGroup changed: %v", s.items)) + } + }) + }}, + {ID: "030", Name: "RadioGroup", ZhName: "单选组", Category: inputCategory, Keys: "Tab 进入组并落在已选项;方向键选择并跳过禁用项;Home、End 选择首末项。", + Code: `items := []mujica.RadioItem[string]{{Value: "s", Label: "Small"}, {Value: "m", Label: "Medium"}, {Value: "l", Label: "Large"}} +if mujica.RadioGroup(c, &size, items, mujica.RadioGroupOptions{Label: "Size"}).Changed() { + fmt.Println("size", size) +}`, + Demo: func(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "030", func() inputRadioDemo { return inputRadioDemo{value: "m"} }) + inputSection(c, "Parameters", func() { + inputFlags(c, log, map[string]*bool{"Horizontal": &s.horizontal, "Disabled": &s.disabledAll}, "Horizontal", "Disabled") + }) + inputSection(c, "Live", func() { + items := []mujica.RadioItem[string]{{Value: "s", Label: "Small"}, {Value: "m", Label: "Medium"}, {Value: "l", Label: "Large"}, {Value: "xl", Label: "Sold out", Disabled: true}} + if mujica.RadioGroup(c, &s.value, items, mujica.RadioGroupOptions{Horizontal: s.horizontal, Disabled: s.disabledAll, Label: "Size"}).Changed() { + log("RadioGroup chose " + s.value) + } + }) + }}, +} diff --git a/icon_button.go b/icon_button.go new file mode 100644 index 0000000..5de2c78 --- /dev/null +++ b/icon_button.go @@ -0,0 +1,33 @@ +package mujica + +import ( + "github.com/egoist/mygo/ui" +) + +// IconButtonOptions configure an IconButton. +type IconButtonOptions struct { + // Variant is the emphasis; the zero value is Primary, as for Button. + Variant ButtonVariant + // Tooltip shows on hover; empty uses the button's name. + Tooltip string + Loading bool + Disabled bool +} + +// IconButton is a square button showing only icon; label names its action. +func IconButton(c *ui.Context, icon *ui.SVG, label string, opts IconButtonOptions) *ui.Element { + if icon == nil { + panic("mujica: IconButton needs an icon") + } + if label == "" { + panic("mujica: IconButton needs an action name") + } + h := Density(c).ControlHeight() + b := Button(c, "", ButtonOptions{Variant: opts.Variant, Icon: icon, Loading: opts.Loading, Disabled: opts.Disabled, Label: label}) + b.Padding(0).Size(h, h) + tip := opts.Tooltip + if tip == "" { + tip = label + } + return b.Tooltip(tip) +} diff --git a/icon_button_test.go b/icon_button_test.go new file mode 100644 index 0000000..9b0794a --- /dev/null +++ b/icon_button_test.go @@ -0,0 +1,78 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" +) + +func TestIconButtonClickByNameAndKeyboard(t *testing.T) { + n := 0 + var w, h float32 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Row(c).Children(func() { + b := IconButton(c, icons.Must("settings"), "Settings", IconButtonOptions{Variant: Ghost}) + w, h = b.Bounds().W, b.Bounds().H + if b.Clicked() { + n++ + } + }) + }, 300, 200) + if err := tt.Click("Settings"); err != nil { + t.Fatal(err) + } + tt.Key(0, ui.KeyEnter) + if n != 2 { + t.Fatalf("clicks %d", n) + } + if w != 36 || h != 36 { + t.Fatalf("size %vx%v, want 36 square", w, h) + } +} + +func TestIconButtonBlockedStates(t *testing.T) { + for _, opts := range []IconButtonOptions{{Disabled: true}, {Loading: true}} { + n := 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if IconButton(c, icons.Must("trash-2"), "Delete", opts).Clicked() { + n++ + } + }, 300, 200) + _ = tt.Click("Delete") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + if n != 0 { + t.Fatalf("%+v: clicked %d", opts, n) + } + } +} + +func TestIconButtonNeedsName(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("no panic without an action name") + } + }() + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + IconButton(c, icons.Must("x"), "", IconButtonOptions{}) + }, 100, 100) +} + +func TestIconButtonSnapshot(t *testing.T) { + snapshot(t, "icon_button", 360, 90, func(c *ui.Context) { + ui.Row(c).Padding(24).Gap(12).Children(func() { + IconButton(c, icons.Must("plus"), "Add", IconButtonOptions{}) + IconButton(c, icons.Must("settings"), "Settings", IconButtonOptions{Variant: Secondary}) + IconButton(c, icons.Must("star"), "Favorite", IconButtonOptions{Variant: Outline}) + IconButton(c, icons.Must("copy"), "Copy", IconButtonOptions{Variant: Ghost}) + IconButton(c, icons.Must("trash-2"), "Delete", IconButtonOptions{Variant: Danger}) + IconButton(c, icons.Must("refresh-cw"), "Refresh", IconButtonOptions{Loading: true}) + IconButton(c, icons.Must("lock"), "Lock", IconButtonOptions{Disabled: true}) + }) + }) +} diff --git a/messages_input.go b/messages_input.go new file mode 100644 index 0000000..5797897 --- /dev/null +++ b/messages_input.go @@ -0,0 +1,22 @@ +package mujica + +func init() { + addMessages(map[string][2]string{ + "text_input.clear": {"Clear", "清空"}, + "number_input.increase": {"Increase", "增加"}, + "number_input.decrease": {"Decrease", "减少"}, + "number_input.invalid": {"Enter a number", "请输入数字"}, + "number_input.range": {"Enter a number from %s to %s", "请输入 %s 到 %s 之间的数字"}, + "password_input.show": {"Show password", "显示密码"}, + "password_input.hide": {"Hide password", "隐藏密码"}, + "search_input.search": {"Search", "搜索"}, + "search_input.find": {"Find", "查找"}, + "search_input.previous": {"Previous match", "上一项"}, + "search_input.next": {"Next match", "下一项"}, + "search_input.count": {"%d of %d", "第 %d 项,共 %d 项"}, + "search_input.none": {"No matches", "无匹配"}, + "checkbox.mixed": {"Partly selected", "部分选中"}, + "text_area.count": {"%d of %d characters", "%d / %d 字"}, + "text_area.over": {"%d characters over the limit", "超出 %d 字"}, + }) +} diff --git a/number_input.go b/number_input.go new file mode 100644 index 0000000..a781378 --- /dev/null +++ b/number_input.go @@ -0,0 +1,227 @@ +package mujica + +import ( + "fmt" + "log/slog" + "math" + "strconv" + "strings" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// NumberInputOptions configure a NumberInput. +type NumberInputOptions struct { + // Min and Max bound the value; equal bounds (the zero value) mean no bounds. + Min, Max float64 + // Step is what Up, Down and the buttons add; zero means 1. + Step float64 + // Precision is the decimals kept and shown; zero takes the decimals of Step. + Precision int + // AllowEmpty lets the field be empty, which sets the value to NaN. + AllowEmpty bool + // StepperOnly shows the value with step buttons and no typing; it needs bounds. + StepperOnly bool + Placeholder string + // Label names the field for assistive technology. + Label string + Disabled bool + // Error marks the value invalid and shows the message below. + Error string +} + +// numberInputSpec is NumberInputOptions resolved. +type numberInputSpec struct { + lo, hi, step float64 + decimals int +} + +func (s numberInputSpec) format(v float64) string { + if math.IsNaN(v) { + return "" + } + return strconv.FormatFloat(v, 'f', s.decimals, 64) +} + +// clamp bounds v and rounds it to the precision. +func (s numberInputSpec) clamp(v float64) float64 { + p := math.Pow(10, float64(s.decimals)) + return math.Round(math.Max(s.lo, math.Min(s.hi, v))*p) / p +} + +func numberInputResolve(opts NumberInputOptions) numberInputSpec { + s := numberInputSpec{lo: opts.Min, hi: opts.Max, step: opts.Step, decimals: opts.Precision} + if s.lo > s.hi { + panic("mujica: NumberInput Min is above Max") + } + if s.step < 0 || opts.Precision < 0 { + panic("mujica: NumberInput Step and Precision cannot be negative") + } + if s.lo == s.hi { + if opts.StepperOnly { + panic("mujica: NumberInput StepperOnly needs Min < Max") + } + s.lo, s.hi = math.Inf(-1), math.Inf(1) + } + if s.step == 0 { + s.step = 1 + } + if s.decimals == 0 { + if t := strconv.FormatFloat(s.step, 'f', -1, 64); strings.Contains(t, ".") { + s.decimals = len(t) - strings.IndexByte(t, '.') - 1 + } + } + return s +} + +// NumberInput edits *value as a number; Up and Down step it. +func NumberInput(c *ui.Context, value *float64, opts NumberInputOptions) InputResult { + if value == nil { + panic("mujica: NumberInput needs a value") + } + if opts.StepperOnly && opts.AllowEmpty { + panic("mujica: NumberInput StepperOnly cannot be empty") + } + if math.IsNaN(*value) && !opts.AllowEmpty { + panic("mujica: NumberInput value is NaN without AllowEmpty") + } + s := numberInputResolve(opts) + if opts.StepperOnly { + return numberInputStepper(c, value, s, opts) + } + var r InputResult + set := func(v float64) { + if !math.IsNaN(v) { + v = s.clamp(v) + } + if v != *value && !(math.IsNaN(v) && math.IsNaN(*value)) { + *value = v + r.changed = true + } + } + stepBy := func(n float64) { + base := *value + if math.IsNaN(base) { + base = math.Max(s.lo, math.Min(s.hi, 0)) + } + set(base + n*s.step) + } + look := &textInputLook{disabled: opts.Disabled, err: opts.Error} + r.Element, r.Input = textInputFrame(c, look, func(frame *ui.Element) *ui.Element { + text := ui.Local(frame, "text", func() string { return s.format(*value) }) + invalid := ui.Local(frame, "invalid", func() string { return "" }) + in := ui.TextInputBase(c, text).Grow(1).MinWidth(Density(c).Unit() * 12). + Placeholder(opts.Placeholder).Label(opts.Label) + if in.Changed() { + *invalid = numberInputParse(c, s, *text, opts.AllowEmpty, set) + } + switch { + case in.Shortcut(0, ui.KeyUp): + stepBy(1) + *text, *invalid = s.format(*value), "" + case in.Shortcut(0, ui.KeyDown): + stepBy(-1) + *text, *invalid = s.format(*value), "" + } + if !in.Focused() { + *text, *invalid = s.format(*value), "" + } + for _, b := range []struct { + name string + icon string + delta float64 + can bool + }{ + {msg(c, "number_input.decrease"), "minus", -1, math.IsNaN(*value) || *value > s.lo}, + {msg(c, "number_input.increase"), "plus", 1, math.IsNaN(*value) || *value < s.hi}, + } { + if numberInputButton(c, b.icon, b.name, b.can) { + stepBy(b.delta) + *text, *invalid = s.format(*value), "" + in.Focus() + } + } + if look.err == "" { + look.err = *invalid + } + return in + }, nil) + if r.changed { + slog.Debug("mujica: number_input change", "value", *value) + } + return r +} + +// numberInputParse applies typed text and returns why it is invalid, if it is. +func numberInputParse(c *ui.Context, s numberInputSpec, text string, allowEmpty bool, set func(float64)) string { + t := strings.TrimSpace(text) + if t == "" && allowEmpty { + set(math.NaN()) + return "" + } + v, err := strconv.ParseFloat(t, 64) + if err != nil || math.IsNaN(v) || math.IsInf(v, 0) { + return msg(c, "number_input.invalid") + } + if v < s.lo || v > s.hi { + return fmt.Sprintf(msg(c, "number_input.range"), s.format(s.lo), s.format(s.hi)) + } + set(v) + return "" +} + +// numberInputButton builds a pointer-only step button; Up and Down are its keys. +func numberInputButton(c *ui.Context, icon, name string, can bool) bool { + k := Tokens(c) + b := ui.Box(c).Size(theme.MinHitSize, theme.MinHitSize).Shrink(0).Center().Radius(theme.ControlRadius). + Role(ui.RoleButton).Label(name).Cursor(ui.CursorPointer).Disabled(!can) + fg := k.TextMuted + if b.Pressed() { + b.Background(k.Selection) + fg = k.Text + } else if b.Hovered() { + b.Background(k.SurfaceHover) + fg = k.Text + } + b.Children(func() { ui.Icon(c, icons.Must(icon)).Size(14, 14).TextColor(fg) }) + return b.Clicked() +} + +// numberInputStepper shows the value beside MyGo's stepper, restyled. +func numberInputStepper(c *ui.Context, value *float64, s numberInputSpec, opts NumberInputOptions) InputResult { + k := Tokens(c) + d := Density(c) + var r InputResult + r.Element = ui.Column(c).Gap(d.Unit()).Shrink(0).Disabled(opts.Disabled) + r.Element.Children(func() { + ui.Row(c).Gap(d.Unit() * 2).MinHeight(d.ControlHeight()).Children(func() { + ui.Text(c, s.format(*value)).FontFeatures("tnum").MinWidth(d.Unit() * 8).TextAlign(ui.End) + // MyGo's stepper arrows ignore Disabled: give them a copy. + target := value + if opts.Disabled { + held := *value + target = &held + } + st := ui.Stepper(c, target, s.lo, s.hi, s.step).Label(opts.Label).Width(d.Unit()*6). + Radius(theme.ControlRadius).Background(k.Surface).Border(theme.BorderWidth, k.ControlBorder) + if opts.Error != "" { + st.Error(opts.Error).Border(theme.BorderWidth, k.Danger) + } + internal.Ring(st, k.Focus, theme.ControlRadius) + r.Input = st + r.changed = st.Changed() && !opts.Disabled + }) + if opts.Error != "" { + ui.Text(c, opts.Error).TextColor(k.Danger).FontSize(theme.CaptionSize) + } + }) + if r.changed { + *value = s.clamp(*value) + slog.Debug("mujica: number_input step", "value", *value) + } + return r +} diff --git a/number_input_test.go b/number_input_test.go new file mode 100644 index 0000000..5259557 --- /dev/null +++ b/number_input_test.go @@ -0,0 +1,141 @@ +package mujica + +import ( + "math" + "testing" + + "github.com/egoist/mygo/ui" +) + +func numberInputTester(v *float64, changes *int, opts NumberInputOptions) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if NumberInput(c, v, opts).Changed() { + *changes++ + } + Button(c, "Elsewhere", ButtonOptions{}) + }, 400, 300) +} + +func TestNumberInputStepsAndBounds(t *testing.T) { + v, n := 9.0, 0 + tt := numberInputTester(&v, &n, NumberInputOptions{Min: 0, Max: 10, Label: "Copies"}) + _ = tt.Click("Copies") + tt.Key(0, ui.KeyUp) + tt.Key(0, ui.KeyUp) + if v != 10 || n != 1 { + t.Fatalf("value %v changes %d, want 10 and 1", v, n) + } + _ = tt.Click("Decrease") + _ = tt.Click("Decrease") + if v != 8 || n != 3 { + t.Fatalf("after buttons %v changes %d", v, n) + } + _ = tt.Click("Increase") + _ = tt.Click("Increase") + _ = tt.Click("Increase") + if v != 10 { + t.Fatalf("increase passed Max: %v", v) + } +} + +func TestNumberInputTypingPrecisionAndErrors(t *testing.T) { + v, n := 1.0, 0 + tt := numberInputTester(&v, &n, NumberInputOptions{Min: 0, Max: 2, Step: 0.25, Label: "Ratio"}) + _ = tt.Click("Ratio") + tt.Command("selectAll") + tt.Type("1.5") + if v != 1.5 { + t.Fatalf("typed value %v", v) + } + tt.Key(0, ui.KeyDown) + if v != 1.25 { + t.Fatalf("Down from 1.5 by 0.25 gave %v", v) + } + tt.Command("selectAll") + tt.Type("abc") + if v != 1.25 || !tt.HasText("Enter a number") { + t.Fatalf("invalid text changed value to %v or showed no error: %q", v, tt.Texts()) + } + tt.Command("selectAll") + tt.Type("7") + if v != 1.25 || !tt.HasText("Enter a number from 0.00 to 2.00") { + t.Fatalf("out of range: value %v texts %q", v, tt.Texts()) + } + _ = tt.Click("Elsewhere") + if tt.HasText("Enter a number") { + t.Fatal("error stays after leaving the field, which shows the value again") + } +} + +func TestNumberInputEmpty(t *testing.T) { + v, n := 3.0, 0 + tt := numberInputTester(&v, &n, NumberInputOptions{AllowEmpty: true, Label: "Limit"}) + _ = tt.Click("Limit") + tt.Command("selectAll") + tt.Key(0, ui.KeyBackspace) + if !math.IsNaN(v) { + t.Fatalf("emptied value %v, want NaN", v) + } + tt.Key(0, ui.KeyUp) + if v != 1 { + t.Fatalf("Up from empty gave %v, want 1", v) + } +} + +func TestNumberInputStepperOnly(t *testing.T) { + v, n := 2.0, 0 + tt := numberInputTester(&v, &n, NumberInputOptions{Min: 1, Max: 3, StepperOnly: true, Label: "Guests"}) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyUp) + tt.Key(0, ui.KeyUp) + if v != 3 || n != 1 || !tt.HasText("3") { + t.Fatalf("value %v changes %d texts %q", v, n, tt.Texts()) + } + tt.Key(0, ui.KeyHome) + if v != 1 { + t.Fatalf("Home gave %v", v) + } +} + +func TestNumberInputDisabled(t *testing.T) { + for _, stepper := range []bool{false, true} { + v, n := 2.0, 0 + tt := numberInputTester(&v, &n, NumberInputOptions{Min: 1, Max: 3, StepperOnly: stepper, Disabled: true, Label: "Off"}) + _ = tt.Click("Increase") + _ = tt.Click("Off") + tt.Key(0, ui.KeyUp) + if v != 2 || n != 0 { + t.Fatalf("stepper %v: disabled changed to %v (%d changes)", stepper, v, n) + } + } +} + +func TestNumberInputBadOptionsPanic(t *testing.T) { + for _, opts := range []NumberInputOptions{{Min: 3, Max: 1}, {StepperOnly: true}, {Step: -1}} { + func() { + defer func() { + if recover() == nil { + t.Errorf("%+v: no panic", opts) + } + }() + v := 0.0 + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + NumberInput(c, &v, opts) + }, 200, 100) + }() + } +} + +func TestNumberInputSnapshot(t *testing.T) { + snapshot(t, "number_input", 420, 260, func(c *ui.Context) { + a, b, e, s := 12.0, math.NaN(), 7.5, 4.0 + ui.Column(c).Padding(24).Gap(12).Width(260).Children(func() { + NumberInput(c, &a, NumberInputOptions{Min: 0, Max: 99, Label: "A"}) + NumberInput(c, &b, NumberInputOptions{AllowEmpty: true, Placeholder: "No limit", Label: "B"}) + NumberInput(c, &e, NumberInputOptions{Step: 0.5, Label: "E", Error: "Must be whole"}) + NumberInput(c, &s, NumberInputOptions{Min: 1, Max: 8, StepperOnly: true, Label: "S"}) + }) + }) +} diff --git a/password_input.go b/password_input.go new file mode 100644 index 0000000..25d07ca --- /dev/null +++ b/password_input.go @@ -0,0 +1,75 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// PasswordInputOptions configure a PasswordInput. +type PasswordInputOptions struct { + Placeholder string + // Label names the field for assistive technology. + Label string + Disabled bool + // Error marks the value invalid and shows the message below. + Error string +} + +// PasswordInput is a masked field with a show and hide toggle. +func PasswordInput(c *ui.Context, value *string, opts PasswordInputOptions) InputResult { + if value == nil { + panic("mujica: PasswordInput needs a value") + } + var r InputResult + look := &textInputLook{disabled: opts.Disabled, err: opts.Error} + r.Element, r.Input = textInputFrame(c, look, func(frame *ui.Element) *ui.Element { + shown := ui.Local(frame, "shown", func() bool { return false }) + var in *ui.Element + // MyGo's mask cannot be lifted, so each mode keeps its own editor. + mode := "masked" + if *shown { + mode = "shown" + } + ui.Row(c).Key(mode).Grow(1).Children(func() { + in = ui.TextInputBase(c, value).Grow(1).MinWidth(Density(c).Unit() * 10). + Placeholder(opts.Placeholder).Label(opts.Label) + if !*shown { + in.Password() + } + }) + r.changed = in.Changed() + r.submitted = in.Submitted() + if passwordInputToggle(c, *shown) { + *shown = !*shown + slog.Debug("mujica: password_input reveal", "shown", *shown) + } + return in + }, nil) + return r +} + +// passwordInputToggle builds the show or hide button and reports a click. +func passwordInputToggle(c *ui.Context, shown bool) bool { + k := Tokens(c) + name, icon := msg(c, "password_input.show"), "eye" + if shown { + name, icon = msg(c, "password_input.hide"), "eye-off" + } + b := ui.ButtonBase(c).Size(theme.MinHitSize, theme.MinHitSize).Radius(theme.ControlRadius).Label(name).Tooltip(name) + internal.Ring(b, k.Focus, theme.ControlRadius) + fg := k.TextMuted + if b.Pressed() { + b.Background(k.Selection) + fg = k.Text + } else if b.Hovered() { + b.Background(k.SurfaceHover) + fg = k.Text + } + b.Children(func() { ui.Icon(c, icons.Must(icon)).Size(16, 16).TextColor(fg) }) + return b.Clicked() +} diff --git a/password_input_test.go b/password_input_test.go new file mode 100644 index 0000000..72f82c0 --- /dev/null +++ b/password_input_test.go @@ -0,0 +1,101 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +func TestPasswordInputMaskPasteAndReveal(t *testing.T) { + pw, changes, submits := "", 0, 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + r := PasswordInput(c, &pw, PasswordInputOptions{Label: "Password"}) + if r.Changed() { + changes++ + } + if r.Submitted() { + submits++ + } + }, 400, 200) + _ = tt.Click("Password") + tt.SetClipboard("s3cr") + tt.Command("paste") + tt.Type("et") + if pw != "s3cret" || changes != 2 { + t.Fatalf("value %q changes %d", pw, changes) + } + tt.SetClipboard("") + tt.Command("selectAll") + tt.Command("copy") + if tt.Clipboard() != "" { + t.Fatalf("masked field copied %q", tt.Clipboard()) + } + for _, s := range tt.Texts() { + if s == "s3cret" { + t.Fatal("masked password shows in the texts") + } + } + if err := tt.Click("Show password"); err != nil { + t.Fatal(err) + } + if _, ok := tt.Find("Hide password"); !ok || pw != "s3cret" { + t.Fatalf("after reveal: value %q, texts %q", pw, tt.Texts()) + } + _ = tt.Click("Password") + tt.Command("selectAll") + tt.Command("copy") + if tt.Clipboard() != "s3cret" { + t.Fatalf("revealed field copied %q", tt.Clipboard()) + } + tt.Key(0, ui.KeyEnter) + if submits != 1 { + t.Fatalf("submits %d", submits) + } + _ = tt.Click("Hide password") + if _, ok := tt.Find("Show password"); !ok { + t.Fatal("hide did not mask again") + } +} + +func TestPasswordInputToggleByKeyboard(t *testing.T) { + pw := "x" + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + PasswordInput(c, &pw, PasswordInputOptions{Label: "PIN"}) + }, 400, 200) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeySpace) + if _, ok := tt.Find("Hide password"); !ok { + t.Fatal("Space on the toggle did not reveal") + } +} + +func TestPasswordInputDisabled(t *testing.T) { + pw := "locked" + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + PasswordInput(c, &pw, PasswordInputOptions{Label: "Off", Disabled: true}) + }, 400, 200) + _ = tt.Click("Show password") + _ = tt.Click("Off") + tt.Type("zz") + if pw != "locked" { + t.Fatalf("disabled value %q", pw) + } + if _, ok := tt.Find("Show password"); !ok { + t.Fatal("disabled toggle revealed") + } +} + +func TestPasswordInputSnapshot(t *testing.T) { + snapshot(t, "password_input", 420, 220, func(c *ui.Context) { + a, b, e := "", "versailles", "short" + ui.Column(c).Padding(24).Gap(12).Width(320).Children(func() { + PasswordInput(c, &a, PasswordInputOptions{Label: "A", Placeholder: "Password"}) + PasswordInput(c, &b, PasswordInputOptions{Label: "B"}) + PasswordInput(c, &e, PasswordInputOptions{Label: "E", Error: "At least 8 characters"}) + }) + }) +} diff --git a/radio_group.go b/radio_group.go new file mode 100644 index 0000000..df0b3d4 --- /dev/null +++ b/radio_group.go @@ -0,0 +1,90 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/internal" + "mujicaui/theme" +) + +// RadioItem is one choice of a RadioGroup; Value is its stable identity. +type RadioItem[T comparable] struct { + Value T + Label string + Disabled bool +} + +// RadioGroupOptions configure a RadioGroup. +type RadioGroupOptions struct { + // Horizontal lays the choices in a row; the default is a column. + Horizontal bool + // Label names the group for assistive technology. + Label string + Disabled bool +} + +// RadioGroup chooses one item's Value into *value; arrows move the choice. +func RadioGroup[T comparable](c *ui.Context, value *T, items []RadioItem[T], opts RadioGroupOptions) InputResult { + if value == nil { + panic("mujica: RadioGroup needs a value") + } + if len(items) == 0 { + panic("mujica: RadioGroup needs items") + } + seen := make(map[T]bool, len(items)) + for _, it := range items { + if seen[it.Value] { + panic("mujica: RadioGroup has a duplicate value") + } + seen[it.Value] = true + } + k := Tokens(c) + d := Density(c) + var r InputResult + r.Element = ui.RadioGroup(c, func() { + for _, it := range items { + if radioGroupItem(c, k, d, value, it) { + r.changed = true + slog.Debug("mujica: radio_group choose", "label", it.Label) + } + } + }).Label(opts.Label).Disabled(opts.Disabled).Gap(0) + if opts.Horizontal { + r.Element.Row().Gap(d.Unit() * 6) + } + return r +} + +// radioGroupItem builds one radio and reports whether it was chosen. +func radioGroupItem[T comparable](c *ui.Context, k theme.Tokens, d theme.Density, value *T, it RadioItem[T]) bool { + row := ui.RadioBase(c, value, it.Value).Gap(d.Unit() * 2).MinHeight(d.ControlHeight()).FocusRing(false).Disabled(it.Disabled) + on := *value == it.Value + hover, pressed := row.Hovered(), row.Pressed() + row.Children(func() { + dot := ui.Box(c).Size(checkboxSize, checkboxSize).Shrink(0).Radius(checkboxSize / 2) + switch { + case on: + dot.Background(k.Accent).Border(theme.BorderWidth, k.AccentText) + case pressed: + dot.Background(k.Selection).Border(theme.BorderWidth, k.AccentText) + case hover: + dot.Background(k.SurfaceHover).Border(theme.BorderWidth, k.AccentText) + default: + dot.Background(k.Surface).Border(theme.BorderWidth, k.ControlBorder) + } + dot.Transition(textInputFade) + dot.DrawOver(func(p *ui.Painter, r ui.Rect) { + if on { + s := r.W * 0.375 + p.Fill(ui.Rect{X: r.X + (r.W-s)/2, Y: r.Y + (r.H-s)/2, W: s, H: s}, k.OnAccent, s/2) + } + if row.FocusVisible() { + internal.FocusRing(p, r, checkboxSize/2, k.Focus) + } + }) + ui.Text(c, it.Label) + }) + return row.Changed() +} diff --git a/radio_group_test.go b/radio_group_test.go new file mode 100644 index 0000000..e4a2099 --- /dev/null +++ b/radio_group_test.go @@ -0,0 +1,99 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +var radioGroupTestItems = []RadioItem[string]{ + {Value: "s", Label: "Small"}, + {Value: "m", Label: "Medium", Disabled: true}, + {Value: "l", Label: "Large"}, +} + +func radioGroupTester(v *string, changes *int, opts RadioGroupOptions) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if RadioGroup(c, v, radioGroupTestItems, opts).Changed() { + *changes++ + } + Button(c, "After", ButtonOptions{}) + }, 400, 300) +} + +func TestRadioGroupClickAndArrows(t *testing.T) { + v, n := "s", 0 + tt := radioGroupTester(&v, &n, RadioGroupOptions{Label: "Size"}) + _ = tt.Click("Medium") + if v != "s" || n != 0 { + t.Fatalf("disabled item chosen: %q", v) + } + _ = tt.Click("Large") + if v != "l" || n != 1 { + t.Fatalf("click: %q changes %d", v, n) + } + tt.Key(0, ui.KeyDown) + if v != "s" || n != 2 { + t.Fatalf("Down wraps past the disabled item to Small, got %q changes %d", v, n) + } + tt.Key(0, ui.KeyUp) + if v != "l" { + t.Fatalf("Up skipped to %q", v) + } + tt.Key(0, ui.KeyHome) + if v != "s" { + t.Fatalf("Home chose %q", v) + } +} + +func TestRadioGroupTabStopsAtChosen(t *testing.T) { + v, n := "l", 0 + tt := radioGroupTester(&v, &n, RadioGroupOptions{Horizontal: true}) + tt.Key(0, ui.KeyTab) + if !tt.Focused("Large") { + t.Fatal("Tab did not go to the chosen radio") + } + tt.Key(0, ui.KeyLeft) + if v != "s" { + t.Fatalf("Left in a row chose %q", v) + } + tt.Key(0, ui.KeyTab) + if !tt.Focused("After") { + t.Fatal("Tab did not leave the group") + } +} + +func TestRadioGroupDisabledGroup(t *testing.T) { + v, n := "s", 0 + tt := radioGroupTester(&v, &n, RadioGroupOptions{Disabled: true}) + _ = tt.Click("Large") + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyDown) + if v != "s" || n != 0 { + t.Fatalf("disabled group chose %q", v) + } +} + +func TestRadioGroupDuplicateValuePanics(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("no panic for duplicate values") + } + }() + v := 1 + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + RadioGroup(c, &v, []RadioItem[int]{{Value: 1, Label: "A"}, {Value: 1, Label: "B"}}, RadioGroupOptions{}) + }, 200, 100) +} + +func TestRadioGroupSnapshot(t *testing.T) { + snapshot(t, "radio_group", 460, 220, func(c *ui.Context) { + v, h := "m", 2 + ui.Column(c).Padding(24).Gap(16).Children(func() { + RadioGroup(c, &v, []RadioItem[string]{{Value: "s", Label: "Sonnet"}, {Value: "m", Label: "Madrigal"}, {Value: "o", Label: "Ode", Disabled: true}}, RadioGroupOptions{}) + RadioGroup(c, &h, []RadioItem[int]{{Value: 1, Label: "Matins"}, {Value: 2, Label: "Vespers"}, {Value: 3, Label: "Compline"}}, RadioGroupOptions{Horizontal: true}) + }) + }) +} diff --git a/search_input.go b/search_input.go new file mode 100644 index 0000000..7a1af8f --- /dev/null +++ b/search_input.go @@ -0,0 +1,140 @@ +package mujica + +import ( + "fmt" + "log/slog" + "runtime" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/theme" +) + +// SearchInputOptions configure a SearchInput. +type SearchInputOptions struct { + // Placeholder is empty for the built-in "Search" or "Find". + Placeholder string + // Label names the field; empty uses the placeholder. + Label string + Disabled bool + // Find turns on find-bar mode: match count, previous and next. + Find bool + // Matches is how many matches the caller found for the query. + Matches int + // Current is the chosen match index; Find mode requires it. + Current *int +} + +// SearchInputResult adds find-bar moves to InputResult. +type SearchInputResult struct { + InputResult + moved bool +} + +// Moved reports that the user went to another match this frame. +func (r SearchInputResult) Moved() bool { return r.moved } + +// SearchInput is a search field with clear, or a find bar with match navigation. +func SearchInput(c *ui.Context, query *string, opts SearchInputOptions) SearchInputResult { + if query == nil { + panic("mujica: SearchInput needs a query") + } + if opts.Find && opts.Current == nil { + panic("mujica: SearchInput Find mode needs Current") + } + if opts.Matches < 0 { + panic("mujica: SearchInput Matches is negative") + } + k := Tokens(c) + place := opts.Placeholder + if place == "" { + place = msg(c, "search_input.search") + if opts.Find { + place = msg(c, "search_input.find") + } + } + name := opts.Label + if name == "" { + name = place + } + var r SearchInputResult + step := func(d int) { + if opts.Matches == 0 { + return + } + *opts.Current = (*opts.Current + d + opts.Matches) % opts.Matches + r.moved = true + slog.Debug("mujica: search_input move", "current", *opts.Current) + } + if opts.Find { + *opts.Current = max(0, min(*opts.Current, opts.Matches-1)) + if !opts.Disabled { + mac := runtime.GOOS == "darwin" + switch { + case mac && c.Shortcut(ui.Cmd, ui.KeyG), !mac && c.Shortcut(0, ui.KeyF3): + step(1) + case mac && c.Shortcut(ui.Shift|ui.Cmd, ui.KeyG), !mac && c.Shortcut(ui.Shift, ui.KeyF3): + step(-1) + } + } + } + look := &textInputLook{disabled: opts.Disabled} + r.Element, r.Input = textInputFrame(c, look, func(frame *ui.Element) *ui.Element { + ui.Icon(c, icons.Must("search")).Size(16, 16).Shrink(0).TextColor(k.TextMuted) + back := ui.Local(frame, "back", func() bool { return false }) + in := ui.TextInputBase(c, query).Grow(1).MinWidth(Density(c).Unit() * 10).Placeholder(place).Label(name) + r.changed = in.Changed() + if opts.Find { + // Shift+Enter would reach the editor as a plain submit. + in.HandleInput(func(ev ui.InputEvent) bool { + if ev.Kind == ui.InputKeyDown && ev.Key == ui.KeyEnter && ev.Mods == ui.Shift { + *back = true + return true + } + return false + }) + switch { + case *back: + *back = false + step(-1) + case in.Submitted(): + step(1) + } + } else { + r.submitted = in.Submitted() + } + if *query != "" && textInputClear(c, in) { + *query = "" + r.changed = true + slog.Debug("mujica: search_input clear") + } + if opts.Find { + searchInputFindControls(c, *query, opts.Matches, *opts.Current, step) + } + return in + }, nil) + return r +} + +// searchInputFindControls shows the match count with previous and next buttons. +func searchInputFindControls(c *ui.Context, query string, matches, current int, step func(int)) { + k := Tokens(c) + status := msg(c, "search_input.none") + switch { + case query == "": + status = "" + case matches > 0: + status = fmt.Sprintf(msg(c, "search_input.count"), current+1, matches) + } + ui.Text(c, status).TextColor(k.TextMuted).FontSize(theme.CaptionSize).FontFeatures("tnum"). + SingleLine().Shrink(0).Role(ui.RoleStatus) + ui.Box(c).Width(theme.BorderWidth).Height(16).Background(k.Border).Shrink(0) + opts := IconButtonOptions{Variant: Ghost, Disabled: matches == 0} + if IconButton(c, icons.Must("chevron-up"), msg(c, "search_input.previous"), opts).Size(theme.MinHitSize, theme.MinHitSize).MinHeight(theme.MinHitSize).Clicked() { + step(-1) + } + if IconButton(c, icons.Must("chevron-down"), msg(c, "search_input.next"), opts).Size(theme.MinHitSize, theme.MinHitSize).MinHeight(theme.MinHitSize).Clicked() { + step(1) + } +} diff --git a/search_input_test.go b/search_input_test.go new file mode 100644 index 0000000..dc6cfb3 --- /dev/null +++ b/search_input_test.go @@ -0,0 +1,129 @@ +package mujica + +import ( + "runtime" + "strings" + "testing" + + "github.com/egoist/mygo/ui" +) + +func TestSearchInputSearchClearSubmit(t *testing.T) { + q, changes, submits := "", 0, 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + r := SearchInput(c, &q, SearchInputOptions{}) + if r.Changed() { + changes++ + } + if r.Submitted() { + submits++ + } + }, 400, 200) + _ = tt.Click("Search") + tt.Type("rose") + tt.Key(0, ui.KeyEnter) + if q != "rose" || changes != 1 || submits != 1 { + t.Fatalf("query %q changes %d submits %d", q, changes, submits) + } + _ = tt.Click("Clear") + if q != "" || changes != 2 { + t.Fatalf("after clear %q changes %d", q, changes) + } + tt.Type("lys") + tt.Key(0, ui.KeyEscape) + if q != "" || changes != 4 { + t.Fatalf("after Escape %q changes %d", q, changes) + } +} + +// searchInputFindTester counts matches of the query in a fixed text. +func searchInputFindTester(q *string, cur, moves *int, locale Locale) *ui.Tester { + const text = "rose lys rose crown rose" + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{Locale: locale}) + n := 0 + if *q != "" { + n = strings.Count(text, *q) + } + if SearchInput(c, q, SearchInputOptions{Find: true, Matches: n, Current: cur, Label: "Find in page"}).Moved() { + *moves++ + } + }, 500, 200) +} + +func TestSearchInputFindBarNavigation(t *testing.T) { + q, cur, moves := "", 0, 0 + tt := searchInputFindTester(&q, &cur, &moves, "") + _ = tt.Click("Find in page") + tt.Type("rose") + if !tt.HasText("1 of 3") { + t.Fatalf("count missing: %q", tt.Texts()) + } + tt.Key(0, ui.KeyEnter) + tt.Key(0, ui.KeyEnter) + if cur != 2 || !tt.HasText("3 of 3") { + t.Fatalf("after two Enters current %d texts %q", cur, tt.Texts()) + } + tt.Key(0, ui.KeyEnter) + if cur != 0 { + t.Fatalf("Enter did not wrap, current %d", cur) + } + tt.Key(ui.Shift, ui.KeyEnter) + if cur != 2 || q != "rose" { + t.Fatalf("Shift+Enter: current %d query %q", cur, q) + } + _ = tt.Click("Previous match") + _ = tt.Click("Next match") + _ = tt.Click("Next match") + if cur != 0 || moves != 7 { + t.Fatalf("buttons: current %d moves %d", cur, moves) + } + if runtime.GOOS == "darwin" { + tt.Key(ui.Cmd, ui.KeyG) + } else { + tt.Key(0, ui.KeyF3) + } + if cur != 1 { + t.Fatalf("find-next shortcut: current %d", cur) + } +} + +func TestSearchInputFindNoMatches(t *testing.T) { + q, cur, moves := "", 0, 0 + tt := searchInputFindTester(&q, &cur, &moves, ZhCN) + _ = tt.Click("Find in page") + tt.Type("tulip") + if !tt.HasText("无匹配") { + t.Fatalf("no-match status missing: %q", tt.Texts()) + } + tt.Key(0, ui.KeyEnter) + _ = tt.Click("下一项") + if cur != 0 || moves != 0 { + t.Fatalf("moved without matches: current %d moves %d", cur, moves) + } +} + +func TestSearchInputFindNeedsCurrent(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("no panic without Current") + } + }() + q := "" + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + SearchInput(c, &q, SearchInputOptions{Find: true}) + }, 200, 100) +} + +func TestSearchInputSnapshot(t *testing.T) { + snapshot(t, "search_input", 460, 220, func(c *ui.Context) { + a, b, f, cur := "", "Marie", "rose", 1 + ui.Column(c).Padding(24).Gap(12).Width(400).Children(func() { + SearchInput(c, &a, SearchInputOptions{}) + SearchInput(c, &b, SearchInputOptions{}) + SearchInput(c, &f, SearchInputOptions{Find: true, Matches: 3, Current: &cur}) + }) + }) +} diff --git a/testdata/snapshots/darwin/button-comfortable-dark.png b/testdata/snapshots/darwin/button-comfortable-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6167924ba821c21f80d3cb5d2d9a9b33d650138a GIT binary patch literal 11237 zcmdsbRa6|`x@QxT;O-&80*y;>Cs=R^?(Xj1KyY_=_lDpQG`Kr7?(W(+4F7Xx?#q3f zwdS6+W@v0C?y7M(4o4d%I#~NLm5_v=tH} zf=X@~$Md6-IJTcVFH-j+BJKnZGrqo_lY{-fYly#x0&6c&^JH`+R3|d)5YBRBu&2ty zLvVjsdlcg(ID9=w#l5H)!jFby*}DRj7Z@KPQQ>*Xj6=8}AJ~a#>hXcSvQnD(r8{Eet&^jh|1tBhl;|EcbS0$Hzxy>-vSx z30T)nCuBQ1E}R{24i^0>$2YAYm0DEEL%lkaqZ(jNOZhd|hBdEyFUK9|WgCxukw)hD zk}A&l1LkM=jgnYun6RD>|-emK{GVYs@m83=lk zLbD{5C>B!L-2(6fe1oAK5Tm62{vy>G&0Z1Di1x=x4vDz3GM%E2(5DgjBV{FhZvwy?|F>3e@wHg?_D-|p-SBk876cg_f&U<8hFo%<^6 z3dfWqr_cTN86I%|7k;w72K(gSb_59DT2(nVAJdE%MWE`gdF=9Cx+s?-_9tN6J6CJbxn4(8BZ2Su&#$F?REzu8$ z!kxK$yv<|^O_0FqPf7a}d+LLogj@93v0!0iBF+84pKyTeO6Y0pDdudPC@>k(6GUCh zYyAZPh$_Neqt~h&o+6Wa_>@2(EvE^m3r7hHepwmogfl36fOX0^HYRpf6rNi7ir(Y+ zYEp~9zs)bQ7LeC!?D6#Cj9iabTs!BX(-VbN@7`OGkM*g~;}5FJkj7zaoaEH)F9ToM z*KW9uhWdK4FYC+W$wEVu=&oS!8vyA053*8-2U%ymd?{(Vo49TP{-_U7#nfJZW#&iZU&sQv4&wixISS=k`^~Pvl z$=u^KVQD4E5}Kg{i>nrIzb#HHFRal`gpCDasernhHlFK0{HFZHc7IP#e++aAu(Pk`S!q2fmM zqDWm?ZCSGhMi3*Zu=H1Qd1^;=Se8pqzb1vXP|cH^u&7+Wm7m<;b8(C>DNG0KJKT#8 zv+6yuO0gL-`V%Kbcl-0Hw3g<`+Mm?2V)Qpp=QY+6T)tV|U8ZiNN5Q9S6b0FoOOGDd zT9@e;XzI$Rop&4Wm)3T5p~@InJ&^afSNTqFsrZ8A%+*OSxST?q{(v{EsU%HQpDGYjxVU)|7b+L!W;s z_Js$$M=2>QtI)(cK0K5zREUe4j{ba~+n!rJEU?`BQ&~B1l!4o68=I#iBqWe~kx`x1 z^S3`rRcLlfip$+Tb*?K;6tTL0pNpHC z2Iq)ovvD*606@7LBa$L17~wz3uNUD2gWZ zXnZ4B@ZOJJnj#)y`Kg78m4YbQuE(c0#R~)g00sARt*^PwT!RuKMQIG^`nFu=3zPKj*G!u@9yj=wd>S~`i zZLVb_vtOEB>o`vpcD&X|VRsmCY~`Y$uy|L^FNO+|$(5JK=5o{XT%SP@6)lv@$NGr! z$?c&dSV>t~S_WAd_3ShA{OLyi{t)76!~x9O@iQi%b4s3rbp|O-;43v3U$pi ziKfl|O2>tLX?{R2Az4!l34Q&nI5$^CjjCfV$M-iI`CPLtkpJtKfECGz4}f_m?1P#* zCss8h1g7IEaABEB57;Xs6BQ6LHrN{fSqvAmXh?~9;!v)5ii*l$Ue2?6youX;`b?tw zd1eM8M~12d=&a-lFK%`R;%@VeNfMv!*9cJIi=x-Seh38T4jy4SAE?g+@aYcC;{ni_ zX6nJ(PP7;50&J0dS4kG7WiWs@oWtEejMY)VPKsN%vcai2p7ypl1o%cOnnr(Oy|Y-J zrmdFK0$VqXs!eoPw8I5$ndf!@01r!=SgKDfPulFD2nFhlB{X#vlT|U7-*hsAWdWrG z2a)^@QcIIjSVR=owys+B6L0PVlvQ_Tw%3|1FiPMJIh7IkCpIs~zxzRr{U;1lIaHsy zYtrIayi`pgy?>IG;u5?mr=3KtafCo*C)Q7%(P76&!PY&~W7ZR*kH@fjcPdYXF<(`t-r!W3 zn3yU;M{v67bOe2_a>aBY4RE0%SuZtwd%Rrg@=jmT+*|vilbai=cEU! ziN|%DPytOYJ9W{w181m#QN(B6M$G)L2Bub8%zh-4(LP(;%cc1Y@JK$`-i((&jgSGp zkRDxZ*69iPs^(OAtMP18@48JS+1E}{}wRrt5 zr49NezHNPWXV|l%cx#Kb84CFg)Jv;|`fh%*;W)wR`}hfegHvbVWMnGkTUWSX{$LGj zmXT?~EQbAEgu>XK>8t;in?1ej(e*uhP#*=`EKvirgV+1~`OBtTxZ&PsG#x&RiI}$t zXpI~pWl=uMp9aNMC*ji#(ETe&yDSCe-0qMjR*(+cnXr4(%!9yqxU;i@W7uGML3 zWNq*MqSi=TkAE^cHy5|v3?yTL8z_6#VK-v&$7eTHDzK4Ey5G~WD^HTRueCIL=FEqz z<=1;;geI|f>_lAT`@6T9kPv*_<~_L5lB-s&*qLYBi1Y=5M(i2(hJ#DZBR7CAE<<(6 zk6eXba2K~rXmfP<)h0DEn{iPP4KOxNM)#T;BP=YtD8;>HA|bViNESW}_eU!nWJX5j zDMz&Y%V(=LUTsk8ir8b5r~9AEJEQpaRREy#cdoFIoEH*6uNodjpJhUUhN6#%Xf<`( z{`K$HBN`Db0QckQ_Lb)5p!lVK2&H#>mUgptsKhwW%ZE2Z%OanDm93h?9UY~wwij_i z>c4o~;)-FX;P6oQ{q=dx%D9>p8QCdR4>ofZ8U9_AoL7`SJ|G7yb4SH&5|N!8RudQ9 z$Py+s9?tGYNSz0L*3T898MO3C|ugyPhO!zmZ&&!!6?oMocmBWtKNtF5yP;q z;Y*2JL6c<(x_TJw4GK<%Z{ViOd%+UyFmdT8Z`Fv*lA?kLfN!1|h(-5Dr+J3Z=YAM~ z`4@j>Lz)GAbi;@t>7#vEa_sGfhH#^?{pAt&tbAMBg-1F@S{fF5?%TF;hwr6IWi<*s z9jRp%1vVDsR_pfxUNTt^cJ!K3HDvnF#}$AmG<5=zV?d{oIhDEPq*CIbLzl-i8o8c$ zCm)8Lus*>fkv%o#Hk&HnxTUojnUs!5!47h=!8WjSFp}ZO)SUNVJ{izo&VrOC*-W#j zvGSuCAr%wDl*=TbdPz@FZV%UnkE8ZVspKvxHa0#s){*&od6`R*qvF*qqDoazjI*(_ zvb`v&34O!C(!mjlhNcV|B~;BXB1rdRrYx3}4!pd5zeN0xBVHz>@F9RN6gr0TDRPm) z`)9{68i4a^OCQM*%f@Z}TF{=2h;K(#adG;YS@clZ;of-d0A}D1 z9Z>>|{b`Phtqx9RnL0QoGgfsBdjnCOii4*GHG7`>jtPd74BAw?3fo-{)+^(orkpar zVao)|5;Ll*a*Fqi5{6a0D^z!@tYVrb?=~U3p^_ zU)jZhsHC}pu`bH{%bmJh8#hJ7@E_jaB)0kBJPj>YSe_{$6QDL0Pn6s?1SC)zKAL%J$8GS=Nt{{5tVSZC@LvcmskFZTi18W8)k_A9Ub;oUz>cfRN4XY zMk|w9?zNAR!bEPk&o8%>6xV6BOGMcOvtNht;a})S`ObUKtQ1JTp7ULI$D1yEvOBS! zHSN9i%FGeT@2=nr)Y?9by^ved7rI1A!>u@wnCIsQ8!@997950VddiPuFT<6-%TXiJCezAGx4{I;l*WoWW?>MY0UJ)%FwhL?p6_G#ZKK0BrYp%SJTr2Mpc2Q%_7Eplot$pP_4IRVwGn_9dG>HG+`+<2-5i za)mV`U$`VKu;%uvoF+&^&F7o5iUJIeSpx9_YQpU7Iw$|qist+((eSDFw?a*9h{~R7 z;@d|e1@o2JXW-nU35?8`x7I6FCYRP)F41yoa$h8mu2 zFbyp3WmXztateadRev@(JdyhXvT}?=$L~~PnSdNfqLcYjs`~gY=X1ufYE}hc#aT5* z%4ER zg6xNXIR7EC#E^1G_=n^6N#@U=u;(fD(Vb<@U&F>;R*ia}82)nV$F4xTk(Bo}xkzAW z5n&7!kUiR%ECg%<}Il!I@$Ygo z;r90yTfH8BSGD?0YeXN5Ns>gP$Z`wvv~oXx8i#<<>l#*?ADKGWRLNrDHI~|Wu>U}7 z*Xh#*u;4YafAqfvR0(oSp{{nYe#3ItzrXKB8JSmzi}Ss<=eU{BI{q^I;IbMdmc0l6=ft%dTYs{g*-Jk^$9U7 zN;t;T_W8(S&H9)Kk5id%enXB5dzqnB<%D=R0JSqZD>bv__=Ix7zL4otF}$>*(V{ zr+SS$KNdyGu@-WY&A{)qJ49P4fX1C^qnAUA8%|5pttxQY8W{Zc#R8VQHOAXSSYBAA3KaB8-UAh4dK2sx5<3-w_6F*-QxSKhq5ZOnyLKw;KR?51etpT#@Hxg$a;b968}fZ2 z>L`5NR0X%T%R*gR(Xgoen$#BGKt2vNWHk>X9$HWOjPZ%Tm9%4R+%L+!!Vbc!_mhCQ zW}wrq^(UFfoZ2K|Y-~pC9?z7zurh(@+Jf;!u!+K(B{kz%F2%*^4s%N!pGrz>9zus_IV+?Cl~F5mEy(^>6IIQ&Egu`ctfnPp+Ar*SJ%8>oY;i4bzR8 z(!>w*2f~ajOPTy^@gpv2P069=Hp=P1J~JhGbQKYbJcrou?{F6>$2P#fJq4uq-lN_3 zujs5DsVu}}ubfYIzObLy0dP2=PNCPVQXc?509Frx>e$ z0RQlf^Wk?A<3??G)kl0uri6H*Ni@mMU5ooThx7089Shql(BI|xC$*Lw{zxf9jeLpG zc~p@K-W7W!|A>6|0k+i?52h93(6fYeN|g4L0!&``9I6Hna=oT+Po>3vms@C29YPKG zM@zIQ>kxf~-7Bfo72$Z|>1_wkkjy=BrfFSaMgz%!<7if<^E~#-0yfBdg*GR6d|CLt zU`#SOU4|Fuz1`)rk1YRxK+_!=fN9>e-N_L|0PKHRdYo7FoRPR)-G$U%Q`^nXhh zDwQVupCz=|dST)?4!G&P2DJr<_lgm(8whtp!20U$3M++aFCxWN(F(rcV;i_y4`&71 ziY#+O0&cQ25%-F-*4^hoL4WvAvSGmW&AS%2{(W0yunH3}0%xeyTzLsuS(`dR7R zIEM$N*8|1pkwfa*aiiZUG9!l=_oG#7uh14-mU1}rZ>*X3=dhsKBx(|P1%i#^iz7Zy zL?en;I!h&V1>X6S2*NqdUWNt`Y?p#;pZWbTa3^EpZn=Ev$RvbdmYZ!o`eoe$Tu-bRzhFb&fx-=v1@V-5x% zPz1~j6u2}R?$^?m$Kn)0_u+fU+I`QmGZ60m17hwMzS}q|E|Qp5&o@669r!kv){By0 z0=E!e`KtED+MwN;l9{_x3qB?+>O$g<>6164SBe<1;Ae_;g;AOE^ zr~LZn4_-1^dAVg}-+VAMl5pHm?g1aX*rE9mQDg0fpov(2?WWRtaX|ugv-2CIK-GG^ssn?|<%=QA;xhsV%4W)QL`xRre{e(7xJM8(x%V$HgzA8NGL8_{xd4M$ zc{;Ly2`>#g3_`HA<8-Yu8)kD^Zeg4C^`bafYw^Uz#-tV|T24#bnBR#0TlW)LVyu#b zp^MkzqG5TWRQ@pS=3&`XASLwbK_F#_>MnOc2m)! znYD4&Pne&j3B__ZXUDvnU=yK%R5XEkjaV!8$43D#Rsr49NHpdA%}$tMG2&Oyj`#JR zz~jNoGuZV^wr1gYE$cq9zRmjlGE$B1Md$U_%;ORIcTQ$a*Q9nK95&gB`zG4w`pa(O zzn~o8mJB%CfJ_v>))2ckEG}wVpOhNW?BB?(5y??-7?dAzFur!uVDERMv zoFb&o@;!SI%x)jOW9n39i~ATk#lz0#VI6=T7eT4PbE_(4Is5TTdUyLbCbd7pXPg^l zsp9A`hVZ~F6X`4yXgJ}~_|aOog- zdat>O2@hZ6I*}WG&4=(ep&KHlp)=2L*gcHBNZ=;_m}Vvzt^sAP1o>$-Yh`72MCFOQN(Em_C=#5eA4hS242s-+mrGkIfp!O* z*B%hF3N5xr{B7_~705b!P8om4?mOt}tD=%&oR$IiX_l->pr{BpDV44z0 zF&;@>rPD5-gBB;UDB5o9#f|$Ne%6Zeb zrDZ(6tk-8t5#lDpKDsuq=wz}Bm(N}=!QCD&yv)Tma-_%v#9TS64vLIrc3{G|`7dl= zxY;hZiiP}E*zj6W{@;or>&*K*igx(*C`$oS6k5wLxqd|{+t(fzw$=0|M%#%T@k&#p z@i=tE*`r=1e{_&$!3txh4(%SaWnultj*4`JKC^k(Puj2{mjrTjDe{b&Y^Z(!$1r86 zM1>uzYRs&R&g11NIDnRLSJKq3fJj%=d`Zkc*1vAI%MId`cDRHD`sK3puWh;Oq-Un88ikG6JoEbq zmU4a7gt*;SUrQkMaBUBav0&Rau&#m%q;(Y4beNBPn?lBNbZx0oKM30tO98VVWG0Lb zejNMDr7z(igq4AKoPsI>dU~1>IqhdviliC#)Kq}Ume(55(`?VL$@7i))oAQ1Rd`iX zvJm5@&$7wgrNe^?<}(bzifS>&BT1{(e;m%&ZG;A-*1VnVHn(kM9HuS|JA6*pPhF!j z(c4!_YF2$no-|Zc)y+LFTZ`)JYo{6}wbUl2XjrW*%B+9#;{jm*Nu&(nIBQIb>uQ8r zV;bvfHdR*Y;YX07HeO(&jAnhYN;%mKD3S443tW*9EQJo>KN0? z($UudF4Z(9p-|{2lMAkd%EG&BBa$S1kDMV>$^=Wo8E9<2Sv~$I*v3ud6`*e9VM>b@>qYuQa=X z46S$i7KaAwRaI>;g?4H5Qqa(#3yR9-IGWaU-7f46p)A_fjPy!zd#~;fc_)f&fjbne zG9R9PwIo-z{OAwRxvgL7RS7R#9AdU|l`5Xh7D?FEVf%C4I|1t!l51dTnr0%9i{7XUk^#O z+rJ9P>hk{fp(GSA{RQtAl6(DUNBzD=xHiMJEB)omIc8i+ffA7VdFw@9uP>7V8zIat z<+oI3m52e;PTH^(cUGMXTRjDky79PlbmB;s*vEDbu|_ma!3S-owi#4l0A3czjl8Z>-s{|7UoY*L2Vv(8TnX~(u%ld#e=2rnm{rAr>_S&ZvOr$1#M};O$ zKEGQ{YHt?klPt=$)FMUyq?uH$Mcs;kXL&zlc%LPdY^WuLvrD8q#|3<|yvu(E$~D|- zOYsVeB7LGatIL`6i<R({Geyw z1(}>6YwNo5z2Md3MZ+J5?fZvZzw;qt@_Sq6wF&$GqO2vx>zwhi5;Q=ouL#Z!x|%`% zHyQ|-1Fpy!vJGp6eniX)$L>)(MD%XBW##$aAXiX_ZMyLn3ID6crbS-|^fNfYGn*Pz z5QXu|#TwF$r7X3`Rwe3yFX3~khDsoj&220Vn>rIsc&w)%zKGrWog%nJ4AqIGMgXyk z%pGN?O;9cJ9MRY3vwX!CgUA>w2g1P{ZT+J>j XyB_OP|5cs~cpDO;vLcm2dVc>4AxVu4 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/button-comfortable-light.png b/testdata/snapshots/darwin/button-comfortable-light.png new file mode 100644 index 0000000000000000000000000000000000000000..cf71679819667b130e0fc7b212bc81dc43f81297 GIT binary patch literal 10937 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 B-Q@rP literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/button-compact-dark.png b/testdata/snapshots/darwin/button-compact-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..73e1a88ed013849f898b767833825b09ccedbf32 GIT binary patch literal 11338 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 Gi2ngsi%cZ| literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/button-compact-light.png b/testdata/snapshots/darwin/button-compact-light.png new file mode 100644 index 0000000000000000000000000000000000000000..6eab1a07a8e246dc03c3e1f5d3610e074cf6eaad GIT binary patch literal 11075 zcmeHtRa9NUw&eyAAh=ry5L|-02M-clf(LiE;0Fk9K@;4AOK>~5yGyWxyUW4pbKkq~ z-P=F?+1+Dw*Q!xtf7GtAS1qYobM0_tMHzGy5)=Rc&}BbKssaE!2=<(f3=bP|)8%Xc zfC)ubQcV3@`q9#`5|ajL$9c*auzGVdrCa_(ZqFA)t*nCWYL@%fhlV98HW-zV*8UMG zis@&g(_sh^;paSAT*4&uMi&V=G~_Vsi0^Vam}!dgR`gS3(-8JPKr!;Cxp~{#zVVLC zmk}#Ya&z%(XFuKdl$5!Lqck1>5eV-8<=&_da%*y#)ik~g|MbYFYneW`J#x|HdaUXH z^94gE5o z4ySw(d~qGxZFjm&PTkwI7b5yf7XyoQPct;!Mpwv*ymn{39Uh?%zZMr1EA2DYOT>|- zkony|TGxTuEH?$-;0Q?!BAh`!jHaxW*W!s|S+!bK@R zCs3%xYqK38b@a-Ldf~HG)fX;vi*_zF35*XZabpDT zH(M$;gZ7EM%u$Pei&kCl9zb@0qQwsV&>R47bp?874WbI0a*1NPrE-lbMXP+7# z-t$8+7KlAMPJP*3^5&Uh6T9`^->=i{*BNd>D&e6>5(!49R1KGd`usLv(M3VbD*Bk` z*zwgBgWyA%Q)CoM#)#ZNl+^5^KREJSw3C)I&=+fCSp}~8dFq>0TzQ;mu#8G4PP9HA zRzVo@r(K9w`^rm=M*|%NNt9Rp-LnswyM=lGN>j_z$m4HtvWz)rz3KS{v#uYf?rJ7Z zxanX#d7eNm)#khWh>M6|)MWR4obKJr!75%^LjP6ohcj(YD;fYqwZVH#fd8=Fk4KUe z0<29<>-c>({~|xjEBF`dz&OU%8uNd7dua#`c(Q7@B_7#l`IacS$=1=*PT{q zUQ0&c-1b|n9A#@!?3A0eA_E5gsV-^EH)M$)GvUAr2F~o)Q_J|Y(aC6~tgqmng-z;` zX7BpPe;8f&VqV#?n_KQA3(snMnl9K-gLNcwRG68+qMP>(Ko-(Mbrz@O313cd$r5q1Ee$5JbX;ri?k<_UW|aS~qskHfL3g1(kK zsRQ4-SnOA_JU4tsyE!-@$CD22$G6w>?_73Aqr&&|mFaoQUOZ=toCX>En_F7qWV4^e z7$WOUN%^PkdywEJvAG29A#(RgTHdkWRCP`Vs8b{Ct# z{^B3{_2VCVJ!p^HcVG3d^tM~rb`D-v5`wS+$E6J`04Pq48KXNb zUnY@O%f-{FyG{~BM(+--KQ$;04INyjx%VkO`79Ofr;^+?KG|HdtX!d?5x|y$TkmQ+3WK#9 zV&3AsC|PJTRa}E^Sq#xup0*$3NAxb{NONZ1@*==L;^HC!!1A)5zYbfa)@i1?yziVT z2eU!z#>l>lbRN4v^X8R9Vbzxp-nWLkECZ(1XJ=KX7QTn;>xy_^SD)~Q=k?k%8F3<; z-H#u)f4<}>(-X29Wb&Jw^vL4!*xwekw&vO`g^~NEGhtzkF4xvZX_U^bG^gww?h4v2 zgl@fqE7xpsT(7RNcvdat&dC|wc{=rWaOi?tplUk>1^6Z?WsHrDWw05IOyEdVGCa5ZS%2F20QZq}?-*yR#pba!K1#20ZZv+U z+`^e(pDu=C1GqIADVrc;A7kml6}5#2NYk6Y;A{z6_PTP2o}Fpl{8_XSS^V>3%;+ip zR^u?>bo<#2EX0&`$auiBt#-Ql04c@c>cn{mZHWc-7e?^DT8>RW%( z(kDnf1$jvL(M4c6Yz1zcdc<5_|H z%kMctn1ldGrBq3~mF7j2B*thJJ7=ZPSJO)nDqFC{mb5ki0EznY<9|K#H;-7;u419S zthA?R48X?$nWrc3UZ*Fa0^-G#rJH2ERxtz9gnSLlNEHb^9bT=Unt0TPpVq2`tCXN& zvUvb--2TvBH7+7_GuhL(by*#(OfSS6u9!1bJfn%Yv@c&UxhxTcXO6dCc2;sXPR_c6Eo#394jJAt{d9fE4S#yiHDNWos3<-uG13RjC;r@h)iSq=Qc?N^ zvagx!o7I;c`P3?RvXvT5dz$<{mE?7I_-Bh61w<1!qd#(TAM|DN&##To)164Q618AC z&8@Drx#)W<;R4bl;tkw9XZ3ny)tz2WtV~M|xsbwmv+v`F$lVWD=O0th7$Z=8g(#7r zs)<_L=`9CKJhoRc+v4QVx85;%3SQ&;hRChUM2bhTbK?oG?w1A9_2RU!Rs~O zT{#$h23Gs@)m)8oz_+RJBUhH0cEh<-q`=TEnpPwGFyJd`sG}Wly z3S0X;2L;L|JYO0>8x8$do4+R-sst^p)nU}}ANF+>BL_l3bwm&va z-N1m|?yr{0G1czaT|g^U6>OrfH)a$OyX!{&o8Dd;+!w)K9JGiCG8V&n0qXq4hBd|G z1$IW*C*Qj*l^%?n$O?&!pI^}!OlaQ$KzorR2k3SeA6vX2Z+lTPtD>YtnmH+f{iBLb zfm#u@SesqQ4K<@d(5eIHR$NvB2B1wz$&TPcD?Lc9@g4^JO0uXuNsAj?1#RYJ5)%KA)(i zp$&rN%!~fdRu2gh-mV8{i=c=jqz77NwlC?;$&9_x6}X`ucc(H^#U6^Ri}#7DUavzo ztq%PVfUxdBIG{5KhqC=SP&{vk{PQ}}ornI7aC4K@Fq-UDAQUJ%D{n^}Q|ktQuO_%?tU z!dw4ZA!qW}7^y(o?1u`8!{^f!w7!if+n*H1t+V05Z_AnghKUIeY<=I>S6E^9BLG0V zEa%q5)n;2DNO|)C-0Ft_O~=oHFLHKVlVP*ej%1u zc>0W#2Nm*(XF4nq6hFk5Inc{k_k`u#K`%W{SKD27$-*Vme_)AjY#ND(tXkLI$BN#J zycpeNi#>%mw@M0GZOklkbKn&mued;#PJc&}-eCjT`YrWLTIEcPUf-?{u7`$7-uc_s z-B+mK>DQQd*IF6s_|CiRjO{J3qX3SgtfKsPBZXPMJ_qU%dMs--P!F5KMN=M!#Yd(% zJdg-EH5%y*E8CAfxPrXBkrWp<0pSGM+A~D-15t|;G#gY_Ha5u2;Pmm5OzP+kXWI52`TO1x7p*u>t)q-3(E+dVd z01(2tyO3UYP(qS8+FEz29!qSZ>+=!q#t8=%L&>n>NoR0FaK3#Z05j9=AUBSbZ)fdK zQi3EhfE;Co3qxA~P*M8rMGLj$BI3Kq39-zWd)B?xVb3=Jq-46l8g3}u7>`Z5R6+R= zV8i+H<5p1;{kH~Zx!&xps&mwgS&~0PJ1vFMd=$ zt2dirG?MSS?tQS9;+dSfNSrtn&H8>SSd6AxM_i^_UxxB!mDNfzQ%J! zBROMtj!SuOo8`)xmpH1VBsDdjqo&hxW}oo_MO}mY*W!p{yjN%_TL!=6C{PfFQ#V6S;?`4Sq@d2q^%XSd!Q~R#ZpD>VQ<47T{~#NfC@kba4-4DPX`o(jqi! z>xDX0zN;!vwCTI?;a(HDeO_Hde+WcT;~cDrlneNo=H~HA+lgPrLek2suAZ8+K}vkS z@g>I8DPsXXvuO^#^+pI?XJsXUFco^#1*sBm_Q+LcunJ8WRFA<87Eckj=<}yj{3Ofo zBCvf_*?z+3b#=SyD<~&F>`1C4E8=oY;?&I;>2Pqe@_{5eWb@n4vB~=L_0hojGHpa) zq4^rx(E)gmI~DF>3@4X2|Fk*WMnSDPw#HiJuw7dX0zgM)>9840zHmT>phq=Aqt!Gd zaf|cehODe4o&XQenCSQX5?NqMUyTu=8@nT?~Q=jwYWE25z-6tUxoffnS9n<&!cFDqSEiJ`G&g4vXTW=#~ zu!WqX5V9z_{AS(Z6=bMhV#t{xW?dlIdSYl_6KIK}stQY^YxYjW7ZC1n@@~=IJM47B z{b{j{)L)MpW8?3&U(YP@`&D19)nDczzvDv_Jd)@>b7DL>lC<9I%Q=lT?pSs` zBGtkO3KVpBzE$V+^230^-9OagGvS~6aOZyc7}PtWCH&Nwa~E4O<4J)XyCS`>?Tm6R zIZso8ItgAp{TkYOmZ!GS~e;K@<+Q;CKJrvC2)btVeaL%Ayfp)^mugd$;Cj` z)dA7$wObg90yIt^3-adrDs-%uq@`$*n)qseP=E|cK*QB1Ys>zDU!&Avi8HmjIyDOJ z%Sz4{^a{(DTV(|31Z~!-9-Lzi$E@vy*w*|=~8YMb54*w_NYL(N< zIV~Ov4lWWkEk>j3`OrXI79CyIIh5|vit^9EVv42Ko8T^$JW=d7!ATlDr&zutcX{*s z#8EN{P~zn9M*(N`*AaiGri ziF?k-P8KS4U6_?RSeRxCB~6Jis#1D#=Oya}KEbwahp>gqcZ+|9LA_+i`sdfR{&t$! zd1w~PLo3F2QcLR@Z1m6dKl-a$N40(Ix6VXt;VJ_n4S%15mq#QC^@}Iw5dgLe=xYG9 zQG4_*uifIj>Dqo(glM#gN`TO&^73O|9<4C;g1KcN^#JrF9MvNxqrLk2>kQqKF)bR6 z8khiw2Q`06#mbxozu-MyPmyY=yj_d@_B#QFan=%FxFp$r1#@rsC9xHycJ@2Ik9;A6 za>H<*Hh7Fl>pgQrNt%d+7N){a@{uOLe zel?Bf#xygltBDL_hVX~KLM%5ZROkI=1V%WdrM&qwhsXF@?7;B#^<(ZVze`vNY9#BE zSGMBBB?CQeytIt}+e`fu!+Co3gRPn+IJOyCv4iLBv>_C$rOr2Pc3oo*%hzRr5!YIetjzcCKgW`b7Ef9(*lzqx&h$%@E8wyt(bHaZ?B#E?QdXT}@V-xLuuYuZ zzmkb1&Ej)vy-u!wX}dgI7afc|7+6{=bvsO^Q~XVxB_QlH^@?L*()rCzL2hk3@9}>7 zH%4N_=heng%NiXXN~shys{p&AFjRisY9-d&oI86i!B1U&N0LSm}HG_JN!teT>29u~LNmrzOA9Snm z{Gv+NLO1-Ei}0JbB|al*w`5y%S~5D^<2}M{u)L=DZEl|Qm5V!eFf_s~8TndiApxiV ztd^=UPlg5_FbIDk1}5@lJO0+CrKhJG3wWrO&K}M`*>a=^NO>fF>N);fmmzHPyzHs& z;nDEAUzkECx9_Pch!{G|JEa+8)+YN)hsXyk$2t z+eRg1i995*xqi!ARH1K@%&Kel+3?GkTJvkfC7T$rUFQr|!#09>=K99QZ=rrHRNbV^0%_OJ4JI+;+TK26%{yR$X`-v6#NpzWc!B88c=y<(@vrW- zGQr926pN)AHB3twi`rdoglZ~(kEty9#WOql!HU0?@MU_SG04Joke|?EJPWP!S-a5c zc-Cm)>b_1~w=X`s?o{`B3sq?$Q(X^k-A+P++ZWfzGE4qbn7$XgW7roye|bc~rf-K# ztGUD>Ubp$?a`E3l&`D&TL%fASY3xVYu2Y1$OS5 z+urA0sWJi(v8lzKEI*KM0~_Fi>!BBae?(~OCH zA>jzEDzp-nlN@{>+CobgP3M?qX~6-VMsHeIMiCP_O2^WrVX2~HI*G67+m^jgbCdwM zEI;scePgYHCT3kJjrcX(BO)9TX9_#6CS6#%qGC@x)5F&-278`OzGwPn+dhSQXfgMM zEyr$pODc@x`26wd{iw5YZcj7>8TuU@tTEcqW(En z80Qq?IbW|23OYL_k%m+2hG~^DpR?X1xC(#^3;X}p4fh)7lC&6aZxpNjR!Zg5D4o5# zyDKwn4;(bTz5Q0HUE}kNiHd|l+GqSHH&2j7M<~lNea;Pkas2V=iGcaps8dNE35|#m z>#RTKU7hQ`+^hFf{dn!lz zLR|MlKDh$JXe)GothY`Mso3pyFV2Qgyj?0Gc1+LB@c<`bwZrA-l_A%5l0w2Un>8?G z{tR{+9|hBu`?|f8M&DzzrXV(acqU)*S$m!El3sT|F)u$VohM(l1}ZRg>4676j%#nm zjO(|Xotc6tDn37XjghQ5GVseaZWFHDzlgji<>bDIm|5y2tlT}SzcW$QviY7@pKaGKv1Z7XcQgc`rD~AYQ&OW*S9B&YP`m*bABD!-|M8uTz-ybqjPGW zooN`Bd(o?)Xo$yu`&vQKA7fHm0Yz?_K^?tkR<)<&*6)&zJOzC5cP!6zLDc4;PJe41 zx6XX>k-;VThs6s;-sG<=L&#RopV)}%w9c;+mRzx{%4S?7bvo~U>iTb$s}>vAXsa{U zDefg`=3H`J!MN5xsy9mNl96$<8i-@+G&P5Jc-QM zxILoQD9G3wPwX+C;Hry1{=x5dmmy2r{3QSKu5?68*V_cb8{peCbF|8ncBqF6aV3T_5o)xrGt>~-hwYPi5lzXmyzR7G;hW8oR_Hsg5K8g zCdx!YHm*p6WjPxybJ3D6-7Z9#Bu*nH2hU$ViJo!ZiQYpYG2OA#duomdJ&*G@%EJ z$;A&15I`VJ7O_>XT2(*tIl#eZpl z)!{%05*7~vcctRI=x|-f+U`#`^RIQ!@^mJO8#!eVlVYUQ|8XXOadWm8M{&ROEMk5r zWj@tdqBSRc`It972-0E*lG@TXNlHtb7pfgC(|(~sAes0bt;>?${wY&8QiLsx%R{y?0JeSf*Ss7hWO#9Jax%4HoU1t-QU9~T z)Zw)$5gx3~9Mb$Uvn?#CIR>q@EeH#Mj!g`;*g34;eaUh%2I7KDa zY-lbxZ-m4HFDeV*BGV;(f;213605)I{i&og=U^Br9e8<_tq|gk{D(Rp#zA!&MfwN< zG4psowFP})9KNQ;bczCuVesr_QdXJlPGXw-yE4Y>fD_Ae-mYf*H0^rtPZtBdxuHzp z&5k5w)zZ{NCz%nY+g#CxEcgCLnC}n+* z%kpu(8aU6-R}&E#pD@GtSF|A_5CLE9dO6aOfu*nA#*}!H8lP*`%#b&z2}o*n02rB} zqpeY%JQQYLJ4t=!3cL5^#hlfpM*rSe(l*ZvkH{4%7jLSF{|mS$hZS)hbVu1{s0J%z zRi0s0ls5iu9MS%eugpN>;mpkuT<4!U>Osrub?JK65jQZv!@?533if(jd-+^Z5+Bh^ z*`()pG@gIjo+aYbqYQlfHcSv6Bmz%xywFza`!LWe?xD_}68PVl(+>$y z$WeI%EgqCa1cIb(IEd~}SZqasBv`N+(ieu&`}+xfK`5y8`86SBxcF4&8nE+Sr2GO0166Rf9-^myel? zf7_TeS!fZS#bD&`OmQMMRfw6zc4Kq1a`6n6OpNdSepp!cPktmI&l1uOW@$S0{flu~1aK zbzhTu2Wfp%loKeJJ>aolZgtu;mk0Q&Ud{@$VkQp5L(SO8lJGMWXY?IOd5O@jbR^nR zM&^y5@n5n1Q>v(dksX&iG8XfM#q3#?ft?R9(q3CZTUN?Vg&||~3Io%P0JRo{CSz1x z{S(uPFaUgl_xaK)Q?5b#lPD$Fgh)Jxtw|9vx`Idhnh`y1SMRcF=AhEtaX~#XBxMw_ zE_u|&-0_PSx0q{v#~har?lB~Qik%jlT!P#9?ar(Cy0Mc!kT3J~E z09f@VDJe;E8$m2EC@sIh><2NH)qupmVzvRh!<9e{vaOh-`fE&4fes^Py};vicGWO! zz2^oQeTq^2q8ddY66Tsg(iS{KPNWu>>7MpDiGz@4IauK!N1<8f6K<0F4)sPJT61md z_o(*@Fjxz9JV!>4|EZ~LsoqwYCTl_8np9j-vEJ0u$ZcnQ7yD}ry?p1qM7_oCK9-S% zrOE61J}~$NH&QAYI9v6063>BjbW*MPa5lkcmCKg~P`9}tzZ1cSFV;}>tE0Q;SWy-X zOw7XthJ%g(ss>ID1O$YE4>{SeW>7)zHbzQ8T3C}pNsbv%_!hr_fvEr%Ms9LRc0ct4 zyBei`7csDyI4;9;EGfElEto0=gr@=3FZ@syAP&zPk;;Y(3jnf;?d zJFD(X2H$f#ZhwNsOLm@2%;f$RbTyI+0Z5WNUc7vw3VrEu@|is-fE7ec`kyTps+4r= zZP#~qZOqQ-vSNrtjQ0*^--_%deB1OofYnKCnvQe+asK`t=9W}R(PG_O+u!ID-dab+ zU8m;J zV1|%Qz9czs1be)Hu5haluyv5LGfpkAKFSvZ9M7uY@c-la0(h{r|x z8eK-LTVTET z89&bncQqPCf!_T3|NZ~W4s61=f%^U4p~B1oAYV2p=DHA3eTAp}{~aRJfesYn%w{@r SLpJ}hJF-%Wk`>}#1OEqM)OB3| literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/button-dark.png b/testdata/snapshots/darwin/button-dark.png index 26539164df773103d20ce043f54387410cef7a7c..df1f5e4c49c85428038885829cfe0315ecb2f396 100644 GIT binary patch delta 2991 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 kdc!I)bV18#r| zGMLfLc#{+mvGf~Pg9f`w6PEjGWkyc z{P84^g=7rC1&`80eH^%es1}wfeqJsM&3$JV8(6;nHkY5Uo>mjCGOF@|?t2{ZnZ(Xx zAVDODCTI^C#3q5BvVJ`>5-5tO=L1QAxZHN87;5CrDp6(shQT3j5b$j&OKjMVJuay; z!k}~iww)#BrY)6dme)nn`Fz;7?O#v+8rw5XB~Zj|8m3HIB=NM)bXy+7%mZGNGYq`L z+9UaGI8=?Jju&rRgG5cVS{6U#UCF{$>Y;{=I)>(XuwyaS)Feup#x^@5&vhFt4$bTG z)?O25Y{<%kRLql@u}`2}9PG77KvYIcFPK+OPE&g-UtCsYGb{!o~zN0an~M z)k5oEBX*?1?I7e1jY~38vLAGxrD_-eY~AdZ>y0G?p)<2b2Io3$YeXU?BUZ1)ZdLma z;6`hj7Q%`g@iIzbo-PbLAs)SOhXR54iOn=mob_QLqh(XdH2DN}15i?`?B1JHQY)w!Mk7*O zQO^%G3&F=A#Be7pj#Qz$Z?47NjP zaLKt*M+e$r%xT66nC*nmn62f$kt;AjO)YsP@A9ynRN=@YRC31Dv25km?m9bnYMC@n`p4M48kUzQ}hw%l%1Hf;x78QT{^PuOY9MtN`%V!ez z$o`|C(PXK33Wt+A5MHpdJT_uJX&Z7VW1jm)xgDiaCneVdJ; zFX>t;ahI<70fy1;<@|EnTkY%tw8cTMa=xzN_Hf}k=1bupPRBF7-gds#qy$+y!NKiD z2eAuKSOmc?T0Zh)Aefl_EPN}mXBY!(UZ_wM3yFxQ9PY6H1uxwanKh5+L4Lj zI<9^L6^kfM%2jZ!T@@H*4_#fOl-e()rJwJr1A-^vVUWtoI=^xPoi}~{*83ost$lO< z+wm%f;(f!O=(Qy(U{?8QYDOAu{%#^j+Tu+cesVG8ymFW)eSqAnFUNYyLqO1KZe`@1 zn9h^>L=XckC*hSFQ_z`0Lk8(S^96Q zAijs6s`?-TfORG+JZx%y>gU|zmXGugW8xKxh5*}pxs^AeFFhX>x_3|-e7vwa+o0s< z2WO`29_TtW9gGdFY2xvWbl2Z7u;I$W8ux_19hT0zo-DIwci_klOt=f2#TH zMbN*E=s$ZKKU$IB-8Hjv$IWMU*8JXg_-z?e8+FBY(V}`f9AD}HNRGKkp6Aq5<_Hu2 zyYVl>x~^({4=T?7V#k)i%9|?r5Dqu_dKsXaJRQG=}AqBGe|A6f_?u}9o5MCkWiOf`v QJ7}k!fm)e9GjWUg7qD^=Bme*a diff --git a/testdata/snapshots/darwin/button-light.png b/testdata/snapshots/darwin/button-light.png index b85d2e5dfb032decc3efaea3a1739c793db53815..c977763d9d0458e5987fe8636f107b9e5742c5cc 100644 GIT binary patch delta 2797 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 delta 1830 zcmb7EdsNbA82(9`<|SKbm^XA;MrfIrLup%SWrf4SC63NQrEsDwguJ9CKee(lH7B)A z6t`vOoHx`8BN3dDc|lARC1-ePWr~@ZhN3X*l-t?a&d%QFyzlwW_r2dA@AG`$Gj+HP zlf4eIfmyZQ#1@p(`($hNU!F;_-xXz!*nfr8eGMs}e$AVB7&Nkb+I-HIKlWLZzw(}6 z-F~yUY~5Xud$F!xX5HFz40*A9+mP0a2drE{TaFUUP9;Cv4e|ZI0N-8EkRTeO*uqny zpu9LSFy<_XQB%cplfk`Ct6i4xvge?%ym-sAii0&2Xd>+py2dGAwYVWS1C|Q`3t(9Y za2g5h(`4A3IPtX#^F_ZdV4SSuvUtcfbmXdFqUZ5n`A8lVIbHDAk!+IW{Q3w8*~=kUX|+b=rU{e$T`e!HzUMq-=cf%?WG)k z;2lNCS3hjQ_l$~{;e+J5Jo}%lRxg!Kl-%Sw%2-{CxB&55hh4?%Z%~!_84R8xwC2%V z9FGeL0&MQp085cZ7z!N=n7Tn6Im30N47sh}1Xg1aJifQPk=%N5n)jnR0vpciLKWM| zwA3Fhd3fibnYir*aQ1Cx{A&#;>2wIC?)mA^Mzc}>Zn$w2%OPb9>JwJjeBG@#exB3C zaU8cT>SA=|-%MosAFOG6#kavrJGbR}77m_YBmUX$;?;$;uv}}&zM7DiFOGxlo*!LI zC&E#IZZOF+f?_S#Qz?}dv3zOV3YM?y<@v$z=tl&9C_mhMoJDlnY<%A~(My(GwLHTk zq)g|SiAAI^F49DWE}|)8)zHl1mU zKtwN;xZ&u$r0544ldUa!Aod%+CVN=b!e=9mnsa`kz&|;JX@qZcZ*578r4=*kNAjfn z6sCyW@R%56r?YMeiaWZeNo4_L#F44zp6xBHmdX4HC;I63!x?CVA;jlGPh4G!n@!et zbVm`Jb$t_UTQK`}z1lt#>YX#AVdPf^_P?0*sm6oOM%SX|luaE|+Y9=V=vOKOeao}( zh)D=IGv7^7R>+E{Q=2zK-Ya9AJmD^!f0bLN{I!$nZj`feGllwG5BYs9L4miosU_6o z%2B4e2h7Y#)4$1H8M@}3BG;)*$=3Q6#jtYZWy0rZv`OMZ?X8XJ)%T22^QBS;@aS_t zgURzNm&C6_0Hrs)4OYk_UOvQ`QN%KMYpl4D$mNTU4 zdW$k$f!`Mj=mkPB@{^p=5hwuQVEO$Rp zX!iu451Q}6c6LqTCELlZyho?#6kK}BSTk>QCXL@Sfg5XJ#T4MW=ZBh|SR`vnY5Y3Y zIT(qpcI$WDS3KVRrW@@KbJ*%94YwTmw&cmp*=Tznp{)i9y#1MP-|~Q$KBufi)c-YM zAW(WJ(^?#^7Ddt<{6rn&!;QjeM|J^NMz)sht#QdDqDxNX;`p0N(2UtHWKH%Z)k&{~ z@T^R_cfga-HyQkDi_gD0%;74B8xP!Vy5tjDTyXZ`c`djz##c6jTNpg^yMD>jn7i>n z$OmVLgM^?-N1Z2}zdcrH_j+zO7iG*BRpuBREy8(P-7Um5{X*@|(+96~mblUUCDraW zb)O& zl(F(lfmW&xXsl39gpr?4+teK4S+KDi%?!`YrHbw>pp>e(Zcw`bk5vUmOzx%S5LSOP ztc$JnY)*&ivBG+S>u)m7a83^(F_nz$T9xk{6vjxH9}d)p#R>Z69LohgEI<6O>ytVhAPB#2J)d1nwfLuLbf19<8r@Ne#| zxdC-)I=WMUy)}pmje&kpPO(7K~c;R>J@Q diff --git a/testdata/snapshots/darwin/button_group-dark.png b/testdata/snapshots/darwin/button_group-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..e8eb37015d8b592a5841b73ec71b5fd3a384d5a8 GIT binary patch literal 5061 zcmdT|XHb*dx(>>ws5EIxRX_zq5D*XoD4hTT(u*W?kX}O*5HW2%PR5-1;J`%X)Aya1ZzJAFg$#4--Yd1 zvQnuGk?l4EFucs6QuYe55_-q9uS~H9jex!#s-!~o(F;~%cTwIb>45t(%6=|anB0vS zNT-|g0Ouv53bR{{Rnr~NAp5z!_$M7OapYJGy{GlB2#RQeN=jRca^kP~k0 zy_ND}UuEI?mSl)F#g{?45WnhC_-kf5RJnDj=Tig+!pettSq;)E}Us?HZnY7YmlfkWxHP` z$+V-AAe)B+Qn13eRT9qx$)@OW&9*2=iozSLPDcG zY3KMMuecc4juZ5<54scbF*gD2>MJm9O?ql}1LetqF-$!J~j zN&f7{{hwmW$v1J6X%S)783njIFZ<3V5gYh$)3Y#Uj%Vr-zY?EHd2zF&yxjfc_jL9j zLik{bFXq1H8IHo4anA1!C7z}3@4Lpu$!}J337n?PEOmaBo1V{iUY5G%>ls=8>eji^ z-dc6VD;ncYX~vA=C!vg55-9hJD0f#KK{BK+vk)5G`C_5z+4ixR3QuNVs6H5bS#p1s zMh+y`(pWMF%gp5+Xlb!l(Q$G49PRFXiRBNb5SGNOV%rB1 zqTp$hqU#^x2L^MfozNC6MBJ>lIJ+fMT~Nb9k|&(Twz&x%x!=RC02KFvvXl@^@494e za_QI0#7(!o8bE1Id~jJBh8&_$wjyU1aN+A}5i0ZGD2R*84}1(e2GZn1?5P;?eZP>M z#viY;O#6@voFqAc!LW?2w_OCOJ2+2Ol@3hZ?j-}}82)+IkSNI2;ji@cmzXn#9)$1l zoJ+EKXD1{q{B4>NW?&vnz4v1B-lO=#5@D0Hrlr{Ux9Bg$#bo(Nwl?Rh<9Fj;CycWu&BX+kbmym7bu{|OVN?;JGO<8PeYDi-1pq#@h z#(ApP`TGl#FM`jrJj}>IeN>(4_{=eJ2a)~m^$A#b-)-#s0DFkNRG6pgmnU2g!yGud z?|OLHTUw@ZI0Ja|$A2tZ(qpVE`+Js&eLZEiyZ_6it=UBNsUWv0`O>> z!<$QE{)dfQq&oMN+l`t%U(Vt)sH~@^gjDmKgZia%yBZrc+3|vc9r-gFXY`3go0Bi* zAH9FiePZ#I#aXYc;rfn3mJ<2buT5TiINuL+vrN|)j-LRY?%4Y&92Hx{(T{Pyjp zD-=#`Ufv;=^MQe8ulj`4@BM_UL{P>KNw2Q}1qF)_4r2TJqv%=vF0>TW)7~y!u$ccO zi$un>VwCUi?&ZStkkQq!lv{l7jT(1{Bj|om!TCH0{*}y>?SPhTa#Z@<`FXS`l`|wnAkg3c zf@Jxpu|B$cs3GFSRmC;L7eg#U;1$H7T#o?4Cn^89XnkS?8L~*BgoK9LNLxqki`6(x zOcFDTZ6y||XYHULa@%oXv#$*$Dh0iO(@&#ywQk(-^YNgZR!>sk>$024ujJ_Hw}@%b zmd>SZbai)^&wVZa7~CRY{2EqMlWT#@>)s1MuFmNbu6h-Gd8!0I_u!Rp**22N(lo#& za>Sjkr$MQNPN~9%hPCDw{S_6Rq>nI0E%$kzt7klAW#6W!6OQlQ=xsQb`Ko;^?LZO& z)b{Rc_D*~*1dN;8_tfl z2&h$B_nO!;5&i^$h9;WpxM4R%lZqT$!Q2`v=S8h%zT#3TOG~9z(x9x!nIJ2ppZ-a` zQ{|Pr+cULrM->b%D`%WYOwjnP`aL#9V0^r2lDU0U?tA_{zvhw=-n50+8>6E!$87<0 z<@f%$IDkqaq((ND*<0Q5+s3;uhQ3!S&$qWLIQ%rTILuA=G}jkmhFRa|^9y>t8MQLQ zx2mfj&>;Dk@$c(tqO&s!ScvR$jK}Qh8FZR4aw41tp9K3|9O(Zt^s&n5`t>EGMe1i~ zv7u3UE%O@gBr9p!&Ey9WQ4g$sUK;h^Ui@CRJ}S_hcJSE$F-gnQi_#-|Eosk)GA&zX zBKbDPf2ljHu5%8(yjHbMUpbn)ZdlUrr%VQ9aCEfRJ=nzj+GJWMhz>isUK7p+ zzjehleFhu4Ob!c~@!TC%>gJ%3b2AIM1)33psxz&fp-RnlDZ41s_%ev4v1#YVY$OIu z>wh*mx$zCc!F~^TTt7DUrOCw@s;Xe7p-g7AW!V+B0znUqb8b2u$D-R4ZU@u;(^&IM_Q0}#WCyvpB z6=4O|7%hFHuBE^+J_!~vazA{!kliY2;i6MHMeW78(LmSD>XnL4I>?7zMG0F=w8gu= zwsPD#)|%FWEtYzwrk_uq6vI|+kK9xTPp)~$%}wnYri++4Up=!v_vMMah85D{0@zS3 zc5V^B?Nj3bxg??r9mV5A`R=Yo9&K|V|m zAxk%bLubUX%6@l1Mups~`;!{L$`bhICZY8tC?z9Kb3Z=rvAk~Z8Lxsd1M=9$n-b0H z-X6bGaQ&F6yaSjVflLGMK`XHll7qNSKowKo# zkr4VVWhbP*xJWNwmfSk|I8{Okfp9XTa%7uJKMVM{au&qQAU~d{d@sIQD-&YAc3f_G z&sgPA^(PJn2Kk?E?w_b5tBR2<#}aOGEHqKZ%?xwy3Nfz?lfrGFDH9qGrmMQC9vrN^ zHl=6vGD9onCDkKVco5o&=U@v~PGV{XDFj5wPjf9qB9}J4_krvm2U_c#E>{UtCZ*~k zN#~k7qUP53oF=!T+PY7PMmDX-Jl!qCS{jutJ5~HCOmSugj(lc^{;#1}TR>E}qxT0( zIQZ7(>}VzO{q_SU-A5BC8EJ=M*H`MaIO->RZ-Lh4mkTZKO34&p6}|ZTo=jw;zH)3W z?TW82+5kzx?vavrh?YxaY;22>@K8vNjr5g=$gqcw!cI4_c;G<)@gr4H4C4qej{-0(9-9!^{>q@O=_bp6Gr*nx!EX! zDX-VjDp?VVK3=w_rlz)fUja(pi2Mb1ajm-Zu17P5>uJkxMx1y?cu`*25~^{2&mEi^ zqnCE4r%@}qo|mxMq)y6l|FACEbaRmQENaOV)Qx(kQ1%ARaP}cV)+{f`g?r&yC+rIl%Su9Q1pmw8|4>3bN z-%@)_kK$`9AYA}ytM#KnbbaWhBZ!Otx2!ZiLM*w~rVZhtm6_j4f>@7mt-40cwxfes z?K|R5Rw)1r5&wN?C&eAAfU{Hhm-)wGTB(XLTg#(X{CI}#Nk2BZdgG8=jIa|wrk;x} zO!aDwAs@six)C4W;tam6tE>BjG2BuGuMIRzF@f=zXn8XmSn52!=59je{j4L*7;di7^lPl{0tvhrXU|#rZ5&|IW04y zHG-tGM{PF5-Almtr~&y0?2gK;_#~xD<}x3@c6g3!@cHg4^P}2xB2+GlZ1~i)nF}Lr z94R6j+J78zpo)JtG-}#~9Lk;TT{*zkRXxcuMiZgl6#~9WM4z`qBTq2xwGnE9#f}`J z|X+Vg|R{Wl)-ceVRJSf69X zfr{FLh2D@Zq|bngl207D)ayqR&ezqf5w!T(*5G?}MW>Qq_D+2$m~l-{QC?_ GC;k_JPuSW3 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/button_group-light.png b/testdata/snapshots/darwin/button_group-light.png new file mode 100644 index 0000000000000000000000000000000000000000..db5d4363198397fdf0e2141d5f2bd99312f360c0 GIT binary patch literal 4956 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/checkbox-comfortable-dark.png b/testdata/snapshots/darwin/checkbox-comfortable-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f50031bba6a89b99485998e924924a0cc01f1452 GIT binary patch literal 12926 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 LRFbF^GYt428ub)s literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/checkbox-compact-light.png b/testdata/snapshots/darwin/checkbox-compact-light.png new file mode 100644 index 0000000000000000000000000000000000000000..546718db88286c3303011a8162cd80ec484e4ad7 GIT binary patch literal 11910 zcmeIYWmH>HwC@`V6beO~LV*Isr4%R*K?*GtcPU=np;&Ne(c)0t3lu39+=3J+?!kh) z2bTarZhFo*U*3CTym7}p1x1bCEq004kMPWFR3 z0D$oe{l&t4gub%FGZO^>a4N}tkks_dL@YcpcsA39bNuW_oGMA+W!wJa#;W4U0%@*S zKuPJ>8LXe5SLR&-iHZM)k)A|w=*^ZJNd64WYyA4N(F`LJU(ZIB7>F&YYk&)4CjQ}- zLzgM)_#tA)ukPj{%YQGE*NS;v@ydHd5x0C(OE~b|t2h-g9#4!)OauV*hw%SrCzPG( z$1eP%j30T>%=zm#O40Q3#0?iD>`6V80`_||HOwkmq4Tc-q zDp*N&9C;K}e4bpwY@GJs88uq_5~1pG>h%0?H*H0kcPKG>O8w29^wTQEvM9@2ziy4mL*Lhd%9a z2*|t&-f$u~w;Z~{qpSTppsDlGXR??CH#ZOz;^H!t|IyTj@3d*Q`>Z#NNT-vEfRD?# z4e!aKpx+$uq@H9IBao9W3h~(-IUbF;;fgHRrcsj9hmI&b==0jmPk9^yUltCR?!uBe9Vs*QIu)4d-frB&E- z9Pe|ed(O%@$Uq-ty759_5{w^X3e)xH$jMXagGY=TtG%Pca^nknWxz+X+5=T?^G8`v zpAP%YN*+ms-}iN?YZ8Zl=z!*Z>1r=nlS@Kw1yGLGR96|+Ad7_JWj_!H|Gtjc+iTX? zwIWY@6QFH4xC#`$Yq0Y1fj*4HVV;C}iMDl{hUE~^NaH$ung8LwX^YJ6t7+}&e~-RB zRMLoW(+m^JxWPYR^<|{A<)Ftw%--JKz~G?A;z|(l+|DM8(RURgQqt-phh7F6z4Ua5 zkcYV4@96w*xlL%3H8glKTgE3i7Pm^I|dj#A%b6vkG zD46Q%LeADudI%P=CGcYgc6LjsDGk4&TBuLd(QFoiWZT)t`7*j6sW@LH_5X0bk@|Gy zuah#Rrw5KrPchSi- zt-HT0yzZ=HbLrta#lYn|e$W0gW#P+-fUwb~Gu@OL7iWEy^z?K?!7EKIEogJuTOOE- zh?}S=PpDL`XJfgRx~bpYg(gu$U032KQStV|LS>1nuJ)IQt^MwBZYGG5e|L8QeSF`dpPiXmLP|>HZr(MEa<;hJRdD*8 zC-nI=Zmvar@>)n}XwQxJ;d~4Z-QV?-(o#D!Q_>W!8a?}_ou1+Ow6qjrsh7%X?^Lf0 z%z_Lh=YhbDMbY}xYv0?H|B#i3vx!fMk`A}!ytf=SJ~dunSM~HMUd~&?eWw5v zsbGHQg5AZ%LeLYRk5N}#!Ngh0AYzZc3A3#5aJBRMoZgZWjveuYA3SC~Iv#jq3sQfi%@-QlS3 zQRs=MVd=phW6LLT`^2U-t#0=xO30lyb{1rFP|!h8SZuLoNmdqtf|{hh&kag~9RmS? zdUQFSniHH71=rRxlVF|PUMu*2WRWDksp+o*NXZ&HNPYMO_zizup&4*;zTMIFk&p5X zeYKV5RatX=MNH;paHR-~_Gbq(q5Ke6SOYtEm z)M55&Rn!pL1`?^*fdQQg1DRY^VyUOPx(7~$&zD+bJm z`tUC?al`w0%=Pv3oTE9`N;tAOD_|#&lH{Lr;fjDrq^hf{JtG4me@R47PvrEj55A?4 zmycMxUkex|k;=+?bfXW3EiCYO{qVNjV$!$6Cx{Nml03fl#m4sPS5E$vW?P(akoD-> zhN|4ri>EDDY#)_lD2OYkoa<2IiF^y8SJc!|M%x<6lAIpLAm=U+@Y_!X?d1C{KCkNt z_uCjkvBk7}ndo9~z37?qtozt7|%D|B!h)y9_m09_P2LyEzvY}!2V^amHm{VA{ z7j~4NN64Kj)@Em`I5aTecbAUrCU@E3tGW6X6&2Ndn>=$tIJzcCAa!WZq<{PVsT+e;eWgyva!);5-OexEgQeoRK$X905hGch&oB4uuMebf{p@}!6ixWm zBU%C;BoC+dX|fSe&&TZV<4t(dR&zmAlo<`z*w3)4zH}@M)ubfE{u2M~n-1PX++t7b z>hyumna{Qj+A>{tj!(iYHgi`W*x9_k8(&VuM%Lt)lvJC4u7E(^=c@Y7enTqISZ*6c zMnz=tTGe|NmzI=d<^&W~R(gKjNJ}3X9T|yKk>&K!q`lj+0#9WMP0ax`X&GU1UwbDtbfoO|1CLs9XA z!2XB#NW}3XS?z3Z&ggb&aa4H3)8v+Lrr!4*8KtbTghcZclw_@)j?|LG=%K!W8sa1v z^JP8+;~dV`%#3uT$rp@diw*iDC>&)K7e_rgMxLB5WoP=rIy&leb5~b7^67F>FP?_3 zmuyD9A*TyQ95~q8?wgttg@hc<^A}MOz&22rMA1E-fuBzvEX>!w~e1dNNb<46pfSfBdzk$nbv8s{o?h z@^VAv7`7&IX11)XK#Xj2IU9R>(<-1(27G+BfBj@xbP7unH>6XXmaXN$^Cs%uD{DJD z9d*;y$A1oadn>4*KYTp!0|uRF#&kppa&9gZuOe9f>nM5{g?Qe4hD&~Xggww}V7^oi z`iz5?AawQc|9UcPhu?AeSkVwo-SnPpr-o3$ev;}|%jh|lMi>{E|F+MyPfDJb29?w2 zO6P9Y$2C7$jPr?)h$~=~PZ6N|VCK{_@-$z#eMZQ&P^!4}U}^j8qSvc!)OEzm=q%GK z=jiOEYa4fUP(1ZNLdIbLy_oIjBa{LEPhWyMkPsN1#u!CdoBjZm{~6ub&xzjqJ@H~$-#G&fv==6 zm5+^dbRI+@Kl9fY?VxscHj*iw_g-_mI7Ig`k?qkb;z~_Tqox(z>rBP|eCBY~N8xY< zY)5+m=!{@ZKI?#Km1lo|4`oCi#x|$PF2O_pS1Gt8oIo6b`(f>#ya8+;9IF}s@G~z= zeS(K0xqRH{v#mv|e{$isZ43znO4Z273(*+h>WaT~%$trhJcmxWqwQLaIkdI4y(DT(jEg%Z!U2l^ z{7S?szKtPGD@FWwEC?#JsCoC;1DOZ%I0OkF@s1gyKMtLTghlu_+V~*JN%^zLk0K>@e0vKir5mFyR|Qw z@Azy~>u$*>fP_6td1zALwNk!741C1|a0|d_g{5xc&H=VwOj}JJ4;@LB#p!!I5{~tqk%ykqW<)+4o1XesLT+b zm}Xj)^FJy)0tnbI)Opt>wJrIMA)l=9ktv(CFYsymObpDH4xf;wnwRm;jECMO`?>Fb zi?9l5gp!-p%t}i`EEO}NKtckpTeaVh@nMEDf`FB>fHC!nZcEG1SQ@d*OY#0E&oj~m zotEAgXxq;?FqALgjDv#$Wi6U@FHl+NyxA5tP)3+-%VKVAx+xs5V z<0f^@&3kt!BEw6X#N_0K=FJ&2#VchX$96K^^3X$swW_f84GM#Vr>6uBqN6&Hp=Y#07T3(I0e$8I0r>}RC^>6D!AvCj3o<2|C|2#~mW3_#^ z!WyER5ZzKwkL%L4uPJFO@!N-{2jzxC_aLiukm*Eb>`)YTsWxNRr*~Xw;vPyZH6At`#gU8=nL?Jh`O|qLoV|- zSw#ujlNEW6rHy=2(lv8Q1d1d$Jss~7SIW?kpNSt65NCY+Lza;SMDvHq(#t|iivY0F z9hq`!X3h=60B{UNADexxp4o&VJt?TDIP`u^Yyz&YrPoaJDjdU_Ryk>n{Uu2ND;6dv z5zhxJ7yNF`Pbb-)xtu`r{g*Q04mdNVJoM+(Z@NSt7?$sE&S z&Zi6I`u(8_=XrTfs;u;9TO(T?%5rkz{QL~e%rP>h`RcFX_Fx|$oM7tUMXNuK$3<0w zM43%n;Fpqd{R-~b!Pq%VvP$QzUv(~--oA}UeNoWZ2=w?8l6O=n#YieR!5V+%sI<+3 z;g2Vcg_=lx+x<5+0n(fwBu$@iawo2eu1BkX_}U}N13B|@SqIE{!U&(QQU9GZAK#E$ zR|6h=uIjs@zyKVBrq4jr1_}~1x=wfF64En z9aQa}zHJHnIC^cDC!4ye1KthQc{cckL8QZ0l$sT!rQZrO`30@(ajd)iOX~etfGFzH z7XkZV1%*=8nLQQdk%_e*>NN!l&3TE^-Yha^u5pVai@E`i0BeNV1>*kWtp9nN z9d%CD@E6XmpBox_yO+V04f-|dH3Fn$H16w`^hQtqXI@=dIo1^>jBZwV99d@LKkc#m4^cT{sO~CD zTKeilsL8{Vf9ES2lOwvlf#|WUkz@SPwsgA)UAp`FQeS+X!``)CSf2-`?%zfu-d0pz zHj~dPqG48|GZRoDD=+`@>`cUE<5yj|*td77Vm{3^30)|h_;`wgrhsh$tA??$()xNb zcXxMku6yUnZJ>li`y#u78N-MHyr-unuX;e@6@2EXthu?QD!wD3=*#e75I-opYPnj% z?5`I(T306t+k+fYO%@}s=x_rY5wm-%yJoiaXf3O@j#rkI#quZk0>N7PDit){K&Rvs z0Y!-q-dgImTezb9W%=I8R0IhmYT^Q_xA`M z2}phkUub^O`s=2p39A0mfvc{x9Hr z`ipJSqbw6A4WD4xqK9=YW+^0ZXJ1EJt}31wOblKo0|yC2Q@`33&wpEcG?7lZhhn1M zZWY0$e+`+0tHy%<(T)EXI6;Iv7+gJT-!j?m;+oTK5ZS9>tc7l36e$~9+nKGzJY?Qv zxB9EEU&h2(jT-Us39QD%meePcxv|-+ieK*RWHiO*tTO#G4}uTf)NX%yAsn4@qvI{3 zJyyWoG6^+>ED!X1%?)3VCZ%1l9{bALP(1hW4Qx|Q@&8a-ULfoU|9#QUG+lq`x<#os zd#h)(q+?lqdOBd%dxsin5PoOa;V;fvzD`;s@lKV3F|8Y;7V)W#srd28@>ISvg1=s|UKh-g*+-~gA8Fe5tnX_qI4 z-;_%{!DVDFAi?#uR7kn4cEm1v^!2rg8X5#jN^EQS_(KVvbszy*Sy?Q~kC&Q!V!QV; zg5!xqz&7%d|Cc1>v-3i_m@`J+)K{RHmR$V_JrP`83?|M?tNka zY;2Hd$zo;Z+}quRI+h-ok3@fv#+#Cdbwp~U&aP4CX3^Rg;kKv)XkLs zMyje~aPyFm5H)$*o=EZ#Qc?!+0i4f$j}h>$zm&)6DB=2=3p)g>j*q_{1R})^#sKfO zf3B)(SZc}bUVhr!-lReOw(%su@)i6LR@wm5QSr)e$sI9BZ>wV4&)k?ncKC4=PLAh7( z>sLDmyPR?aCC>&+i}1ffC+s8mHP_42J{8Xgr+}q5^M8Uo{T}ir_94b9tXznjZ1L_yOfnWHBwRp9bvS@-jZE!^P4eX+Lac_h5vR$5i;Ob zd##J$S->~?p9we_u*g$PPfoUYozbw@nNIZ7txxuN(;O=(%CBc1%Fx%fz?POA7aFUc zKCWqL;bG)6t;-;JYm}D)?kiqmvewaq`ub3-jDl=9;{`y#xIbJToupsgrdK zbbr&evcZf8?XJfF0NnnvPzk!fPgU>W`pNv~GiQEgAx6^`!yB&RpFd@F7Xr?lb}6fiY7Uf1R3I!|ng@p&)y zhGGI%4xRZp@9RUF#!He0p<~*Mn~z7&@C+_#G^tBltdLu3qzoQMC*Dfse_~v3hK|_T zBSw^CZf{#z48m@{olDb$fYgo1d{Pn;@vUt+`gk|8TNS$)6I;EWQwwG^V`>yBi+KLQ zmLwJvbKpIjTBt=gi**Yqf> zRN@;!sg`ej*!r8X5wBS#pcyO-B&EeLtS3|L(cstl?`tyS*Z;0Cg?M|qth zunz$$*;~%-0_>TkzDov5Z{85tw<3nAnp0m`nc@OIuU4f-M3}nB-#qTE`@}puJuUD! z!H0;}&B8*gq@*G|`bqaA5hI;;law|=4J|D~{Mcqc)X44i!+QA?B}ctM!*tJdk0^Sh z2DL7xPfep4A(P%Dts9!Q!K#Gl9EuF{IhIj zR`!^1To4hUxU`f=ls4iB>jDBJ0|)3p94JoHjYUv5FyMZ& zZBA8W#>dAO^G($-Fz`k?ZZ-Y+>|5jk`+vq@2%>_7;V%oiv%azO`#h>_VZjRI;r021 z0eq5}qGMsTO$G!WxQhk*udVU?tE{&F5MnIs$9mAY5UipDVP@vowD1=VoTjtsnVCgB zGLKtA{oAtf@Lcp8n$pwDZ$R7qZzZ@ms%s1^J3p@I+cbRBGh$RWe1btnH!qIxJX{QbD8YtX;%d&a*WaUPj-3&$0`8 zIALN^FIf%FR~k50gQG9HBLiM!lpTwoX8Z>}2gMTL0RGHawb#~e^e90OrtK*ujI^}D zd|M6r7HkX*b!bb`G*n#7iid~xLF;k;ySvxHe64If4G;1EH$E2EMT5qha)+)Dp=&W7 zdpn=&-o6kk6%qLa7bU6L+9D$jXMOeRE2u4T4kUu!jlIn`O3i$q$jE@j4xiayLxMrx z(6AoA}Jg&iRf1{Bc=bUDCT( z=eL;|>FNFEFrxG8E`F#}y=4)f(+x}O+7m9nnC~Ab}lV8<0bwXO2Ta$!EP>bK)nZ&&tYL3@Ll4@$eY7F|d01XY>(Cq|v*t!Hih4 z7$#;4jWYEwd!rZBCgZsfZiNTuCD+8Q2*Di-iI0Y$2_fe_W@k;4XrnSF8I8dthF|`uyq(C9Y{ylOMO2_EB}7HM`rYMz|loIYYpJvEIu=pky!7Q9HysfW=KNZSxZv4 z={t!3bMjUtgnz9~S={_kNzm$yXbVVp;!bB=R9Ji^oSyUgQ8w0n`<@F413l zZo90^o%@9+ZE30)ABjf1RfwRc{+ggd&Mk8A=ym(@c<1C;g> zN3aC{?Nq79Ynf}6a9q5hzoUQ8KE7a&uyz8uZfWZ4m;MmOd(;)oq-N_-N0Thv21^}7 zT%Y+tjJm7G&3Rf4!#0IFoNqUP>n_69dhJ%|M|}SrSOTx}PE_v=j)NsPTA^PufkJQZ zYc|z)r7aomeK*fQ$j~qxu|vmJqlew1_ENzYlg~(SvDUCo1S)HUKv4pAO`1m8K6*c5 ziZ#Z^RGp5j8G?mgUb^1bEJw%0Mk{$PEC$Cx+HM4hk9~X=cFEIDPJX+Iyq`Fy$Ppwy zetkj8WMdldU>6`Y@+RQc6!$qzzQE0RiZ zJjuYWLp82~J)U%Ga~1)mhc*Se&;^=r%{x~1YL48+k_Ugs6_k95eURh z+_x>*es5V+V&r*Q#W5(+?(#b~*Z(|c{p2b_B#%!LeuHXta-F@!p*65}aG=0f=HwJB zO@wS6Euv!9@lv>q5w#5xFLKl&?<~WH2-6IQt-zF7(`yJ-LJKc5_tquzTCZl-2*wms z1Lo3f_rOZML_PL?&F1vN6VXxUkVx`Tr~zTh;P})g-;2Zu)g_vSqgoHBc#C#EdMa6U zxgrg`PJNCoJBIh@rO|pgpW}DE(XSEKRpF0mGRxZg-2V=>pM>(n$M$!0Tv|UgGBpc) zb$cl&NJ*7M`o=;xJ8MxRk>=kD(1F5}3Sd2Z-mYQ8a|dO1#ZI-X*zb4;!x4JwVw>i4 zxcb3yi$0GY2j#XdUaoX74$5SWC_BYM1A$d~!=u^VTREISJYUX?1PgWc*1sdGl}>YH6whXHW|LERXU~ZHDyx=Tk?+0W88HU3EKOeU$eexB>%e>B~|XY{o+4vcpc6L zXN$B8pY-8#IMmcWoMtGS^IKbK?0ovHK6Tg~Di28>w2=GZD-Idm-n?Ejc3Qkf-byJ% zy3=(MKFvHL%47%@^%s5U>Kx&93;)~fElaxJ?`I*SUq+T3ZP+~7u9Q(6Tpejzmr72a zpU2v!<0Z;{QrOS-PbvxCBoFTMy+UK@4|g>&~DMN!q=Y{h*w(l`VEb7nn~v&5}FLR z7HzvZ8T+{R9cIAU+m-ead4z-c%{7lT2Ad^4ozlsG*175B1W|i?fQ092=V*14=(BV! z2;iTLPH}@1L+OEasE9a;$@4dfWS#gMgZ@N9gQMU=*-NGw;uQZ_;lkC`(u4%w2FC!oiJSYc0XM72NsIuYN8hf( zagr1`OL`x)7OvNGs2q~>185Y~x?eV=4czXj1gJunxINp7XJ%~pe6q7wy|N2!_S~7D zM@pl0YA$!r^1F8F`0nKc=E^m_5-pgH2V@TJL)fy`oISn#7??XLh1k&%O-mQ0#h#22 zj6G0-`@P7cQ4=E7< literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/checkbox-dark.png b/testdata/snapshots/darwin/checkbox-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..8a1d8c72d719fd39f4acda5c10234fe34b552808 GIT binary patch literal 12385 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/checkbox-light.png b/testdata/snapshots/darwin/checkbox-light.png new file mode 100644 index 0000000000000000000000000000000000000000..116207f24dad51597fd5f6ac597345d5f770239a GIT binary patch literal 11756 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/icon_button-dark.png b/testdata/snapshots/darwin/icon_button-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ff1961b86f207444990a1c6eba6e81ab337d4f44 GIT binary patch literal 3561 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/icon_button-light.png b/testdata/snapshots/darwin/icon_button-light.png new file mode 100644 index 0000000000000000000000000000000000000000..6a4ca9bad08db334cd27e3b9d60c1bfa7fde53d6 GIT binary patch literal 3551 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 G2>vhn!c4ya literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/password_input-dark.png b/testdata/snapshots/darwin/password_input-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..e893138b47697d22d7572dc36cce4c34ca4ad658 GIT binary patch literal 7652 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 NN($=WIyuXT{{v{wT2BA~ literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/password_input-light.png b/testdata/snapshots/darwin/password_input-light.png new file mode 100644 index 0000000000000000000000000000000000000000..cec5085c0e34e1bb7ef858f3da5d1748db1d014d GIT binary patch literal 7542 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/radio_group-dark.png b/testdata/snapshots/darwin/radio_group-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6f77a865ca1558f76ae60366e71655046b8f8b91 GIT binary patch literal 10665 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 D{C`}s literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/radio_group-light.png b/testdata/snapshots/darwin/radio_group-light.png new file mode 100644 index 0000000000000000000000000000000000000000..609f18c8893fd2a9780f705f2d76b59c2bc24675 GIT binary patch literal 10032 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 T=L6zTI3!s~C5dw2H~;?yVG{>! literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/search_input-dark.png b/testdata/snapshots/darwin/search_input-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fb6d0e4fc95bbcf024143d9770af3633193416f1 GIT binary patch literal 7926 zcmeHsXHZmKvo4|_2m+FkoDs=U$qY!6pddL33^_@bEEz#^jw3mzA!j8cFuX9rFyx$J zBn}MBaQM#qedpJ?b?-g5&W}@dckNo$z4njYtNZEhXZQa4PE+~mljl#cu&|!0swiq> zVLceXmlyG{?^kzfTnrW#L$|7;{D;rEhfBflQjqkI|7cA|;e~`VKDef_in)z>Gw_0f zQ=01?)0aZs&C=Dc*AUkF9COM&Ti%N5od`~*E?Q}GFr&FR$VBizSINUSj12zs{lc?vy*T_;MS=m>qs1?@pB}o1FY={}8Y|J} zH0k&D4Awn>GsZe;0~W6%mGVxAdcOb)7?7lRk52#key;m9K^RP2bC8OPX66Zxs3-AO zGhkVNRXZ%OdayCUj|G1$N2!CYjxWIeBlV-D8Wvqo+(Tgax5Q^c5GK}^sAgupSOZ?m z=I9xg|2F}XVA(8dX+>>g-=$WOcoRJs#^I4t+T3V7%=qY^fx5vOQBvj}Q;R7k{rYpx zwQ)hW;r;%&NL&m0lkUaHE>|$+KVu4KjCb-Zc85Vgj!j1t!^D~6{m1NupLNw$ry|X} zn>K2?Z;p`1Cp$sVCjVc^qo6=oM_08KW8QX#EpG_`v);nnqdj`XkTu>P zEMWq#fu0RB+Te@=UyQ0!(e_~d`(faW;fJhkC(R;e>}e|8@u1t5dYyOqx5IEyt;yQn z>jd+h<`ycd2A)pD>J)4_;O0lclY(~!dM0cncvl2ZP7S5?NBF+q2crHf~b%JWIFsbW(4Z!-T)v^=v0U{geBx zshpFFD0|#|sm=EoApPuXcb6FD=8)2x7)6$_21Ho4u%80xaevpzJb#WzO%eeG^G|u# zo^F^!bB%cl87;+&%hTz-r<|HImlwp}dO3K_pZ5lyamdQrYt^moHW1tT6YK(~MhjEk zaNcl98ZtJ_*|eVdLmfZQp^_fmA6;%&+FDsfG(*ctw>y>C{l@V%iwly)__nM?!+9@b>NjG$x{t$?!+xi>hj| zg$NXG&O}dl+iuooF~nsl1JeDs#V$$=|8N$>WhQ z^aSq$ceFVr?S!f|u&?xQc|M${|d*d1KFPgOGLIFogMD{!364AFv2Zk@&*j2n35 zxliC|NGGmU?>nx5i!G|fjo)MDCXQWh7gfP6Ej}bkOD>a>kUwc^M;nXct#(LyDK*6q z@E7)2s{=mK4|m<^(IWFL_YtU1T*W`un#sS}oVI51+Zxm^0YJ?0{)RDx9e97z{qd%I z;HD_uAVx}SH5urHXl`(ijq@rxyin$M+sMkyH*Qn!U#7Ef0*i;LEH6_L`ikL=JjUN4 z*|%bDUlV#k{QUy-rc0wQgHF#+6~89D{jXRYIb3qmT+e0+4QfJ@(*lZG#hyNlIT_NL7x8|g)u0Xd{e}+z94L-AAW?*0-D)X4L%*vHD;GrAFe-x^3#uezk z7FwHc*4>bxLLw!b82sGQG=(2IKz1w{!j};%>u&x!7czQhA~J@bIcmufo5f=TP6*<7 zs~A;PS);db4D%@|VVfjQo*?_0`sBK0BI3RZgvk8~lrbV9qcFrQh?8dUcq2$&=RqzP zQk+XQUH^Q{6t+F6tklxg1xff6V9p%lEcxqHO4gxc`a#HJ|1?eqzo$x=tmCSDvxmG+Uiy@kA%_zzN;`i8X+;NCdR%gQRzowTvrZVU4D9iBa-;`jIUtJSq# zrl<4UAx22j5$T>6TH|ZomkOGSs%zVhIuv5@Xn${FLe16?A|#ZYm;ZbfVeF5=4yOCN zZ{0B_dad|%_#oz#%N!kKiHPwpFTI0(LK<8@I;hoK#LYW2n_izv1f$N~U*&Dx+-Y}| zeA<{ddCuQmfcQB0m~MFQJW_#Tn7|$Ma>?YCpo;WqD>1$1PD4r=0l}%a6FO_grqk_g z_H=-qXSgA^)4=7_>vg>3r`@^*F{*9bGGRhtpir+*o4eDvgqsDOQ8?{(NKm+e@E zKwETdcV~jbe%A&T#>D*vHTK$@-y=B{g`{cX@1tsL3u~Aj(hmzHG5j=YJ}dXw@{}CT zJ96@}{j0f5+sN6+lcE&`7NcCShq=tk&NKMf=zb4nX4WJR$8uK3_GRTj9uNF6pk(@9 zFrAD*UUMRS_&51wWu%ap{8-|vReeV4(Nz2MMy=}!h{g>Os93p&!{dDibnmwC@~siI z7&CJpUW0+FKqjxA(ZOW#>c{vU6zZ@^jym#L1l|PYL9}B}NJt2_{Fe!_%40J^LPGu` zr^Z|4O~PNS<3Pq)^;!R}aSQ24xRYQG@A>YX(3QPO{*J$fjo&7(&vAf1E%WLSl}o_d zKbF8T@g9Nu>lTRhUmzMXY`{Fas8-U|nn#~sK3G;;J<-FCw8*9NVU)!JMk&nxWfha6 z2xWaFe=AihKuE@)Ww|S8fe00x>s)mY^V^#CY*3*l5wQ7W_3>jsT~x{jp>*lk(|wD& zAImsJE1g*KB#&rvu@bRJ<*-$*A|L%X5h3qF7D*f00Up(?)>rH=2x$jChEY3_ggv#y zbtdsx8>?!<1u~Mu2Vbb#PMW(wgWeF}g3@=L|1`0wJAG* za%4M|d=#|OUQ>AbrKT>yOwuVinG^?G-l`~u62+P}6gy}U7snmdFYmYvc7i8s&<3AI z#Z(^f)-**j1yQA2KfX($0Y{6%5vXjQF|e^(Osd1g!Q+HQvUHN^?;kP{3yd_(d?RC} zqOQJH!Gq>iRW=jJ)1i)!aKTZS^V2njx`APhvgT)}yWg&wny%lcu-ZS6zvbf@>pAbs z|MnYb^eOJ!@68Oexqk4*C6X^OP!6a=HPQ!ASP3eN-0?L!NLc<@{rc?0O4fj!j!w~$ zwfK`M1A6!QOMRZ$Z-iyaMZcytM6Vs+@|#tc;XFF&d_@<(5kssNyM@f1P|@JyO=r{( z_>xtfAPjfAl2ywlffXD*e-%ZaSyj1xfpaYgEyW;*$}yiOCrk}5P#|8)gT(F9Qpig8 zL6&mK31wAHOG`ml;V-9#WAqY#VIj+*_f6mVW-AfM&iUZ83v%{I64})1_@*#%$J^Bu z%$8@3lfh?RQ7u*8SyR?aD9_=}H)GBmo=Q13x^%zXx!)Fd;sJYYM`FSORTD}HQdT0D zqyPXQylIuU)y3Y*ioLx`KQ{oO02ryx5}uykZf$k6vSd3pKQ-Dii{FsF9c~W~pPPAY zXwz77I|yS-en9|D@sdEpwPbX}M281dEUnm6Lc_4JGiB57xP^r`QanHlN0+&W6ekT( z(6aWnr^Fr=%ZOrp&hIi1H(U5UgyalXBIp@`UVdRtE-ccg~C%sW1cSLLE>_PX5nxRJhxbN zysRXWjI1oTbyr01?XR40lA4yAtO;6DvJ&nYQB(w8C=)WnO|C`0;#Z)MV~CSxn6`%F z3h;U(t7E~>*|v4(YeAn|*Lt_Gwd_iIG7r?m@%sHS87MHQpsFz#@u_ie{&(@H*+u`+ zWO{hy*S`KiA3C(hG_AO+7ZEC^n2iceL!h%P^@oL-O-kw;iI5M3=RQTyj|`C#P8WiM z-ChsXZ302#@ejeg;tQz`8mdWM0V_cXY4F=zPRg<}xwgpJJU+Ds_I#5;OE=?La&ozRh3ER^d$u~O|E-zpm$910Ji4cfO z+P;y0XL`PJ;#a!X`iC%!wZqI;l0+jN8UFbz?aqjNaJDd`xvnT}TsM?mCqp*B{grft zMdp;OksO}jwV1+BfJ)jOxjv{-hX{e z7~uQkV?g4OXcjj&G5Mx-opDNM4^wY&&1DN_x3erXENs)!9iMqeMp}!Xk@?Bso~UmX z>ADrN+waq=m4%Tr6*Ev_Dxs*T$Q_)al}~3cWV}1dJYC(sJUxwq+KNAkNRenV)pF)i zQHeG+?^>FJ9=NfGs@LCVr#Ysj?;-TU!Jk*6#aicDAuz zH_FV*i^k4H6%~2XpvT^sZdqR4JuG zw}!VS@oo+8(DW19pNi=|@Aaby{y_||@OzW~yT&EU6(dH@VVS#${zU+6oH-`kf06@_ z8C=0ZPR%KX#Ab4MdEyU5Lh9^G{%PD$CI#vHLyke6mDK0nDa|@GYKE{f_5lp=2rN1y z*uy=&yz*YJ>>lpQ(aL#ajaa5(RXs9b|H1vB^L}pOw~j@_{10*vI1&xkd+>it$6#Sj z^((JXq~=wFFb7_=Q4Nj-HHXNn5!mop(xj_{eNCe7?CcCQ<=%5X02dnY#t^EsjDsLI z7xI#S_Z;;d>#pr_>DZ=jPK%0&5idQ?-%|y-%b_HC@mZg(Q%>M%Wu1puQ&VN_?OO^F z8BxRY+Zaw*wP~HJYnfG20d1rOA?`!z{W@RtntMB|iD|Zxkp>6Zktr(?(XE>mTExiN zYl6SYhg~Xi?c}qw1ikY;beA&?^eXIZm5}8rFK#( zbudyT0ot2e&@HpR`ePF17ij4FM(&5SRe%zwbcfRw9&FHFl`Qn3k?wwSG8qkHKp`v# zM#sXc05aBxg+FbfeN}5Qy{EjA+46`SWiVtdyFD zGLrcueXY%D6{KZ{qow4BZq1CLQI_SaPdqnw% z=dU|}=FKFj0N;B&e?J|h9xg!5J7WcT)u*1O%X zRwE-_a~B9cF@f3DTxcW#RqOU<&&{Q5cwh9xYaDuddJmfwgtXu9_472Pq9ikhcGJG( zjw?YyW+0UE>)<_^-`}5fo_8ONjjqRch`ZE=A~4`m_Shj5%4y|V);2^3u*lP_Wc;~F zF}am9@cn6i;PolA+4FmQF@+FO6d9e!a{q)g3b=NRzCQn!*00tYw894%(P`X%25^aN z^e-vVyu8ha*~%W@x%bj*X=ihGc>FakQHPH& zZcUgZGZXJ?&5*Q!^eel72z5>WUh8?Fg^ouoxByA)33|bo1n%X0@Brh`oKBHWa*7UN zw1s4nQtt*=7k8bkm!xhE%w>+OuY(bn49V!~Oj_}Nsf;Y@(-V{r9y1>wHbCXamH(GR z=V+czqE7qRV*jO&OeuzdXyk4uRarDK<7>Zjq))dJp^r87b}l%i`@qW#PO>VSo_{EL zL{HD()iH0ln#!VP02Z*H*+=ft8~`C1TcUeRNxWD4mY)M1 z5B9B3D}Mv07HAIqYQ~2qvuG$7lG~3K4g$JLZ*ZgIp4LJCQe7x+gx+QkTX{;L3!8eS zZ~qEw5KOXsf6KalT?GpmS^m`NS@G30!O_mHy1H7%M^kkrZjsL-;;5ZSQqI;i7iSDg zrK^{>oZcCASzD}IB9^6opG%NjQCYUt{r%}hM6V7pB-czoSdXJlyFwJ_4g1S{65RMKg$^}%ms}XyGDiIF_=TjBznphH^B7;Pbnp78xS3hI z6>?c8?Ma%N@Gq#>{-Lz{^r)tVLQuXE53hCLoWD*Wq&59ZXzcA?z=XCi8nTHlNL+ znV6qy_~%PVP29xk`G>PU^cny$RfNa!`1S#-#_J>P)}Z!?_W<+crhZtjjej3U@G zz8O(Lc3Kv4x{Qxc*#+l4msBm9xl91#yngq7Ss8hXdJ*WWgKbtbcu=FLS2R;=*eT<- ze289=zSIsHG^#bg#1vk*JmhDYnzm8a{aY=Ta zTUvjEaJ`+PX1$OxKJeKGdI zL8ESLx#3z?5=l1gLO=Wc$T9>03+^Mwe=Dsl)`TT5M2{i9j69||zWhGwhy@fcSDF-S>w&*1b zL%8+na<*EDcdRTQPuC@8UioAty+uENWZpN8Nxv3=mz;5EAiw#_$f&ad{o}4t>8L!`|)3J@=lHkj`Jnmmx;}14ThH_SE z>4B(aU(ubHd`IH(07vj3B5zGH z%4N4JTiuL$G2OcPyi)1CJ>p|`y~j392SGN1kK|d>5L?ohM{G=M;g9||@Bh!O`k%QA yllj~2vuuvZqND#2h5xVqFT4SFbWBEjVexVF8a-_@{>2w<%dDiHL}9 z>*{D26A|4QAjm%{hzYGPGx;?U5xcjphMH+m!Ol+))A9BDHxJfn)Kqn&NmuANW8CTK z<3Mh2Bk5&!2OF*YU4??az(Xv-{*!I4gNHk0W!5Q;3KcHePYOqYoaQeNjKSg)-*qeL zzL!S!I7_Gt-tfE2eJc%b7)K+2r}|W8ehD|2zk*eXVY3Y#T28^svX!0EsnL?Eu^SR^ z&~s8bMhK^p!Bv^i#FqbiJ3Fpu-;H$K;PgAZSW#8Ltk>JOvKuUsoG;}gA_`uy8(k-< z3&ISi-|V0scqm%qI{y@Cj54&m;Y3@|^uu>QHMX0XCpkHC%zXXk)}&@ZL1hozsjZEo zjj@l?HMt+i3L=7^M+ko+&7pgt_eLNBsz=1;-3$D6qn#s?lfu{fX@zDL6T)i3{n`Ia zz-uFBAwfZ?g&6r|r}Qs1P1(Kc{VTrq@8fJq|7jrz2f7hq`?JRQ(fuKd2u>-fhSD$C z?z9rRTq#kgbasC!^36ZZxu691sseyL=S0$UWd+Qmv^6fWDBQeVh0XSHCna9_nH;3C zQ6s3u^tJ`t?ab=W8ymOm={IKIrgS;0xQGp0>YBZJB?cn-_kA(Fbe1*KNW0Sa=#L(< z-Y=MAMCfxBS5Z|zA|L8`IXySrGj0j(mAilEw0eFqd|c)vL6Ij-7^(onb<>|*zBK?h zJ-2?AoA-(6@70j%XLtWBRTK|x_{%NYH2)5?ze+iXi^C=|6=IF|x4@$a1uc{x7=L;V zmhln1aKv4LW#xAQPlx7D9(*Tb2E4F&^SZ<0KEOsM*MTf@NuVRHw_#=F$NRTghV>hL ze4DfU_t@B4Jta^VvlS*h4(f3hTM7Vho`OY|6Z2X^kFSmO{M6Ww!~}zWG#Xv-gyQh) z{A@z`S`2y993w2}tD_~mieLimQL%5u11{94#iE-GAQWEMwPb2;26A=Z+TNv4&`{|Q zlZ@+!vhyvSs zsk7^Lwev`&u<3=G5jZ6zJ0Y34CB^Ly6&*c1dxeyYER%zOY}>u)8NY3i(?aIHutH|nVU=S1R;IB4VMmGCO*po$Jg(}3Jl?j%I&3Ja@$z$B{q-q@xqJ% zdpV3M!;45iaPYI&ny=$IflJM~k`i!)7TS<42Udy=l)5X$X{_-a+d1WRhCgTil z_cllC>e@s-*I()3P33;wqhJAOP~?gWy?kve0_>jLFQ0@B*}~=g_Sn?X42LGYh)E^0 z?GYO88qp!_sNXQ1`i^OmJsMw>)ck5#^pf4ppv4je2 zAeVB!mvugf-}*W-aWa`J8LQWC)!tU?+$E|oJ4Zr7f>>pgr6~uQSsT#+xkZ%QMlF2g zuE1qo_PbjSmVw_O^caoNL7X39vSn6b)_cX1ALmA9HFnw*ujSaUe z)BcTwVFjs-yz$%;ZgnAx5bI1X-uhmt*kM*`A7MKt+JndI%#l$+YU+OqvTZB*1*fJ% zmufLe-osyCFL!PXHacud;RhQvx55Hk+VcdNdb@kz!nk4m#j$hFE@%;-FDW6=xrUA}>bRgRvDVSFY9_Osju16F>3r8BxPr#lc1LUle@AYK6Cb!|+vP zO!dL-?!#kEW|v0U)LjO56Hle>eloWLbqrjkSnT@33nd-@np^cnDv=aL$ai6~0RzzR zh5o2i(SQ~|1o@?N6CEr^l|mc=IvN(L1|b9Y47}X)B5k#4Nt=<1ERM}Kd(NvjXMYGj z3D$J#>&UO4)wyQv&u+F6d1Cnp$i0ni_Q&zZ$0z!oo&$EDyNLG1C%?O@9{2sY_0-=W zsir9ZeW*c+z@MEIzjf3~V6z@oVo>P9>^oNV-W2?&Qt8#rO{IAyzVehY@MTKW>t?## zlaY?G)REL$vAt)5OUY;b^>Fw`z~45wf~scG(y`IKPe-00qNyGhI^)5B?(Ux3cv%}0 zGv)A3Qq4<)mM}-=7|Zre^Jv&E28&#z8P+wg4$h~gd*n7&9Z~9$(lev) z1}ic^A%t;<^6RXzm(tAF*#Hmw61kM8*d^u{T2|zUxr|gGakP4W%JcB~+n#6|9YcB6>KS_AsMTkz7Y=1&ZJv)*`g zVyH4ypuNnRm#-%Ioo-ktlQNTYZo!IVQdt?_L)zr!0p9d%od&U+;wb`IsKDJkRsN4; zMBgO(!muNLo4F?x3K#`MdO&iz(oQQ6EoJ-CzEO&|L-B)P#RWRQrqGzXVgtXYZxFpP zQT#6zA(!1+ksxUWIpE~?s|Lx2RSSrJE3y}%Y(b20GY`uqAYHlR)dq#b3^Gk6D zMlQ2|Z+wz0R^|5e7S|o({lECU>P0xH*fS_}ZkPApUJl9kN|+)d@?cSh-PQk?a9_{r z+YT|n8SsHGu}C-szR~v=9}c?n-_q`1KGn{=5QdSJb{w-XJ2v6k{f3!3uHzp~vzuy? zMje-;#vyH$8oWQ#Q{Uv}%7QEY;f)3&B8%-A?fYlv6VJ12ocgLQkl*C0W9{uNn3-Y< zrG2c4lv&iy7P8?}M@lhDzG`&^Ip0z6L4P70k_tB0(OPwjQzB7MlprFd4tC;uE zF+Bw-2dxBNW8 zun4W&|Knmd?0nRtoi591w+oPiwduOJFbTB}3EP zf8aVM#r^T)$F4WtNZ;%d6F+?26RlZa>MG(|0oh)d z8=PaGGo7-|Os%D^6Ly6isO$<4Z;Kt5tSIkqZEdy48XOF(FTVbBx;@PS@toGb=SCdy zCR~PS&mhNGmqI{9_`x^>fT@RvS1uuSM~N46s~!{IEE6XyS6xizqOlkM6jp%>ZQfmq zWsIUt>@mh>m!r}9UncW5F)EE2uxn#}hU=};$0X+Di@{|tmcQ4OedK=k4)nZ2+TNa~ z^wYIXF~xmmW)?QKygc|_b=&^%5;%OV+3sUdNJ!fi5`3GyE1%DA6Gr|ffBEUwrV10C z`tNjldyDDYNcs1fI;8|>8Y#ghQQubhhdPP}s^2!C;Br$Jw)a)l#&e!O7dRB9g)qxC z?R3n{zjhz;Ml~Q1cJ6JSP*$Mvmz4<^6`O1?IeCopj*9p*W8=V`i&2-N;5^#j%Ulp; z>8sD-KMw;5kB+>8)3RB;_{*c|(J2vg&oTsSsLdiLAvM0d9P510-E%+au!rm3y-kNY zi&FV|pGA}H>0w3gZ(;_j-x_J80zjboW%9>HMvH5>tFqzL55H~#l*11;%jVg7uTa%$ zWgfgyIfL}$J%nh=UYbqxYe??0_OLI$K8(cE8MHW1-TAI&(7K7V@3HAVqUK&aZG5ZX4R6cWN>hg?V;GmKMkJJRyMvjTTO5W*`zpS;_bFy*h{E2%p)3>0nV5yF- z@6+WoT4~M7MaT*Y%1QaZ4eCOV9Q2;v9<+Mc``WDHRHlt6CO#QsXKXw*f7NWgN9E1!Gks=iw$ls)xwLds<0ca>+q2Vd~gCT5#PyD*Lx9M%srOW{f)vzqJvtz znav=Bhb05V09+Syh;(Js)uh>cl`G^q;Uf7}60+q7vkzIh&ZEpA;r;yqM=adKK$ zVj7s9e#9o>^kbz||LXmFWnCSeJSn%|t-*VgrDF#-Z%>b2<+n-#C49qX%B9^A-#a?O z*M~F+RVx0hbE|OD2W+d+!f5z%p0Q=Vg4<_~?sO=yWqPjQ>QE}Xzwij}-7s=Y$O|*| zoV@1W@sZ}`=M%)Ha8eSI<#4WWla+D=>n3}(Bfe4yGc=Bs_H1$pk@c_97jI^5iRGji zJEm^gze}n{`*Hfle}g8tN>5$&4HoVnQz9(kWsybbs7_I!t&XwMli8c>k(?xov$ew3 z$NHJlP*texylcC?M*6%Vd!PH~Yy<)^MkwM*cLk5Hdj zo zeK`T1c6XQQ@tV&naO7iP@52I=#`w}4*Y)AYn?;8vMdlV+)~e^>MwZ@c!M4Ep$02mK zK7ftuuU4Rk{;$MZW26VZ9xm5Q-kDnXy0@`o;BlV3P7LF5fTifgYNgJTM=wGY}gKOZU<%=9u`D#b>4$UWEHdx;H-U z6W4j)PNj7@Un)Ql$Q|Z0JFm1G10C@N)!lq1$UxOv#IY=qO#55HzH@0nIMdio+>t`b z(8|h6qFwHw-qhXOUfgRfDY%F#gHqGRfRLQQxVe>=mFN750fqWna>>5zN+F*!Gre)@ zxf$%@;X^z9B0*39P=m|dkcwd(E&~?W9vD?TQHw5uNbDBO4}$78agbsOuPh&o-}s-m^?y5n?SB&yze~pXR=%D+3(h(SC^3V z+u90ONKNBqn7yk`PQzYM(29E}`@j)?Y29?q%6`37iIH?3EE0Fw^Ne^?^ORpgLZYb^ zu)K}Tp_TB=+0C2ucw7g%^-JVQC^rzq!#qO!&nst8EhdMVsPS#D2kK)fa0!@Pn>n zVoW<7y!yfDVQUHC<2p!_-gWo9Kv4Mi9Ocf=uENCrz0vN&UFe^+bxIc(zQWq5R2OH( z!qim%=B*z&btQa8xeadPYmxMJ!v)x+>}fyZ8|@7zZ2fRMn6RJ#HlFrDwh#pnAZlg+ zQ+`LVRQASY?G2#XWt*Chi1RHV*n81%zPW!KQe5rxAw|79RaRQbdHVWph=D7(uC;)@ z)knrV*=x$x_fB~3wWWJ^OhAKYLB=YRf2!gBhvrNtJDV4cHP9yMrMf*viaCfq#~nBU z6MI`)*mRy);{yF-hj!|IcBwD|M8h6^NKBdDD07=&F)^XH;{C)s>xIyIOriT^KJ3Kx zdYUh>v6s&~#mGQk|C!+P*?ev5h`k6KWf%t=+~(W*I85tO-@lXP%pS5?sa1lN62NG3 zhn#T?k6J;5V=Qv=awn(zFB*x}bx@THF^ia8(?c2+Y7X(vrNiDQ22Wr`(#Ks7tqBqT zHHXs5QIPV!X23Ups}D0jf4rYdjGd9^7$@%elw#ou&5eg4`*@M%0z!c@1e`Mu}X z-i;EVi~t^0l~wLFi*nB`PE1~l_ru)-nm8UZ%X%AxhesHHX{a3uSN=HWD*_(L5ihwH z^Q>Z$@W==*2;M`7wqC*EzFfA`3w%Q`mEQTVsd>DzcSS`-J%TZHuZXcklu+`-o|Umu zR@9%4T%X)Z=RN&(gCxsI1@AxnBE4f+^vKQKeXP^nzGKz*6w1FEKU$K)(MLsnRc0fC zZ`;UkrjkdRwwfJpr>Tn1{-a-?fQ1YPNBZV9Q~a4fo+Wd|-mVYug9tj0XU%{K^}&3Z03_wU z!u4QN@6FVD{L6K3+hu+dqB}+fnEeb;pkFG3P(ovnfW;GceHx|DPm9^DNZqI=84^C+ zwMQDOp>&j7M=1x(fom(e5L(|;qk|7mjlxZdx74=Gc_u6e^yr**e>+3xa#Tg6YC&5AGWWwKWM<`;w4B;V>Bhw{hCel*>-7;Ug@lIrYOTuyBsEt^_^C$ zcQ&yjaE=~b{ilBoj-RK2oYZL_N2_m#{nY9`t!dYZ(eLGo{l30dJ>PO_t_-uj+Uaht zr(YjhXvKPbG4%wAG9^k%p2{Tyn3(i<@+rw3Ow_Wq_7=?@IOEBD_*L< zhoglZf&Zn5qr`|MwP1^abxEGrW2n16mqB~N)f!Djh8Hhn9;HkDdN}DRv)+#XWLoWy zdt($DaM3+|O|lFd2H}>^7nuNf-D+KyjZQJaOd%XilGkS0N$_Ln^$|#-k=NtNR9>aD zr3W0<@_$w1zgF&l@hG0=Kdtb8?D7Alf9(b!9=y1HqM!g604)6-pb&e{9y)72fWq#%imfQJAD1%)gvC8h!e^`QW=S;BvW>`8&at%QOS zvX&MTR`bj}SwmD(wOE0>*r(vu{TM_cM6$*Rs{{k{DS(Vj2A$Cmoj#GKa)n2=Q{kEU zTK@Sq!(q+dqiNQz*uA)!u-Sgq%|oZy1Kh-*(G!^G`5hhuLqzD~XAdc<779{}{hb}d zs0MJ=%FOAtKkux|1R%bh5v9v3$E9~m`kV029z&-0!>tdP(SlZ^iO|RH{$@HYJtcnHQob9U&V{M+g?lRf^Q6w)H6cFSXxm$&%M4e_=rUqo58cya*mO`olxb>*n?;Ar`gK zJ%N*l2f)ITt{W^rk{nH&fVtdpK3VofdX)obt;fk;x66IMiT;G>UycdrZBzaEh@_#PQpg%Rzah z9m*nwL2_}KOv|H5L79mCMgL{b+S~f-;Gv(^fvC#Q)()6ZK z6SWoCnuPU*Au_>GNQ$Vo*{tX^73v) zxt&{pBP6e+EhNL6yjKK)vm!xUGA2e**Sb^N<;mvRhrBFetCG%UA%dHe2pEXx;ZJS zjT&IV9$U(3i~0oBs?tco6G#Hj$>}VuCT92ADxL47)gGn4Fd)WEb-~a7^4kB{y6jw7 zcIeCs1@rLib@|v9kel4(4rOVlnc4M#48^BgOHRewAzEr}l~7zvd0y@FlLY=Q|Dego zYVGyjjvY_lV4i)+w&`l-Z%G(a%0AxNs(NyAx=&^PwTg?4uzn2c^Acm+RI{~#nW^W& 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/text_area-light.png b/testdata/snapshots/darwin/text_area-light.png new file mode 100644 index 0000000000000000000000000000000000000000..b47461597ca28879db07ff97c99a8f6ef7a6dbf2 GIT binary patch literal 15926 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 R%LhDg^3uvuH4-M@{ud|9{qg_+ literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/text_input-comfortable-light.png b/testdata/snapshots/darwin/text_input-comfortable-light.png new file mode 100644 index 0000000000000000000000000000000000000000..281d895ea6b35a41da5c1e04912b0d71d1b0db47 GIT binary patch literal 12823 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/text_input-compact-dark.png b/testdata/snapshots/darwin/text_input-compact-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..3ddd459019f9fd09e9300c134e3677d283378460 GIT binary patch literal 13079 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 C`<<`= literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/text_input-compact-light.png b/testdata/snapshots/darwin/text_input-compact-light.png new file mode 100644 index 0000000000000000000000000000000000000000..30cc1d1672d20328014c5a6b0b78b5e10eecc863 GIT binary patch literal 12710 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 Hli>daVGrHK literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/text_input-dark.png b/testdata/snapshots/darwin/text_input-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..18bde1fe3d845dd977c429c14c7259c1a550fd73 GIT binary patch literal 12964 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/text_input-light.png b/testdata/snapshots/darwin/text_input-light.png new file mode 100644 index 0000000000000000000000000000000000000000..d600c90803ba7f2642dd18d73f5b52e086fd6d94 GIT binary patch literal 12498 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 literal 0 HcmV?d00001 diff --git a/text_area.go b/text_area.go new file mode 100644 index 0000000..e87274b --- /dev/null +++ b/text_area.go @@ -0,0 +1,88 @@ +package mujica + +import ( + "fmt" + "unicode/utf8" + + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +// TextAreaOptions configure a TextArea. +type TextAreaOptions struct { + Placeholder string + // Label names the field for assistive technology. + Label string + // MinHeight is the least height in DIPs; zero fits three lines. + MinHeight float32 + // MaxHeight caps the height in DIPs, then the text scrolls; zero grows freely. + MaxHeight float32 + // MaxLength shows a character count against it; zero hides the count. + MaxLength int + // SubmitKey with SubmitMods submits; a zero key means Cmd+Enter. + SubmitKey ui.Key + SubmitMods ui.Modifiers + Disabled bool + ReadOnly bool + // Error marks the value invalid and shows the message below. + Error string +} + +// TextArea is a multi-line field editing *value. +func TextArea(c *ui.Context, value *string, opts TextAreaOptions) InputResult { + if value == nil { + panic("mujica: TextArea needs a value") + } + if opts.MinHeight < 0 || opts.MaxHeight < 0 || opts.MaxHeight > 0 && opts.MaxHeight < opts.MinHeight { + panic("mujica: TextArea needs 0 <= MinHeight <= MaxHeight") + } + if opts.MaxLength < 0 { + panic("mujica: TextArea MaxLength is negative") + } + key, mods := opts.SubmitKey, opts.SubmitMods + if key == 0 { + key, mods = ui.KeyEnter, ui.Cmd + } + d := Density(c) + n := utf8.RuneCountInString(*value) + over := opts.MaxLength > 0 && n > opts.MaxLength + errMsg := opts.Error + if errMsg == "" && over { + errMsg = fmt.Sprintf(msg(c, "text_area.over"), n-opts.MaxLength) + } + count := textAreaCount(c, n, opts.MaxLength) + var r InputResult + look := &textInputLook{disabled: opts.Disabled, readOnly: opts.ReadOnly, err: errMsg, area: true} + r.Element, r.Input = textInputFrame(c, look, func(frame *ui.Element) *ui.Element { + in := textInputEditor(c, frame, value, opts.ReadOnly, true).Grow(1).Padding(d.Unit()*2, d.Unit()*3). + Placeholder(opts.Placeholder).Label(opts.Label) + if opts.MinHeight > 0 { + in.MinHeight(opts.MinHeight) + } + if opts.MaxHeight > 0 { + in.MaxHeight(opts.MaxHeight) + } + r.changed = in.Changed() && !opts.ReadOnly + r.submitted = in.Shortcut(mods, key) + return in + }, count) + return r +} + +// textAreaCount builds the character count against max, or nil without one. +func textAreaCount(c *ui.Context, n, max int) func() { + if max == 0 { + return nil + } + return func() { + k := Tokens(c) + color := k.TextMuted + over := n > max + if over { + color = k.Danger + } + ui.Text(c, fmt.Sprintf("%d / %d", n, max)).TextColor(color).FontSize(theme.CaptionSize). + FontFeatures("tnum").Shrink(0).Label(fmt.Sprintf(msg(c, "text_area.count"), n, max)) + } +} diff --git a/text_area_test.go b/text_area_test.go new file mode 100644 index 0000000..4e51b59 --- /dev/null +++ b/text_area_test.go @@ -0,0 +1,94 @@ +package mujica + +import ( + "strings" + "testing" + + "github.com/egoist/mygo/ui" +) + +func TestTextAreaNewlinesAndSubmit(t *testing.T) { + s, submits := "", 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if TextArea(c, &s, TextAreaOptions{Label: "Notes"}).Submitted() { + submits++ + } + }, 400, 300) + _ = tt.Click("Notes") + tt.Type("one") + tt.Key(0, ui.KeyEnter) + tt.Type("two") + if s != "one\ntwo" || submits != 0 { + t.Fatalf("value %q submits %d", s, submits) + } + tt.Key(ui.Cmd, ui.KeyEnter) + if submits != 1 || s != "one\ntwo" { + t.Fatalf("Cmd+Enter: value %q submits %d", s, submits) + } +} + +func TestTextAreaCustomSubmitKey(t *testing.T) { + s, submits := "", 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if TextArea(c, &s, TextAreaOptions{Label: "Chat", SubmitKey: ui.KeyEnter, SubmitMods: ui.Ctrl | ui.Shift}).Submitted() { + submits++ + } + }, 400, 300) + _ = tt.Click("Chat") + tt.Type("hi") + tt.Key(ui.Cmd, ui.KeyEnter) + tt.Key(ui.Ctrl|ui.Shift, ui.KeyEnter) + if submits != 1 { + t.Fatalf("submits %d", submits) + } +} + +func TestTextAreaHeightsAndCount(t *testing.T) { + s := strings.Repeat("line\n", 40) + "end" + var h float32 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).AlignItems(ui.Start).Width(300).Children(func() { + r := TextArea(c, &s, TextAreaOptions{Label: "Log", MinHeight: 60, MaxHeight: 120, MaxLength: 100}) + h = r.Input.Bounds().H + }) + }, 400, 400) + tt.Frame() + if h != 120 { + t.Fatalf("height %v, want the 120 cap", h) + } + if !tt.HasText("203 of 100 characters") || !tt.HasText("103 characters over the limit") { + t.Fatalf("count missing: %q", tt.Texts()) + } + s = "ok" + tt.Frame() + if h < 60 || h >= 120 || !tt.HasText("2 of 100 characters") { + t.Fatalf("height %v texts %q", h, tt.Texts()) + } +} + +func TestTextAreaBadOptionsPanic(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("no panic for MaxHeight below MinHeight") + } + }() + s := "" + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + TextArea(c, &s, TextAreaOptions{MinHeight: 100, MaxHeight: 50}) + }, 300, 200) +} + +func TestTextAreaSnapshot(t *testing.T) { + snapshot(t, "text_area", 420, 360, func(c *ui.Context) { + a, b, e := "", "Les lys d’or sur fond d’azur.\nUne cour, un bal, un serment.", "Trop long" + ui.Column(c).Padding(24).Gap(12).Width(360).Children(func() { + TextArea(c, &a, TextAreaOptions{Label: "A", Placeholder: "Write a dedication…"}) + TextArea(c, &b, TextAreaOptions{Label: "B", MaxLength: 120}) + TextArea(c, &e, TextAreaOptions{Label: "E", MinHeight: 40, MaxLength: 5}) + }) + }) +} diff --git a/text_input.go b/text_input.go new file mode 100644 index 0000000..07107cc --- /dev/null +++ b/text_input.go @@ -0,0 +1,172 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// InputResult is a value input's outer element and its events. +type InputResult struct { + *ui.Element + // Input is the text field inside, for focus and keys. + Input *ui.Element + changed bool + submitted bool +} + +// Changed reports that the user changed the value this frame. +func (r InputResult) Changed() bool { return r.changed } + +// Submitted reports Enter, or the submit shortcut of a TextArea. +func (r InputResult) Submitted() bool { return r.submitted } + +// TextInputOptions configure a TextInput. +type TextInputOptions struct { + Placeholder string + // Label names the field for assistive technology. + Label string + // Leading and Trailing build content inside the field's edges. + Leading func() + Trailing func() + // Clearable shows a clear button while there is text; Escape clears too. + Clearable bool + Disabled bool + // ReadOnly keeps the text selectable and copyable but not editable. + ReadOnly bool + // Error marks the value invalid and shows the message below. + Error string +} + +// TextInput is a single-line field editing *value. +func TextInput(c *ui.Context, value *string, opts TextInputOptions) InputResult { + if value == nil { + panic("mujica: TextInput needs a value") + } + var r InputResult + look := &textInputLook{disabled: opts.Disabled, readOnly: opts.ReadOnly, err: opts.Error} + r.Element, r.Input = textInputFrame(c, look, func(frame *ui.Element) *ui.Element { + if opts.Leading != nil { + opts.Leading() + } + in := textInputEditor(c, frame, value, opts.ReadOnly, false).Grow(1).MinWidth(Density(c).Unit() * 10). + Placeholder(opts.Placeholder).Label(opts.Label) + r.changed = in.Changed() && !opts.ReadOnly + r.submitted = in.Submitted() + if opts.Clearable && *value != "" && !opts.ReadOnly && !opts.Disabled { + if textInputClear(c, in) { + *value = "" + r.changed = true + slog.Debug("mujica: text_input clear") + } + } + if opts.Trailing != nil { + opts.Trailing() + } + return in + }, nil) + return r +} + +// textInputFade eases hover, focus and error colors. +var textInputFade = ui.ElementTransition{Colors: true, Duration: theme.StateDuration} + +// textInputLook is the state a field frame shows. +type textInputLook struct { + disabled, readOnly, area bool + err string +} + +// textInputFrame builds the bordered field around what build returns as the input. +func textInputFrame(c *ui.Context, look *textInputLook, build func(frame *ui.Element) *ui.Element, footer func()) (outer, in *ui.Element) { + k := Tokens(c) + d := Density(c) + outer = ui.Column(c).Gap(d.Unit()).Shrink(0).Disabled(look.disabled) + outer.Children(func() { + frame := ui.Row(c).Radius(theme.ControlRadius).Gap(d.Unit() * 2).Cursor(ui.CursorText) + if look.area { + frame.AlignItems(ui.Stretch) + } else { + frame.MinHeight(d.ControlHeight()).Padding(0, d.Unit()*3) + } + frame.Children(func() { in = build(frame) }) + in.FocusRing(false) + if look.err != "" { + in.Error(look.err) + } + if frame.Clicked() { + in.Focus() + } + bg, border := k.Surface, k.ControlBorder + switch { + case look.readOnly: + bg, border = k.Background, k.Border + case frame.Hovered(): + border = k.ControlBorder.Mix(k.Text, 0.35) + } + switch { + case look.err != "": + border = k.Danger + case in.Focused() && !look.readOnly: + border = k.Focus + } + frame.Background(bg).Border(theme.BorderWidth, border).Transition(textInputFade) + frame.DrawOver(func(p *ui.Painter, r ui.Rect) { + if in.FocusVisible() { + internal.FocusRing(p, r, theme.ControlRadius, k.Focus) + } + }) + if look.err == "" && footer == nil { + return + } + ui.Row(c).Gap(d.Unit() * 2).AlignItems(ui.Start).Children(func() { + if look.err != "" { + ui.Text(c, look.err).TextColor(k.Danger).FontSize(theme.CaptionSize).Grow(1) + } else { + ui.Spacer(c) + } + if footer != nil { + footer() + } + }) + }) + return outer, in +} + +// textInputEditor builds the MyGo editor; read-only edits are undone. +func textInputEditor(c *ui.Context, frame *ui.Element, value *string, readOnly, area bool) *ui.Element { + base := ui.TextInputBase + if area { + base = ui.TextAreaBase + } + if !readOnly { + return base(c, value) + } + shown := ui.Local(frame, "readonly", func() string { return *value }) + *shown = *value + in := base(c, shown) + *shown = *value + return in +} + +// textInputClear builds the clear button and reports a clear by click or Escape. +func textInputClear(c *ui.Context, in *ui.Element) bool { + k := Tokens(c) + b := ui.Box(c).Size(theme.MinHitSize, theme.MinHitSize).Shrink(0).Center().Radius(theme.ControlRadius). + Role(ui.RoleButton).Label(msg(c, "text_input.clear")).Cursor(ui.CursorPointer) + fg := k.TextMuted + if b.Hovered() { + b.Background(k.SurfaceHover) + fg = k.Text + } + b.Children(func() { ui.Icon(c, icons.Must("x")).Size(14, 14).TextColor(fg) }) + if b.Clicked() || in.Shortcut(0, ui.KeyEscape) { + in.Focus() + return true + } + return false +} diff --git a/text_input_test.go b/text_input_test.go new file mode 100644 index 0000000..8758dbf --- /dev/null +++ b/text_input_test.go @@ -0,0 +1,141 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" +) + +func TestTextInputTypingAndSubmit(t *testing.T) { + name, changes, submits := "", 0, 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + r := TextInput(c, &name, TextInputOptions{Label: "Name", Placeholder: "Your name"}) + if r.Changed() { + changes++ + } + if r.Submitted() { + submits++ + } + }, 400, 200) + if err := tt.Click("Name"); err != nil { + t.Fatal(err) + } + tt.Type("Ada") + tt.Key(0, ui.KeyEnter) + if name != "Ada" || changes == 0 || submits != 1 { + t.Fatalf("name %q changes %d submits %d", name, changes, submits) + } +} + +func TestTextInputUndoClipboardIME(t *testing.T) { + s := "" + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + TextInput(c, &s, TextInputOptions{Label: "Note"}) + }, 400, 200) + _ = tt.Click("Note") + tt.Compose("にほ", 2) + if s != "" { + t.Fatalf("composition leaked into value: %q", s) + } + tt.Type("日本") + tt.Command("selectAll") + tt.Command("copy") + if tt.Clipboard() != "日本" { + t.Fatalf("clipboard %q", tt.Clipboard()) + } + tt.Type("x") + tt.Command("undo") + if s != "日本" { + t.Fatalf("after undo %q", s) + } +} + +func TestTextInputClear(t *testing.T) { + s, changes := "draft", 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + if TextInput(c, &s, TextInputOptions{Label: "Draft", Clearable: true}).Changed() { + changes++ + } + }, 400, 200) + if err := tt.Click("Clear"); err != nil { + t.Fatal(err) + } + if s != "" || changes != 1 { + t.Fatalf("after clear %q, changes %d", s, changes) + } + if _, ok := tt.Find("Clear"); ok { + t.Fatal("clear button stays on an empty field") + } + tt.Type("again") + tt.Key(0, ui.KeyEscape) + if s != "" || changes != 3 { + t.Fatalf("after Escape %q, changes %d", s, changes) + } +} + +func TestTextInputReadOnlyAndDisabled(t *testing.T) { + ro, off := "fixed", "locked" + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Gap(8).Children(func() { + TextInput(c, &ro, TextInputOptions{Label: "RO", ReadOnly: true, Clearable: true}) + TextInput(c, &off, TextInputOptions{Label: "Off", Disabled: true}) + }) + }, 400, 200) + _ = tt.Click("RO") + tt.Command("selectAll") + tt.Command("copy") + tt.Type("zz") + tt.Key(0, ui.KeyBackspace) + if ro != "fixed" || tt.Clipboard() != "fixed" { + t.Fatalf("read-only value %q clipboard %q", ro, tt.Clipboard()) + } + if _, ok := tt.Find("Clear"); ok { + t.Fatal("read-only field offers clear") + } + _ = tt.Click("Off") + tt.Type("zz") + if off != "locked" || tt.Focused("Off") { + t.Fatalf("disabled value %q focused %v", off, tt.Focused("Off")) + } +} + +func TestTextInputSlotsAndError(t *testing.T) { + s := "x" + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + TextInput(c, &s, TextInputOptions{ + Label: "Price", + Leading: func() { ui.Text(c, "¥") }, + Trailing: func() { ui.Text(c, "CNY") }, + Error: "Not a price", + }) + }, 400, 200) + for _, want := range []string{"¥", "CNY", "Not a price"} { + if !tt.HasText(want) { + t.Fatalf("missing %q in %q", want, tt.Texts()) + } + } +} + +func TestTextInputSnapshot(t *testing.T) { + view := func(c *ui.Context) { + a, b, e, ro, dis := "", "Elisabeth", "1789-13-01", "Read only", "Disabled" + ui.Column(c).Padding(24).Gap(12).Width(360).Children(func() { + TextInput(c, &a, TextInputOptions{Placeholder: "Placeholder", Label: "A"}) + TextInput(c, &b, TextInputOptions{Label: "B", Clearable: true, Leading: func() { + ui.Icon(c, icons.Must("user")).Size(16, 16).TextColor(Tokens(c).TextMuted) + }}) + TextInput(c, &e, TextInputOptions{Label: "E", Error: "No such date"}) + TextInput(c, &ro, TextInputOptions{Label: "R", ReadOnly: true}) + TextInput(c, &dis, TextInputOptions{Label: "D", Disabled: true}) + }) + } + snapshot(t, "text_input", 420, 320, view) + buttonDensitySnapshots(t, "text_input", 420, 360, view) +}