These focused recipes demonstrate the main ways an application composes and controls a Container. Each example includes a Svelte source tab. The Svelte component contract is documented in the Container reference. The underlying core behavior is shared across framework bindings.

Rendering a Collection

Container renders ordinary optional children. Put fixed markup and the application-owned keyed entries loop exactly where they belong in that body. There are no collection-specific items or getItemId props.

Rendering a collection

Changing Container Behavior

The config prop changes sorting behavior. This example switches direction, which sets the main layout direction, without changing who owns the rendered collection.

Changing container behavior

See the complete configuration table and Placement Modes.

Fixed Content Around Items

Fixed content is ordinary markup before or after the keyed sortable loop. It is never registered as a SnapSort Item. Use entry.itemId directly as the loop’s reconciliation key; ordinary Items, nested Containers, and live ghosts already share one identity domain within a root.

Fixed content around items

The Add control changes application state directly. SnapSort does not emit an item insertion callback for an Item that the framework mounts from that state.

Programmatic Cross-Container Moves

Use bind:container when a button, keyboard command, or other control needs to call the core API directly. The bound value may be undefined or null before mount and becomes null after unmount.

Clicking Move → calls moveItem. That command requests the move and emits the root structural callback; the callback still updates Svelte state synchronously because the core object does not own the rendered collection. The command is authoritative: it bypasses dropPriority and getDropPriority, so application controls must enforce any equivalent policy before invoking it.

Programmatic cross-container moves

Containers that interact must share one root. Drop-policy callbacks can filter destinations inside that tree; they cannot connect independent roots.

Nested Containers

A Container can itself be an entry in a parent Container. Give it the entry’s itemId, then set locked={false} to let the entire nested Container drag. locked defaults to true, which suits Containers that only organize child Items.

selected remains consumer-owned. In this default move mode, dragging one selected, unlocked entry moves the other unlocked selected entries in the same tree. Swap mode exchanges only its primary Item. The application owns selection controls and state.

Nested containers
Note

Spacing between multiple dragged Items currently does not preserve the original layout’s gap or margins.

Custom Ghost Rendering

SnapSort owns each ghost’s presence during a session, so the application handles explicit insert, move, and remove events even when all three callbacks delegate to reduceRenderTree. Ordinary values remain application-owned and do not need equivalent callbacks when application code adds or removes them.

Custom Ghost Rendering

See Drags and Ghosts for every ghost role, lifecycle transition, and the insertion-marker rendering API.

Container Presentation and HTML Attributes

Container renders a div, so aria-*, data-*, style, and other div attributes pass through. Svelte’s class prop and the cross-framework className alias merge with SnapSort’s own classes.

Classes, styles, and HTML attributes