fix(ui): prevent plain comment clicks from sending prompts (#62070)

This commit is contained in:
usrnk1
2026-11-05 14:28:08 +01:00
committed by GitHub
Unverified
parent fa2843f270
commit 97be25f046
4 changed files with 51 additions and 6 deletions
@@ -71,13 +71,15 @@ export const DisplayMultiline = {
}
export const Editor = {
args: { variant: "default", allowEmpty: false },
args: { variant: "default", allowEmpty: false, alternateSubmit: false },
argTypes: {
variant: { control: "select", options: ["default", "compact"] },
allowEmpty: { control: "boolean" },
alternateSubmit: { control: "boolean" },
},
render: (args) => {
const [value, setValue] = createSignal("")
const [result, setResult] = createSignal("")
return (
@@ -95,6 +97,18 @@ export const Editor = {
setValue("")
setResult(`Submitted: ${comment}`)
}}
alternateSubmit={
args.alternateSubmit
? {
label: "Send",
keys: ["Ctrl", "Enter"],
onSubmit: (comment) => {
setValue("")
setResult(`Sent: ${comment}`)
},
}
: undefined
}
/>
<output aria-label="Editor result">{result()}</output>
</div>
@@ -453,6 +453,9 @@ export function LineCommentEditor(props: LineCommentEditorProps) {
onPointerEnter={(event) =>
dispatch({ type: "modifier.changed", active: modified(event), config: readConfig() })
}
onPointerDown={(event) =>
dispatch({ type: "modifier.changed", active: modified(event), config: readConfig() })
}
onClick={(event) =>
dispatch({ type: "action.clicked", modified: modified(event), config: readConfig() })
}
@@ -238,7 +238,7 @@ describe("line comment editor machine", () => {
expect(done.state.status).toBe("editing")
})
test("the alternate submit follows the held modifier and clears on blur or when it goes away", () => {
test("click submission ignores stale modifiers", () => {
const settings = config({ value: "Ship it", alternateSubmit: { disabled: false } })
const held = transitionLineCommentEditor(createLineCommentEditorState(), {
@@ -250,7 +250,7 @@ describe("line comment editor machine", () => {
expect(viewLineCommentEditor(held.state, settings).alternateActive).toBe(true)
expect(
transitionLineCommentEditor(held.state, { type: "action.clicked", modified: false, config: settings }).effects,
).toEqual([{ type: "submit", mode: "alternate", value: "Ship it" }])
).toEqual([{ type: "submit", mode: "primary", value: "Ship it" }])
// Entering the action without the modifier clears a stale hold.
const entered = transitionLineCommentEditor(held.state, {
@@ -281,6 +281,35 @@ describe("line comment editor machine", () => {
expect(unsupported.state).toMatchObject({ alternate: false })
})
test("a modified click uses the alternate submit without a tracked modifier", () => {
const settings = config({ value: "Ship it", alternateSubmit: { disabled: false } })
expect(
transitionLineCommentEditor(createLineCommentEditorState(), {
type: "action.clicked",
modified: true,
config: settings,
}).effects,
).toEqual([{ type: "submit", mode: "alternate", value: "Ship it" }])
})
test.each([false, true])("empty draft clicks use the event modifier (tracked: %s)", (active) => {
const settings = config({ alternateSubmit: { disabled: false } })
const held = transitionLineCommentEditor(createLineCommentEditorState(), {
type: "modifier.changed",
active,
config: settings,
})
expect(
transitionLineCommentEditor(held.state, { type: "action.clicked", modified: false, config: settings }).effects,
).toEqual([{ type: "cancel", blur: false }])
expect(
transitionLineCommentEditor(held.state, { type: "action.clicked", modified: true, config: settings }).effects,
).toEqual([])
})
test("Mod+Enter with the list open sends through the alternate submit", () => {
const settings = config({ value: "@src", alternateSubmit: { disabled: false } })
@@ -176,12 +176,11 @@ export function transitionLineCommentEditor(
}
if (event.type === "action.clicked") {
const alternate = state.alternate && allowsAlternate(event.config)
const alternate = event.modified && event.config.alternateSubmit !== null
// An empty compact editor's action cancels, unless Mod turned it into the alternate submit.
if (!alternate && !canSubmit(event.config)) return cancel(state, false)
return submit(state, event.config, alternate || (event.modified && event.config.alternateSubmit !== null))
return submit(state, event.config, alternate)
}
if (event.type === "submit.requested") return submit(state, event.config, false)