A delete button that only fires while Shift is held. A plain click shakes it harder each time and pops a hint with a pressing keycap; holding Shift turns it into a striped red button.
npx shadcn@latest add https://hyperblur.dev/r/button-shift-arm.jsonWorks in any React project set up with the shadcn CLI. The file lands in components/hyperblur/button-shift-arm.tsx.
import { ButtonShiftArm } from "@/components/hyperblur/button-shift-arm"
<ButtonShiftArm onConfirm={() => deleteBranch("feature/checkout-v2")} />| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | "Delete branch" | Label in the safe state. |
| armedLabel | ReactNode | "Delete forever" | Label while Shift is held over the button. |
| doneLabel | ReactNode | "Branch deleted" | Label after confirming. |
| hint | ReactNode | "to delete" | Text after the Shift keycap in the hint bubble. |
| touchFallback | boolean | true | On touch screens a second tap while the hint is visible confirms, since there is no Shift key. |
| onBlocked | (attempts: number) => void | undefined | Called on each click without Shift. |
| onConfirm | () => void | undefined | Called on a Shift click. |
| accent | string | "#ef4444" | Danger color used for fills, glows and the focus ring. |
| size | "sm" | "md" | "lg" | "md" | Height and font size preset. |
| resetAfter | number | 2400 | Milliseconds before the finished state returns to the start. Use 0 to keep the finished state. |
| disabled | boolean | false | Blocks every interaction and dims the control. |