Nested Item Elements

The Sortable provides options for nesting additional Sortable components and focusable elements inside its items.

You can also prevent dragging over interactive elements by using the onDragStart event.

import React from 'react';
import ReactDOM from 'react-dom';
import { Sortable } from '@progress/kendo-react-sortable';

const NestedSortableUI = (props) => {
    const { style, attributes, dataItem, forwardRef, isActive } = props;

    return (
        <div
            ref={forwardRef}
            {...attributes}
            style={{
                ...style,
                border: isActive ? '2px dashed black' : 0,
                paddingTop: 1,
                paddingBottom: 1,
                paddingLeft: 2,
                paddingRight: 2

            }}
        >
            <div
                style={{
                    backgroundColor: dataItem.color,
                    color: 'white',
                    height: 30,
                    border: '1px solid black'
                }}
            >
                {dataItem.color}
            </div>
        </div>
    );
};

class SortableItemUI extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            colors: props.dataItem.data.map(item => ({
                colorId: item,
                color: item
            }))
        };
    }

    onDragOver = (event) => {
        this.setState({
            colors: event.newState
        });
    }

    onNavigate = (event) => {
        this.setState({
            colors: event.newState
        });
    }

    render() {
        const { style, attributes, dataItem, forwardRef } = this.props;

        return (
            <div
                ref={forwardRef}
                {...attributes}
                style={{
                    ...style,
                    float: 'left',
                    display: 'inline-block',
                    width: 125,
                    backgroundColor: '#fffaed',
                    margin: 4,
                    border: '1px solid black'
                }}
            >
                {dataItem.name}
                <Sortable
                    idField={'colorId'}
                    data={this.state.colors}

                    itemUI={NestedSortableUI}

                    onDragOver={this.onDragOver}
                    onNavigate={this.onNavigate}
                />
            </div>
        );
    }
}

class App extends React.Component {
    colorsA = [ 'Violet', 'Magenta', 'Purple', 'SlateBlue' ];
    colorsB = [ 'SteelBlue', 'CornflowerBlue', 'RoyalBlue', 'MediumBlue' ];
    colorsC = [ 'LimeGreen', 'SeaGreen', 'Green', 'OliveDrab' ];
    colorsD = [ 'LightSalmon', 'Salmon', 'IndianRed', 'FireBrick' ];

    state = {
        palettes: [
            { data: this.colorsA, name: 'Palette A', id: 1 },
            { data: this.colorsB, name: 'Palette B', id: 2 },
            { data: this.colorsC, name: 'Palette C', id: 3 },
            { data: this.colorsD, name: 'Palette D', id: 4 }
        ]
    };

    onDragOver = (event) => {
        this.setState({
            palettes: event.newState
        });
    }

    onNavigate = (event) => {
        this.setState({
            palettes: event.newState
        });
    }

    render() {
        return (
            <Sortable
                idField={'id'}
                data={this.state.palettes}

                itemUI={SortableItemUI}

                onDragOver={this.onDragOver}
                onNavigate={this.onNavigate}
            />
        );
    }
}

ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);
In this article
 /