Anchor sync menu below chevron

This commit is contained in:
Joe Julian
2026-04-07 21:25:56 -07:00
parent cbfbe3be14
commit 9b3f10f086
2 changed files with 54 additions and 19 deletions
+28 -9
View File
@@ -5667,8 +5667,7 @@ func (u *ui) syncButtonGroup(gtx layout.Context) layout.Dimensions {
if u.mode == "phone" { if u.mode == "phone" {
spacing = unit.Dp(3) spacing = unit.Dp(3)
} }
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, row := func(gtx layout.Context) layout.Dimensions {
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Alignment: layout.Middle}.Layout(gtx, return layout.Flex{Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return syncPrimaryButton(gtx, u.theme, &u.synchronizeVault, label, u.mode == "phone") return syncPrimaryButton(gtx, u.theme, &u.synchronizeVault, label, u.mode == "phone")
@@ -5678,14 +5677,26 @@ func (u *ui) syncButtonGroup(gtx layout.Context) layout.Dimensions {
return u.syncMenuToggle(gtx) return u.syncMenuToggle(gtx)
}), }),
) )
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
if !u.syncMenuOpen {
return layout.Dimensions{}
} }
return layout.Inset{Top: unit.Dp(6)}.Layout(gtx, u.syncMenu) rowDims := row(gtx)
}), if !u.syncMenuOpen {
) return rowDims
}
menuGTX := gtx
menuGTX.Constraints.Min = image.Point{}
menuOps := op.Record(gtx.Ops)
menuDims := layout.Inset{Top: unit.Dp(6)}.Layout(menuGTX, u.syncMenu)
menuCall := menuOps.Stop()
menuX := rowDims.Size.X - menuDims.Size.X
if menuX < 0 {
menuX = 0
}
stack := op.Offset(image.Pt(menuX, rowDims.Size.Y)).Push(gtx.Ops)
menuCall.Add(gtx.Ops)
stack.Pop()
return rowDims
} }
func (u *ui) syncMenuToggle(gtx layout.Context) layout.Dimensions { func (u *ui) syncMenuToggle(gtx layout.Context) layout.Dimensions {
@@ -7196,6 +7207,14 @@ func (u *ui) topRightActionOrder() []string {
return []string{"Sync", "Lock", "Menu"} return []string{"Sync", "Lock", "Menu"}
} }
func (u *ui) syncMenuDropsBelowTrigger() bool {
return true
}
func (u *ui) syncMenuRightAlignsToTrigger() bool {
return true
}
func detailLine(th *material.Theme, label, value string) layout.Widget { func detailLine(th *material.Theme, label, value string) layout.Widget {
return func(gtx layout.Context) layout.Dimensions { return func(gtx layout.Context) layout.Dimensions {
valueSize := unit.Sp(16) valueSize := unit.Sp(16)
+16
View File
@@ -324,6 +324,22 @@ func TestUITopRightActionOrderMatchesAcrossModes(t *testing.T) {
} }
} }
func TestUISyncMenuAnchorsMatchAcrossModes(t *testing.T) {
t.Parallel()
desktop := newUIWithSession("desktop", summarySession{hasVault: true})
desktop.state.Section = appstate.SectionEntries
phone := newUIWithSession("phone", summarySession{hasVault: true})
phone.state.Section = appstate.SectionEntries
if !desktop.syncMenuDropsBelowTrigger() || !phone.syncMenuDropsBelowTrigger() {
t.Fatal("sync menu should drop below trigger across desktop and phone")
}
if !desktop.syncMenuRightAlignsToTrigger() || !phone.syncMenuRightAlignsToTrigger() {
t.Fatal("sync menu should right-align to trigger across desktop and phone")
}
}
func TestUICurrentVaultSummary(t *testing.T) { func TestUICurrentVaultSummary(t *testing.T) {
t.Parallel() t.Parallel()