@bquery/bquery 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -23
- package/dist/a11y/announce.d.ts +43 -0
- package/dist/a11y/announce.d.ts.map +1 -0
- package/dist/a11y/audit.d.ts +42 -0
- package/dist/a11y/audit.d.ts.map +1 -0
- package/dist/a11y/index.d.ts +53 -0
- package/dist/a11y/index.d.ts.map +1 -0
- package/dist/a11y/media-preferences.d.ts +77 -0
- package/dist/a11y/media-preferences.d.ts.map +1 -0
- package/dist/a11y/roving-tab-index.d.ts +38 -0
- package/dist/a11y/roving-tab-index.d.ts.map +1 -0
- package/dist/a11y/skip-link.d.ts +37 -0
- package/dist/a11y/skip-link.d.ts.map +1 -0
- package/dist/a11y/trap-focus.d.ts +49 -0
- package/dist/a11y/trap-focus.d.ts.map +1 -0
- package/dist/a11y/types.d.ts +152 -0
- package/dist/a11y/types.d.ts.map +1 -0
- package/dist/a11y-C5QOVvRn.js +421 -0
- package/dist/a11y-C5QOVvRn.js.map +1 -0
- package/dist/a11y.es.mjs +14 -0
- package/dist/component/component.d.ts +13 -5
- package/dist/component/component.d.ts.map +1 -1
- package/dist/component/html.d.ts +40 -3
- package/dist/component/html.d.ts.map +1 -1
- package/dist/component/index.d.ts +3 -2
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/library.d.ts.map +1 -1
- package/dist/component/scope.d.ts +138 -0
- package/dist/component/scope.d.ts.map +1 -0
- package/dist/component/types.d.ts +184 -17
- package/dist/component/types.d.ts.map +1 -1
- package/dist/component-CuuTijA6.js +684 -0
- package/dist/component-CuuTijA6.js.map +1 -0
- package/dist/component.es.mjs +10 -6
- package/dist/{config-DRmZZno3.js → config-BW35FKuA.js} +4 -4
- package/dist/config-BW35FKuA.js.map +1 -0
- package/dist/constraints-3lV9yyBw.js +100 -0
- package/dist/constraints-3lV9yyBw.js.map +1 -0
- package/dist/core/collection.d.ts +48 -0
- package/dist/core/collection.d.ts.map +1 -1
- package/dist/core/element.d.ts +92 -0
- package/dist/core/element.d.ts.map +1 -1
- package/dist/core/env.d.ts +18 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/shared.d.ts +8 -0
- package/dist/core/shared.d.ts.map +1 -1
- package/dist/core/utils/index.d.ts +52 -41
- package/dist/core/utils/index.d.ts.map +1 -1
- package/dist/core-Cjl7GUu8.js +717 -0
- package/dist/core-Cjl7GUu8.js.map +1 -0
- package/dist/{core-DPdbItcq.js → core-DnlyjbF2.js} +1 -1
- package/dist/{core-DPdbItcq.js.map → core-DnlyjbF2.js.map} +1 -1
- package/dist/core.es.mjs +45 -44
- package/dist/custom-directives-7wAShnnd.js +9 -0
- package/dist/custom-directives-7wAShnnd.js.map +1 -0
- package/dist/devtools/devtools.d.ts +212 -0
- package/dist/devtools/devtools.d.ts.map +1 -0
- package/dist/devtools/index.d.ts +20 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/types.d.ts +69 -0
- package/dist/devtools/types.d.ts.map +1 -0
- package/dist/devtools-D2fQLhDN.js +122 -0
- package/dist/devtools-D2fQLhDN.js.map +1 -0
- package/dist/devtools.es.mjs +19 -0
- package/dist/dnd/draggable.d.ts +51 -0
- package/dist/dnd/draggable.d.ts.map +1 -0
- package/dist/dnd/droppable.d.ts +38 -0
- package/dist/dnd/droppable.d.ts.map +1 -0
- package/dist/dnd/index.d.ts +47 -0
- package/dist/dnd/index.d.ts.map +1 -0
- package/dist/dnd/sortable.d.ts +43 -0
- package/dist/dnd/sortable.d.ts.map +1 -0
- package/dist/dnd/types.d.ts +250 -0
- package/dist/dnd/types.d.ts.map +1 -0
- package/dist/dnd-B8EgyzaI.js +244 -0
- package/dist/dnd-B8EgyzaI.js.map +1 -0
- package/dist/dnd.es.mjs +6 -0
- package/dist/env-NeVmr4Gf.js +19 -0
- package/dist/env-NeVmr4Gf.js.map +1 -0
- package/dist/forms/create-form.d.ts +49 -0
- package/dist/forms/create-form.d.ts.map +1 -0
- package/dist/forms/index.d.ts +39 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/types.d.ts +139 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/validators.d.ts +179 -0
- package/dist/forms/validators.d.ts.map +1 -0
- package/dist/forms-C3yovgH9.js +141 -0
- package/dist/forms-C3yovgH9.js.map +1 -0
- package/dist/forms.es.mjs +14 -0
- package/dist/full.d.ts +37 -9
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +186 -91
- package/dist/full.iife.js +47 -31
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +47 -31
- package/dist/full.umd.js.map +1 -1
- package/dist/i18n/formatting.d.ts +40 -0
- package/dist/i18n/formatting.d.ts.map +1 -0
- package/dist/i18n/i18n.d.ts +48 -0
- package/dist/i18n/i18n.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +57 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/translate.d.ts +83 -0
- package/dist/i18n/translate.d.ts.map +1 -0
- package/dist/i18n/types.d.ts +156 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n-BnnhTFOS.js +89 -0
- package/dist/i18n-BnnhTFOS.js.map +1 -0
- package/dist/i18n.es.mjs +6 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.mjs +233 -138
- package/dist/media/battery.d.ts +35 -0
- package/dist/media/battery.d.ts.map +1 -0
- package/dist/media/breakpoints.d.ts +51 -0
- package/dist/media/breakpoints.d.ts.map +1 -0
- package/dist/media/clipboard.d.ts +30 -0
- package/dist/media/clipboard.d.ts.map +1 -0
- package/dist/media/device-sensors.d.ts +54 -0
- package/dist/media/device-sensors.d.ts.map +1 -0
- package/dist/media/geolocation.d.ts +38 -0
- package/dist/media/geolocation.d.ts.map +1 -0
- package/dist/media/index.d.ts +42 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/media-query.d.ts +36 -0
- package/dist/media/media-query.d.ts.map +1 -0
- package/dist/media/network.d.ts +35 -0
- package/dist/media/network.d.ts.map +1 -0
- package/dist/media/types.d.ts +173 -0
- package/dist/media/types.d.ts.map +1 -0
- package/dist/media/viewport.d.ts +32 -0
- package/dist/media/viewport.d.ts.map +1 -0
- package/dist/media-Di2Ta22s.js +340 -0
- package/dist/media-Di2Ta22s.js.map +1 -0
- package/dist/media.es.mjs +12 -0
- package/dist/motion/index.d.ts +7 -3
- package/dist/motion/index.d.ts.map +1 -1
- package/dist/motion/morph.d.ts +27 -0
- package/dist/motion/morph.d.ts.map +1 -0
- package/dist/motion/parallax.d.ts +30 -0
- package/dist/motion/parallax.d.ts.map +1 -0
- package/dist/motion/reduced-motion.d.ts +36 -3
- package/dist/motion/reduced-motion.d.ts.map +1 -1
- package/dist/motion/types.d.ts +58 -0
- package/dist/motion/types.d.ts.map +1 -1
- package/dist/motion/typewriter.d.ts +31 -0
- package/dist/motion/typewriter.d.ts.map +1 -0
- package/dist/motion-qPj_TYGv.js +530 -0
- package/dist/motion-qPj_TYGv.js.map +1 -0
- package/dist/motion.es.mjs +27 -23
- package/dist/mount-SM07RUa6.js +403 -0
- package/dist/mount-SM07RUa6.js.map +1 -0
- package/dist/{object-qGpWr6-J.js → object-BCk-1c8T.js} +5 -4
- package/dist/{object-qGpWr6-J.js.map → object-BCk-1c8T.js.map} +1 -1
- package/dist/{platform-B7JhGBc7.js → platform-CPbCprb6.js} +3 -3
- package/dist/platform-CPbCprb6.js.map +1 -0
- package/dist/platform.es.mjs +2 -2
- package/dist/plugin/index.d.ts +22 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/registry.d.ts +108 -0
- package/dist/plugin/registry.d.ts.map +1 -0
- package/dist/plugin/types.d.ts +110 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin-cPoOHFLY.js +64 -0
- package/dist/plugin-cPoOHFLY.js.map +1 -0
- package/dist/plugin.es.mjs +9 -0
- package/dist/reactive/computed.d.ts +7 -0
- package/dist/reactive/computed.d.ts.map +1 -1
- package/dist/reactive-Cfv0RK6x.js +233 -0
- package/dist/reactive-Cfv0RK6x.js.map +1 -0
- package/dist/reactive.es.mjs +18 -17
- package/dist/registry-CWf368tT.js +26 -0
- package/dist/registry-CWf368tT.js.map +1 -0
- package/dist/router/bq-link.d.ts +112 -0
- package/dist/router/bq-link.d.ts.map +1 -0
- package/dist/router/constraints.d.ts +9 -0
- package/dist/router/constraints.d.ts.map +1 -0
- package/dist/router/index.d.ts +14 -6
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/match.d.ts +0 -1
- package/dist/router/match.d.ts.map +1 -1
- package/dist/router/path-pattern.d.ts +14 -0
- package/dist/router/path-pattern.d.ts.map +1 -0
- package/dist/router/query.d.ts.map +1 -1
- package/dist/router/router.d.ts +3 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/types.d.ts +48 -4
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/use-route.d.ts +50 -0
- package/dist/router/use-route.d.ts.map +1 -0
- package/dist/router/utils.d.ts +3 -0
- package/dist/router/utils.d.ts.map +1 -1
- package/dist/router-BrthaP_z.js +473 -0
- package/dist/router-BrthaP_z.js.map +1 -0
- package/dist/router.es.mjs +13 -10
- package/dist/{sanitize-jyJ2ryE2.js → sanitize-B1V4JswB.js} +95 -83
- package/dist/sanitize-B1V4JswB.js.map +1 -0
- package/dist/security/index.d.ts +2 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/sanitize.d.ts +4 -1
- package/dist/security/sanitize.d.ts.map +1 -1
- package/dist/security/trusted-html.d.ts +53 -0
- package/dist/security/trusted-html.d.ts.map +1 -0
- package/dist/security.es.mjs +10 -9
- package/dist/ssr/hydrate.d.ts +65 -0
- package/dist/ssr/hydrate.d.ts.map +1 -0
- package/dist/ssr/index.d.ts +59 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/render.d.ts +62 -0
- package/dist/ssr/render.d.ts.map +1 -0
- package/dist/ssr/serialize.d.ts +118 -0
- package/dist/ssr/serialize.d.ts.map +1 -0
- package/dist/ssr/types.d.ts +70 -0
- package/dist/ssr/types.d.ts.map +1 -0
- package/dist/ssr-B2qd_WBB.js +248 -0
- package/dist/ssr-B2qd_WBB.js.map +1 -0
- package/dist/ssr.es.mjs +9 -0
- package/dist/store/create-store.d.ts.map +1 -1
- package/dist/store/define-store.d.ts +1 -1
- package/dist/store/define-store.d.ts.map +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/mapping.d.ts +1 -1
- package/dist/store/mapping.d.ts.map +1 -1
- package/dist/store/persisted.d.ts +38 -4
- package/dist/store/persisted.d.ts.map +1 -1
- package/dist/store/types.d.ts +140 -3
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/utils.d.ts +2 -2
- package/dist/store/utils.d.ts.map +1 -1
- package/dist/store/watch.d.ts +1 -1
- package/dist/store/watch.d.ts.map +1 -1
- package/dist/store-DWpyH6p5.js +338 -0
- package/dist/store-DWpyH6p5.js.map +1 -0
- package/dist/store.es.mjs +11 -10
- package/dist/storybook/index.d.ts +37 -0
- package/dist/storybook/index.d.ts.map +1 -0
- package/dist/storybook.es.mjs +151 -0
- package/dist/storybook.es.mjs.map +1 -0
- package/dist/testing/index.d.ts +23 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/testing.d.ts +156 -0
- package/dist/testing/testing.d.ts.map +1 -0
- package/dist/testing/types.d.ts +134 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing-CsqjNUyy.js +224 -0
- package/dist/testing-CsqjNUyy.js.map +1 -0
- package/dist/testing.es.mjs +9 -0
- package/dist/type-guards-Do9DWgNp.js +44 -0
- package/dist/type-guards-Do9DWgNp.js.map +1 -0
- package/dist/untrack-DJVQQ2WM.js +33 -0
- package/dist/untrack-DJVQQ2WM.js.map +1 -0
- package/dist/view/custom-directives.d.ts +20 -0
- package/dist/view/custom-directives.d.ts.map +1 -0
- package/dist/view/evaluate.d.ts.map +1 -1
- package/dist/view/process.d.ts.map +1 -1
- package/dist/view.es.mjs +11 -10
- package/package.json +52 -11
- package/src/a11y/announce.ts +131 -0
- package/src/a11y/audit.ts +314 -0
- package/src/a11y/index.ts +68 -0
- package/src/a11y/media-preferences.ts +255 -0
- package/src/a11y/roving-tab-index.ts +164 -0
- package/src/a11y/skip-link.ts +255 -0
- package/src/a11y/trap-focus.ts +184 -0
- package/src/a11y/types.ts +183 -0
- package/src/component/component.ts +345 -65
- package/src/component/html.ts +153 -53
- package/src/component/index.ts +12 -2
- package/src/component/library.ts +66 -28
- package/src/component/scope.ts +212 -0
- package/src/component/types.ts +238 -19
- package/src/core/collection.ts +707 -628
- package/src/core/element.ts +981 -774
- package/src/core/env.ts +60 -0
- package/src/core/index.ts +49 -48
- package/src/core/shared.ts +62 -13
- package/src/core/utils/index.ts +148 -83
- package/src/devtools/devtools.ts +410 -0
- package/src/devtools/index.ts +48 -0
- package/src/devtools/types.ts +104 -0
- package/src/dnd/draggable.ts +296 -0
- package/src/dnd/droppable.ts +228 -0
- package/src/dnd/index.ts +62 -0
- package/src/dnd/sortable.ts +307 -0
- package/src/dnd/types.ts +293 -0
- package/src/forms/create-form.ts +278 -0
- package/src/forms/index.ts +65 -0
- package/src/forms/types.ts +154 -0
- package/src/forms/validators.ts +265 -0
- package/src/full.ts +260 -3
- package/src/i18n/formatting.ts +67 -0
- package/src/i18n/i18n.ts +200 -0
- package/src/i18n/index.ts +67 -0
- package/src/i18n/translate.ts +182 -0
- package/src/i18n/types.ts +171 -0
- package/src/index.ts +108 -36
- package/src/media/battery.ts +116 -0
- package/src/media/breakpoints.ts +131 -0
- package/src/media/clipboard.ts +80 -0
- package/src/media/device-sensors.ts +158 -0
- package/src/media/geolocation.ts +119 -0
- package/src/media/index.ts +76 -0
- package/src/media/media-query.ts +92 -0
- package/src/media/network.ts +115 -0
- package/src/media/types.ts +177 -0
- package/src/media/viewport.ts +84 -0
- package/src/motion/index.ts +57 -48
- package/src/motion/morph.ts +151 -0
- package/src/motion/parallax.ts +120 -0
- package/src/motion/reduced-motion.ts +66 -17
- package/src/motion/transition.ts +97 -97
- package/src/motion/types.ts +63 -0
- package/src/motion/typewriter.ts +164 -0
- package/src/platform/announcer.ts +208 -208
- package/src/platform/config.ts +163 -163
- package/src/platform/cookies.ts +165 -165
- package/src/platform/index.ts +39 -39
- package/src/platform/meta.ts +168 -168
- package/src/plugin/index.ts +37 -0
- package/src/plugin/registry.ts +269 -0
- package/src/plugin/types.ts +137 -0
- package/src/reactive/async-data.ts +486 -486
- package/src/reactive/computed.ts +130 -92
- package/src/reactive/index.ts +37 -37
- package/src/reactive/signal.ts +29 -29
- package/src/router/bq-link.ts +279 -0
- package/src/router/constraints.ts +201 -0
- package/src/router/index.ts +49 -41
- package/src/router/match.ts +312 -106
- package/src/router/path-pattern.ts +52 -0
- package/src/router/query.ts +38 -35
- package/src/router/router.ts +402 -211
- package/src/router/types.ts +139 -93
- package/src/router/use-route.ts +68 -0
- package/src/router/utils.ts +157 -116
- package/src/security/constants.ts +211 -211
- package/src/security/index.ts +12 -10
- package/src/security/sanitize.ts +6 -2
- package/src/security/trusted-html.ts +71 -0
- package/src/ssr/hydrate.ts +82 -0
- package/src/ssr/index.ts +70 -0
- package/src/ssr/render.ts +508 -0
- package/src/ssr/serialize.ts +296 -0
- package/src/ssr/types.ts +81 -0
- package/src/store/create-store.ts +467 -329
- package/src/store/define-store.ts +2 -1
- package/src/store/index.ts +27 -22
- package/src/store/mapping.ts +2 -1
- package/src/store/persisted.ts +249 -61
- package/src/store/types.ts +247 -94
- package/src/store/utils.ts +135 -141
- package/src/store/watch.ts +2 -1
- package/src/storybook/index.ts +480 -0
- package/src/testing/index.ts +42 -0
- package/src/testing/testing.ts +593 -0
- package/src/testing/types.ts +170 -0
- package/src/view/custom-directives.ts +30 -0
- package/src/view/evaluate.ts +292 -290
- package/src/view/process.ts +108 -92
- package/dist/component-CY5MVoYN.js +0 -531
- package/dist/component-CY5MVoYN.js.map +0 -1
- package/dist/config-DRmZZno3.js.map +0 -1
- package/dist/core-CK2Mfpf4.js +0 -648
- package/dist/core-CK2Mfpf4.js.map +0 -1
- package/dist/motion-C5DRdPnO.js +0 -415
- package/dist/motion-C5DRdPnO.js.map +0 -1
- package/dist/platform-B7JhGBc7.js.map +0 -1
- package/dist/reactive-BDya-ia8.js +0 -253
- package/dist/reactive-BDya-ia8.js.map +0 -1
- package/dist/router-CijiICxt.js +0 -188
- package/dist/router-CijiICxt.js.map +0 -1
- package/dist/sanitize-jyJ2ryE2.js.map +0 -1
- package/dist/store-CPK9E62U.js +0 -262
- package/dist/store-CPK9E62U.js.map +0 -1
- package/dist/view-Cdi0g-qo.js +0 -396
- package/dist/view-Cdi0g-qo.js.map +0 -1
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make an element draggable using pointer events.
|
|
3
|
+
*
|
|
4
|
+
* Uses Pointer Events (not HTML5 Drag & Drop) for reliable
|
|
5
|
+
* cross-platform behavior including touch support.
|
|
6
|
+
*
|
|
7
|
+
* @module bquery/dnd
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
BoundsRect,
|
|
12
|
+
DragBounds,
|
|
13
|
+
DragEventData,
|
|
14
|
+
DragPosition,
|
|
15
|
+
DraggableHandle,
|
|
16
|
+
DraggableOptions,
|
|
17
|
+
} from './types';
|
|
18
|
+
|
|
19
|
+
/** Global registry of active draggable elements for drop zone detection. */
|
|
20
|
+
const activeDrags = new Map<HTMLElement, { element: HTMLElement; position: DragPosition }>();
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns the currently active drag state, if any.
|
|
24
|
+
* Used internally by `droppable()` to detect drag interactions.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export const getActiveDrag = (): { element: HTMLElement; position: DragPosition } | undefined => {
|
|
28
|
+
const entries = Array.from(activeDrags.values());
|
|
29
|
+
return entries[entries.length - 1];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Resolves a `DragBounds` value to an absolute `BoundsRect`.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
const resolveBounds = (el: HTMLElement, bounds: DragBounds): BoundsRect | null => {
|
|
37
|
+
if (typeof bounds === 'object') {
|
|
38
|
+
return bounds;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let target: HTMLElement | null = null;
|
|
42
|
+
|
|
43
|
+
if (bounds === 'parent') {
|
|
44
|
+
target = el.parentElement;
|
|
45
|
+
} else {
|
|
46
|
+
target = document.querySelector(bounds) as HTMLElement | null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!target) return null;
|
|
50
|
+
|
|
51
|
+
const rect = target.getBoundingClientRect();
|
|
52
|
+
const elRect = el.getBoundingClientRect();
|
|
53
|
+
const rawLeft = parseFloat(el.style.left || '0');
|
|
54
|
+
const rawTop = parseFloat(el.style.top || '0');
|
|
55
|
+
const leftOffset = Number.isNaN(rawLeft) ? 0 : rawLeft;
|
|
56
|
+
const topOffset = Number.isNaN(rawTop) ? 0 : rawTop;
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
left: rect.left - elRect.left + leftOffset,
|
|
60
|
+
top: rect.top - elRect.top + topOffset,
|
|
61
|
+
right: rect.right - elRect.right + leftOffset + (rect.width - elRect.width),
|
|
62
|
+
bottom: rect.bottom - elRect.bottom + topOffset + (rect.height - elRect.height),
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Clamp a position within bounds.
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
const clampPosition = (pos: DragPosition, bounds: BoundsRect | null): DragPosition => {
|
|
71
|
+
if (!bounds) return pos;
|
|
72
|
+
return {
|
|
73
|
+
x: Math.max(bounds.left, Math.min(bounds.right, pos.x)),
|
|
74
|
+
y: Math.max(bounds.top, Math.min(bounds.bottom, pos.y)),
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Makes an element draggable using pointer events.
|
|
80
|
+
*
|
|
81
|
+
* Features:
|
|
82
|
+
* - Touch and mouse support via Pointer Events
|
|
83
|
+
* - Axis locking (`x`, `y`, or `both`)
|
|
84
|
+
* - Bounds constraint (parent, selector, or explicit rect)
|
|
85
|
+
* - Optional drag handle
|
|
86
|
+
* - Ghost/clone preview during drag
|
|
87
|
+
* - Callbacks: `onDragStart`, `onDrag`, `onDragEnd`
|
|
88
|
+
*
|
|
89
|
+
* @param el - The element to make draggable
|
|
90
|
+
* @param options - Configuration options
|
|
91
|
+
* @returns A handle with `destroy()`, `disable()`, and `enable()` methods
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { draggable } from '@bquery/bquery/dnd';
|
|
96
|
+
*
|
|
97
|
+
* const handle = draggable(document.querySelector('#box'), {
|
|
98
|
+
* axis: 'both',
|
|
99
|
+
* bounds: 'parent',
|
|
100
|
+
* onDragEnd: ({ position }) => {
|
|
101
|
+
* console.log('Dropped at', position.x, position.y);
|
|
102
|
+
* },
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* // Later:
|
|
106
|
+
* handle.destroy();
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export const draggable = (el: HTMLElement, options: DraggableOptions = {}): DraggableHandle => {
|
|
110
|
+
const {
|
|
111
|
+
axis = 'both',
|
|
112
|
+
bounds,
|
|
113
|
+
handle,
|
|
114
|
+
ghost = false,
|
|
115
|
+
ghostClass = 'bq-drag-ghost',
|
|
116
|
+
draggingClass = 'bq-dragging',
|
|
117
|
+
onDragStart,
|
|
118
|
+
onDrag,
|
|
119
|
+
onDragEnd,
|
|
120
|
+
} = options;
|
|
121
|
+
|
|
122
|
+
let enabled = !options.disabled;
|
|
123
|
+
let isDragging = false;
|
|
124
|
+
let startPointer: DragPosition = { x: 0, y: 0 };
|
|
125
|
+
let currentPosition: DragPosition = { x: 0, y: 0 };
|
|
126
|
+
let previousPosition: DragPosition = { x: 0, y: 0 };
|
|
127
|
+
let ghostEl: HTMLElement | null = null;
|
|
128
|
+
let ghostStartPosition: DragPosition | null = null;
|
|
129
|
+
const previousTouchAction = el.style.touchAction;
|
|
130
|
+
const previousUserSelect = el.style.userSelect;
|
|
131
|
+
|
|
132
|
+
const createEventData = (event: PointerEvent): DragEventData => ({
|
|
133
|
+
element: el,
|
|
134
|
+
position: { ...currentPosition },
|
|
135
|
+
delta: {
|
|
136
|
+
x: currentPosition.x - previousPosition.x,
|
|
137
|
+
y: currentPosition.y - previousPosition.y,
|
|
138
|
+
},
|
|
139
|
+
event,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const createGhost = (): HTMLElement => {
|
|
143
|
+
const clone = el.cloneNode(true) as HTMLElement;
|
|
144
|
+
const rect = el.getBoundingClientRect();
|
|
145
|
+
clone.classList.add(ghostClass);
|
|
146
|
+
clone.style.position = 'fixed';
|
|
147
|
+
clone.style.left = `${rect.left}px`;
|
|
148
|
+
clone.style.top = `${rect.top}px`;
|
|
149
|
+
clone.style.width = `${rect.width}px`;
|
|
150
|
+
clone.style.height = `${rect.height}px`;
|
|
151
|
+
clone.style.pointerEvents = 'none';
|
|
152
|
+
clone.style.zIndex = '999999';
|
|
153
|
+
clone.style.opacity = '0.7';
|
|
154
|
+
clone.style.margin = '0';
|
|
155
|
+
document.body.appendChild(clone);
|
|
156
|
+
return clone;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const removeGhost = (): void => {
|
|
160
|
+
if (ghostEl) {
|
|
161
|
+
ghostEl.remove();
|
|
162
|
+
ghostEl = null;
|
|
163
|
+
}
|
|
164
|
+
ghostStartPosition = null;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const onPointerDown = (e: PointerEvent): void => {
|
|
168
|
+
if (!enabled) return;
|
|
169
|
+
|
|
170
|
+
// Check handle constraint
|
|
171
|
+
if (handle) {
|
|
172
|
+
const target = e.target as Element;
|
|
173
|
+
if (!target.closest(handle)) return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
e.preventDefault();
|
|
177
|
+
isDragging = true;
|
|
178
|
+
startPointer = { x: e.clientX, y: e.clientY };
|
|
179
|
+
previousPosition = { ...currentPosition };
|
|
180
|
+
|
|
181
|
+
el.classList.add(draggingClass);
|
|
182
|
+
el.setPointerCapture(e.pointerId);
|
|
183
|
+
|
|
184
|
+
if (ghost) {
|
|
185
|
+
const rect = el.getBoundingClientRect();
|
|
186
|
+
ghostStartPosition = { x: rect.left, y: rect.top };
|
|
187
|
+
ghostEl = createGhost();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Register in global active drags
|
|
191
|
+
activeDrags.set(el, { element: el, position: currentPosition });
|
|
192
|
+
|
|
193
|
+
onDragStart?.(createEventData(e));
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const onPointerMove = (e: PointerEvent): void => {
|
|
197
|
+
if (!isDragging) return;
|
|
198
|
+
|
|
199
|
+
e.preventDefault();
|
|
200
|
+
previousPosition = { ...currentPosition };
|
|
201
|
+
|
|
202
|
+
let newX = currentPosition.x + (e.clientX - startPointer.x);
|
|
203
|
+
let newY = currentPosition.y + (e.clientY - startPointer.y);
|
|
204
|
+
|
|
205
|
+
// Reset start pointer to current for delta calculation
|
|
206
|
+
startPointer = { x: e.clientX, y: e.clientY };
|
|
207
|
+
|
|
208
|
+
// Apply axis constraint
|
|
209
|
+
if (axis === 'x') newY = currentPosition.y;
|
|
210
|
+
if (axis === 'y') newX = currentPosition.x;
|
|
211
|
+
|
|
212
|
+
let newPos: DragPosition = { x: newX, y: newY };
|
|
213
|
+
|
|
214
|
+
// Apply bounds constraint
|
|
215
|
+
if (bounds) {
|
|
216
|
+
const resolvedBounds = resolveBounds(el, bounds);
|
|
217
|
+
newPos = clampPosition(newPos, resolvedBounds);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
currentPosition = newPos;
|
|
221
|
+
|
|
222
|
+
// Update active drag position
|
|
223
|
+
activeDrags.set(el, { element: el, position: currentPosition });
|
|
224
|
+
|
|
225
|
+
// Apply the position
|
|
226
|
+
if (ghost && ghostEl) {
|
|
227
|
+
const start = ghostStartPosition ?? {
|
|
228
|
+
x: el.getBoundingClientRect().left,
|
|
229
|
+
y: el.getBoundingClientRect().top,
|
|
230
|
+
};
|
|
231
|
+
ghostEl.style.left = `${start.x + currentPosition.x}px`;
|
|
232
|
+
ghostEl.style.top = `${start.y + currentPosition.y}px`;
|
|
233
|
+
} else {
|
|
234
|
+
el.style.transform = `translate(${currentPosition.x}px, ${currentPosition.y}px)`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
onDrag?.(createEventData(e));
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const onPointerUp = (e: PointerEvent): void => {
|
|
241
|
+
if (!isDragging) return;
|
|
242
|
+
|
|
243
|
+
isDragging = false;
|
|
244
|
+
el.classList.remove(draggingClass);
|
|
245
|
+
try {
|
|
246
|
+
if (
|
|
247
|
+
typeof el.releasePointerCapture === 'function' &&
|
|
248
|
+
(typeof el.hasPointerCapture !== 'function' || el.hasPointerCapture(e.pointerId))
|
|
249
|
+
) {
|
|
250
|
+
el.releasePointerCapture(e.pointerId);
|
|
251
|
+
}
|
|
252
|
+
} catch {
|
|
253
|
+
// Pointer capture may already be released in some interrupted drag flows.
|
|
254
|
+
} finally {
|
|
255
|
+
removeGhost();
|
|
256
|
+
|
|
257
|
+
// Remove from active drags
|
|
258
|
+
activeDrags.delete(el);
|
|
259
|
+
|
|
260
|
+
onDragEnd?.(createEventData(e));
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// Attach listeners
|
|
265
|
+
el.addEventListener('pointerdown', onPointerDown);
|
|
266
|
+
el.addEventListener('pointermove', onPointerMove);
|
|
267
|
+
el.addEventListener('pointerup', onPointerUp);
|
|
268
|
+
el.addEventListener('pointercancel', onPointerUp);
|
|
269
|
+
|
|
270
|
+
// Prevent default drag behavior
|
|
271
|
+
el.style.touchAction = 'none';
|
|
272
|
+
el.style.userSelect = 'none';
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
destroy: () => {
|
|
276
|
+
el.removeEventListener('pointerdown', onPointerDown);
|
|
277
|
+
el.removeEventListener('pointermove', onPointerMove);
|
|
278
|
+
el.removeEventListener('pointerup', onPointerUp);
|
|
279
|
+
el.removeEventListener('pointercancel', onPointerUp);
|
|
280
|
+
removeGhost();
|
|
281
|
+
activeDrags.delete(el);
|
|
282
|
+
el.style.touchAction = previousTouchAction;
|
|
283
|
+
el.style.userSelect = previousUserSelect;
|
|
284
|
+
el.classList.remove(draggingClass);
|
|
285
|
+
},
|
|
286
|
+
disable: () => {
|
|
287
|
+
enabled = false;
|
|
288
|
+
},
|
|
289
|
+
enable: () => {
|
|
290
|
+
enabled = true;
|
|
291
|
+
},
|
|
292
|
+
get enabled() {
|
|
293
|
+
return enabled;
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Define drop zones for draggable elements.
|
|
3
|
+
*
|
|
4
|
+
* Drop zones detect when draggable elements enter, move over,
|
|
5
|
+
* leave, or are dropped onto them using pointer event hit-testing.
|
|
6
|
+
*
|
|
7
|
+
* @module bquery/dnd
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { getActiveDrag } from './draggable';
|
|
11
|
+
import type { DropEventData, DroppableHandle, DroppableOptions } from './types';
|
|
12
|
+
|
|
13
|
+
type DroppableListener = {
|
|
14
|
+
handlePointerMove: (event: PointerEvent) => void;
|
|
15
|
+
handlePointerUp: (event: PointerEvent) => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const passivePointerMoveListenerOptions = { passive: true } as const;
|
|
19
|
+
|
|
20
|
+
const droppableListeners = new Set<DroppableListener>();
|
|
21
|
+
let queuedPointerMove: PointerEvent | null = null;
|
|
22
|
+
let pointerMoveFrame: number | null = null;
|
|
23
|
+
|
|
24
|
+
const getDroppableListenersSnapshot = (): DroppableListener[] => Array.from(droppableListeners);
|
|
25
|
+
|
|
26
|
+
const hasDroppableEnvironment = (): boolean => {
|
|
27
|
+
return (
|
|
28
|
+
typeof document !== 'undefined' &&
|
|
29
|
+
typeof document.addEventListener === 'function' &&
|
|
30
|
+
typeof document.removeEventListener === 'function' &&
|
|
31
|
+
typeof requestAnimationFrame === 'function' &&
|
|
32
|
+
typeof cancelAnimationFrame === 'function'
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const dispatchPointerMove = (event: PointerEvent): void => {
|
|
37
|
+
for (const listener of getDroppableListenersSnapshot()) {
|
|
38
|
+
listener.handlePointerMove(event);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const flushPointerMove = (): void => {
|
|
43
|
+
pointerMoveFrame = null;
|
|
44
|
+
const event = queuedPointerMove;
|
|
45
|
+
queuedPointerMove = null;
|
|
46
|
+
if (!event) return;
|
|
47
|
+
dispatchPointerMove(event);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handleDocumentPointerMove = (event: PointerEvent): void => {
|
|
51
|
+
queuedPointerMove = event;
|
|
52
|
+
if (pointerMoveFrame === null) {
|
|
53
|
+
pointerMoveFrame = requestAnimationFrame(flushPointerMove);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const handleDocumentPointerUp = (event: PointerEvent): void => {
|
|
58
|
+
if (pointerMoveFrame !== null) {
|
|
59
|
+
cancelAnimationFrame(pointerMoveFrame);
|
|
60
|
+
pointerMoveFrame = null;
|
|
61
|
+
queuedPointerMove = null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (const listener of getDroppableListenersSnapshot()) {
|
|
65
|
+
listener.handlePointerUp(event);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const registerDroppableListener = (listener: DroppableListener): void => {
|
|
70
|
+
if (droppableListeners.size === 0) {
|
|
71
|
+
document.addEventListener(
|
|
72
|
+
'pointermove',
|
|
73
|
+
handleDocumentPointerMove,
|
|
74
|
+
passivePointerMoveListenerOptions
|
|
75
|
+
);
|
|
76
|
+
document.addEventListener('pointerup', handleDocumentPointerUp);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
droppableListeners.add(listener);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const unregisterDroppableListener = (listener: DroppableListener): void => {
|
|
83
|
+
droppableListeners.delete(listener);
|
|
84
|
+
|
|
85
|
+
if (droppableListeners.size !== 0) return;
|
|
86
|
+
|
|
87
|
+
document.removeEventListener('pointermove', handleDocumentPointerMove);
|
|
88
|
+
document.removeEventListener('pointerup', handleDocumentPointerUp);
|
|
89
|
+
if (pointerMoveFrame !== null) {
|
|
90
|
+
cancelAnimationFrame(pointerMoveFrame);
|
|
91
|
+
pointerMoveFrame = null;
|
|
92
|
+
}
|
|
93
|
+
queuedPointerMove = null;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Checks whether a dragged element is accepted by the drop zone.
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
const isAccepted = (dragged: HTMLElement, accept: DroppableOptions['accept']): boolean => {
|
|
101
|
+
if (!accept) return true;
|
|
102
|
+
if (typeof accept === 'string') return dragged.matches(accept);
|
|
103
|
+
return accept(dragged);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Defines an element as a drop zone.
|
|
108
|
+
*
|
|
109
|
+
* Drop zones respond to draggable elements being moved over them
|
|
110
|
+
* by firing callbacks and applying CSS classes. They work with
|
|
111
|
+
* the `draggable()` function from this module.
|
|
112
|
+
*
|
|
113
|
+
* @param el - The drop zone element
|
|
114
|
+
* @param options - Configuration options
|
|
115
|
+
* @returns A handle with a `destroy()` method
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* import { droppable } from '@bquery/bquery/dnd';
|
|
120
|
+
*
|
|
121
|
+
* const handle = droppable(document.querySelector('#dropzone'), {
|
|
122
|
+
* accept: '.draggable-item',
|
|
123
|
+
* overClass: 'drop-active',
|
|
124
|
+
* onDrop: ({ dragged }) => {
|
|
125
|
+
* console.log('Dropped:', dragged);
|
|
126
|
+
* },
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* // Later:
|
|
130
|
+
* handle.destroy();
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export const droppable = (el: HTMLElement, options: DroppableOptions = {}): DroppableHandle => {
|
|
134
|
+
const {
|
|
135
|
+
overClass = 'bq-drop-over',
|
|
136
|
+
accept,
|
|
137
|
+
onDragEnter,
|
|
138
|
+
onDragOver,
|
|
139
|
+
onDragLeave,
|
|
140
|
+
onDrop,
|
|
141
|
+
} = options;
|
|
142
|
+
|
|
143
|
+
if (!hasDroppableEnvironment()) {
|
|
144
|
+
return {
|
|
145
|
+
destroy: () => {},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let isOver = false;
|
|
150
|
+
let currentDragged: HTMLElement | null = null;
|
|
151
|
+
|
|
152
|
+
const createEventData = (dragged: HTMLElement, event: PointerEvent): DropEventData => ({
|
|
153
|
+
zone: el,
|
|
154
|
+
dragged,
|
|
155
|
+
event,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const isPointerInside = (event: PointerEvent): boolean => {
|
|
159
|
+
const rect = el.getBoundingClientRect();
|
|
160
|
+
return (
|
|
161
|
+
event.clientX >= rect.left &&
|
|
162
|
+
event.clientX <= rect.right &&
|
|
163
|
+
event.clientY >= rect.top &&
|
|
164
|
+
event.clientY <= rect.bottom
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const resolveDraggedElement = (): HTMLElement | null => {
|
|
169
|
+
return getActiveDrag()?.element ?? currentDragged;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const clearOverState = (event: PointerEvent, dragged = currentDragged): void => {
|
|
173
|
+
if (!isOver) return;
|
|
174
|
+
isOver = false;
|
|
175
|
+
el.classList.remove(overClass);
|
|
176
|
+
if (dragged) {
|
|
177
|
+
onDragLeave?.(createEventData(dragged, event));
|
|
178
|
+
}
|
|
179
|
+
currentDragged = null;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const handlePointerMove = (e: PointerEvent): void => {
|
|
183
|
+
const dragged = getActiveDrag()?.element ?? null;
|
|
184
|
+
const isInside = isPointerInside(e);
|
|
185
|
+
const acceptsDragged = dragged !== null && dragged !== el && isAccepted(dragged, accept);
|
|
186
|
+
|
|
187
|
+
if (!acceptsDragged || !isInside) {
|
|
188
|
+
clearOverState(e, dragged ?? currentDragged);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!isOver) {
|
|
193
|
+
isOver = true;
|
|
194
|
+
currentDragged = dragged;
|
|
195
|
+
el.classList.add(overClass);
|
|
196
|
+
onDragEnter?.(createEventData(dragged, e));
|
|
197
|
+
} else {
|
|
198
|
+
onDragOver?.(createEventData(dragged, e));
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const handlePointerUp = (e: PointerEvent): void => {
|
|
203
|
+
const dragged = resolveDraggedElement();
|
|
204
|
+
const isInside = isPointerInside(e);
|
|
205
|
+
const acceptsDragged = dragged !== null && dragged !== el && isAccepted(dragged, accept);
|
|
206
|
+
|
|
207
|
+
if (isInside && acceptsDragged && dragged) {
|
|
208
|
+
onDrop?.(createEventData(dragged, e));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (isOver) {
|
|
212
|
+
isOver = false;
|
|
213
|
+
el.classList.remove(overClass);
|
|
214
|
+
}
|
|
215
|
+
currentDragged = null;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const listener: DroppableListener = { handlePointerMove, handlePointerUp };
|
|
219
|
+
registerDroppableListener(listener);
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
destroy: () => {
|
|
223
|
+
unregisterDroppableListener(listener);
|
|
224
|
+
el.classList.remove(overClass);
|
|
225
|
+
currentDragged = null;
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
};
|
package/src/dnd/index.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bQuery Drag & Drop module.
|
|
3
|
+
*
|
|
4
|
+
* Provides pointer-event-based drag-and-drop, drop zones, and sortable
|
|
5
|
+
* lists with built-in touch support, axis locking, bounds constraints,
|
|
6
|
+
* and animated reordering.
|
|
7
|
+
*
|
|
8
|
+
* @module bquery/dnd
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { draggable, droppable, sortable } from '@bquery/bquery/dnd';
|
|
13
|
+
*
|
|
14
|
+
* // Make an element draggable
|
|
15
|
+
* const drag = draggable(document.querySelector('#box'), {
|
|
16
|
+
* axis: 'both',
|
|
17
|
+
* bounds: 'parent',
|
|
18
|
+
* ghost: true,
|
|
19
|
+
* onDragEnd: ({ position }) => console.log(position),
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Define a drop zone
|
|
23
|
+
* const drop = droppable(document.querySelector('#zone'), {
|
|
24
|
+
* accept: '.draggable',
|
|
25
|
+
* onDrop: ({ dragged }) => console.log('Dropped!', dragged),
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* // Make a list sortable
|
|
29
|
+
* const sort = sortable(document.querySelector('#list'), {
|
|
30
|
+
* items: 'li',
|
|
31
|
+
* axis: 'y',
|
|
32
|
+
* onSortEnd: ({ oldIndex, newIndex }) => {
|
|
33
|
+
* console.log(`Moved from ${oldIndex} to ${newIndex}`);
|
|
34
|
+
* },
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // Cleanup when done
|
|
38
|
+
* drag.destroy();
|
|
39
|
+
* drop.destroy();
|
|
40
|
+
* sort.destroy();
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
export { draggable } from './draggable';
|
|
45
|
+
export { droppable } from './droppable';
|
|
46
|
+
export { sortable } from './sortable';
|
|
47
|
+
|
|
48
|
+
export type {
|
|
49
|
+
BoundsRect,
|
|
50
|
+
DragAxis,
|
|
51
|
+
DragBounds,
|
|
52
|
+
DragEventData,
|
|
53
|
+
DragPosition,
|
|
54
|
+
DraggableHandle,
|
|
55
|
+
DraggableOptions,
|
|
56
|
+
DropEventData,
|
|
57
|
+
DroppableHandle,
|
|
58
|
+
DroppableOptions,
|
|
59
|
+
SortEventData,
|
|
60
|
+
SortableHandle,
|
|
61
|
+
SortableOptions,
|
|
62
|
+
} from './types';
|