@@ -9,6 +9,7 @@ import { randomRef } from "@pitter-patter/refs";
99
1010import { isShuffleRow , supportsDrag , supportsResize } from "./schema" ;
1111import { autogroup } from "./transform/autogroup" ;
12+ import { inflate } from "./transform/inflate.js" ;
1213import { reorder } from "./transform/reorder" ;
1314import { reposition } from "./transform/reposition" ;
1415import { TranslateCalculator } from "./translation.js" ;
@@ -277,6 +278,28 @@ export function shuffle({ hoverDecorations }: ShufflePluginOptions = {}) {
277278 } ,
278279 } ,
279280 } ,
281+ view ( view ) {
282+ function handleInflatePointerDown ( event : PointerEvent ) {
283+ if ( ! view . editable ) return ;
284+ if ( ! ( event . target instanceof HTMLElement ) ) return ;
285+
286+ if ( view . dom . contains ( event . target ) ) return ;
287+
288+ const draggable = event . target . closest ( "[data-shuffle-inflatable]" ) ;
289+
290+ if ( ! ( draggable instanceof HTMLElement ) ) return ;
291+
292+ startDragOnPointerDown ( view , null , draggable , event . clientX , event . clientY ) ;
293+ }
294+
295+ view . root . addEventListener ( "pointerdown" , handleInflatePointerDown as EventListener ) ;
296+
297+ return {
298+ destroy ( ) {
299+ view . root . removeEventListener ( "pointerdown" , handleInflatePointerDown as EventListener ) ;
300+ } ,
301+ } ;
302+ } ,
280303 } ) ;
281304}
282305
@@ -293,7 +316,7 @@ interface NodeViewDesc {
293316
294317export function startDragOnPointerDown (
295318 view : EditorView ,
296- pos : number ,
319+ pos : number | null ,
297320 dom : HTMLElement & { pmViewDesc ?: ViewDesc } ,
298321 clientX : number ,
299322 clientY : number ,
@@ -329,16 +352,19 @@ export function startDragOnPointerDown(
329352 let layout : AutoLayout | null = null ;
330353 let currentAnimation : Timeline | null = null ;
331354 let skeletonOn = false ;
355+
332356 const onMove = throttle ( function onMove ( e : PointerEvent ) {
333357 if ( ! skeletonOn || ! clone || ! initialStyles || ! layout ) {
334358 const startResult = startDrag ( dom ! , translateCalc ) ;
335359
336- view . dispatch (
337- view . state . tr . setMeta ( shufflePluginKey , {
338- type : "map" ,
339- payload : { newPos : pos } ,
340- } ) ,
341- ) ;
360+ if ( pos !== null ) {
361+ view . dispatch (
362+ view . state . tr . setMeta ( shufflePluginKey , {
363+ type : "map" ,
364+ payload : { newPos : pos } ,
365+ } satisfies ShufflePluginMeta ) ,
366+ ) ;
367+ }
342368
343369 clone = startResult . clone ;
344370 clone . dataset [ "shuffleClone" ] = "true" ;
@@ -362,14 +388,13 @@ export function startDragOnPointerDown(
362388
363389 const before = shufflePluginKey . getState ( view . state ) ?. activeNodePos ;
364390
365- if ( before === undefined ) return ;
366-
367391 if ( currentAnimation ?. began && ! currentAnimation . completed ) return ;
368392
369- const tr =
370- autogroup ( view , before , e . clientX , e . clientY ) ??
371- reorder ( view , before , e . clientX , e . clientY ) ??
372- reposition ( view , before , clone ! . getBoundingClientRect ( ) ) ;
393+ const tr = before
394+ ? ( autogroup ( view , before , e . clientX , e . clientY ) ??
395+ reorder ( view , before , e . clientX , e . clientY ) ??
396+ reposition ( view , before , clone . getBoundingClientRect ( ) ) )
397+ : inflate ( view , clone , e . clientX , e . clientY ) ;
373398
374399 if ( ! tr ) return ;
375400
@@ -389,6 +414,26 @@ export function startDragOnPointerDown(
389414 dom . dataset [ "shuffleActive" ] = "true" ;
390415 } ) ;
391416
417+ function endDrag ( domRect ?: DOMRect ) {
418+ if ( ! clone || ! initialStyles ) return ;
419+
420+ clone . style . transition = "transform 0.2s ease" ;
421+ clone . style . boxShadow = initialStyles . boxShadow ;
422+
423+ const { transform, transformOrigin } = domRect
424+ ? translateCalc . place ( domRect . left , domRect . top )
425+ : translateCalc . reset ( ) ;
426+
427+ clone . style . transform = transform ;
428+ clone . style . transformOrigin = transformOrigin ;
429+
430+ setTimeout ( ( ) => {
431+ clone ! . style . transition = "none" ;
432+ delete dom . dataset [ "shuffleActive" ] ;
433+ clone ! . remove ( ) ;
434+ } , 250 ) ;
435+ }
436+
392437 function onUp ( ) {
393438 document . removeEventListener ( "mousedown" , preventSelection ) ;
394439 document . removeEventListener ( "mousedown" , preventSelection ) ;
@@ -410,34 +455,20 @@ export function startDragOnPointerDown(
410455
411456 const before = shufflePluginKey . getState ( view . state ) ?. activeNodePos ;
412457
413- if ( before === undefined ) return ;
458+ if ( before === undefined ) return endDrag ( ) ;
414459
415460 const dom = view . nodeDOM ( before ) ;
416- if ( ! ( dom instanceof HTMLElement ) ) return ;
461+ if ( ! ( dom instanceof HTMLElement ) ) return endDrag ( ) ;
417462
418463 view . dispatch (
419464 view . state . tr . setMeta ( shufflePluginKey , {
420465 type : "end" ,
421466 } satisfies ShufflePluginMeta ) ,
422467 ) ;
423468
424- clone . style . transition = "transform 0.2s ease" ;
425- clone . style . boxShadow = initialStyles . boxShadow ;
426-
427469 const domRect = dom . getBoundingClientRect ( ) ;
428470
429- const { transform, transformOrigin } = translateCalc . place ( domRect . left , domRect . top ) ;
430-
431- clone . style . transform = transform ;
432- clone . style . transformOrigin = transformOrigin ;
433-
434- setTimeout ( ( ) => {
435- clone ! . style . transition = "none" ;
436- delete dom . dataset [ "shuffleActive" ] ;
437- clone ! . remove ( ) ;
438- } , 250 ) ;
439-
440- return ;
471+ return endDrag ( domRect ) ;
441472 }
442473
443474 const preventSelection = ( e : MouseEvent ) => {
0 commit comments