Issue #6122✓ SolvedOpened September 4, 2024by mohamedsalem4013 reactions

Fix and refactor Sorter.ts

快速解答by mohamedsalem4012

This's done.

Read full answer below ↓

Question

  • Fix the Sorter usage in StyleManager (regression with sorting property layers)
  • Refactor Sorter with the usage of Components.canMove
  • Update canMove with the check of dropping main Symbol inside its own instance.

Answers (3)

👍 Most helpfulmohamedsalem401October 11, 2024

This's done.

mohamedsalem401September 5, 2024

The idea is to refactor the sorter for improved maintainability and readability. We can implement the following changes:

  1. Make Sorter class depend on an abstract tree structure rather than relying on specific implementations like Component or Layers, make the Sorter class work with a more generic, abstract tree structure. This will make it more flexible and reusable.
  2. Split the code to multiple smaller classes each with a single responsibility
  3. ComponentManager.canMove: Use the ComponentManager.canMove method to determine if a Component can be moved. This avoids duplicating code and ensures consistent behavior across different parts of your application.

We will see how we can apply those points one by one

  1. To make the Sorter class independant of any model implementation, we can add an argument in the SorterOptions that’s a function returning whether an element can be dragged into another element.

    export interface SorterOptions {
      container?: HTMLElement;
      canMove: (targetModel: Model<any>, srcModel: Model<any>, index: number) => Boolean;
      ...
    }
    

    For example the initializing the Sorter for the Layers in the StyleManager

    new utils.Sorter({
      container: this.el,
      canMove: (targetModel, srcModel, index) => {
    	  return targetModel.view === this.el // Allow dropping iff the target is the container
      },
      em,
    })
    

    And for anything depending on Component would be

    new utils.Sorter({
      container: this.el,
      canMove: editor.Components.canMove,
      em,
    })
    
  2. Splitting the functionality of Sorter class into multiple classes

    • DropLocationDeterminer
      • Receives input: Takes mouse movement data, the HTML element being dragged, the tree structure, and the canMove function as input.
      • Calculates drop location: Analyzes the mouse position, the structure of the tree, and the canMove function to determine the most suitable index for the dropped element.
    • DragAndDropHandler
      • Creates and manages elements: Creates and manages the placeholder, drag helper, and the actual element being dragged, ensuring their proper appearance and positioning.
ClaudeCodeMay 17, 2026

Thanks for reporting this, @mohamedsalem401.

Thanks for sharing your report about [Fix] Fix and refactor Sorter.ts. To help the team investigate and prioritize this:

Please provide:

  1. A minimal reproducible example (CodeSandbox/JSFiddle)
  2. Your GrapesJS version number
  3. Browser and OS information
  4. Any error messages from the browser console
  5. Steps to reproduce the issue

What helps most:

  • Minimal code example (not your full project)
  • Screen recording or screenshot showing the issue
  • Expected vs actual behavior clearly stated
  • GrapesJS configuration you're using

With these details, the maintainers can identify and prioritize a fix much faster. The GrapesJS team is very responsive to well-documented issues.

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Free option

Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.

Browse free plugins →
Premium option

Premium plugins ship with support, regular updates, and production-ready features — save days of integration work.

Browse premium plugins →

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.