Dev #9
No files matched your search
@@ -598,7 +598,7 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
|||||||
block.collapsed && hasChildren
|
block.collapsed && hasChildren
|
||||||
? 'bg-accent ring-2 ring-accent/30'
|
? 'bg-accent ring-2 ring-accent/30'
|
||||||
: activeFocus
|
: activeFocus
|
||||||
? 'bg-accent scale-125'
|
? 'bg-main scale-125'
|
||||||
: 'bg-faint group-hover/bullet:bg-accent group-hover/bullet:scale-125'
|
: 'bg-faint group-hover/bullet:bg-accent group-hover/bullet:scale-125'
|
||||||
} ${
|
} ${
|
||||||
isEmpty
|
isEmpty
|
||||||
|
|||||||
@@ -525,24 +525,37 @@ export const OutlinerTree = forwardRef<OutlinerTreeHandle, OutlinerTreeProps>(({
|
|||||||
const handleMergeWithPrevious = useCallback(
|
const handleMergeWithPrevious = useCallback(
|
||||||
(blockId: string, content: string) => {
|
(blockId: string, content: string) => {
|
||||||
if (!canEdit) return false;
|
if (!canEdit) return false;
|
||||||
const mergeable = ['text', 'paragraph', 'bullet', 'todo', 'h1', 'h2', 'h3', 'callout'];
|
const notMergeable = ['code', 'divider', 'table', 'progress'];
|
||||||
const visIdx = visibleEntries.findIndex((e) => e.block.id === blockId);
|
const visIdx = visibleEntries.findIndex((e) => e.block.id === blockId);
|
||||||
if (visIdx <= 0) return false;
|
if (visIdx <= 0) return false;
|
||||||
const prev = visibleEntries[visIdx - 1].block;
|
const prev = visibleEntries[visIdx - 1].block;
|
||||||
const idx = blocks.findIndex((b) => b.id === blockId);
|
const idx = blocks.findIndex((b) => b.id === blockId);
|
||||||
const cur = blocks[idx];
|
const cur = blocks[idx];
|
||||||
if (!cur || !mergeable.includes(prev.type) || !mergeable.includes(cur.type)) return false;
|
if (!cur || notMergeable.includes(prev.type) || notMergeable.includes(cur.type)) return false;
|
||||||
// Blocks with children would leave them orphaned at a wrong indent level
|
|
||||||
const next = blocks[idx + 1];
|
// Children of the merged block move up so they become children of the previous block
|
||||||
if (next && (next.level || 0) > (cur.level || 0)) return false;
|
const curLevel = Math.max(0, cur.level || 0);
|
||||||
|
const delta = Math.max(0, prev.level || 0) - curLevel;
|
||||||
|
const movedChildren: DocumentBlock[] = [];
|
||||||
|
for (let j = idx + 1; j < blocks.length; j++) {
|
||||||
|
const lvl = Math.max(0, blocks[j].level || 0);
|
||||||
|
if (lvl <= curLevel) break;
|
||||||
|
movedChildren.push({ ...blocks[j], level: Math.max(levelOffset || 0, lvl + delta) });
|
||||||
|
}
|
||||||
|
|
||||||
const joinPos = (prev.content || '').length;
|
const joinPos = (prev.content || '').length;
|
||||||
onUpdateBlock({ ...prev, content: (prev.content || '') + content }, true);
|
const mergedPrev: DocumentBlock = { ...prev, content: (prev.content || '') + content };
|
||||||
|
if (movedChildren.length > 0 && onUpdateBlocks) {
|
||||||
|
onUpdateBlocks([mergedPrev, ...movedChildren]);
|
||||||
|
} else {
|
||||||
|
onUpdateBlock(mergedPrev, true);
|
||||||
|
movedChildren.forEach((c) => onUpdateBlock(c));
|
||||||
|
}
|
||||||
onDeleteBlock(cur.id);
|
onDeleteBlock(cur.id);
|
||||||
focusBlockInput(prev.id, joinPos);
|
focusBlockInput(prev.id, joinPos);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[blocks, canEdit, focusBlockInput, onDeleteBlock, onUpdateBlock, visibleEntries]
|
[blocks, canEdit, focusBlockInput, levelOffset, onDeleteBlock, onUpdateBlock, onUpdateBlocks, visibleEntries]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleIndentBlock = useCallback(
|
const handleIndentBlock = useCallback(
|
||||||
|
|||||||
Reference in new issue
Block a user