editor: explain slot refusals on-page; auto-scroll while dragging\n\nDrag state now records the tagged slot under the pointer. When the\ndragged type does not fit it, a badge on the zone names the accepted\ntypes (from the slot schema) and the pointer chip turns refused -\npreviously a refused slot silently fell back to a container drop.\nHolding the pointer near a viewport edge scrolls the page (ramped\nrAF loop, re-targeting after each step) so long pages are droppable\nend to end. Helpers are unit-tested; harness covers refusal badge,\naccept path and the scroll step.\n\n🤖 Generated with Codebuff\nCo-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
1 parent
8e8823421d
commit
40b33f89a4
6 files changed
+154
-12
No files matched your search
+22
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { dropTarget, moveTarget } from '../src/page/dnd'
|
||||
import { dropTarget, edgeScroll, moveTarget, slotAt } from '../src/page/dnd'
|
||||
import type { DndBlock, DndSlot } from '../src/page/dnd'
|
||||
|
||||
const r = (y: number, h = 100, x = 0, w = 600) => ({ x, y, w, h })
|
||||
@@ -63,6 +63,27 @@ describe('dropTarget with tagged slots ([data-cms-slot])', () => {
|
||||
it('without an acceptsSlot filter the slot still wins over the container', () => {
|
||||
expect(dropTarget(pdp, { x: 50, y: 200 }, 'C', undefined, slots)).toMatchObject({ parentId: 'p1', handle: '3d-accessories' })
|
||||
})
|
||||
it('slotAt reports the zone under the pointer regardless of fit', () => {
|
||||
const zones: DndSlot[] = [
|
||||
{ handle: 'sidebar', parentId: 's1', rect: r(190, 150, 0, 600), kids: [] },
|
||||
{ handle: 'hero', parentId: 's1', rect: r(10, 100, 0, 600), kids: [] },
|
||||
]
|
||||
expect(slotAt(zones, { x: 50, y: 200 })?.handle).toBe('sidebar')
|
||||
expect(slotAt(zones, { x: 50, y: 50 })?.handle).toBe('hero')
|
||||
expect(slotAt(zones, { x: 50, y: 500 })).toBeNull()
|
||||
})
|
||||
|
||||
it('edgeScroll stays put inside the safe area and ramps to max at the edge', () => {
|
||||
expect(edgeScroll(400, 300, 800, 600)).toEqual({ dx: 0, dy: 0 })
|
||||
expect(edgeScroll(0, 300, 800, 600).dx).toBe(-24)
|
||||
expect(edgeScroll(800, 300, 800, 600).dx).toBe(24)
|
||||
expect(edgeScroll(400, 0, 800, 600).dy).toBe(-24)
|
||||
expect(edgeScroll(400, 600, 800, 600).dy).toBe(24)
|
||||
const half = edgeScroll(36, 300, 800, 600)
|
||||
expect(half.dx).toBeLessThan(0)
|
||||
expect(half.dx).toBeGreaterThan(-24)
|
||||
})
|
||||
|
||||
it('moveTarget sorts within the dragged block\'s own slot', () => {
|
||||
const two: DndBlock[] = [
|
||||
{ id: 'p1', container: true, depth: 0, rect: r(0, 400) },
|
||||
|
||||
Reference in new issue
Block a user