The safety layer: two presses for anything you cannot take back

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-25 00:39:07 -04:00
parent 8b1205e4b8
commit 88371d19f0
17 changed files with 447 additions and 36 deletions
@@ -17,6 +17,31 @@ Rectangle {
implicitHeight: 31
radius: 9
opacity: enabled ? 1 : 0.45
// The keyboard half of this component's own contract. Eleven files used
// to bolt these on by hand while the other hundred-odd instantiations --
// including every confirming button in every destructive flow -- were
// pointer-only. The button carries them itself now, so a consumer cannot
// forget them.
activeFocusOnTab: root.enabled
Accessible.role: Accessible.Button
Accessible.name: root.text
Accessible.focusable: root.enabled
Accessible.focused: root.activeFocus
Accessible.onPressAction: root.clicked()
Keys.onReturnPressed: root.clicked()
Keys.onEnterPressed: root.clicked()
Keys.onSpacePressed: root.clicked()
Rectangle {
anchors.fill: parent
anchors.margins: -3
radius: parent.radius + 3
visible: root.activeFocus
color: "transparent"
border.width: 2
border.color: Theme.accentSecondary
}
color: {
if (tone === "accent")
return mouse.containsMouse ? Theme.mix(Theme.accent, Theme.fg, 0.12) : Theme.accent;