Mouse Interactions

JavaScript components for drag-and-drop functionality.

Drag and Drop Manager

Comprehensive drag-and-drop with zones and callbacks.

⋮⋮ Draggable Item 1
⋮⋮ Draggable Item 2
⋮⋮ Draggable Item 3
Drop items here
HTML
<!-- Draggable items -->
        <div
            style="
                display: flex;
                flex-direction: column;
                gap: 8px;
                margin-bottom: 24px;
            "
        >
            <div
                data-ss="draggable"
                data-ss-draggable-handle=".drag-handle"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 12px 16px;
                    background: var(--color_fill_secondary);
                    border-radius: 8px;
                    cursor: move;
                "
            >
                <span class="ss-c-drag-handle" style="cursor: grab; opacity: 0.5">
                    ⋮⋮
                </span>
                <span>Draggable Item 1</span>
            </div>
            <div
                data-ss="draggable"
                data-ss-draggable-handle=".drag-handle"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 12px 16px;
                    background: var(--color_fill_secondary);
                    border-radius: 8px;
                    cursor: move;
                "
            >
                <span class="ss-c-drag-handle" style="cursor: grab; opacity: 0.5">
                    ⋮⋮
                </span>
                <span>Draggable Item 2</span>
            </div>
            <div
                data-ss="draggable"
                data-ss-draggable-handle=".drag-handle"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 12px 16px;
                    background: var(--color_fill_secondary);
                    border-radius: 8px;
                    cursor: move;
                "
            >
                <span class="ss-c-drag-handle" style="cursor: grab; opacity: 0.5">
                    ⋮⋮
                </span>
                <span>Draggable Item 3</span>
            </div>
        </div>

        <!-- Drop zone -->
        <div
            data-ss="dropzone"
            data-ss-dropzone-accept=".task-card"
            style="
                min-height: 150px;
                padding: 24px;
                border: 2px dashed var(--color_line_secondary);
                border-radius: 12px;
                display: flex;
                align-items: center;
                justify-content: center;
                background: var(--color_fill_secondary);
                transition:
                    border-color 0.2s,
                    background 0.2s;
            "
        >
            <span style="opacity: 0.6">Drop items here</span>
        </div>

Kanban Board

Drag-and-drop kanban board implementation.

To Do

Design mockups Due: Jan 25
Write documentation Due: Jan 28

In Progress

Implement API In progress...

Done

Setup project Completed
HTML
<div
            style="
                display: grid;
                grid-template-columns: repeat(3, 1fr);
                gap: 16px;
            "
        >
            <!-- To Do Column -->
            <div
                style="
                    background: var(--color_fill_secondary);
                    border-radius: 12px;
                    padding: 16px;
                "
            >
                <h4
                    style="
                        margin: 0 0 16px;
                        font-size: 14px;
                        text-transform: uppercase;
                        opacity: 0.6;
                    "
                >
                    To Do
                </h4>
                <div
                    data-ss="dropzone"
                    data-ss-dropzone-accept=".task-card"
                    style="
                        display: flex;
                        flex-direction: column;
                        gap: 8px;
                        min-height: 200px;
                    "
                >
                    <div
                        class="ss-c-task-card"
                        data-ss="draggable"
                        style="
                            padding: 12px;
                            background: white;
                            border-radius: 8px;
                            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
                            cursor: move;
                        "
                    >
                        <strong style="display: block; margin-bottom: 4px">
                            Design mockups
                        </strong>
                        <span style="font-size: 12px; opacity: 0.6">
                            Due: Jan 25
                        </span>
                    </div>
                    <div
                        class="ss-c-task-card"
                        data-ss="draggable"
                        style="
                            padding: 12px;
                            background: white;
                            border-radius: 8px;
                            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
                            cursor: move;
                        "
                    >
                        <strong style="display: block; margin-bottom: 4px">
                            Write documentation
                        </strong>
                        <span style="font-size: 12px; opacity: 0.6">
                            Due: Jan 28
                        </span>
                    </div>
                </div>
            </div>

            <!-- In Progress Column -->
            <div
                style="
                    background: var(--color_fill_secondary);
                    border-radius: 12px;
                    padding: 16px;
                "
            >
                <h4
                    style="
                        margin: 0 0 16px;
                        font-size: 14px;
                        text-transform: uppercase;
                        opacity: 0.6;
                    "
                >
                    In Progress
                </h4>
                <div
                    data-ss="dropzone"
                    data-ss-dropzone-accept=".task-card"
                    style="
                        display: flex;
                        flex-direction: column;
                        gap: 8px;
                        min-height: 200px;
                    "
                >
                    <div
                        class="ss-c-task-card"
                        data-ss="draggable"
                        style="
                            padding: 12px;
                            background: white;
                            border-radius: 8px;
                            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
                            border-left: 3px solid var(--color_state_warning);
                            cursor: move;
                        "
                    >
                        <strong style="display: block; margin-bottom: 4px">
                            Implement API
                        </strong>
                        <span style="font-size: 12px; opacity: 0.6">
                            In progress...
                        </span>
                    </div>
                </div>
            </div>

            <!-- Done Column -->
            <div
                style="
                    background: var(--color_fill_secondary);
                    border-radius: 12px;
                    padding: 16px;
                "
            >
                <h4
                    style="
                        margin: 0 0 16px;
                        font-size: 14px;
                        text-transform: uppercase;
                        opacity: 0.6;
                    "
                >
                    Done
                </h4>
                <div
                    data-ss="dropzone"
                    data-ss-dropzone-accept=".task-card"
                    style="
                        display: flex;
                        flex-direction: column;
                        gap: 8px;
                        min-height: 200px;
                    "
                >
                    <div
                        class="ss-c-task-card"
                        data-ss="draggable"
                        style="
                            padding: 12px;
                            background: white;
                            border-radius: 8px;
                            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
                            border-left: 3px solid var(--color_state_success);
                            cursor: move;
                            opacity: 0.7;
                        "
                    >
                        <strong
                            style="
                                display: block;
                                margin-bottom: 4px;
                                text-decoration: line-through;
                            "
                        >
                            Setup project
                        </strong>
                        <span style="font-size: 12px; opacity: 0.6">
                            Completed
                        </span>
                    </div>
                </div>
            </div>
        </div>

