fix(workspace): auto-scroll slash command popup when navigating with arrow keys
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 55s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 55s
This commit is contained in:
1 parent
290848a93e
commit
ec79a2493e
1 file changed
+30
-1
@@ -128,6 +128,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
const [slashBlockId, setSlashBlockId] = useState<string | null>(null);
|
||||
const [slashSearch, setSlashSearch] = useState('');
|
||||
const [slashSelectedIndex, setSlashSelectedIndex] = useState(0);
|
||||
const slashMenuRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
// Drag and Drop reordering state for blocks
|
||||
const [draggingBlockId, setDraggingBlockId] = useState<string | null>(null);
|
||||
@@ -933,6 +934,12 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
ensureLock();
|
||||
|
||||
if (slashBlockId === block.id) {
|
||||
if (filteredSlashCommands.length === 0) {
|
||||
if (e.key === 'Escape') {
|
||||
setSlashBlockId(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
setSlashSelectedIndex((prev) => (prev + 1) % filteredSlashCommands.length);
|
||||
@@ -1010,6 +1017,27 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
);
|
||||
}, [slashSearch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (slashBlockId && slashMenuRef.current) {
|
||||
const container = slashMenuRef.current;
|
||||
const activeBtn = container.querySelector<HTMLElement>(
|
||||
`[data-slash-index="${slashSelectedIndex}"]`
|
||||
);
|
||||
if (activeBtn) {
|
||||
const itemTop = activeBtn.offsetTop;
|
||||
const itemBottom = itemTop + activeBtn.offsetHeight;
|
||||
const containerTop = container.scrollTop;
|
||||
const containerBottom = containerTop + container.clientHeight;
|
||||
|
||||
if (itemTop < containerTop) {
|
||||
container.scrollTop = itemTop;
|
||||
} else if (itemBottom > containerBottom) {
|
||||
container.scrollTop = itemBottom - container.clientHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [slashSelectedIndex, slashBlockId]);
|
||||
|
||||
const applySlashCommand = (blockId: string, type: BlockType) => {
|
||||
if (isReadOnly || !selectedDoc) return;
|
||||
const block = selectedDoc.blocks.find((b) => b.id === blockId);
|
||||
@@ -2431,11 +2459,12 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
<div className="px-2 py-1 text-[10px] text-faint font-semibold uppercase tracking-wider border-b border-border">
|
||||
Block-Typ wählen:
|
||||
</div>
|
||||
<div className="max-h-48 overflow-y-auto space-y-0.5">
|
||||
<div ref={slashMenuRef} className="relative max-h-48 overflow-y-auto space-y-0.5">
|
||||
{filteredSlashCommands.map((cmd, idx) => (
|
||||
<button
|
||||
key={cmd.type}
|
||||
type="button"
|
||||
data-slash-index={idx}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
onClick={() => applySlashCommand(block.id, cmd.type)}
|
||||
className={`w-full text-left px-2 py-1.5 rounded-btn text-xs flex items-center justify-between transition-colors ${
|
||||
|
||||
Reference in new issue
Block a user