diff --git a/packages/ui/src/data-display/line-comment/line-comment.stories.tsx b/packages/ui/src/data-display/line-comment/line-comment.stories.tsx index a4055afab33..60d05757f50 100644 --- a/packages/ui/src/data-display/line-comment/line-comment.stories.tsx +++ b/packages/ui/src/data-display/line-comment/line-comment.stories.tsx @@ -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 + } /> {result()} diff --git a/packages/ui/src/data-display/line-comment/line-comment.tsx b/packages/ui/src/data-display/line-comment/line-comment.tsx index ea8fcb7d52c..e920d601f03 100644 --- a/packages/ui/src/data-display/line-comment/line-comment.tsx +++ b/packages/ui/src/data-display/line-comment/line-comment.tsx @@ -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() }) } diff --git a/packages/ui/src/data-display/line-comment/machine.test.ts b/packages/ui/src/data-display/line-comment/machine.test.ts index 3baa9f54a1d..850809edbe8 100644 --- a/packages/ui/src/data-display/line-comment/machine.test.ts +++ b/packages/ui/src/data-display/line-comment/machine.test.ts @@ -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 } }) diff --git a/packages/ui/src/data-display/line-comment/machine.ts b/packages/ui/src/data-display/line-comment/machine.ts index ed580da902e..51a8bb599fe 100644 --- a/packages/ui/src/data-display/line-comment/machine.ts +++ b/packages/ui/src/data-display/line-comment/machine.ts @@ -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)