Fix enter key loop in sweep commands (#7112)

* use effect for focus of command palette submit button, not autoFocus

autoFocus is being overridden by the Headless UI Dialog component's
focus management here
https://headlessui.com/v1/react/dialog#focus-management (we do not have
access to pass back initialFocus in this case). So we can use an effect
to imperatively focus the button when this component is mounted.

* Update sweep tests to submit the command with Enter
This commit is contained in:
Frank Noirot
2025-05-20 12:04:56 -04:00
committed by GitHub
parent 511334683a
commit 597f1087f9
3 changed files with 30 additions and 11 deletions

View File

@ -105,14 +105,19 @@ export class CmdBarFixture {
expectState = async (expected: CmdBarSerialised) => {
return expect.poll(() => this._serialiseCmdBar()).toEqual(expected)
}
/** The method will use buttons OR press enter randomly to progress the cmdbar,
* this could have unexpected results depending on what's focused
*
* TODO: This method assumes the user has a valid input to the current stage,
/**
* This method is used to progress the command bar to the next step, defaulting to clicking the next button.
* Optionally, with the `shouldUseKeyboard` parameter, it will hit `Enter` to progress.
* * TODO: This method assumes the user has a valid input to the current stage,
* and assumes we are past the `pickCommand` step.
*/
progressCmdBar = async (shouldFuzzProgressMethod = true) => {
progressCmdBar = async (shouldUseKeyboard = false) => {
await this.page.waitForTimeout(2000)
if (shouldUseKeyboard) {
await this.page.keyboard.press('Enter')
return
}
const arrowButton = this.page.getByRole('button', {
name: 'arrow right Continue',
})

View File

@ -1855,7 +1855,11 @@ sketch002 = startSketchOn(XZ)
},
stage: 'review',
})
await cmdBar.progressCmdBar()
// Confirm we can submit from the review step with just `Enter`
await cmdBar.progressCmdBar(true)
await cmdBar.expectState({
stage: 'commandBarClosed',
})
})
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
@ -1995,7 +1999,7 @@ profile001 = ${circleCode}`
},
stage: 'review',
})
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar(true)
await editor.expectEditor.toContain(sweepDeclaration)
})

View File

@ -1,4 +1,5 @@
import React, { useMemo, useState } from 'react'
import type React from 'react'
import { useMemo, useEffect, useRef, useState } from 'react'
import { useHotkeys } from 'react-hotkeys-hook'
import { ActionButton } from '@src/components/ActionButton'
@ -121,6 +122,7 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
data-is-current-arg={
argName === currentArgument?.name ? 'true' : 'false'
}
type="button"
disabled={!isReviewing && currentArgument?.name === argName}
onClick={() => {
commandBarActor.send({
@ -244,13 +246,20 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
type ButtonProps = { bgClassName?: string; iconClassName?: string }
function ReviewingButton({ bgClassName, iconClassName }: ButtonProps) {
const buttonRef = useRef<HTMLButtonElement>(null)
useEffect(() => {
if (buttonRef.current) {
buttonRef.current.focus()
}
}, [])
return (
<ActionButton
Element="button"
autoFocus
ref={buttonRef}
type="submit"
form="review-form"
className="w-fit !p-0 rounded-sm hover:shadow"
className="w-fit !p-0 rounded-sm hover:shadow focus:outline-current"
tabIndex={0}
data-testid="command-bar-submit"
iconStart={{
icon: 'checkmark',
@ -269,7 +278,8 @@ function GatheringArgsButton({ bgClassName, iconClassName }: ButtonProps) {
Element="button"
type="submit"
form="arg-form"
className="w-fit !p-0 rounded-sm hover:shadow"
className="w-fit !p-0 rounded-sm hover:shadow focus:outline-current"
tabIndex={0}
data-testid="command-bar-continue"
iconStart={{
icon: 'arrowRight',