feat(workbench): 优化电商出品工作台

This commit is contained in:
ddcat666
2026-10-13 22:45:58 +08:00
parent f6b60a3855
commit 17e9f5ed4e
6 changed files with 1050 additions and 181 deletions

View File

@@ -138,7 +138,7 @@ export function ModelPicker({
window.requestAnimationFrame(() => {
const buttons = menuRef.current?.querySelectorAll<HTMLButtonElement>('[data-model-picker-item]:not(:disabled)');
const target = last ? buttons?.item((buttons?.length || 1) - 1) : buttons?.item(0);
target?.focus();
focusPickerOption(target);
});
};
const handleTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {
@@ -151,7 +151,7 @@ export function ModelPicker({
if (event.key === "Escape") {
event.preventDefault();
setOpen(false);
triggerRef.current?.focus();
triggerRef.current?.focus({ preventScroll: true });
return;
}
if (event.key === "ArrowLeft" && activeGroupKey !== null) {
@@ -166,7 +166,7 @@ export function ModelPicker({
event.preventDefault();
const activeIndex = buttons.indexOf(document.activeElement as HTMLButtonElement);
const nextIndex = event.key === "Home" ? 0 : event.key === "End" ? buttons.length - 1 : event.key === "ArrowUp" ? Math.max(0, activeIndex - 1) : Math.min(buttons.length - 1, activeIndex + 1);
buttons[nextIndex]?.focus();
focusPickerOption(buttons[nextIndex]);
};
const content = (
<div
@@ -265,6 +265,7 @@ export function ModelPicker({
placement="bottomLeft"
align={{ overflow: { adjustY: true, shiftX: true } }}
arrow={false}
motion={{ motionName: "" }}
content={content}
classNames={{
root: cn("canvas-model-picker-popover", "creation-model-picker-popover", popoverClassName),
@@ -296,6 +297,19 @@ export function ModelPicker({
);
}
function focusPickerOption(target: HTMLButtonElement | null | undefined) {
if (!target) return;
target.focus({ preventScroll: true });
// Only reveal the focused row inside its pane; scrolling portal ancestors moves the page.
const pane = target.closest<HTMLElement>(".canvas-model-picker-model-pane, .canvas-model-picker-menu");
if (!pane) return;
const row = target.getBoundingClientRect();
const top = pane.getBoundingClientRect().top + pane.clientTop;
const bottom = top + pane.clientHeight;
const delta = row.top < top ? row.top - top : row.bottom > bottom ? row.bottom - bottom : 0;
if (delta) pane.scrollTop += delta;
}
function emptyModelLabel(config: AiConfig, capability?: ModelCapability) {
const label = capability === "image" ? "生图" : capability === "video" ? "视频" : capability === "text" ? "文本" : capability === "audio" ? "音频" : "";
if (capability && config.models.length) return `暂无支持当前输入的${label}模型`;