@chayns-components/swipeable-wrapper
Version:
A set of beautiful React components for developing your own applications with chayns.
114 lines (108 loc) • 4.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.SWIPEABLE_ACTION_WIDTH = void 0;
var _react = require("motion/react");
var _react2 = _interopRequireWildcard(require("react"));
var _SwipeableAction = require("./SwipeableAction.styles");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const SWIPEABLE_ACTION_WIDTH = exports.SWIPEABLE_ACTION_WIDTH = 72;
const SwipeableAction = ({
activationThreshold,
close,
index,
item,
listItemXOffset,
position,
shouldUseOpacityAnimation,
totalActionCount
}) => {
const [pointerEvents, setPointerEvents] = _react2.default.useState('none');
const handleButtonClick = () => {
item.action();
close();
};
/**
* By default, the action sticks to the content of the swipeable item. This
* makes it move outwards to reveal the inner items.
*/
const actionOffset = (0, _react.useTransform)(listItemXOffset, newValue => {
const maxOffset = SWIPEABLE_ACTION_WIDTH * index;
const fractionalOffset = -newValue / totalActionCount * index;
switch (position) {
case 'left':
return Math.max(-maxOffset, fractionalOffset);
case 'right':
return Math.min(maxOffset, fractionalOffset);
default:
return 0;
}
});
/**
* Brings the item in again if past the threshold. Only relevant for
* outermost items.
*/
const actionOverlayOffset = (0, _react.useSpring)(0, {
bounce: 0
});
/**
* Combines the two values above to create the correct X transform that has
* to be applied to the action.
*/
const actionX = (0, _react.useTransform)([actionOffset, actionOverlayOffset], ([x, y]) => {
if (position === 'left') {
return Math.min((x ?? 0) + (y ?? 0), 0);
}
return Math.max((x ?? 0) + (y ?? 0), 0);
});
const opacity = (0, _react.useTransform)(listItemXOffset, x => Math.max(0, Math.min(1, Math.abs(x) / 72)));
(0, _react.useMotionValueEvent)(opacity, 'change', value => {
setPointerEvents(value < 0.5 ? 'none' : 'auto');
});
// Animate to the middle after passing threshold if outermost item
(0, _react2.useEffect)(() => {
const isOuterMost = index === totalActionCount - 1;
if (!isOuterMost) return undefined;
return listItemXOffset.onChange(newValue => {
const lastValue = listItemXOffset.getPrevious();
if (!lastValue) {
return;
}
// eslint-disable-next-line default-case
switch (position) {
case 'left':
if (newValue > activationThreshold && lastValue <= activationThreshold) {
actionOverlayOffset.set(SWIPEABLE_ACTION_WIDTH * index);
} else if (newValue < activationThreshold && lastValue >= activationThreshold) {
actionOverlayOffset.set(0);
}
break;
case 'right':
if (newValue < activationThreshold && lastValue >= activationThreshold) {
actionOverlayOffset.set(SWIPEABLE_ACTION_WIDTH * -1 * index);
} else if (newValue > activationThreshold && lastValue <= activationThreshold) {
actionOverlayOffset.set(0);
}
}
});
}, [actionOverlayOffset, activationThreshold, index, listItemXOffset, position, totalActionCount]);
return /*#__PURE__*/_react2.default.createElement(_SwipeableAction.StyledMotionSwipeableAction, {
$backgroundColor: item.backgroundColor,
$position: position,
style: {
x: actionX,
opacity: shouldUseOpacityAnimation ? opacity : 1
}
}, /*#__PURE__*/_react2.default.createElement(_SwipeableAction.StyledSwipeableActionButton, {
onClick: handleButtonClick,
style: {
pointerEvents
},
$color: item.color,
$width: `${SWIPEABLE_ACTION_WIDTH}px`
}, item.icon, item.text));
};
SwipeableAction.displayName = 'SwipeableAction';
var _default = exports.default = SwipeableAction;
//# sourceMappingURL=SwipeableAction.js.map