Skip to content

fix: Data instance is wrong in FluentDragEvents #3925

Open
@MarvinKlein1508

Description

@MarvinKlein1508

🐛 Bug Report

When you use multiple FluentDropZones from different lists in one large FluentDragContainer and then provide the parent as Data attribute then the source and target will have the exact same data.

💻 Repro or Code Sample

For IssueTester:

<style>
    .form-editor {
        display: flex;
        flex-direction: column;
        height: 100dvh;
    }

    .form-editor-content {
        flex: 1;
        background-color: pink;
    }

    .form-row {
        border: 1px dashed red;
        border-radius: .5em;
        background-color: #fff;
        padding: 1em;
        display: flex;
        gap: 1em;
    }

    .form-column {
        flex: 1;
        border: 2px dashed orange;
        border-radius: .5em;
        min-height: 5em;
    }
</style>
<div class="form-editor">
    <div class="form-editor-content">
        <FluentDragContainer TItem="FormRow"
                             OnDropEnd="OnRowDropEnd">
            <FluentDragContainer TItem="FormColumn"
                                 OnDragEnd="OnColumnDropEnd">
                @foreach (var row in _testForm.Rows)
                {
                    <span>Row: @row.RowId</span>
                    <FluentDropZone Item="row" Class="form-row" Draggable="true" Droppable="true">
                        @foreach (var column in row.Columns)
                        {
                            <FluentDropZone Item="column" Data="@row" Class="form-column" Draggable="true" Droppable="true">
                                Column: @column.ColumnId
                            </FluentDropZone>
                        }
                    </FluentDropZone>
                }
            </FluentDragContainer>
        </FluentDragContainer>
    </div>
</div>

@code {
    private Form _testForm;

    public IssueTester()
    {
        _testForm = new Form();

        var testRow1 = new FormRow() { RowId = 1 };
        var testRow2 = new FormRow() { RowId = 2 };
        var testRow3 = new FormRow() { RowId = 3 };
        var testRow4 = new FormRow() { RowId = 4 };
        var testRow5 = new FormRow() { RowId = 5 };
        var testColumn1 = new FormColumn() { ColumnId = 1 };
        var testColumn2 = new FormColumn() { ColumnId = 2 };
        var testColumn3 = new FormColumn() { ColumnId = 3 };
        var testColumn4 = new FormColumn() { ColumnId = 4 };
        var testColumn5 = new FormColumn() { ColumnId = 5 };
        var testColumn6 = new FormColumn() { ColumnId = 6 };
        var testColumn7 = new FormColumn() { ColumnId = 7 };
        var testColumn8 = new FormColumn() { ColumnId = 8 };


        testRow1.Columns.Add(testColumn1);
        testRow1.Columns.Add(testColumn2);
        testRow2.Columns.Add(testColumn3);
        testRow3.Columns.Add(testColumn4);
        testRow4.Columns.Add(testColumn5);
        testRow4.Columns.Add(testColumn6);
        testRow5.Columns.Add(testColumn7);
        testRow5.Columns.Add(testColumn8);
        _testForm.Rows.Add(testRow1);
        _testForm.Rows.Add(testRow2);
        _testForm.Rows.Add(testRow3);
        _testForm.Rows.Add(testRow4);
        _testForm.Rows.Add(testRow5);
    }

    private void OnRowDropEnd(FluentDragEventArgs<FormRow> e)
    {
        var target = e.Target.Item;
        var source = e.Source.Item;

        int targetIndex = _testForm.Rows.IndexOf(target);

        _testForm.Rows.Remove(source);
        _testForm.Rows.Insert(targetIndex, source);
    }

    private void OnColumnDropEnd(FluentDragEventArgs<FormColumn> e)
    {
        var sourceRow = e.Source.Data as FormRow;
        var targetRow = e.Target.Data as FormRow;

        if (sourceRow is null || targetRow is null)
        {
            return;
        }

        var target = e.Target.Item;
        var source = e.Source.Item;
        int targetIndex = targetRow.Columns.IndexOf(target);

        if (sourceRow == targetRow)
        {
            sourceRow.Columns.Remove(source);
            sourceRow.Columns.Insert(targetIndex, source);
        }
        else
        {
            sourceRow.Columns.Remove(source);
            targetRow.Columns.Insert(targetIndex, source);
        }

        StateHasChanged();
    }


    public class Form
    {
        public int FormId { get; set; }
        public List<FormRow> Rows { get; set; } = [];
    }

    public class FormRow
    {
        public int RowId { get; set; }
        public List<FormColumn> Columns { get; set; } = [];
    }

    public class FormColumn
    {
        public int ColumnId { get; set; }
    }
}

🤔 Expected Behavior

I expect my target and source data to be different when I drop one column from one list to another within OnColumnDropEnd method

😯 Current Behavior

Both Data properties return the same instance.

🔦 Context

To get nested drag and drop to work the FluentDropzone needs to have

@ondrop:stopPropagation
@ondragenter:stopPropagation
@ondragend:stopPropagation
@ondragover:stopPropagation
@ondragleave:stopPropagation
@ondragstart:stopPropagation

What I want to achive:

  • Drag and drop rows
  • Drag and drop columns (within same list and into lists from other rows)

🌍 Your Environment

.NET 9.0.6; FluentUI 4.12.1

Metadata

Metadata

Assignees

Labels

community:contributionIssue will/can be addressed by community contribution

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions