Skip to content

Commit

Permalink
feat(ui): suppot drag on mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
xiejay97 committed Dec 13, 2021
1 parent 51c3d86 commit 46dd985
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 32 deletions.
101 changes: 71 additions & 30 deletions packages/ui/src/components/drag-drop/Drag.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { isNumber } from 'lodash';
import { isNumber, isUndefined } from 'lodash';
import React, { useEffect, useMemo } from 'react';
import { useRef } from 'react';
import ReactDOM from 'react-dom';
import { merge } from 'rxjs';

import { useComponentConfig, useRefSelector, useThrottle, useAsync, usePrefixConfig, useId, useCustomContext, useImmer } from '../../hooks';
import { DDropContext } from './Drop';
Expand All @@ -23,6 +25,8 @@ export function DDrag(props: DDragProps) {
useCustomContext(DDropContext);
//#endregion

const dataRef = useRef<{ dragEl: HTMLElement | null }>({ dragEl: null });

const asyncCapture = useAsync();
const { throttleByAnimationFrame } = useThrottle();
const id = useId();
Expand Down Expand Up @@ -62,11 +66,61 @@ export function DDrag(props: DDragProps) {

useEffect(() => {
const [asyncGroup, asyncId] = asyncCapture.createGroup();

if (isDragging) {
if (isDragging && dataRef.current.dragEl) {
let clientY: number | undefined;
let clientX: number | undefined;
let movementY = 0;
let movementX = 0;

const handleMove = (movementY: number, movementX: number) => {
setFixedStyle((draft) => {
draft.top = (draft.top as number) + movementY;
if (draft.top < 0) {
draft.top = 0;
}
if (draft.top > window.innerHeight - dragSize.height) {
draft.top = window.innerHeight - dragSize.height;
}

draft.left = (draft.left as number) + movementX;
if (draft.left < 0) {
draft.left = 0;
}
if (draft.left > window.innerWidth - dragSize.width) {
draft.left = window.innerWidth - dragSize.width;
}

draft.cursor = dropOuter ? 'not-allowed' : 'grabbing';
});
};

asyncGroup.fromEvent<TouchEvent>(window, 'touchmove', { capture: true, passive: false }).subscribe({
next: (e) => {
e.preventDefault();
},
});
asyncGroup.fromEvent<TouchEvent>(dataRef.current.dragEl, 'touchmove', { capture: true, passive: false }).subscribe({
next: (e) => {
e.preventDefault();

if (isUndefined(clientY) || isUndefined(clientX)) {
clientY = e.touches[0].clientY;
clientX = e.touches[0].clientX;
} else {
movementY += e.touches[0].clientY - clientY;
movementX += e.touches[0].clientX - clientX;
clientY = e.touches[0].clientY;
clientX = e.touches[0].clientX;
}
throttleByAnimationFrame.run(() => {
handleMove(movementY, movementX);

movementY = 0;
movementX = 0;
});
},
});

asyncGroup.fromEvent<MouseEvent>(window, 'mousemove', { capture: true }).subscribe({
next: (e) => {
e.preventDefault();
Expand All @@ -75,27 +129,7 @@ export function DDrag(props: DDragProps) {
movementX += e.movementX / window.devicePixelRatio;

throttleByAnimationFrame.run(() => {
((movementY, movementX) => {
setFixedStyle((draft) => {
draft.top = (draft.top as number) + movementY;
if (draft.top < 0) {
draft.top = 0;
}
if (draft.top > window.innerHeight - dragSize.height) {
draft.top = window.innerHeight - dragSize.height;
}

draft.left = (draft.left as number) + movementX;
if (draft.left < 0) {
draft.left = 0;
}
if (draft.left > window.innerWidth - dragSize.width) {
draft.left = window.innerWidth - dragSize.width;
}

draft.cursor = dropOuter ? 'not-allowed' : 'grabbing';
});
})(movementY, movementX);
handleMove(movementY, movementX);

movementY = 0;
movementX = 0;
Expand All @@ -112,9 +146,14 @@ export function DDrag(props: DDragProps) {
useEffect(() => {
const [asyncGroup, asyncId] = asyncCapture.createGroup();

if (isDragging) {
asyncGroup.fromEvent<MouseEvent>(window, 'mouseup', { capture: true }).subscribe({
next: () => {
if (isDragging && dataRef.current.dragEl) {
merge(
asyncGroup.fromEvent<MouseEvent>(window, 'mouseup', { capture: true }),
asyncGroup.fromEvent<MouseEvent>(dataRef.current.dragEl, 'touchend', { capture: true })
).subscribe({
next: (e) => {
e.preventDefault();

setIsDragging(false);
if (inDrop) {
setFixedStyle((draft) => {
Expand Down Expand Up @@ -191,15 +230,17 @@ export function DDrag(props: DDragProps) {

onDragStart: (e) => {
e.preventDefault();

_child.props.onDragStart?.(e);

onDragStart?.();
if (dId) {
_onDragStart?.(dId);
}

const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
const dragStyle = getComputedStyle(e.currentTarget);
const currentTarget = e.currentTarget as HTMLElement;
dataRef.current.dragEl = currentTarget;
const rect = currentTarget.getBoundingClientRect();
const dragStyle = getComputedStyle(currentTarget);

setDragSize({
width: rect.width,
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/src/components/input/InputAffix.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ export function DInputAffix(props: DInputAffixProps) {
[dPasswordToggle, password, setPassword]
);

const handleMouseUp = useCallback((e) => {
if (document.activeElement === dataRef.current.inputEl) {
e.preventDefault();
}
}, []);

const contextValue = useMemo<DInputAffixContextData>(
() => ({
inputAffixDisabled: disabled,
Expand Down Expand Up @@ -136,6 +142,7 @@ export function DInputAffix(props: DInputAffixProps) {
}
aria-label={t('Common', 'Clear')}
onMouseDown={handleClearMouseDown}
onMouseUp={handleMouseUp}
></DButton>
)}
{dPassword && !disabled && (
Expand All @@ -158,6 +165,7 @@ export function DInputAffix(props: DInputAffixProps) {
}
aria-label={t('DInputAffix', password ? 'Password is visible' : 'Password is not visible')}
onMouseDown={handlePasswordMouseDown}
onMouseUp={handleMouseUp}
></DButton>
)}
{dSuffix && <div className={`${dPrefix}input-affix__suffix`}>{dSuffix}</div>}
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/styles/components/_input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
.#{$variable-prefix}input-affix {
#{$selector} {
flex: 1 0 0;
width: unset;
width: 0;
}
}
}
Expand Down Expand Up @@ -90,7 +90,7 @@
.#{$variable-prefix}compose {
#{$selector} {
flex: 1 0 0;
width: unset;
width: 0;
}
}
}
Expand Down

0 comments on commit 46dd985

Please sign in to comment.