mirror of
https://github.com/unslothai/unsloth.git
synced 2026-10-21 22:12:39 +00:00
Studio: delete selected recipe blocks with the Delete key (#14223)
Fixes https://github.com/unslothai/unsloth/issues/9211 (the "couldn't
find a way to remove a node" part).
## Problem
The Data Recipes canvas only deletes a selected block with Backspace,
which is React Flow's default `deleteKeyCode`. On Windows and most Linux
keyboards people press Delete to remove things, and on the Data Recipes
canvas Delete does nothing. There is also no visible delete button, so
users conclude blocks cannot be removed at all (see the comment on #9211
from a Windows 10 / Edge user).
## Change
Pass `deleteKeyCode={["Backspace", "Delete"]}` to the recipe canvas, as
a module-level constant so React Flow's key listener is not
re-subscribed on every render.
- Backspace keeps working exactly as before (macOS users are
unaffected).
- Delete now removes the selected blocks and edges through the same
React Flow path Backspace already uses, so node removal, edge cleanup
and the store's removal helpers are unchanged.
- Typing in inputs, textareas and editors is unaffected: React Flow
ignores the delete key while focus is in an editable element, same as
for Backspace today.
- No UI changes, no new buttons, no flow changes.
## Tests
- `tests/recipe-canvas-delete-keys.test.ts`: fails on main (constant
missing) and when only the canvas wiring is reverted, passes with the
change.
- Typecheck clean; eslint / biome diagnostics on the touched source
files are identical to main.
## Before / after
Two fresh Studio installs (merge base `a33463f` vs this branch), the
"Text to SQL" learning recipe opened fresh on each, one block selected,
then the key pressed. Node counts are read from the canvas DOM.
| | Chromium | Firefox | WebKit |
|---|---|---|---|
| Delete removes the selected block, before | no | no | no |
| Delete removes the selected block, after | yes | yes | yes |
| Backspace removes the selected block, before and after | yes | yes |
yes |
| Delete while typing in a block's inline field keeps the block, before
and after | not exercised (no block selected) | yes | yes |

Before: the selected block on the right edge (and its dashed link) is
still there after pressing Delete. After: it is removed.
This commit is contained in:
parent
e632df1ca6
commit
f5e91f1ca5
3 changed files with 22 additions and 0 deletions
|
|
@ -6,3 +6,5 @@ export const DEFAULT_NODE_HEIGHT = 120;
|
|||
export const MIN_NODE_WIDTH = 260;
|
||||
export const MAX_NODE_WIDTH = 900;
|
||||
export const MAX_NOTE_NODE_WIDTH = 600;
|
||||
// React Flow deletes on Backspace only; Windows and Linux keyboards reach for Delete (#9211).
|
||||
export const CANVAS_DELETE_KEYS = ["Backspace", "Delete"];
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { GuidedTour, useGuidedTourController } from "@/features/tour";
|
||||
import { buildRecipeEditorTourSteps } from "./tour";
|
||||
import { BlockSheet } from "./components/block-sheet";
|
||||
import { CANVAS_DELETE_KEYS } from "./constants";
|
||||
import { LayoutControls } from "./components/controls/layout-controls";
|
||||
import { RunValidateFloatingControls } from "./components/controls/run-validate-floating-controls";
|
||||
import { ViewportControls } from "./components/controls/viewport-controls";
|
||||
|
|
@ -669,6 +670,7 @@ export function RecipeStudioPage({
|
|||
onConnect={onConnect}
|
||||
onNodeClick={handleNodeClick}
|
||||
onNodeDoubleClick={handleNodeDoubleClick}
|
||||
deleteKeyCode={CANVAS_DELETE_KEYS}
|
||||
isValidConnection={isValidConnection}
|
||||
onMoveEnd={(event) => {
|
||||
if (event) {
|
||||
|
|
|
|||
18
studio/frontend/tests/recipe-canvas-delete-keys.test.ts
Normal file
18
studio/frontend/tests/recipe-canvas-delete-keys.test.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { test } from "node:test";
|
||||
|
||||
import { CANVAS_DELETE_KEYS } from "../src/features/recipe-studio/constants.ts";
|
||||
import { readSrc } from "./helpers/kit.ts";
|
||||
|
||||
test("recipe canvas deletes selected blocks on Delete as well as Backspace", () => {
|
||||
assert.deepEqual([...CANVAS_DELETE_KEYS].sort(), ["Backspace", "Delete"]);
|
||||
const src = readSrc("features/recipe-studio/recipe-studio-page.tsx");
|
||||
const canvas = src.slice(src.indexOf("<ReactFlow<"));
|
||||
assert.match(
|
||||
canvas.slice(0, canvas.indexOf("\n >\n")),
|
||||
/\bdeleteKeyCode=\{CANVAS_DELETE_KEYS\}/,
|
||||
);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue