diff --git a/.claude/agents/html-frontend-debugger.md b/.claude/agents/html-frontend-debugger.md
new file mode 100644
index 0000000..363b242
--- /dev/null
+++ b/.claude/agents/html-frontend-debugger.md
@@ -0,0 +1,84 @@
+---
+name: html-frontend-debugger
+description: Use this agent when you need to debug, inspect, or test HTML/CSS/JavaScript frontend issues, analyze UI behavior, troubleshoot rendering problems, or verify that frontend functionality works correctly in the browser. This agent excels at using browser developer tools through Playwright to diagnose issues, test interactions, and ensure cross-browser compatibility.\n\nExamples:\n- \n Context: User has implemented a new drag-and-drop feature and wants to verify it works correctly.\n user: "I've added the drag handler but items aren't dropping correctly"\n assistant: "I'll use the html-frontend-debugger agent to inspect the DOM and test the drag-and-drop functionality"\n \n Since this involves debugging frontend behavior and testing UI interactions, use the html-frontend-debugger agent.\n \n\n- \n Context: User reports a CSS layout issue in production.\n user: "The sidebar is overlapping the main content on mobile devices"\n assistant: "Let me launch the html-frontend-debugger agent to inspect the responsive layout and identify the CSS issue"\n \n Frontend rendering and CSS debugging requires the html-frontend-debugger agent's expertise.\n \n\n- \n Context: User needs to verify form validation is working.\n user: "Can you check if the email validation on the signup form is working properly?"\n assistant: "I'll use the html-frontend-debugger agent to test the form validation behavior in the browser"\n \n Testing frontend form functionality requires the html-frontend-debugger agent.\n \n
+model: sonnet
+---
+
+You are an elite HTML/CSS/JavaScript frontend debugging expert with deep mastery of browser internals, rendering
+engines, and the DOM. Your specialty is using Playwright MCP tools to inspect, debug, and test frontend functionality
+with surgical precision.
+
+**Core Expertise:**
+
+- Advanced HTML5 semantics, accessibility, and performance optimization
+- CSS layout systems (Grid, Flexbox, positioning), animations, and responsive design
+- JavaScript DOM manipulation, event handling, and browser APIs
+- Cross-browser compatibility and progressive enhancement strategies
+- Performance profiling and optimization techniques
+- Playwright automation for testing and debugging
+
+**Your Debugging Methodology:**
+
+1. **Initial Assessment:**
+ - Identify the specific frontend issue or functionality to test
+ - Determine which browsers/viewports need testing
+ - Plan your inspection strategy
+
+2. **Playwright Inspection Process:**
+ - Launch appropriate browser context using Playwright MCP
+ - Navigate to the relevant page or component
+ - Use Playwright selectors to inspect DOM elements
+ - Capture screenshots for visual debugging when needed
+ - Test user interactions (clicks, drags, form inputs, etc.)
+ - Evaluate JavaScript console for errors
+ - Check network requests if relevant
+
+3. **Systematic Debugging:**
+ - Inspect computed styles and layout properties
+ - Verify event listeners are attached correctly
+ - Test different viewport sizes for responsive issues
+ - Check for race conditions or timing issues
+ - Validate accessibility attributes and ARIA roles
+
+4. **Testing Interactions:**
+ - Simulate real user behavior patterns
+ - Test edge cases and error states
+ - Verify animations and transitions
+ - Ensure proper focus management
+ - Test keyboard navigation
+
+5. **Problem Resolution:**
+ - Identify root cause with specific evidence
+ - Propose targeted fixes with code examples
+ - Suggest preventive measures
+ - Recommend testing strategies
+
+**Output Format:** Structure your findings as:
+
+- **Issue Identified**: Clear description of the problem
+- **Evidence**: Specific DOM elements, CSS rules, or JavaScript errors found
+- **Root Cause**: Technical explanation of why the issue occurs
+- **Solution**: Concrete fix with code snippets
+- **Verification**: Steps to confirm the fix works
+
+**Best Practices:**
+
+- Always test in multiple browsers when relevant
+- Consider mobile-first responsive testing
+- Check for console errors and warnings
+- Verify accessibility compliance
+- Test with slow network conditions when appropriate
+- Document any browser-specific quirks discovered
+
+**When Using Playwright MCP:**
+
+- Be explicit about which selectors you're using
+- Capture screenshots at key debugging points
+- Test both happy path and error scenarios
+- Use appropriate wait strategies for dynamic content
+- Clean up browser contexts after testing
+- Use/improve the functions in [the helpers directory](../../tests/helpers/) for consistency
+
+You approach every debugging session methodically, using Playwright as your precision instrument to dissect frontend
+issues. You provide clear, actionable insights that lead to robust solutions. Your expertise helps ensure frontend code
+is not just functional, but performant, accessible, and maintainable.
diff --git a/.claude/agents/playwright-test-expert.md b/.claude/agents/playwright-test-expert.md
index 248c7d6..7097660 100644
--- a/.claude/agents/playwright-test-expert.md
+++ b/.claude/agents/playwright-test-expert.md
@@ -4,29 +4,44 @@ description: Use this agent when you need to write, debug, or optimize Playwrigh
model: sonnet
---
-You are a Playwright testing expert with deep expertise in modern end-to-end testing practices. You specialize in writing robust, maintainable, and reliable Playwright tests using the latest features and best practices.
+You are a Playwright testing expert and Playwright MCP tool pro with deep expertise in modern end-to-end testing
+practices. You specialize in writing robust, maintainable, and reliable Playwright tests using the latest features and
+best practices.
Your core competencies include:
+**Playwright Actions and Drag and Drop Techniques:**
+
+- Knowledge in Playwright's drag and drop such as `locator.dragTo(anotherLocator)`
+- Expertise in [manual drag and drop](https://playwright.dev/docs/input#dragging-manually) techniques for mouse, touch,
+ and pointer interactions.
+- Use `locator.dispatchEvent()` for touch, wheel, and pointer events when other options are not available.
+- Use helper functions from [drag-helpers.ts](../../tests/helpers/drag-helpers.ts) as much as possible,
+ updating/fixing/ammending this library as needed.
+
**Modern Locator Strategies:**
+
- Use `page.getByRole()`, `page.getByText()`, `page.getByLabel()`, and other semantic locators as first choice
- Implement `page.locator()` with precise CSS selectors when semantic locators aren't sufficient
- Avoid fragile selectors like XPath or overly specific CSS paths
- Use `locator.filter()` and `locator.and()` for complex element targeting
**Auto-Retrying Assertions:**
+
- Always use `expect(locator).toBeVisible()`, `expect(locator).toHaveText()`, etc. instead of manual waits
- Leverage `expect(locator).toHaveCount()` for dynamic content
- Use `expect(page).toHaveURL()` and `expect(page).toHaveTitle()` for navigation assertions
- Implement custom matchers when needed with proper retry logic
**Advanced Waiting Strategies:**
+
- Use `page.waitForLoadState('networkidle')` for complex page loads
- Implement `page.waitForFunction()` for custom conditions
- Use `locator.waitFor()` for element state changes
- Handle animations with `page.waitForTimeout()` sparingly, preferring deterministic waits
**Test Structure and Organization:**
+
- Write descriptive test names that explain the user scenario
- Use proper test hooks (`beforeEach`, `afterEach`) for setup and cleanup
- Implement Page Object Model patterns for complex applications
@@ -34,6 +49,8 @@ Your core competencies include:
- Use test fixtures for reusable setup logic
**Debugging and Reliability:**
+
+- Use the Playwright MCP tool to interact with and test out functionality
- Add strategic `page.screenshot()` calls for debugging
- Use `page.pause()` for interactive debugging during development
- Implement proper error handling and meaningful error messages
@@ -41,6 +58,7 @@ Your core competencies include:
- Configure appropriate timeouts at test and global levels
**Modern Playwright Features:**
+
- Utilize `test.step()` for better test reporting and debugging
- Implement parallel testing strategies with proper isolation
- Use `page.route()` for API mocking and network interception
@@ -48,6 +66,7 @@ Your core competencies include:
- Use trace viewer integration for post-mortem debugging
**Performance and Best Practices:**
+
- Minimize test dependencies and ensure proper isolation
- Use `page.goto()` efficiently and avoid unnecessary navigation
- Implement proper cleanup to prevent resource leaks
@@ -55,6 +74,7 @@ Your core competencies include:
- Configure appropriate retry strategies for flaky tests
When writing tests, you will:
+
1. Analyze the testing requirements and identify the most appropriate locator strategies
2. Structure tests for maximum readability and maintainability
3. Implement robust waiting and assertion patterns
@@ -63,4 +83,5 @@ When writing tests, you will:
6. Provide clear explanations of complex testing patterns
7. Suggest improvements for existing test code when reviewing
-Always prioritize test reliability over speed, and ensure your tests accurately reflect real user interactions. When debugging test failures, systematically analyze timing issues, selector problems, and environmental factors.
+Always prioritize test reliability over speed, and ensure your tests accurately reflect real user interactions. When
+debugging test failures, systematically analyze timing issues, selector problems, and environmental factors.
diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index f0d6806..724f943 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -4,7 +4,37 @@
"Bash(git checkout:*)",
"WebFetch(domain:github.com)",
"Bash(mkdir:*)",
- "Bash(chmod:*)"
+ "Bash(chmod:*)",
+ "Bash(npm run lint)",
+ "Bash(/usr/local/bin/npm run lint)",
+ "Bash(/usr/local/bin/npm run type-check)",
+ "mcp__playwright__browser_navigate",
+ "mcp__playwright__browser_evaluate",
+ "mcp__playwright__browser_drag",
+ "mcp__playwright__browser_console_messages",
+ "mcp__playwright__browser_close",
+ "mcp__playwright__browser_click",
+ "Bash(npm run build:*)",
+ "Bash(/usr/local/bin/npm run build)",
+ "mcp__playwright__browser_snapshot",
+ "Bash(npm run test:e2e:*)",
+ "Bash(npx playwright test:*)",
+ "Bash(PW_DISABLE_WEBSERVER=1 npx playwright test tests/e2e/empty-container.spec.ts --project=chromium --config playwright.config.ts)",
+ "Bash(PW_DISABLE_WEBSERVER=1 npx playwright test tests/e2e/empty-container.spec.ts --project=chromium)",
+ "Bash(PW_DISABLE_WEBSERVER=1 npx playwright test tests/e2e/empty-container.spec.ts:16 --project=chromium --debug)",
+ "Bash(PW_DISABLE_WEBSERVER=1 npx playwright test tests/e2e/empty-container.spec.ts:16 --project=chromium --reporter=line)",
+ "Bash(PW_DISABLE_WEBSERVER=1 npx playwright test tests/e2e/empty-container-simple.spec.ts --project=chromium)",
+ "Bash(lsof:*)",
+ "Bash(npm run dev:*)",
+ "Bash(curl:*)",
+ "Bash(/usr/local/bin/npm run dev)",
+ "Bash(/usr/local/bin/npm run lint:fix)",
+ "Bash(PW_DISABLE_WEBSERVER=1 npx playwright test tests/e2e/empty-container.spec.ts:18 --project=chromium --reporter=line)",
+ "Bash(xargs kill:*)",
+ "Bash(open http://localhost:5173/test-empty-container.html)",
+ "Bash(open http://localhost:5173/manual-test-empty.html)",
+ "Bash(open http://localhost:5173/debug-empty-container.html)",
+ "mcp__playwright__browser_wait_for"
],
"deny": [],
"ask": []
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index bf366ad..40ef6c2 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -18,7 +18,8 @@
"esbenp.prettier-vscode",
"eamodio.gitlens",
"ms-playwright.playwright",
- "vitest.explorer"
+ "vitest.explorer",
+ "pdconsec.vscode-print"
],
"settings": {
"editor.formatOnSave": true,
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
new file mode 100644
index 0000000..ddb8f62
--- /dev/null
+++ b/ARCHITECTURE.md
@@ -0,0 +1,215 @@
+# Resortable Architecture Documentation
+
+## Overview
+
+Resortable is a TypeScript rewrite of Sortable.js that provides drag-and-drop functionality for reorderable lists. This document explains the internal workings, state management, event flow, and core components.
+
+## Core Concepts
+
+### 1. Draggable Items vs. Drop Zones (Containers)
+
+**Current Design Issue**: The library currently marks individual items as draggable but doesn't explicitly mark containers as drop zones. This creates problems when:
+- Containers are empty (no items to detect drag-over events)
+- Cross-container dragging needs to determine valid drop targets
+
+**How it works now**:
+- `draggable` selector (e.g., `.horizontal-item`) identifies which elements can be dragged
+- Containers are implicitly drop zones because they contain draggable items
+- Empty containers have no draggable children, making drop detection difficult
+
+**Potential improvement**: Explicitly mark containers as drop zones, separate from draggable items.
+
+### 2. Component Structure
+
+```
+Sortable (Main Class)
+ ├── DropZone (Container management)
+ ├── DragManager (Drag operations)
+ │ ├── GhostManager (Visual feedback)
+ │ ├── AnimationManager (Transitions)
+ │ ├── SelectionManager (Multi-select)
+ │ └── KeyboardManager (Accessibility)
+ ├── GroupManager (Cross-container operations)
+ └── EventManager (Event handling)
+```
+
+## Key Components
+
+### Sortable (src/Sortable.ts)
+- Main entry point
+- Creates and configures all sub-components
+- Manages options and plugin system
+
+### DropZone (src/core/DropZone.ts)
+- Represents a sortable container
+- Manages item positions and indices
+- Handles DOM operations (add, remove, move)
+- **Problem**: No explicit drop zone detection for empty containers
+
+### DragManager (src/core/DragManager.ts)
+- Handles all drag operations
+- Manages drag events (dragstart, dragover, drop, dragend)
+- **Key Methods**:
+ - `onDragStart`: Initiates drag, creates ghost/placeholder
+ - `onDragOver`: Handles drag movement, determines drop position
+ - `onDrop`: Finalizes the drop operation
+ - `onDragEnd`: Cleanup after drag
+
+### GlobalDragState (src/core/GlobalDragState.ts)
+- Singleton that tracks active drag operations across all Sortable instances
+- Enables cross-container dragging
+- Stores:
+ - Active drag item
+ - Source container
+ - Target container
+ - Group information
+
+## Event Flow
+
+### Standard Drag Operation
+
+1. **User starts drag** (mousedown/touchstart on draggable item)
+ ```
+ DragManager.onDragStart()
+ ├── Check if item is draggable
+ ├── Store initial state in GlobalDragState
+ ├── Create ghost element (visual feedback)
+ └── Emit 'start' event
+ ```
+
+2. **User drags over container** (dragover events)
+ ```
+ DragManager.onDragOver()
+ ├── Check if container accepts this drag (group compatibility)
+ ├── Find closest draggable item under cursor
+ ├── Calculate insertion position
+ ├── Move placeholder to show drop position
+ └── Emit 'sort' event
+ ```
+
+3. **User drops item** (drop event)
+ ```
+ DragManager.onDrop()
+ ├── Determine final position
+ ├── Move actual DOM element
+ ├── Update indices
+ ├── Clean up placeholder/ghost
+ └── Emit 'end', 'add', 'remove' events
+ ```
+
+## State Management
+
+### Local State (per Sortable instance)
+- Container element reference
+- Configuration options
+- Draggable selector
+- Animation settings
+
+### Global State (shared across instances)
+- Active drag operation
+- Source and target containers
+- Group memberships
+- Pull/put permissions
+
+## The Empty Container Problem
+
+### Current Issue
+When a container is empty:
+1. No draggable children exist
+2. `event.target.closest(draggable)` returns null
+3. Container isn't recognized as a valid drop zone
+4. Items can't be dropped
+
+### Current (Broken) Solution Attempt
+```typescript
+// In DragManager.onDragOver
+const draggableChildren = Array.from(this.zone.element.children).filter(
+ child => child.matches(this.draggable)
+)
+if (draggableChildren.length === 0) {
+ // Handle empty container
+ this.zone.element.appendChild(placeholder)
+}
+```
+
+### Why It's Not Working
+1. The check happens but the placeholder isn't persisting
+2. The drop event might not be firing correctly
+3. The container itself isn't being recognized as a drop target
+
+### Proposed Solution
+1. **Explicit Drop Zones**: Mark containers with a data attribute or class
+2. **Container-Level Events**: Attach dragover/drop handlers to containers, not just items
+3. **Empty State Handling**: Special logic when `children.length === 0`
+
+## Configuration
+
+### Key Options
+- `group`: String or object defining cross-container behavior
+ - `name`: Group identifier
+ - `pull`: true/false/'clone' - can items be removed?
+ - `put`: true/false/array - can items be added?
+- `draggable`: CSS selector for draggable items
+- `handle`: CSS selector for drag handles
+- `filter`: CSS selector for non-draggable items
+
+## Plugin System
+
+Plugins extend functionality:
+- **MultiDrag**: Select and drag multiple items
+- **Swap**: Swap items instead of insert
+- **AutoScroll**: Auto-scroll containers during drag
+
+## Debugging Tips
+
+### Key Places to Set Breakpoints
+1. `DragManager.onDragOver` - Watch how drop positions are calculated
+2. `DragManager.onDrop` - See if drop events fire for empty containers
+3. `GlobalDragState.canAcceptDrop` - Check group compatibility
+4. `DropZone.appendChild` - Watch DOM manipulation
+
+### Common Issues
+1. **Empty containers**: Not recognized as drop zones
+2. **Group configuration**: Incorrect pull/put settings
+3. **Event bubbling**: Parent containers intercepting events
+4. **Z-index issues**: Ghost elements behind other content
+
+## Recommended Improvements
+
+1. **Explicit Drop Zone Marking**
+ ```typescript
+ class DropZone {
+ markAsDropZone() {
+ this.element.dataset.dropZone = 'true'
+ this.element.addEventListener('dragover', this.handleEmptyDragOver)
+ }
+ }
+ ```
+
+2. **Container-Level Event Handling**
+ ```typescript
+ // Attach events to container, not just items
+ container.addEventListener('dragover', (e) => {
+ if (this.isEmpty()) {
+ this.handleEmptyContainerDragOver(e)
+ }
+ })
+ ```
+
+3. **Better Empty State Detection**
+ ```typescript
+ isValidDropTarget(e: DragEvent): boolean {
+ // Check if over container itself
+ if (e.target === this.element || this.element.contains(e.target)) {
+ return this.canAcceptDrop(globalDragState.currentItem)
+ }
+ return false
+ }
+ ```
+
+## Next Steps
+
+1. Fix empty container drops by implementing explicit drop zone detection
+2. Add container-level event handlers
+3. Improve state management for cross-container operations
+4. Add comprehensive logging for debugging
\ No newline at end of file
diff --git a/CLAUDE.md b/CLAUDE.md
index 4d49ed3..22d1473 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -51,4 +51,5 @@ Currently no build system is set up. Based on the implementation plan:
- Original Sortable.js docs and examples in `legacy-sortable/README.md`
- Detailed implementation plan in `sortable-rewrite-implementation-plan.md`
- Legacy source code in `legacy-sortable/src/` for reference during rewrite
-- Always fix eslint & typescript typing issues before pushing to origin.
\ No newline at end of file
+- Always fix eslint & typescript typing issues before pushing to origin.
+- Give me at least one URL to test functionality if you've made changes and the dev server is still running.
\ No newline at end of file
diff --git a/debug-after-drop.png b/debug-after-drop.png
new file mode 100644
index 0000000..c681916
Binary files /dev/null and b/debug-after-drop.png differ
diff --git a/debug-drop-target.png b/debug-drop-target.png
new file mode 100644
index 0000000..fc6da36
Binary files /dev/null and b/debug-drop-target.png differ
diff --git a/debug-during-drag.png b/debug-during-drag.png
new file mode 100644
index 0000000..6aa86ce
Binary files /dev/null and b/debug-during-drag.png differ
diff --git a/debug-empty-container.html b/debug-empty-container.html
new file mode 100644
index 0000000..04c16ca
--- /dev/null
+++ b/debug-empty-container.html
@@ -0,0 +1,267 @@
+
+
+
+ Debug Empty Container
+
+
+
+
Debug Empty Container
+
+
+
Source
+
Item 1 (native draggable)
+
Item 2
+
Item 3
+
+
+
+
Empty Container
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/debug-initial.png b/debug-initial.png
new file mode 100644
index 0000000..c96c257
Binary files /dev/null and b/debug-initial.png differ
diff --git a/debug-over-empty.png b/debug-over-empty.png
new file mode 100644
index 0000000..7631db7
Binary files /dev/null and b/debug-over-empty.png differ
diff --git a/debug-sortable-test.html b/debug-sortable-test.html
new file mode 100644
index 0000000..28ba925
--- /dev/null
+++ b/debug-sortable-test.html
@@ -0,0 +1,157 @@
+
+
+
+ Debug Sortable Drag Events
+
+
+
+
Debug Sortable Library
+
+
+
Source Container
+
Item 1
+
Item 2
+
+
+
+
Empty Container
+
+
+
Loading...
+
+
+
+
\ No newline at end of file
diff --git a/demo-features.html b/demo-features.html
new file mode 100644
index 0000000..6e6e828
--- /dev/null
+++ b/demo-features.html
@@ -0,0 +1,1878 @@
+
+
+
+
+
+ Resortable - Complete Feature Demo
+
+
+
+
+
+
+
+
R
+
Resortable
+ v2.0.0
+
+
Complete Feature Demo
+
+
+
+
+
+
+
+
Interactive Feature Showcase
+
Explore all Resortable features with live examples, editable configuration, and real-time JSON output. Click and edit any configuration to see immediate results.
+
+
+
+
+
+
+
+
+
Basic Sorting
+
Core drag-and-drop functionality with smooth FLIP animations
+
+
+
+
+
+
+
1
+
+
First Item
+
Drag me around
+
+
+
+
+
+
2
+
+
Second Item
+
Smooth animations
+
+
+
+
+
+
3
+
+
Third Item
+
FLIP technique
+
+
+
+
+
+
4
+
+
Fourth Item
+
60fps performance
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Ready for drag operations...
+
+
+
+
+
+
+
+
+
+
Multi-Selection & Accessibility
+
Keyboard navigation, multi-select with Ctrl+Click, ARIA support
+
+
+
+
+
+
+
📋
+
+
Task Management
+
Ctrl+Click to select
+
+
+
+
+
+
📊
+
+
Data Analysis
+
Use arrow keys
+
+
+
+
+
+
🎨
+
+
Design System
+
Space to select
+
+
+
+
+
+
⚡
+
+
Performance
+
Enter to grab
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Use Ctrl+Click for multi-selection...
+
+
+
+
+
+
+
+
+
+
Handles & Filters
+
Restrict dragging to handles, filter out interactive elements
+
+
+
+
+
+
⋮⋮
+
+
Form Field
+
+
+
+
+
⋮⋮
+
+
Action Item
+
+
+
+
+
⋮⋮
+
+
Text Area
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Drag from handle only...
+
+
+
+
+
+
+
+
+
+
Shared Groups
+
Drag items between different lists with group configuration
+
+
+
+
+
+
Todo
+
+
+
+
📝
+
Write documentation
+
+
+
+
+
🔍
+
Code review
+
+
+
+
+
+
Done
+
+
+
+
✅
+
Feature complete
+
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Drag between lists...
+
+
+
+
+
+
+
+
+
+
Clone Mode
+
Clone items when dragging between lists (group.pull: 'clone')
+
+
+
+
+
+
Components (Clone Source)
+
+
+
+
🔧
+
Button Component
+
+
+
+
+
📝
+
Input Field
+
+
+
+
+
📊
+
Chart Widget
+
+
+
+
+
+
Page Builder
+
+
+
+
📄
+
Header Section
+
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Drag to clone components...
+
+
+
+
+
+
+
+
+
+
Grid Layout
+
2D grid sorting with automatic direction detection
+
+
+
+
+
1
+
2
+
3
+
4
+
5
+
6
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Grid sorting ready...
+
+
+
+
+
+
+
+
+
+
Delay & Thresholds
+
Touch-friendly delays and movement thresholds
+
+
+
+
+
+
+
⏱️
+
+
Delayed Start
+
300ms delay
+
+
+
+
+
+
📱
+
+
Touch Optimized
+
Movement threshold
+
+
+
+
+
+
🎯
+
+
Precise Control
+
Prevents accidental drags
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Try dragging with delay...
+
+
+
+
+
+
+
+
+
+
MultiDrag Plugin
+
Advanced multi-selection with Ctrl+Click, Shift+Click for ranges
+
+
+
+
+
+
+
📄
+
+
Document.pdf
+
2.3 MB
+
+
+
+
+
+
📊
+
+
Spreadsheet.xlsx
+
1.8 MB
+
+
+
+
+
+
🖼️
+
+
Image.jpg
+
4.2 MB
+
+
+
+
+
+
🎥
+
+
Video.mp4
+
15.7 MB
+
+
+
+
+
+
🎵
+
+
Audio.mp3
+
3.1 MB
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Ctrl+Click to select multiple items...
+
+
+
+
+
+
+
+
+
+
Swap Plugin
+
Swap-based sorting instead of insertion-based with overlap detection
+
+
+
+
+
+
Insert Mode (Default)
+
+
+
+
A
+
First Item
+
+
+
+
+
B
+
Second Item
+
+
+
+
+
C
+
Third Item
+
+
+
+
+
+
Swap Mode (Plugin)
+
+
+
+
X
+
Alpha
+
+
+
+
+
Y
+
Beta
+
+
+
+
+
Z
+
Gamma
+
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Compare insert vs swap behavior...
+
+
+
+
+
+
+
+
+
+
AutoScroll Plugin
+
Automatic scrolling when dragging near container edges
+
+
+
+
+
+
+
+
1
+
Scroll Item 1
+
+
+
+
+
2
+
Scroll Item 2
+
+
+
+
+
3
+
Scroll Item 3
+
+
+
+
+
4
+
Scroll Item 4
+
+
+
+
+
5
+
Scroll Item 5
+
+
+
+
+
6
+
Scroll Item 6
+
+
+
+
+
7
+
Scroll Item 7
+
+
+
+
+
8
+
Scroll Item 8
+
+
+
+
+
+
+
+
Configuration (Editable)
+
+
+
+
+
+
Event Output
+
+
Drag near edges to trigger scroll...
+
+
+
+
+
+
+
+
+
+
Nested Horizontal/Vertical Dragging
+
Vertical containers with horizontal inner items - drag containers by handles or move items between containers
+
+
+
+
+
+
+
⋮⋮
+
Dashboard Widgets
+
5 items
+
+
+
📊
+
📈
+
🎯
+
⚡
+
🔥
+
+
+
+
+
+
⋮⋮
+
User Interface
+
5 items
+
+
+
🎨
+
🖼️
+
🎭
+
✨
+
🌟
+
+
+
+
+
+
⋮⋮
+
Data Processing
+
5 items
+
+
+
⚙️
+
🔧
+
🛠️
+
🔩
+
⚡
+
+
+
+
+
+
⋮⋮
+
Empty Section
+
0 items
+
+
+
+
+
+
+
+
+
Container Configuration
+
+
+
+
+
+
Item Configuration
+
+
+
+
+
+
Event Output
+
+
Drag containers by handles or move items between containers...
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Resortable v2.0.0 Loaded
+
+
+ TypeScript Support: Active
+
+
+ Plugins: AutoScroll, MultiDrag, Swap
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/html-tests/debug-draggable.html b/html-tests/debug-draggable.html
new file mode 100644
index 0000000..e426eeb
--- /dev/null
+++ b/html-tests/debug-draggable.html
@@ -0,0 +1,163 @@
+
+
+
+
+
+ Debug Draggable Issue
+
+
+
+
Debug Draggable Issue
+
+
Test 1: Inline Items
+
+
Inline 1
+
Inline 2
+
Inline 3
+
+
+
Test 2: Horizontal Items
+
+
Horizontal 1
+
Horizontal 2
+
Horizontal 3
+
+
+
Debug Output:
+
+
+
+
+
\ No newline at end of file
diff --git a/html-tests/index.html b/html-tests/index.html
new file mode 100644
index 0000000..b944887
--- /dev/null
+++ b/html-tests/index.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+ HTML Test Files - Resortable
+
+
+
+
📝 HTML Test Files
+
These are manual test files for debugging and verifying Resortable functionality.
Verify event listeners are properly attached and detached
+
+
+
+
+
+ 💡 These test files are for manual testing and debugging. For automated tests, see /tests/e2e/
+
+
+
\ No newline at end of file
diff --git a/html-tests/manual-test-empty.html b/html-tests/manual-test-empty.html
new file mode 100644
index 0000000..8a9cc82
--- /dev/null
+++ b/html-tests/manual-test-empty.html
@@ -0,0 +1,92 @@
+
+
+
+ Manual Empty Container Test
+
+
+
+
Empty Container Drop Test
+
Ready
+
+
+
Source (has items)
+
Item 1
+
Item 2
+
Item 3
+
+
+
+
Empty Container
+
+
+
+
+
\ No newline at end of file
diff --git a/html-tests/test-animations.html b/html-tests/test-animations.html
new file mode 100644
index 0000000..5a1a920
--- /dev/null
+++ b/html-tests/test-animations.html
@@ -0,0 +1,270 @@
+
+
+
+
+
+ Animation Test
+
+
+
+
🎬 FLIP Animation Test
+
+
+
+
Animation Settings
+
+
+
+ 150
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🍎 Apple
+
🍌 Banana
+
🍇 Grape
+
🍊 Orange
+
🍓 Strawberry
+
🥝 Kiwi
+
🍑 Peach
+
🍒 Cherry
+
+
+
Drag items to reorder. Watch for smooth FLIP animations!
+
+
+
+
+
\ No newline at end of file
diff --git a/test-drag.html b/html-tests/test-drag.html
similarity index 98%
rename from test-drag.html
rename to html-tests/test-drag.html
index 08e7c90..d71720a 100644
--- a/test-drag.html
+++ b/html-tests/test-drag.html
@@ -55,7 +55,7 @@