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 [slashBlockId, setSlashBlockId] = useState<string | null>(null);
|
||||||
const [slashSearch, setSlashSearch] = useState('');
|
const [slashSearch, setSlashSearch] = useState('');
|
||||||
const [slashSelectedIndex, setSlashSelectedIndex] = useState(0);
|
const [slashSelectedIndex, setSlashSelectedIndex] = useState(0);
|
||||||
|
const slashMenuRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
// Drag and Drop reordering state for blocks
|
// Drag and Drop reordering state for blocks
|
||||||
const [draggingBlockId, setDraggingBlockId] = useState<string | null>(null);
|
const [draggingBlockId, setDraggingBlockId] = useState<string | null>(null);
|
||||||
@@ -933,6 +934,12 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
ensureLock();
|
ensureLock();
|
||||||
|
|
||||||
if (slashBlockId === block.id) {
|
if (slashBlockId === block.id) {
|
||||||
|
if (filteredSlashCommands.length === 0) {
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
setSlashBlockId(null);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (e.key === 'ArrowDown') {
|
if (e.key === 'ArrowDown') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setSlashSelectedIndex((prev) => (prev + 1) % filteredSlashCommands.length);
|
setSlashSelectedIndex((prev) => (prev + 1) % filteredSlashCommands.length);
|
||||||
@@ -1010,6 +1017,27 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
);
|
);
|
||||||
}, [slashSearch]);
|
}, [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) => {
|
const applySlashCommand = (blockId: string, type: BlockType) => {
|
||||||
if (isReadOnly || !selectedDoc) return;
|
if (isReadOnly || !selectedDoc) return;
|
||||||
const block = selectedDoc.blocks.find((b) => b.id === blockId);
|
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">
|
<div className="px-2 py-1 text-[10px] text-faint font-semibold uppercase tracking-wider border-b border-border">
|
||||||
Block-Typ wählen:
|
Block-Typ wählen:
|
||||||
</div>
|
</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) => (
|
{filteredSlashCommands.map((cmd, idx) => (
|
||||||
<button
|
<button
|
||||||
key={cmd.type}
|
key={cmd.type}
|
||||||
type="button"
|
type="button"
|
||||||
|
data-slash-index={idx}
|
||||||
onMouseDown={(e) => e.preventDefault()}
|
onMouseDown={(e) => e.preventDefault()}
|
||||||
onClick={() => applySlashCommand(block.id, cmd.type)}
|
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 ${
|
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