Dev #2

Merged
sandrodach merged 37 commits from dev into main 2026-10-25 12:14:23 +01:00
Showing only changes of commit ec79a2493e - Show all commits
@@ -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 ${