@amaui/ui-react
Version:
UI for React
161 lines (160 loc) • 7.01 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
const _excluded = ["version", "manage", "manageLevel", "disabled", "onMouseDown", "onTouchStart", "Component", "className", "style", "children"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import React from 'react';
import { element, is, isEnvironment } from '@amaui/utils';
import { classNames, style as styleMethod, useAmauiTheme } from '@amaui/style-react';
import { staticClassName } from '../utils';
const useStyle = styleMethod(theme => ({
root: {
pointerEvents: 'auto',
touchAction: 'none'
}
}), {
name: 'amaui-Move'
});
const Move = /*#__PURE__*/React.forwardRef((props_, ref) => {
const theme = useAmauiTheme();
const props = React.useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.amauiMove?.props?.default), props_), [props_]);
const {
classes
} = useStyle();
const {
version = 'regular',
manage = false,
manageLevel = 0,
disabled,
onMouseDown: onMouseDown_,
onTouchStart: onTouchStart_,
Component = 'div',
className,
style,
children
} = props,
other = _objectWithoutProperties(props, _excluded);
const refs = {
root: React.useRef(undefined),
values: React.useRef(undefined),
version: React.useRef(undefined),
mouseDown: React.useRef(undefined),
onMouseDown: React.useRef(undefined),
onTouchStart: React.useRef(undefined),
previousMouseEvent: React.useRef(undefined),
disabled: React.useRef(undefined)
};
const [mouseDown, setMouseDown] = React.useState(false);
const [values, setValues] = React.useState({});
refs.version.current = version;
refs.values.current = values;
refs.mouseDown.current = mouseDown;
refs.onMouseDown.current = onMouseDown_;
refs.onTouchStart.current = onTouchStart_;
refs.disabled.current = disabled;
const styles = {
root: {}
};
const onMouseDown = React.useCallback(event => {
setMouseDown(true);
if (is('function', refs.onMouseDown.current)) refs.onMouseDown.current(event);
}, []);
const onTouchStart = React.useCallback(event => {
setMouseDown(true);
if (is('function', refs.onTouchStart.current)) refs.onTouchStart.current(event);
}, []);
const onMouseUp = React.useCallback(event => {
setMouseDown(false);
refs.previousMouseEvent.current = undefined;
if (is('function', refs.onMouseDown.current)) refs.onMouseDown.current(event);
}, []);
React.useEffect(() => {
const onMove = (x_, y_) => {
if (refs.mouseDown.current && refs.previousMouseEvent.current && !refs.disabled.current) {
const {
clientX: xPrevious,
clientY: yPrevious
} = refs.previousMouseEvent.current;
const x = x_ - xPrevious;
const y = y_ - yPrevious;
const transform = refs.root.current.style.transform;
const {
left: left_,
top: top_
} = refs.root.current.style;
const [xTransform, yTransform] = (transform?.match(/[-+]?\d+\.?\d*/g) || [0, 0]).map(item => Number(item));
const left = +(left_ || '').replace('px', '');
const top = +(top_ || '').replace('px', '');
const valuesNew = _objectSpread(_objectSpread({}, refs.values.current), {}, {
x: x + (left || xTransform || 0),
y: y + (top || yTransform || 0)
});
if (refs.version.current === 'regular') refs.root.current.style.transform = `translate(${valuesNew.x}px, ${valuesNew.y}px)`;else {
refs.root.current.style.position = 'fixed';
refs.root.current.style.left = `${valuesNew.x}px`;
refs.root.current.style.top = `${valuesNew.y}px`;
}
setValues(valuesNew);
}
};
const onMouseMove = event => {
if (refs.mouseDown.current && !refs.disabled.current) {
const {
clientY,
clientX
} = event;
onMove(clientX, clientY);
refs.previousMouseEvent.current = event;
}
};
const onTouchMove = event => {
if (refs.mouseDown.current && !refs.disabled.current) {
const {
clientY,
clientX
} = event.touches[0];
onMove(clientX, clientY);
refs.previousMouseEvent.current = event;
// Normalize for use as a mouseDown value
refs.previousMouseEvent.current.clientY = clientY;
refs.previousMouseEvent.current.clientX = clientX;
}
};
if (manage && refs.root.current) {
const parents = element(refs.root.current).parents();
const parent = parents[manageLevel || 0];
if (parent && !['HTML', 'html', 'BODY', 'body', 'HEAD', 'head'].includes(parent.tagName)) {
parent.style.pointerEvents = 'none';
styles.root.pointerEvents = 'auto';
}
}
const rootDocument = isEnvironment('browser') ? refs.root.current?.ownerDocument || window.document : undefined;
rootDocument.addEventListener('mouseup', onMouseUp);
rootDocument.addEventListener('mousemove', onMouseMove);
rootDocument.addEventListener('touchend', onMouseUp);
rootDocument.addEventListener('touchmove', onTouchMove, {
passive: true
});
return () => {
rootDocument.removeEventListener('mouseup', onMouseUp);
rootDocument.removeEventListener('mousemove', onMouseMove);
rootDocument.removeEventListener('touchend', onMouseUp);
rootDocument.removeEventListener('touchmove', onTouchMove);
};
}, []);
return /*#__PURE__*/React.createElement(Component, _extends({
ref: item => {
if (ref) {
if (is('function', ref)) ref(item);else ref.current = item;
}
refs.root.current = item;
},
onMouseDown: onMouseDown,
onTouchStart: onTouchStart,
className: classNames([staticClassName('Move', theme) && ['amaui-Move-root'], className, classes.root]),
style: _objectSpread(_objectSpread({}, styles.root), style)
}, other), children);
});
Move.displayName = 'amaui-Move';
export default Move;