File Upload Drop Zone

Drag-and-drop file upload area.

Drag & drop files here

or click to browse

Drop files to upload

document.pdf 2.4 MB
image.jpg 1.8 MB - Uploading...
HTML
<!-- File drop zone -->
        <div
            data-ss="dropzone"
            data-ss-dropzone-accept="*"
            style="
                padding: 48px;
                border: 2px dashed var(--color_line_secondary);
                border-radius: 16px;
                text-align: center;
                cursor: pointer;
                transition: all 0.2s;
            "
        >
            <div style="font-size: 48px; margin-bottom: 16px">▤</div>
            <p style="margin: 0 0 8px; font-size: 18px; font-weight: 500">
                Drag & drop files here
            </p>
            <p style="margin: 0; opacity: 0.6">or click to browse</p>
            <input type="file" multiple style="display: none" />
        </div>

        <!-- Active drop state -->
        <div
            style="
                margin-top: 16px;
                padding: 48px;
                border: 2px dashed var(--color_fill_primary);
                border-radius: 16px;
                text-align: center;
                background: rgba(var(--color_fill_primary_rgb), 0.05);
            "
        >
            <div style="font-size: 48px; margin-bottom: 16px">⇩</div>
            <p
                style="
                    margin: 0;
                    font-size: 18px;
                    font-weight: 500;
                    color: var(--color_fill_primary);
                "
            >
                Drop files to upload
            </p>
        </div>

        <!-- Uploaded files list -->
        <div
            style="
                margin-top: 24px;
                display: flex;
                flex-direction: column;
                gap: 8px;
            "
        >
            <div
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 12px 16px;
                    background: var(--color_fill_secondary);
                    border-radius: 8px;
                "
            >
                <span style="font-size: 24px">▭</span>
                <div style="flex: 1">
                    <strong style="display: block">document.pdf</strong>
                    <span style="font-size: 12px; opacity: 0.6">2.4 MB</span>
                </div>
                <span style="color: var(--color_state_success)">✓</span>
            </div>
            <div
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 12px 16px;
                    background: var(--color_fill_secondary);
                    border-radius: 8px;
                "
            >
                <span style="font-size: 24px">▭</span>
                <div style="flex: 1">
                    <strong style="display: block">image.jpg</strong>
                    <span style="font-size: 12px; opacity: 0.6">
                        1.8 MB - Uploading...
                    </span>
                </div>
                <div
                    style="
                        width: 60px;
                        height: 4px;
                        background: var(--color_line_secondary);
                        border-radius: 2px;
                        overflow: hidden;
                    "
                >
                    <div
                        style="
                            width: 60%;
                            height: 100%;
                            background: var(--color_fill_primary);
                        "
                    ></div>
                </div>
            </div>
        </div>

