diff --git a/src/packages/drag/demos/h5/demo1.tsx b/src/packages/drag/demos/h5/demo1.tsx index a3eaaaadb6..c24a0bbb8c 100644 --- a/src/packages/drag/demos/h5/demo1.tsx +++ b/src/packages/drag/demos/h5/demo1.tsx @@ -2,8 +2,22 @@ import React from 'react' import { Drag, Button } from '@nutui/nutui-react' const Demo1 = () => { + const onDragStart = () => { + console.log('dragStart') + } + const onDragEnd = (state: any) => { + console.log('dragEnd', state) + } + const onDrag = (state: any) => { + console.log('dragging', state) + } return ( - + ) diff --git a/src/packages/drag/demos/taro/demo1.tsx b/src/packages/drag/demos/taro/demo1.tsx index dfc7b69728..d72f7c1767 100644 --- a/src/packages/drag/demos/taro/demo1.tsx +++ b/src/packages/drag/demos/taro/demo1.tsx @@ -2,8 +2,22 @@ import React from 'react' import { Drag, Button } from '@nutui/nutui-react-taro' const Demo1 = () => { + const onDragStart = () => { + console.log('dragStart') + } + const onDragEnd = (state: any) => { + console.log('dragEnd', state) + } + const onDrag = (state: any) => { + console.log('dragging', state) + } return ( - + ) diff --git a/src/packages/drag/doc.en-US.md b/src/packages/drag/doc.en-US.md index 67d8819a76..88f62cb52d 100644 --- a/src/packages/drag/doc.en-US.md +++ b/src/packages/drag/doc.en-US.md @@ -1,7 +1,5 @@ # Drag - - Implement draggable arbitrary elements. ## Import @@ -14,34 +12,34 @@ import { Drag } from '@nutui/nutui-react' ### Basic Usage -:::demo - - - +:::demo + + + ::: ### Limit Direction -:::demo - - - +:::demo + + + ::: ### Attract -:::demo - - - +:::demo + + + ::: ### Limit Boundaries -:::demo - - - +:::demo + + + ::: ## Drag @@ -52,4 +50,7 @@ import { Drag } from '@nutui/nutui-react' | --- | --- | --- | --- | | attract | Whether to enable automatic edge suction | `boolean` | `false` | | direction | The drag direction limit of the dragged element | `x` \| `y` \| `all` | `all` | -| boundary | The drag boundary of the dragged element | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | \ No newline at end of file +| boundary | The drag boundary of the dragged element | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | +| onDragStart | Start dragging elements | `() => void` | `-` | +| onDrag | Drag element | `(state: { offset: [x: number, y: number] }) => void` | `-` | +| onDragEnd | Stop dragging elements | `(state: { offset: [x: number, y: number] }) => void` | `-` | diff --git a/src/packages/drag/doc.md b/src/packages/drag/doc.md index 816e1d2c23..20cf316c6a 100644 --- a/src/packages/drag/doc.md +++ b/src/packages/drag/doc.md @@ -1,6 +1,5 @@ # Drag 拖拽 - 实现可拖拽的任意元素 ## 引入 @@ -13,34 +12,34 @@ import { Drag } from '@nutui/nutui-react' ### 基础用法 -:::demo - - - +:::demo + + + ::: ### 限制拖拽方向 -:::demo - - - +:::demo + + + ::: ### 自动吸边 -:::demo - - - +:::demo + + + ::: ### 限制拖拽边界 -:::demo - - - +:::demo + + + ::: ## Drag @@ -51,4 +50,7 @@ import { Drag } from '@nutui/nutui-react' | --- | --- | --- | --- | | attract | 是否开启自动吸边 | `boolean` | `false` | | direction | 拖拽元素的拖拽方向限制 | `x` \| `y` \| `all` | `all` | -| boundary | 拖拽元素的拖拽边界 | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | \ No newline at end of file +| boundary | 拖拽元素的拖拽边界 | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | +| onDragStart | 开始拖拽元素| `() => void` | `-` | +| onDrag | 拖拽元素| `(state: { offset: [x: number, y: number] }) => void` | `-` | +| onDragEnd | 停止拖拽元素| `(state: { offset: [x: number, y: number] }) => void` | `-` | diff --git a/src/packages/drag/doc.taro.md b/src/packages/drag/doc.taro.md index 40f67d5de9..a618a819f5 100644 --- a/src/packages/drag/doc.taro.md +++ b/src/packages/drag/doc.taro.md @@ -1,6 +1,5 @@ # Drag 拖拽 - 实现可拖拽的任意元素 ## 引入 @@ -13,34 +12,34 @@ import { Drag } from '@nutui/nutui-react-taro' ### 基础用法 -:::demo - - - +:::demo + + + ::: ### 限制拖拽方向 -:::demo - - - +:::demo + + + ::: ### 自动吸边 -:::demo - - - +:::demo + + + ::: ### 限制拖拽边界 -:::demo - - - +:::demo + + + ::: ## Drag @@ -51,4 +50,7 @@ import { Drag } from '@nutui/nutui-react-taro' | --- | --- | --- | --- | | attract | 是否开启自动吸边 | `boolean` | `false` | | direction | 拖拽元素的拖拽方向限制 | `x` \| `y` \| `all` | `all` | -| boundary | 拖拽元素的拖拽边界 | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | \ No newline at end of file +| boundary | 拖拽元素的拖拽边界 | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | +| onDragStart | 开始拖拽元素| `() => void` | `-` | +| onDrag | 拖拽元素| `(state: { offset: [x: number, y: number] }) => void` | `-` | +| onDragEnd | 停止拖拽元素| `(state: { offset: [x: number, y: number] }) => void` | `-` | diff --git a/src/packages/drag/doc.zh-TW.md b/src/packages/drag/doc.zh-TW.md index b9e515b8bc..7800753708 100644 --- a/src/packages/drag/doc.zh-TW.md +++ b/src/packages/drag/doc.zh-TW.md @@ -1,7 +1,5 @@ # Drag 拖拽 - - 實現可拖拽的任意元素 ## 引入 @@ -14,34 +12,34 @@ import { Drag } from '@nutui/nutui-react' ### 基礎用法 -:::demo - - - +:::demo + + + ::: ### 限製拖拽方向 -:::demo - - - +:::demo + + + ::: ### 自動吸邊 -:::demo - - - +:::demo + + + ::: ### 限製拖拽邊界 -:::demo - - - +:::demo + + + ::: ## Drag @@ -52,4 +50,7 @@ import { Drag } from '@nutui/nutui-react' | --- | --- | --- | --- | | attract | 是否開啟自動吸邊 | `boolean` | `false` | | direction | 拖拽元素的拖拽方向限製 | `x` \| `y` \| `all` | `all` | -| boundary | 拖拽元素的拖拽邊界 | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | \ No newline at end of file +| boundary | 拖拽元素的拖拽邊界 | `Object` | `{top: 0, left: 0, right: 0, bottom: 0}` | +| onDragStart | 開始拖拽元素| `() => void` | `-` | +| onDrag | 拖拽元素| `(state: { offset: [x: number, y: number] }) => void` | `-` | +| onDragEnd | 停止拖拽元素| `(state: { offset: [x: number, y: number] }) => void` | `-` | diff --git a/src/packages/drag/drag.taro.tsx b/src/packages/drag/drag.taro.tsx index a3f97afb4f..39a7f91b62 100644 --- a/src/packages/drag/drag.taro.tsx +++ b/src/packages/drag/drag.taro.tsx @@ -2,6 +2,7 @@ import React, { FunctionComponent, useState, useEffect, useRef } from 'react' import { getSystemInfoSync, createSelectorQuery } from '@tarojs/taro' import { BasicComponent, ComponentDefaults } from '@/utils/typings' import { getRectByTaro } from '@/utils/get-rect-by-taro' +import { DragState } from './drag' export interface DragProps extends BasicComponent { attract: boolean @@ -12,6 +13,9 @@ export interface DragProps extends BasicComponent { right: number bottom: number } + onDragStart: () => void + onDragEnd: (state: DragState) => void + onDrag: (state: DragState) => void } const defaultProps = { ...ComponentDefaults, @@ -28,11 +32,21 @@ const defaultProps = { export const Drag: FunctionComponent< Partial & React.HTMLAttributes > = (props) => { - const { attract, direction, boundary, children, className, style, ...reset } = - { - ...defaultProps, - ...props, - } + const { + attract, + direction, + boundary, + onDrag, + onDragStart, + onDragEnd, + children, + className, + style, + ...reset + } = { + ...defaultProps, + ...props, + } const classPrefix = 'nut-drag' const [boundaryState, setBoundaryState] = useState(boundary) const myDrag = useRef(null) @@ -72,7 +86,7 @@ export const Drag: FunctionComponent< } const touchStart = (e: React.TouchEvent) => { - const target = e.currentTarget as HTMLElement + onDragStart?.() const touches = e.touches[0] axisCache.current = { x: touches.clientX, y: touches.clientY } transformCache.current = { x: translateX.current, y: translateY.current } @@ -85,7 +99,9 @@ export const Drag: FunctionComponent< const y = touch.clientY - axisCache.current.y translateX.current = x + transformCache.current.x translateY.current = y + transformCache.current.y - + onDrag?.({ + offset: [translateX.current, translateY.current], + }) // 边界判断 if (translateX.current < boundaryState.left) { translateX.current = boundaryState.left @@ -107,6 +123,9 @@ export const Drag: FunctionComponent< } const touchEnd = (e: React.TouchEvent) => { + onDragEnd?.({ + offset: [translateX.current, translateY.current], + }) if (direction !== 'y' && attract && dragRef.current) { if (translateX.current < middleLine.current) { translateX.current = boundaryState.left diff --git a/src/packages/drag/drag.tsx b/src/packages/drag/drag.tsx index cb76fdd9b7..0b06293687 100644 --- a/src/packages/drag/drag.tsx +++ b/src/packages/drag/drag.tsx @@ -3,6 +3,9 @@ import { useDrag } from '@use-gesture/react' import { useSpring, animated } from '@react-spring/web' import { BasicComponent, ComponentDefaults } from '@/utils/typings' +export interface DragState { + offset: [x: number, y: number] +} export interface DragProps extends BasicComponent { attract: boolean direction: 'x' | 'y' | 'lock' | undefined @@ -12,6 +15,9 @@ export interface DragProps extends BasicComponent { right: number bottom: number } + onDragStart: () => void + onDragEnd: (state: DragState) => void + onDrag: (state: DragState) => void } const defaultProps = { ...ComponentDefaults, @@ -27,11 +33,21 @@ const defaultProps = { export const Drag: FunctionComponent< Partial & React.HTMLAttributes > = (props) => { - const { attract, direction, boundary, children, className, style, ...reset } = - { - ...defaultProps, - ...props, - } + const { + attract, + direction, + boundary, + onDrag, + onDragStart, + onDragEnd, + children, + className, + style, + ...reset + } = { + ...defaultProps, + ...props, + } const classPrefix = 'nut-drag' const [boundaryState, setBoundaryState] = useState(boundary) const myDrag = useRef(null) @@ -63,7 +79,16 @@ export const Drag: FunctionComponent< } const bind = useDrag( - ({ down, last, offset: [x, y] }) => { + (state) => { + const { + down, + last, + offset: [x, y], + first, + } = state + first && onDragStart?.() + onDrag?.({ offset: [x, y] }) + last && onDragEnd?.({ offset: [x, y] }) api.start({ x, y, immediate: down }) if (last) { if (direction !== 'y' && attract) {