Keep marking the copy source's first cell after the selection moves on
Copying a range showed the dashed marquee around the whole source, but the distinct border on its first (anchor) cell disappeared the moment you selected something else -- that border was drawn from the *live* selection's anchor, which had just moved to the new (paste-destination) cell. - ClipboardData now also stores the copy/cut selection's own anchor -- the cell the drag/shift-selection actually started from, which isn't always rect's top-left corner (a drag can start at any corner). - clipboardRect exposes it; TableGrid renders a second small overlay, .clip-anchor, positioned on just that one cell -- independent of the current selection, so it stays visible for as long as the marquee does. Verified interactively: copy B2:B5, click a cell elsewhere -- the marquee and the solid border on B2 both remain, while the new cell gets its own live-selection border. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -137,6 +137,20 @@ const clipMarqueeStyle = computed(() => {
|
||||
height: rowTop(k.r1 + 1) - top + 'px',
|
||||
};
|
||||
});
|
||||
/** The copy/cut selection's *own* first cell, called out inside the marquee
|
||||
* even once the live selection has moved on to pick a paste destination
|
||||
* (which is when `is-active` no longer sits there). */
|
||||
const clipAnchorStyle = computed(() => {
|
||||
const k = clipRect.value;
|
||||
if (!k || k.tableId !== props.tableId) return null;
|
||||
const { col, row } = k.anchor;
|
||||
return {
|
||||
left: colLeft(col) + 'px',
|
||||
top: rowTop(row) + 'px',
|
||||
width: colWidth(col) + 'px',
|
||||
height: rowH(row) + 'px',
|
||||
};
|
||||
});
|
||||
|
||||
const clampC = (c: number) => Math.max(0, Math.min((table.value?.cols ?? 1) - 1, c));
|
||||
const clampR = (r: number) => Math.max(0, Math.min((table.value?.rows ?? 1) - 1, r));
|
||||
@@ -771,6 +785,7 @@ defineExpose({
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-if="clipMarqueeStyle" class="clip-marquee" :style="clipMarqueeStyle" />
|
||||
<div v-if="clipAnchorStyle" class="clip-anchor" :style="clipAnchorStyle" />
|
||||
</div>
|
||||
|
||||
<ContextMenu v-model:open="menu.open" :x="menu.x" :y="menu.y" :items="menuItems" />
|
||||
@@ -909,6 +924,14 @@ defineExpose({
|
||||
opacity: 0.45;
|
||||
}
|
||||
}
|
||||
/* the copy/cut selection's own first cell -- called out inside the marquee
|
||||
even once the live selection has moved elsewhere to pick a paste target */
|
||||
.clip-anchor {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
box-shadow: inset 0 0 0 2px var(--accent);
|
||||
z-index: 8;
|
||||
}
|
||||
.handle {
|
||||
position: absolute;
|
||||
right: -3px;
|
||||
|
||||
Reference in New Issue
Block a user