#1311: window.panel.dock rejects an edge zone without anchor or side

A zone is a side of the anchor. Without anchor or side, craft-ui would
make a frame on the outer edge of DesignCraft's root, which splits the
canvas; the error names anchor and side instead.
This commit is contained in:
aiongg
2026-10-20 18:01:17 +00:00
parent c75ff9d32c
commit 9e633b06b8
3 changed files with 13 additions and 1 deletions
+5
View File
@@ -491,6 +491,11 @@ fn shared_command(app: &mut DesignApp, id: &str, params: &Value) -> Result<Value
DockCommand::Window { .. } => return Err("DesignCraft does not move panels to their own windows".into()),
_ => {}
}
// A zone is a side of `anchor`. DesignCraft's docks are columns beside the canvas, so a dock at
// a window edge is a `side`, not a frame on the outer edge (craft-ui's `Placement::Edge`).
if let DockCommand::Dock { anchor: None, side: None, zone: Some(_), .. } = &command {
return Err("zone needs an anchor: dock beside a panel with anchor, or in a new dock column with side (Start or End)".into());
}
let rtl = crate::i18n::is_rtl(&app.ui.language);
let space = float_space(app);
let mut txn = Transaction::begin(app)?;
@@ -997,10 +997,15 @@ fn shared_panel_commands_float_dock_and_reject_atomically() {
("window.panel.window", json!({"panel": "pages"})),
("window.panel.move", json!({"panel": "stroke", "anchor": "pages", "zone": "left", "before": "pages"})),
("window.panel.dock", json!({"panel": "stroke", "side": "Middle"})),
("window.panel.dock", json!({"panel": "stroke", "zone": "left"})),
("window.dockPanel", json!({"panel": "properties", "zone": "bottom"})),
] {
assert!(app.run(id, params).is_err(), "{id}");
assert_eq!((app.ui.docking.clone(), app.ui.docking_hidden.clone()), before, "{id}");
}
// A zone is a side of an anchor; the error names the two ways to say where.
let error = app.run("window.panel.dock", json!({"panel": "stroke", "zone": "right"})).unwrap_err();
assert!(error.contains("anchor") && error.contains("side"), "{error}");
// Every shared id is registered for the command list and MCP.
for id in craft_ui::docking::DockCommand::<String>::IDS {
assert!(crate::menus::UI_COMMANDS.iter().any(|c| c.0 == *id), "{id} is not registered");
+3 -1
View File
@@ -116,7 +116,9 @@ read as `anchor`.
rect unless the params change it.
- `window.panel.dock {panel, anchor?, zone?, before?, group?, column?, side?}` (and
`window.dockPanel`) docks beside `anchor`, or in a new column of the dock at `side`
(`Start` or `End`; a new dock when there is none). Without either, a panel that floated from
(`Start` or `End`; a new dock when there is none). A panel that already leads that dock's
last column stays where it is. `zone` places the panel beside `anchor`, so a `zone` without
`anchor` or `side` is an error. Without `anchor` and `side`, a panel that floated from
the dock goes back to that place, and another floating panel joins the first dock group. For
the float-only Tabs panel (`tabs`), which has its own window outside the layout, float opens
that window and dock closes it.