UNPKG

@wordpress/block-editor

Version:
8 lines (7 loc) 5.71 kB
{ "version": 3, "sources": ["../../../src/components/block-draggable/use-scroll-when-dragging.js"], "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { getScrollContainer } from '@wordpress/dom';\nimport { useCallback, useEffect, useRef } from '@wordpress/element';\n\nconst SCROLL_INACTIVE_DISTANCE_PX = 50;\nconst SCROLL_INTERVAL_MS = 25;\nconst PIXELS_PER_SECOND_PER_PERCENTAGE = 1000;\nconst VELOCITY_MULTIPLIER =\n\tPIXELS_PER_SECOND_PER_PERCENTAGE * ( SCROLL_INTERVAL_MS / 1000 );\n\n/**\n * React hook that scrolls the scroll container when a block is being dragged.\n *\n * @return {Function[]} `startScrolling`, `scrollOnDragOver`, `stopScrolling`\n * functions to be called in `onDragStart`, `onDragOver`\n * and `onDragEnd` events respectively.\n */\nexport default function useScrollWhenDragging() {\n\tconst dragStartYRef = useRef( null );\n\tconst velocityYRef = useRef( null );\n\tconst scrollParentYRef = useRef( null );\n\tconst scrollEditorIntervalRef = useRef( null );\n\n\t// Clear interval when unmounting.\n\tuseEffect(\n\t\t() => () => {\n\t\t\tif ( scrollEditorIntervalRef.current ) {\n\t\t\t\tclearInterval( scrollEditorIntervalRef.current );\n\t\t\t\tscrollEditorIntervalRef.current = null;\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\tconst startScrolling = useCallback( ( event ) => {\n\t\tdragStartYRef.current = event.clientY;\n\n\t\t// Find nearest parent(s) to scroll.\n\t\tscrollParentYRef.current = getScrollContainer( event.target );\n\n\t\tscrollEditorIntervalRef.current = setInterval( () => {\n\t\t\tif ( scrollParentYRef.current && velocityYRef.current ) {\n\t\t\t\tconst newTop =\n\t\t\t\t\tscrollParentYRef.current.scrollTop + velocityYRef.current;\n\n\t\t\t\t// Setting `behavior: 'smooth'` as a scroll property seems to hurt performance.\n\t\t\t\t// Better to use a small scroll interval.\n\t\t\t\tscrollParentYRef.current.scroll( {\n\t\t\t\t\ttop: newTop,\n\t\t\t\t} );\n\t\t\t}\n\t\t}, SCROLL_INTERVAL_MS );\n\t}, [] );\n\n\tconst scrollOnDragOver = useCallback( ( event ) => {\n\t\tif ( ! scrollParentYRef.current ) {\n\t\t\treturn;\n\t\t}\n\t\tconst scrollParentHeight = scrollParentYRef.current.offsetHeight;\n\t\tconst offsetDragStartPosition =\n\t\t\tdragStartYRef.current - scrollParentYRef.current.offsetTop;\n\t\tconst offsetDragPosition =\n\t\t\tevent.clientY - scrollParentYRef.current.offsetTop;\n\n\t\tif ( event.clientY > offsetDragStartPosition ) {\n\t\t\t// User is dragging downwards.\n\t\t\tconst moveableDistance = Math.max(\n\t\t\t\tscrollParentHeight -\n\t\t\t\t\toffsetDragStartPosition -\n\t\t\t\t\tSCROLL_INACTIVE_DISTANCE_PX,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst dragDistance = Math.max(\n\t\t\t\toffsetDragPosition -\n\t\t\t\t\toffsetDragStartPosition -\n\t\t\t\t\tSCROLL_INACTIVE_DISTANCE_PX,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst distancePercentage =\n\t\t\t\tmoveableDistance === 0 || dragDistance === 0\n\t\t\t\t\t? 0\n\t\t\t\t\t: dragDistance / moveableDistance;\n\t\t\tvelocityYRef.current = VELOCITY_MULTIPLIER * distancePercentage;\n\t\t} else if ( event.clientY < offsetDragStartPosition ) {\n\t\t\t// User is dragging upwards.\n\t\t\tconst moveableDistance = Math.max(\n\t\t\t\toffsetDragStartPosition - SCROLL_INACTIVE_DISTANCE_PX,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst dragDistance = Math.max(\n\t\t\t\toffsetDragStartPosition -\n\t\t\t\t\toffsetDragPosition -\n\t\t\t\t\tSCROLL_INACTIVE_DISTANCE_PX,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst distancePercentage =\n\t\t\t\tmoveableDistance === 0 || dragDistance === 0\n\t\t\t\t\t? 0\n\t\t\t\t\t: dragDistance / moveableDistance;\n\t\t\tvelocityYRef.current = -VELOCITY_MULTIPLIER * distancePercentage;\n\t\t} else {\n\t\t\tvelocityYRef.current = 0;\n\t\t}\n\t}, [] );\n\n\tconst stopScrolling = () => {\n\t\tdragStartYRef.current = null;\n\t\tscrollParentYRef.current = null;\n\n\t\tif ( scrollEditorIntervalRef.current ) {\n\t\t\tclearInterval( scrollEditorIntervalRef.current );\n\t\t\tscrollEditorIntervalRef.current = null;\n\t\t}\n\t};\n\n\treturn [ startScrolling, scrollOnDragOver, stopScrolling ];\n}\n"], "mappings": ";AAGA,SAAS,0BAA0B;AACnC,SAAS,aAAa,WAAW,cAAc;AAE/C,IAAM,8BAA8B;AACpC,IAAM,qBAAqB;AAC3B,IAAM,mCAAmC;AACzC,IAAM,sBACL,oCAAqC,qBAAqB;AAS5C,SAAR,wBAAyC;AAC/C,QAAM,gBAAgB,OAAQ,IAAK;AACnC,QAAM,eAAe,OAAQ,IAAK;AAClC,QAAM,mBAAmB,OAAQ,IAAK;AACtC,QAAM,0BAA0B,OAAQ,IAAK;AAG7C;AAAA,IACC,MAAM,MAAM;AACX,UAAK,wBAAwB,SAAU;AACtC,sBAAe,wBAAwB,OAAQ;AAC/C,gCAAwB,UAAU;AAAA,MACnC;AAAA,IACD;AAAA,IACA,CAAC;AAAA,EACF;AAEA,QAAM,iBAAiB,YAAa,CAAE,UAAW;AAChD,kBAAc,UAAU,MAAM;AAG9B,qBAAiB,UAAU,mBAAoB,MAAM,MAAO;AAE5D,4BAAwB,UAAU,YAAa,MAAM;AACpD,UAAK,iBAAiB,WAAW,aAAa,SAAU;AACvD,cAAM,SACL,iBAAiB,QAAQ,YAAY,aAAa;AAInD,yBAAiB,QAAQ,OAAQ;AAAA,UAChC,KAAK;AAAA,QACN,CAAE;AAAA,MACH;AAAA,IACD,GAAG,kBAAmB;AAAA,EACvB,GAAG,CAAC,CAAE;AAEN,QAAM,mBAAmB,YAAa,CAAE,UAAW;AAClD,QAAK,CAAE,iBAAiB,SAAU;AACjC;AAAA,IACD;AACA,UAAM,qBAAqB,iBAAiB,QAAQ;AACpD,UAAM,0BACL,cAAc,UAAU,iBAAiB,QAAQ;AAClD,UAAM,qBACL,MAAM,UAAU,iBAAiB,QAAQ;AAE1C,QAAK,MAAM,UAAU,yBAA0B;AAE9C,YAAM,mBAAmB,KAAK;AAAA,QAC7B,qBACC,0BACA;AAAA,QACD;AAAA,MACD;AACA,YAAM,eAAe,KAAK;AAAA,QACzB,qBACC,0BACA;AAAA,QACD;AAAA,MACD;AACA,YAAM,qBACL,qBAAqB,KAAK,iBAAiB,IACxC,IACA,eAAe;AACnB,mBAAa,UAAU,sBAAsB;AAAA,IAC9C,WAAY,MAAM,UAAU,yBAA0B;AAErD,YAAM,mBAAmB,KAAK;AAAA,QAC7B,0BAA0B;AAAA,QAC1B;AAAA,MACD;AACA,YAAM,eAAe,KAAK;AAAA,QACzB,0BACC,qBACA;AAAA,QACD;AAAA,MACD;AACA,YAAM,qBACL,qBAAqB,KAAK,iBAAiB,IACxC,IACA,eAAe;AACnB,mBAAa,UAAU,CAAC,sBAAsB;AAAA,IAC/C,OAAO;AACN,mBAAa,UAAU;AAAA,IACxB;AAAA,EACD,GAAG,CAAC,CAAE;AAEN,QAAM,gBAAgB,MAAM;AAC3B,kBAAc,UAAU;AACxB,qBAAiB,UAAU;AAE3B,QAAK,wBAAwB,SAAU;AACtC,oBAAe,wBAAwB,OAAQ;AAC/C,8BAAwB,UAAU;AAAA,IACnC;AAAA,EACD;AAEA,SAAO,CAAE,gBAAgB,kBAAkB,aAAc;AAC1D;", "names": [] }