refactor: centralize multi-card bring-to-front logic and document new spatial workspace architecture.
This commit is contained in:
@@ -274,7 +274,6 @@ export class LayoutStore {
|
|||||||
const dx = card.x - x;
|
const dx = card.x - x;
|
||||||
const dy = card.y - y;
|
const dy = card.y - y;
|
||||||
|
|
||||||
// Check if center is within inner radius of top card
|
|
||||||
// Use squared distance to avoid sqrt
|
// Use squared distance to avoid sqrt
|
||||||
const distSq = dx * dx + dy * dy;
|
const distSq = dx * dx + dy * dy;
|
||||||
if (distSq < radius * radius) {
|
if (distSq < radius * radius) {
|
||||||
@@ -296,6 +295,20 @@ export class LayoutStore {
|
|||||||
.map(c => c.id);
|
.map(c => c.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bringToFront(ids: string[]) {
|
||||||
|
const cards = ids
|
||||||
|
.map(id => this.items.get(id))
|
||||||
|
.filter((c): c is LayoutCard => !!c);
|
||||||
|
|
||||||
|
// Sort by current Z-index to preserve relative order
|
||||||
|
cards.sort((a, b) => a.z - b.z);
|
||||||
|
|
||||||
|
// Assign new Z-indices
|
||||||
|
for (const card of cards) {
|
||||||
|
card.update({ z: this.zCounter++ });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getSnapshot() {
|
getSnapshot() {
|
||||||
return Array.from(this.items.values()).map(card => card.toSnapshot());
|
return Array.from(this.items.values()).map(card => card.toSnapshot());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,16 +51,30 @@ export const useCardPointer = (
|
|||||||
|
|
||||||
if (state === 'drag-start') {
|
if (state === 'drag-start') {
|
||||||
let effectiveSelection = selection;
|
let effectiveSelection = selection;
|
||||||
if (!isSelected) {
|
|
||||||
onSelect([card.id], hasModifier);
|
if (!hasModifier) {
|
||||||
if (hasModifier) {
|
if (!isSelected) {
|
||||||
effectiveSelection = [...selection, card.id];
|
|
||||||
} else {
|
|
||||||
effectiveSelection = [card.id];
|
effectiveSelection = [card.id];
|
||||||
|
onSelect([card.id], false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Modifier pressed: Add card and stack to selection
|
||||||
|
const stackIds = card.store.getStackBelow(card);
|
||||||
|
const idsToAdd = new Set<string>();
|
||||||
|
|
||||||
|
if (!isSelected) idsToAdd.add(card.id);
|
||||||
|
stackIds.forEach(id => idsToAdd.add(id));
|
||||||
|
|
||||||
|
// Only select what isn't already selected to avoid toggling off
|
||||||
|
const unselectedIdsToAdd = Array.from(idsToAdd).filter(id => !selection.includes(id));
|
||||||
|
|
||||||
|
if (unselectedIdsToAdd.length > 0) {
|
||||||
|
onSelect(unselectedIdsToAdd, true);
|
||||||
|
effectiveSelection = [...selection, ...unselectedIdsToAdd];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
card.bringToFront();
|
card.store.bringToFront(effectiveSelection);
|
||||||
|
|
||||||
setState('drag');
|
setState('drag');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user