Skip to content
SortableGuides

Copy and Clone

comins-sortable@0.1.6

Playground paths below are local routes for the module repository’s development server. They are not live routes on this documentation site.

Return copy from a source group’s pull policy and provide a factory that creates a new stable ID. The source array remains unchanged.

The original source item remains rendered in its list during the drag. A separate drag preview follows the pointer and only the destination placeholder marks the pending copy; drop and cancel both remove all temporary feedback.

import { useState } from 'react';
import { SortableArea, SortableRoot } from 'comins-sortable/react';
type Item = { id: string; label: string };
const sourceGroup = { name: 'tasks', pull: 'copy' as const };
export function CopyExample() {
const [catalog, setCatalog] = useState<Item[]>([
{ id: 'template-1', label: 'Template' },
]);
const [board, setBoard] = useState<Item[]>([]);
return (
<SortableRoot<Item>>
<SortableArea
areaId="catalog"
group={sourceGroup}
items={catalog}
itemKey="id"
copyItem={(item) => ({
...item,
id: crypto.randomUUID(),
label: `${item.label} copy`,
})}
onItemsChange={(next) => setCatalog([...next])}
>
{(item) => <div>{item.label}</div>}
</SortableArea>
<SortableArea
areaId="board"
group="tasks"
items={board}
itemKey="id"
onItemsChange={(next) => setBoard([...next])}
>
{(item) => <div>{item.label}</div>}
</SortableArea>
</SortableRoot>
);
}

React, Vue, and Svelte use copyItem(item, context). Vanilla uses copyElement(source, context) and must return a detached element whose ID is new and matches getItemId. An attached, missing, or duplicate copy fails closed without changing either area.

Vanilla evaluates relative selectors such as :scope > .item in the registered area. The inserted copy must match the destination’s item selector and resolve to its prepared ID through the destination’s getItemId. A mismatch is rolled back before the consumer’s onChange callback is called.

pull may also be a callback. The modifier-copy example reads the activation snapshot and returns copy for Alt/Option, otherwise move.

Playground: clone, custom-clone, and modifier-copy under /examples/clone/react.

The visual drag preview and the new data/element returned by copyItem/copyElement have separate roles. These callbacks and new-ID requirements are unchanged. The candidate fits preview dimensions in the preview parent’s coordinate basis when source and body scales differ, and removes inherited min/max clamps from the preview only. Source consumer styles remain intact.

Scaled and nested body/source copy checks confirm measured size, retained original items, new IDs, final order and feedback cleanup. Table-tagged checks are fixtures, not a new public table example. See feedback coordinates and current verification.


Runnable example · Source guide for this version