Sortable List

Reorderable list with drag-and-drop.

1 First item ⋮⋮
2 Second item ⋮⋮
3 Dragging this item ⋮⋮
4 Fourth item ⋮⋮
5 Fifth item ⋮⋮
HTML
<div
            data-ss="sortable"
            style="
                max-width: 400px;
                display: flex;
                flex-direction: column;
                gap: 4px;
            "
        >
            <div
                data-ss="draggable"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 14px 16px;
                    background: white;
                    border: 1px solid var(--color_line_secondary);
                    border-radius: 8px;
                    cursor: move;
                "
            >
                <span style="opacity: 0.4">1</span>
                <span style="flex: 1">First item</span>
                <span style="opacity: 0.3">⋮⋮</span>
            </div>
            <div
                data-ss="draggable"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 14px 16px;
                    background: white;
                    border: 1px solid var(--color_line_secondary);
                    border-radius: 8px;
                    cursor: move;
                "
            >
                <span style="opacity: 0.4">2</span>
                <span style="flex: 1">Second item</span>
                <span style="opacity: 0.3">⋮⋮</span>
            </div>
            <div
                data-ss="draggable"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 14px 16px;
                    background: var(--color_fill_primary);
                    color: white;
                    border-radius: 8px;
                    cursor: move;
                    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                    transform: scale(1.02);
                "
            >
                <span style="opacity: 0.6">3</span>
                <span style="flex: 1">Dragging this item</span>
                <span style="opacity: 0.5">⋮⋮</span>
            </div>
            <div
                style="
                    height: 52px;
                    border: 2px dashed var(--color_fill_primary);
                    border-radius: 8px;
                    background: rgba(var(--color_fill_primary_rgb), 0.05);
                "
            ></div>
            <div
                data-ss="draggable"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 14px 16px;
                    background: white;
                    border: 1px solid var(--color_line_secondary);
                    border-radius: 8px;
                    cursor: move;
                "
            >
                <span style="opacity: 0.4">4</span>
                <span style="flex: 1">Fourth item</span>
                <span style="opacity: 0.3">⋮⋮</span>
            </div>
            <div
                data-ss="draggable"
                style="
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    padding: 14px 16px;
                    background: white;
                    border: 1px solid var(--color_line_secondary);
                    border-radius: 8px;
                    cursor: move;
                "
            >
                <span style="opacity: 0.4">5</span>
                <span style="flex: 1">Fifth item</span>
                <span style="opacity: 0.3">⋮⋮</span>
            </div>
        </div>

JavaScript API

Programmatic control of drag-and-drop components.

JavaScript
<script>
            // DragAndDropManager
            import { DragAndDropManager } from "stylescape";

            const dnd = new DragAndDropManager({
                draggableSelector: '[data-ss="draggable"]',
                dropzoneSelector: '[data-ss="dropzone"]',
                handleSelector: ".drag-handle",
                ghostClass: "is-dragging",
                dropIndicatorClass: "drop-indicator",

                // Callbacks
                onDragStart: (element, event) => {
                    console.log("Started dragging:", element);
                },
                onDragOver: (dropzone, draggable, event) => {
                    dropzone.classList.add("is-over");
                },
                onDragLeave: (dropzone, draggable, event) => {
                    dropzone.classList.remove("is-over");
                },
                onDrop: (dropzone, draggable, event) => {
                    console.log("Dropped:", draggable, "into:", dropzone);
                    // Update data/state
                    updateOrder(draggable, dropzone);
                },
                onDragEnd: (element, event) => {
                    console.log("Drag ended");
                },

                // Validation
                canDrop: (dropzone, draggable) => {
                    const accepts = dropzone.dataset.ssDropzoneAccept;
                    return draggable.matches(accepts);
                },
            });

            // Methods
            dnd.enable();
            dnd.disable();
            dnd.destroy();

            // Sortable list helper
            import { SortableList } from "stylescape";

            const sortable = new SortableList(listElement, {
                handle: ".sort-handle",
                animation: 150,
                ghostClass: "sortable-ghost",
                onSort: (oldIndex, newIndex, element) => {
                    console.log(`Moved from ${oldIndex} to ${newIndex}`);
                    // Save new order
                    saveOrder(sortable.getOrder());
                },
            });

            sortable.getOrder(); // Get current order
            sortable.setOrder([3, 1, 2, 4]); // Set specific order
        </script>