({
definition,
overrides,
currentBinding,
onClose,
onSave
}: {
definition: KeymapDefinition
overrides: KeymapOverrides
currentBinding: string
onClose: () => void
onSave: (binding: string) => void
})
| 3670 | } |
| 3671 | |
| 3672 | function KeymapRecorderModal({ |
| 3673 | definition, |
| 3674 | overrides, |
| 3675 | currentBinding, |
| 3676 | onClose, |
| 3677 | onSave |
| 3678 | }: { |
| 3679 | definition: KeymapDefinition |
| 3680 | overrides: KeymapOverrides |
| 3681 | currentBinding: string |
| 3682 | onClose: () => void |
| 3683 | onSave: (binding: string) => void |
| 3684 | }): JSX.Element { |
| 3685 | const [binding, setBinding] = useState(currentBinding) |
| 3686 | const mac = isMacPlatform() |
| 3687 | // Block saving a global shortcut that another action already owns (#298). |
| 3688 | const conflict = binding ? findKeymapConflict(overrides, definition.id, binding) : null |
| 3689 | |
| 3690 | useEffect(() => { |
| 3691 | const onKey = (event: KeyboardEvent): void => { |
| 3692 | const target = event.target as HTMLElement | null |
| 3693 | if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA')) return |
| 3694 | const key = event.key |
| 3695 | if (key === 'Backspace' || key === 'Delete') { |
| 3696 | event.preventDefault() |
| 3697 | event.stopPropagation() |
| 3698 | if (definition.kind === 'shortcut') { |
| 3699 | setBinding('') |
| 3700 | return |
| 3701 | } |
| 3702 | setBinding((current) => { |
| 3703 | const tokens = current.split(/\s+/).filter(Boolean) |
| 3704 | tokens.pop() |
| 3705 | return tokens.join(' ') |
| 3706 | }) |
| 3707 | return |
| 3708 | } |
| 3709 | |
| 3710 | const next = |
| 3711 | definition.kind === 'shortcut' |
| 3712 | ? shortcutBindingFromEvent(event) |
| 3713 | : sequenceTokenFromEvent(event) |
| 3714 | if (!next) return |
| 3715 | |
| 3716 | event.preventDefault() |
| 3717 | event.stopPropagation() |
| 3718 | |
| 3719 | if (definition.kind === 'shortcut') { |
| 3720 | setBinding(next) |
| 3721 | return |
| 3722 | } |
| 3723 | |
| 3724 | setBinding((current) => { |
| 3725 | const limit = definition.maxTokens ?? 2 |
| 3726 | const tokens = current.split(/\s+/).filter(Boolean) |
| 3727 | if (limit <= 1) return next |
| 3728 | if (tokens.length >= limit) return next |
| 3729 | return [...tokens, next].join(' ') |
nothing calls this directly
no test coverage detected