@sandstreamdev/react-swipeable-list
Advanced tools
Comparing version 0.4.1 to 0.5.0
@@ -1,30 +0,144 @@ | ||
import * as React from 'react'; | ||
import { FunctionComponent, PureComponent, ReactNode } from 'react'; | ||
interface ISwipeableListProps { | ||
scrollStartThreshold?: number; | ||
swipeStartThreshold?: number; | ||
threshold?: number; | ||
export enum ActionAnimations { | ||
/** | ||
* Item returns to start position. | ||
*/ | ||
RETURN, | ||
/** | ||
* Item moves out of the screen. | ||
*/ | ||
REMOVE, | ||
/** | ||
* Item stays in place it was dragged to. | ||
*/ | ||
NONE | ||
} | ||
export class SwipeableList extends React.Component<ISwipeableListProps> {} | ||
interface ISwipeActionProps { | ||
/** | ||
* Callback function that should be run when swipe is done beyond threshold. | ||
*/ | ||
action: () => void; | ||
content: React.ReactNode; | ||
/** | ||
* default: `RETURN` | ||
* | ||
* Animation type to be played swipe is done beyond threshold. | ||
*/ | ||
actionAnimation?: ActionAnimations; | ||
/** | ||
* Content that is revealed when swiping. | ||
*/ | ||
content: ReactNode; | ||
} | ||
interface ISwipeableListItemProps { | ||
/** | ||
* default: `false` | ||
* | ||
* If set to `true` all defined swipe actions are blocked. | ||
*/ | ||
blockSwipe?: boolean; | ||
/** | ||
* Data for defining left swipe action and rendering content after item is swiped. | ||
*/ | ||
swipeLeft?: ISwipeActionProps; | ||
/** | ||
* Data for defining right swipe action and rendering content after item is swiped. | ||
*/ | ||
swipeRight?: ISwipeActionProps; | ||
/** | ||
* default: `10` | ||
* | ||
* How far in pixels scroll needs to be done to block swiping. After scrolling is started and goes beyond the threshold, swiping is blocked. | ||
* | ||
* It can be set for the whole list or for every item. See `scrollStartThreshold` for `SwipeableList`. Value from the `SwipeableListItem` takes precedence. | ||
*/ | ||
scrollStartThreshold?: number; | ||
/** | ||
* default: `10` | ||
* | ||
* How far in pixels swipe needs to be done to start swiping on list item. After a swipe is started and goes beyond the threshold, scrolling is blocked. | ||
* | ||
* It can be set for the whole list or for every item. See `swipeStartThreshold` for `SwipeableList`. Value from the `SwipeableListItem` takes precedence. | ||
*/ | ||
swipeStartThreshold?: number; | ||
/** | ||
* default: `0.5` | ||
* | ||
* How far swipe needs to be done to trigger attached action. `0.5` means that item needs to be swiped to half of its width, `0.25` - one-quarter of width. | ||
* | ||
* It can be set for the whole list or for every item. See `threshold` for `SwipeableList`. Value from the `SwipeableListItem` takes precedence. | ||
*/ | ||
threshold?: number; | ||
/** | ||
* Fired after swipe has started (after drag gesture passes the `swipeStartThreshold` distance in pixels). | ||
*/ | ||
onSwipeStart?: () => void; | ||
/** | ||
* Fired after swipe has ended. | ||
*/ | ||
onSwipeEnd?: () => void; | ||
/** | ||
* Fired every time swipe progress changes. The reported `progress` value is always an integer in range 0 to 100 inclusive. | ||
*/ | ||
onSwipeProgress?: (progress: number) => void; | ||
} | ||
export class SwipeableListItem extends React.Component< | ||
ISwipeableListItemProps | ||
> {} | ||
interface IBaseSwipeableListProps { | ||
/** | ||
* default: `10` | ||
* | ||
* How far in pixels scroll needs to be done to block swiping. After scrolling is started and goes beyond the threshold, swiping is blocked. | ||
* | ||
* It can be set for the whole list or for every item. See `scrollStartThreshold` for `SwipeableListItem`. Value from the `SwipeableListItem` takes precedence. | ||
*/ | ||
scrollStartThreshold?: number; | ||
/** | ||
* default: `10` | ||
* | ||
* How far in pixels swipe needs to be done to start swiping on list item. After a swipe is started and goes beyond the threshold, scrolling is blocked. | ||
* | ||
* It can be set for the whole list or for every item. See `swipeStartThreshold` for `SwipeableListItem`. Value from the `SwipeableListItem` takes precedence. | ||
*/ | ||
swipeStartThreshold?: number; | ||
/** | ||
* default: `0.5` | ||
* | ||
* How far swipe needs to be done to trigger attached action. `0.5` means that item needs to be swiped to half of its width, `0.25` - one-quarter of width. | ||
* | ||
* It can be set for the whole list or for every item. See `threshold` for `SwipeableListItem`. Value from the `SwipeableListItem` takes precedence. | ||
*/ | ||
threshold?: number; | ||
} | ||
interface IStyledSwipeableListProps extends IBaseSwipeableListProps { | ||
className: string; | ||
} | ||
type SwipeableListChildren = | ||
| ReactNode | ||
| ((props: IStyledSwipeableListProps) => ReactNode); | ||
interface ISwipeableListProps extends IBaseSwipeableListProps { | ||
/** | ||
* A function child can be used instead of a SwipeableListItem elements. This function is | ||
* called with the SwipeableList props (scrollStartThreshold, swipeStartThreshold, threshold), | ||
* which can be used to apply context specific props to a component. | ||
* ```jsx | ||
* <SwipeableList threshold={0.5}> | ||
* {props => ( | ||
* <SwipeableListItme {...props} /> | ||
* )} | ||
* </SwipeableList> | ||
* ``` | ||
*/ | ||
children?: SwipeableListChildren; | ||
} | ||
export class SwipeableListItem extends PureComponent<ISwipeableListItemProps> {} | ||
/** | ||
* NOTE: A function child can be used instead of a SwipeableListItem elements. | ||
*/ | ||
export const SwipeableList: FunctionComponent<ISwipeableListProps>; |
@@ -18,10 +18,14 @@ 'use strict'; | ||
threshold = _ref.threshold; | ||
return React__default.createElement("div", { | ||
return typeof children === 'function' ? children({ | ||
className: styles.swipeableList, | ||
"data-testid": "list-wrapper" | ||
scrollStartThreshold: scrollStartThreshold, | ||
swipeStartThreshold: swipeStartThreshold, | ||
threshold: threshold | ||
}) : /*#__PURE__*/React__default.createElement("div", { | ||
className: styles.swipeableList | ||
}, React__default.Children.map(children, function (child) { | ||
return React__default.cloneElement(child, { | ||
scrollStartThreshold, | ||
swipeStartThreshold, | ||
threshold | ||
scrollStartThreshold: scrollStartThreshold, | ||
swipeStartThreshold: swipeStartThreshold, | ||
threshold: threshold | ||
}); | ||
@@ -32,3 +36,3 @@ })); | ||
SwipeableList.propTypes = { | ||
children: PropTypes.node, | ||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | ||
scrollStartThreshold: PropTypes.number, | ||
@@ -107,2 +111,15 @@ swipeStartThreshold: PropTypes.number, | ||
function _isNativeReflectConstruct() { | ||
if (typeof Reflect === "undefined" || !Reflect.construct) return false; | ||
if (Reflect.construct.sham) return false; | ||
if (typeof Proxy === "function") return true; | ||
try { | ||
Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
function _assertThisInitialized(self) { | ||
@@ -124,6 +141,29 @@ if (self === void 0) { | ||
var styles$1 = {"swipeableListItem":"SwipeableListItem_swipeableListItem__3Tgya","contentRight":"SwipeableListItem_contentRight__doq05","contentLeft":"SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05","return":"SwipeableListItem_return__25gWI","contentLeftReturn":"SwipeableListItem_contentLeftReturn___PqJ1 SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","contentRightReturn":"SwipeableListItem_contentRightReturn__3jXBY SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","content":"SwipeableListItem_content__3wbMa","contentReturn":"SwipeableListItem_contentReturn__Kx-Al SwipeableListItem_content__3wbMa"}; | ||
function _createSuper(Derived) { | ||
return function () { | ||
var Super = _getPrototypeOf(Derived), | ||
result; | ||
if (_isNativeReflectConstruct()) { | ||
var NewTarget = _getPrototypeOf(this).constructor; | ||
result = Reflect.construct(Super, arguments, NewTarget); | ||
} else { | ||
result = Super.apply(this, arguments); | ||
} | ||
return _possibleConstructorReturn(this, result); | ||
}; | ||
} | ||
var styles$1 = {"swipeableListItem":"SwipeableListItem_swipeableListItem__3Tgya","contentRight":"SwipeableListItem_contentRight__doq05","contentLeft":"SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05","return":"SwipeableListItem_return__25gWI","contentLeftReturn":"SwipeableListItem_contentLeftReturn___PqJ1 SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","contentRightReturn":"SwipeableListItem_contentRightReturn__3jXBY SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","content":"SwipeableListItem_content__3wbMa","contentReturn":"SwipeableListItem_contentReturn__Kx-Al SwipeableListItem_content__3wbMa","contentRemove":"SwipeableListItem_contentRemove__L9cWZ SwipeableListItem_content__3wbMa"}; | ||
var ActionAnimations = { | ||
RETURN: Symbol('Return'), | ||
REMOVE: Symbol('Remove'), | ||
NONE: Symbol('None') | ||
}; | ||
var SwipeActionPropType = PropTypes.shape({ | ||
action: PropTypes.func.isRequired, | ||
actionAnimation: PropTypes.oneOf(Object.values(ActionAnimations)), | ||
content: PropTypes.node.isRequired | ||
@@ -140,8 +180,8 @@ }); | ||
var SwipeableListItem = | ||
/*#__PURE__*/ | ||
function (_PureComponent) { | ||
var SwipeableListItem = /*#__PURE__*/function (_PureComponent) { | ||
_inherits(SwipeableListItem, _PureComponent); | ||
function SwipeableListItem(props) { | ||
var _super = _createSuper(SwipeableListItem); | ||
function SwipeableListItem(_props) { | ||
var _this; | ||
@@ -151,3 +191,3 @@ | ||
_this = _possibleConstructorReturn(this, _getPrototypeOf(SwipeableListItem).call(this, props)); | ||
_this = _super.call(this, _props); | ||
@@ -265,11 +305,82 @@ _defineProperty(_assertThisInitialized(_this), "resetState", function () { | ||
_defineProperty(_assertThisInitialized(_this), "playReturnAnimation", function () { | ||
var _assertThisInitialize = _assertThisInitialized(_this), | ||
contentLeft = _assertThisInitialize.contentLeft, | ||
contentRight = _assertThisInitialize.contentRight, | ||
listElement = _assertThisInitialize.listElement; | ||
if (listElement) { | ||
listElement.className = styles$1.contentReturn; | ||
listElement.style.transform = 'translateX(0px)'; | ||
} // hide backgrounds | ||
if (contentLeft !== null) { | ||
contentLeft.style.opacity = 0; | ||
contentLeft.className = styles$1.contentLeftReturn; | ||
} | ||
if (contentRight !== null) { | ||
contentRight.style.opacity = 0; | ||
contentRight.className = styles$1.contentRightReturn; | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "playRemoveAnimation", function (direction) { | ||
var _assertThisInitialize2 = _assertThisInitialized(_this), | ||
listElement = _assertThisInitialize2.listElement; | ||
if (listElement) { | ||
listElement.className = styles$1.contentRemove; | ||
listElement.style.transform = "translateX(".concat(listElement.offsetWidth * (direction === DragDirection.LEFT ? -1 : 1), "px)"); | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "playActionAnimation", function (type, direction) { | ||
var _assertThisInitialize3 = _assertThisInitialized(_this), | ||
listElement = _assertThisInitialize3.listElement; | ||
if (listElement) { | ||
switch (type) { | ||
case ActionAnimations.REMOVE: | ||
_this.playRemoveAnimation(direction); | ||
break; | ||
case ActionAnimations.NONE: | ||
break; | ||
default: | ||
_this.playReturnAnimation(); | ||
} | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "handleDragEnd", function () { | ||
var _assertThisInitialize4 = _assertThisInitialized(_this), | ||
left = _assertThisInitialize4.left, | ||
listElement = _assertThisInitialize4.listElement, | ||
props = _assertThisInitialize4.props; | ||
var swipeLeft = props.swipeLeft, | ||
swipeRight = props.swipeRight, | ||
_props$threshold = props.threshold, | ||
threshold = _props$threshold === void 0 ? 0.5 : _props$threshold; | ||
var actionTriggered = false; | ||
if (_this.isSwiping()) { | ||
var threshold = _this.props.threshold || 0.5; | ||
if (listElement) { | ||
if (left < listElement.offsetWidth * threshold * -1) { | ||
_this.playActionAnimation(swipeLeft.actionAnimation, DragDirection.LEFT); | ||
if (_this.listElement) { | ||
if (_this.left < _this.listElement.offsetWidth * threshold * -1) { | ||
_this.handleSwipedLeft(); | ||
} else if (_this.left > _this.listElement.offsetWidth * threshold) { | ||
actionTriggered = true; | ||
} else if (left > listElement.offsetWidth * threshold) { | ||
_this.playActionAnimation(swipeRight.actionAnimation, DragDirection.RIGHT); | ||
_this.handleSwipedRight(); | ||
actionTriggered = true; | ||
} | ||
@@ -285,17 +396,5 @@ } | ||
if (_this.listElement) { | ||
_this.listElement.className = styles$1.contentReturn; | ||
_this.listElement.style.transform = "translateX(".concat(_this.left, "px)"); | ||
} // hide backgrounds | ||
if (_this.contentLeft !== null) { | ||
_this.contentLeft.style.opacity = 0; | ||
_this.contentLeft.className = styles$1.contentLeftReturn; | ||
if (!actionTriggered) { | ||
_this.playReturnAnimation(); | ||
} | ||
if (_this.contentRight !== null) { | ||
_this.contentRight.style.opacity = 0; | ||
_this.contentRight.className = styles$1.contentRightReturn; | ||
} | ||
}); | ||
@@ -526,17 +625,17 @@ | ||
swipeRight = _this$props.swipeRight; | ||
return React__default.createElement("div", { | ||
return /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.swipeableListItem, | ||
ref: this.bindWrapper | ||
}, swipeLeft && React__default.createElement("div", { | ||
ref: this.bindContentLeft, | ||
}, swipeLeft && /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.contentLeft, | ||
"data-testid": "swipe-left-content" | ||
}, swipeLeft.content), swipeRight && React__default.createElement("div", { | ||
ref: this.bindContentRight, | ||
"data-testid": "swipe-left-content", | ||
ref: this.bindContentLeft | ||
}, swipeLeft.content), swipeRight && /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.contentRight, | ||
"data-testid": "swipe-right-content" | ||
}, swipeRight.content), React__default.createElement("div", { | ||
ref: this.bindListElement, | ||
"data-testid": "swipe-right-content", | ||
ref: this.bindContentRight | ||
}, swipeRight.content), /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.content, | ||
"data-testid": "content" | ||
"data-testid": "content", | ||
ref: this.bindListElement | ||
}, children)); | ||
@@ -582,3 +681,4 @@ } | ||
exports.ActionAnimations = ActionAnimations; | ||
exports.SwipeableList = SwipeableList; | ||
exports.SwipeableListItem = SwipeableListItem; |
@@ -11,10 +11,14 @@ import React, { PureComponent } from 'react'; | ||
threshold = _ref.threshold; | ||
return React.createElement("div", { | ||
return typeof children === 'function' ? children({ | ||
className: styles.swipeableList, | ||
"data-testid": "list-wrapper" | ||
scrollStartThreshold: scrollStartThreshold, | ||
swipeStartThreshold: swipeStartThreshold, | ||
threshold: threshold | ||
}) : /*#__PURE__*/React.createElement("div", { | ||
className: styles.swipeableList | ||
}, React.Children.map(children, function (child) { | ||
return React.cloneElement(child, { | ||
scrollStartThreshold, | ||
swipeStartThreshold, | ||
threshold | ||
scrollStartThreshold: scrollStartThreshold, | ||
swipeStartThreshold: swipeStartThreshold, | ||
threshold: threshold | ||
}); | ||
@@ -25,3 +29,3 @@ })); | ||
SwipeableList.propTypes = { | ||
children: PropTypes.node, | ||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | ||
scrollStartThreshold: PropTypes.number, | ||
@@ -100,2 +104,15 @@ swipeStartThreshold: PropTypes.number, | ||
function _isNativeReflectConstruct() { | ||
if (typeof Reflect === "undefined" || !Reflect.construct) return false; | ||
if (Reflect.construct.sham) return false; | ||
if (typeof Proxy === "function") return true; | ||
try { | ||
Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
function _assertThisInitialized(self) { | ||
@@ -117,6 +134,29 @@ if (self === void 0) { | ||
var styles$1 = {"swipeableListItem":"SwipeableListItem_swipeableListItem__3Tgya","contentRight":"SwipeableListItem_contentRight__doq05","contentLeft":"SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05","return":"SwipeableListItem_return__25gWI","contentLeftReturn":"SwipeableListItem_contentLeftReturn___PqJ1 SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","contentRightReturn":"SwipeableListItem_contentRightReturn__3jXBY SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","content":"SwipeableListItem_content__3wbMa","contentReturn":"SwipeableListItem_contentReturn__Kx-Al SwipeableListItem_content__3wbMa"}; | ||
function _createSuper(Derived) { | ||
return function () { | ||
var Super = _getPrototypeOf(Derived), | ||
result; | ||
if (_isNativeReflectConstruct()) { | ||
var NewTarget = _getPrototypeOf(this).constructor; | ||
result = Reflect.construct(Super, arguments, NewTarget); | ||
} else { | ||
result = Super.apply(this, arguments); | ||
} | ||
return _possibleConstructorReturn(this, result); | ||
}; | ||
} | ||
var styles$1 = {"swipeableListItem":"SwipeableListItem_swipeableListItem__3Tgya","contentRight":"SwipeableListItem_contentRight__doq05","contentLeft":"SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05","return":"SwipeableListItem_return__25gWI","contentLeftReturn":"SwipeableListItem_contentLeftReturn___PqJ1 SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","contentRightReturn":"SwipeableListItem_contentRightReturn__3jXBY SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","content":"SwipeableListItem_content__3wbMa","contentReturn":"SwipeableListItem_contentReturn__Kx-Al SwipeableListItem_content__3wbMa","contentRemove":"SwipeableListItem_contentRemove__L9cWZ SwipeableListItem_content__3wbMa"}; | ||
var ActionAnimations = { | ||
RETURN: Symbol('Return'), | ||
REMOVE: Symbol('Remove'), | ||
NONE: Symbol('None') | ||
}; | ||
var SwipeActionPropType = PropTypes.shape({ | ||
action: PropTypes.func.isRequired, | ||
actionAnimation: PropTypes.oneOf(Object.values(ActionAnimations)), | ||
content: PropTypes.node.isRequired | ||
@@ -133,8 +173,8 @@ }); | ||
var SwipeableListItem = | ||
/*#__PURE__*/ | ||
function (_PureComponent) { | ||
var SwipeableListItem = /*#__PURE__*/function (_PureComponent) { | ||
_inherits(SwipeableListItem, _PureComponent); | ||
function SwipeableListItem(props) { | ||
var _super = _createSuper(SwipeableListItem); | ||
function SwipeableListItem(_props) { | ||
var _this; | ||
@@ -144,3 +184,3 @@ | ||
_this = _possibleConstructorReturn(this, _getPrototypeOf(SwipeableListItem).call(this, props)); | ||
_this = _super.call(this, _props); | ||
@@ -258,11 +298,82 @@ _defineProperty(_assertThisInitialized(_this), "resetState", function () { | ||
_defineProperty(_assertThisInitialized(_this), "playReturnAnimation", function () { | ||
var _assertThisInitialize = _assertThisInitialized(_this), | ||
contentLeft = _assertThisInitialize.contentLeft, | ||
contentRight = _assertThisInitialize.contentRight, | ||
listElement = _assertThisInitialize.listElement; | ||
if (listElement) { | ||
listElement.className = styles$1.contentReturn; | ||
listElement.style.transform = 'translateX(0px)'; | ||
} // hide backgrounds | ||
if (contentLeft !== null) { | ||
contentLeft.style.opacity = 0; | ||
contentLeft.className = styles$1.contentLeftReturn; | ||
} | ||
if (contentRight !== null) { | ||
contentRight.style.opacity = 0; | ||
contentRight.className = styles$1.contentRightReturn; | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "playRemoveAnimation", function (direction) { | ||
var _assertThisInitialize2 = _assertThisInitialized(_this), | ||
listElement = _assertThisInitialize2.listElement; | ||
if (listElement) { | ||
listElement.className = styles$1.contentRemove; | ||
listElement.style.transform = "translateX(".concat(listElement.offsetWidth * (direction === DragDirection.LEFT ? -1 : 1), "px)"); | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "playActionAnimation", function (type, direction) { | ||
var _assertThisInitialize3 = _assertThisInitialized(_this), | ||
listElement = _assertThisInitialize3.listElement; | ||
if (listElement) { | ||
switch (type) { | ||
case ActionAnimations.REMOVE: | ||
_this.playRemoveAnimation(direction); | ||
break; | ||
case ActionAnimations.NONE: | ||
break; | ||
default: | ||
_this.playReturnAnimation(); | ||
} | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "handleDragEnd", function () { | ||
var _assertThisInitialize4 = _assertThisInitialized(_this), | ||
left = _assertThisInitialize4.left, | ||
listElement = _assertThisInitialize4.listElement, | ||
props = _assertThisInitialize4.props; | ||
var swipeLeft = props.swipeLeft, | ||
swipeRight = props.swipeRight, | ||
_props$threshold = props.threshold, | ||
threshold = _props$threshold === void 0 ? 0.5 : _props$threshold; | ||
var actionTriggered = false; | ||
if (_this.isSwiping()) { | ||
var threshold = _this.props.threshold || 0.5; | ||
if (listElement) { | ||
if (left < listElement.offsetWidth * threshold * -1) { | ||
_this.playActionAnimation(swipeLeft.actionAnimation, DragDirection.LEFT); | ||
if (_this.listElement) { | ||
if (_this.left < _this.listElement.offsetWidth * threshold * -1) { | ||
_this.handleSwipedLeft(); | ||
} else if (_this.left > _this.listElement.offsetWidth * threshold) { | ||
actionTriggered = true; | ||
} else if (left > listElement.offsetWidth * threshold) { | ||
_this.playActionAnimation(swipeRight.actionAnimation, DragDirection.RIGHT); | ||
_this.handleSwipedRight(); | ||
actionTriggered = true; | ||
} | ||
@@ -278,17 +389,5 @@ } | ||
if (_this.listElement) { | ||
_this.listElement.className = styles$1.contentReturn; | ||
_this.listElement.style.transform = "translateX(".concat(_this.left, "px)"); | ||
} // hide backgrounds | ||
if (_this.contentLeft !== null) { | ||
_this.contentLeft.style.opacity = 0; | ||
_this.contentLeft.className = styles$1.contentLeftReturn; | ||
if (!actionTriggered) { | ||
_this.playReturnAnimation(); | ||
} | ||
if (_this.contentRight !== null) { | ||
_this.contentRight.style.opacity = 0; | ||
_this.contentRight.className = styles$1.contentRightReturn; | ||
} | ||
}); | ||
@@ -519,17 +618,17 @@ | ||
swipeRight = _this$props.swipeRight; | ||
return React.createElement("div", { | ||
return /*#__PURE__*/React.createElement("div", { | ||
className: styles$1.swipeableListItem, | ||
ref: this.bindWrapper | ||
}, swipeLeft && React.createElement("div", { | ||
ref: this.bindContentLeft, | ||
}, swipeLeft && /*#__PURE__*/React.createElement("div", { | ||
className: styles$1.contentLeft, | ||
"data-testid": "swipe-left-content" | ||
}, swipeLeft.content), swipeRight && React.createElement("div", { | ||
ref: this.bindContentRight, | ||
"data-testid": "swipe-left-content", | ||
ref: this.bindContentLeft | ||
}, swipeLeft.content), swipeRight && /*#__PURE__*/React.createElement("div", { | ||
className: styles$1.contentRight, | ||
"data-testid": "swipe-right-content" | ||
}, swipeRight.content), React.createElement("div", { | ||
ref: this.bindListElement, | ||
"data-testid": "swipe-right-content", | ||
ref: this.bindContentRight | ||
}, swipeRight.content), /*#__PURE__*/React.createElement("div", { | ||
className: styles$1.content, | ||
"data-testid": "content" | ||
"data-testid": "content", | ||
ref: this.bindListElement | ||
}, children)); | ||
@@ -575,2 +674,2 @@ } | ||
export { SwipeableList, SwipeableListItem }; | ||
export { ActionAnimations, SwipeableList, SwipeableListItem }; |
@@ -8,3 +8,3 @@ (function (global, factory) { | ||
var React__default = 'default' in React ? React['default'] : React; | ||
PropTypes = PropTypes && PropTypes.hasOwnProperty('default') ? PropTypes['default'] : PropTypes; | ||
PropTypes = PropTypes && Object.prototype.hasOwnProperty.call(PropTypes, 'default') ? PropTypes['default'] : PropTypes; | ||
@@ -18,10 +18,14 @@ var styles = {"swipeableList":"SwipeableList_swipeableList__1FACG"}; | ||
threshold = _ref.threshold; | ||
return React__default.createElement("div", { | ||
return typeof children === 'function' ? children({ | ||
className: styles.swipeableList, | ||
"data-testid": "list-wrapper" | ||
scrollStartThreshold: scrollStartThreshold, | ||
swipeStartThreshold: swipeStartThreshold, | ||
threshold: threshold | ||
}) : /*#__PURE__*/React__default.createElement("div", { | ||
className: styles.swipeableList | ||
}, React__default.Children.map(children, function (child) { | ||
return React__default.cloneElement(child, { | ||
scrollStartThreshold, | ||
swipeStartThreshold, | ||
threshold | ||
scrollStartThreshold: scrollStartThreshold, | ||
swipeStartThreshold: swipeStartThreshold, | ||
threshold: threshold | ||
}); | ||
@@ -32,3 +36,3 @@ })); | ||
SwipeableList.propTypes = { | ||
children: PropTypes.node, | ||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | ||
scrollStartThreshold: PropTypes.number, | ||
@@ -107,2 +111,15 @@ swipeStartThreshold: PropTypes.number, | ||
function _isNativeReflectConstruct() { | ||
if (typeof Reflect === "undefined" || !Reflect.construct) return false; | ||
if (Reflect.construct.sham) return false; | ||
if (typeof Proxy === "function") return true; | ||
try { | ||
Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
function _assertThisInitialized(self) { | ||
@@ -124,6 +141,29 @@ if (self === void 0) { | ||
var styles$1 = {"swipeableListItem":"SwipeableListItem_swipeableListItem__3Tgya","contentRight":"SwipeableListItem_contentRight__doq05","contentLeft":"SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05","return":"SwipeableListItem_return__25gWI","contentLeftReturn":"SwipeableListItem_contentLeftReturn___PqJ1 SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","contentRightReturn":"SwipeableListItem_contentRightReturn__3jXBY SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","content":"SwipeableListItem_content__3wbMa","contentReturn":"SwipeableListItem_contentReturn__Kx-Al SwipeableListItem_content__3wbMa"}; | ||
function _createSuper(Derived) { | ||
return function () { | ||
var Super = _getPrototypeOf(Derived), | ||
result; | ||
if (_isNativeReflectConstruct()) { | ||
var NewTarget = _getPrototypeOf(this).constructor; | ||
result = Reflect.construct(Super, arguments, NewTarget); | ||
} else { | ||
result = Super.apply(this, arguments); | ||
} | ||
return _possibleConstructorReturn(this, result); | ||
}; | ||
} | ||
var styles$1 = {"swipeableListItem":"SwipeableListItem_swipeableListItem__3Tgya","contentRight":"SwipeableListItem_contentRight__doq05","contentLeft":"SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05","return":"SwipeableListItem_return__25gWI","contentLeftReturn":"SwipeableListItem_contentLeftReturn___PqJ1 SwipeableListItem_contentLeft__2yNci SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","contentRightReturn":"SwipeableListItem_contentRightReturn__3jXBY SwipeableListItem_contentRight__doq05 SwipeableListItem_return__25gWI","content":"SwipeableListItem_content__3wbMa","contentReturn":"SwipeableListItem_contentReturn__Kx-Al SwipeableListItem_content__3wbMa","contentRemove":"SwipeableListItem_contentRemove__L9cWZ SwipeableListItem_content__3wbMa"}; | ||
var ActionAnimations = { | ||
RETURN: Symbol('Return'), | ||
REMOVE: Symbol('Remove'), | ||
NONE: Symbol('None') | ||
}; | ||
var SwipeActionPropType = PropTypes.shape({ | ||
action: PropTypes.func.isRequired, | ||
actionAnimation: PropTypes.oneOf(Object.values(ActionAnimations)), | ||
content: PropTypes.node.isRequired | ||
@@ -140,8 +180,8 @@ }); | ||
var SwipeableListItem = | ||
/*#__PURE__*/ | ||
function (_PureComponent) { | ||
var SwipeableListItem = /*#__PURE__*/function (_PureComponent) { | ||
_inherits(SwipeableListItem, _PureComponent); | ||
function SwipeableListItem(props) { | ||
var _super = _createSuper(SwipeableListItem); | ||
function SwipeableListItem(_props) { | ||
var _this; | ||
@@ -151,3 +191,3 @@ | ||
_this = _possibleConstructorReturn(this, _getPrototypeOf(SwipeableListItem).call(this, props)); | ||
_this = _super.call(this, _props); | ||
@@ -265,11 +305,82 @@ _defineProperty(_assertThisInitialized(_this), "resetState", function () { | ||
_defineProperty(_assertThisInitialized(_this), "playReturnAnimation", function () { | ||
var _assertThisInitialize = _assertThisInitialized(_this), | ||
contentLeft = _assertThisInitialize.contentLeft, | ||
contentRight = _assertThisInitialize.contentRight, | ||
listElement = _assertThisInitialize.listElement; | ||
if (listElement) { | ||
listElement.className = styles$1.contentReturn; | ||
listElement.style.transform = 'translateX(0px)'; | ||
} // hide backgrounds | ||
if (contentLeft !== null) { | ||
contentLeft.style.opacity = 0; | ||
contentLeft.className = styles$1.contentLeftReturn; | ||
} | ||
if (contentRight !== null) { | ||
contentRight.style.opacity = 0; | ||
contentRight.className = styles$1.contentRightReturn; | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "playRemoveAnimation", function (direction) { | ||
var _assertThisInitialize2 = _assertThisInitialized(_this), | ||
listElement = _assertThisInitialize2.listElement; | ||
if (listElement) { | ||
listElement.className = styles$1.contentRemove; | ||
listElement.style.transform = "translateX(".concat(listElement.offsetWidth * (direction === DragDirection.LEFT ? -1 : 1), "px)"); | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "playActionAnimation", function (type, direction) { | ||
var _assertThisInitialize3 = _assertThisInitialized(_this), | ||
listElement = _assertThisInitialize3.listElement; | ||
if (listElement) { | ||
switch (type) { | ||
case ActionAnimations.REMOVE: | ||
_this.playRemoveAnimation(direction); | ||
break; | ||
case ActionAnimations.NONE: | ||
break; | ||
default: | ||
_this.playReturnAnimation(); | ||
} | ||
} | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "handleDragEnd", function () { | ||
var _assertThisInitialize4 = _assertThisInitialized(_this), | ||
left = _assertThisInitialize4.left, | ||
listElement = _assertThisInitialize4.listElement, | ||
props = _assertThisInitialize4.props; | ||
var swipeLeft = props.swipeLeft, | ||
swipeRight = props.swipeRight, | ||
_props$threshold = props.threshold, | ||
threshold = _props$threshold === void 0 ? 0.5 : _props$threshold; | ||
var actionTriggered = false; | ||
if (_this.isSwiping()) { | ||
var threshold = _this.props.threshold || 0.5; | ||
if (listElement) { | ||
if (left < listElement.offsetWidth * threshold * -1) { | ||
_this.playActionAnimation(swipeLeft.actionAnimation, DragDirection.LEFT); | ||
if (_this.listElement) { | ||
if (_this.left < _this.listElement.offsetWidth * threshold * -1) { | ||
_this.handleSwipedLeft(); | ||
} else if (_this.left > _this.listElement.offsetWidth * threshold) { | ||
actionTriggered = true; | ||
} else if (left > listElement.offsetWidth * threshold) { | ||
_this.playActionAnimation(swipeRight.actionAnimation, DragDirection.RIGHT); | ||
_this.handleSwipedRight(); | ||
actionTriggered = true; | ||
} | ||
@@ -285,17 +396,5 @@ } | ||
if (_this.listElement) { | ||
_this.listElement.className = styles$1.contentReturn; | ||
_this.listElement.style.transform = "translateX(".concat(_this.left, "px)"); | ||
} // hide backgrounds | ||
if (_this.contentLeft !== null) { | ||
_this.contentLeft.style.opacity = 0; | ||
_this.contentLeft.className = styles$1.contentLeftReturn; | ||
if (!actionTriggered) { | ||
_this.playReturnAnimation(); | ||
} | ||
if (_this.contentRight !== null) { | ||
_this.contentRight.style.opacity = 0; | ||
_this.contentRight.className = styles$1.contentRightReturn; | ||
} | ||
}); | ||
@@ -526,17 +625,17 @@ | ||
swipeRight = _this$props.swipeRight; | ||
return React__default.createElement("div", { | ||
return /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.swipeableListItem, | ||
ref: this.bindWrapper | ||
}, swipeLeft && React__default.createElement("div", { | ||
ref: this.bindContentLeft, | ||
}, swipeLeft && /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.contentLeft, | ||
"data-testid": "swipe-left-content" | ||
}, swipeLeft.content), swipeRight && React__default.createElement("div", { | ||
ref: this.bindContentRight, | ||
"data-testid": "swipe-left-content", | ||
ref: this.bindContentLeft | ||
}, swipeLeft.content), swipeRight && /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.contentRight, | ||
"data-testid": "swipe-right-content" | ||
}, swipeRight.content), React__default.createElement("div", { | ||
ref: this.bindListElement, | ||
"data-testid": "swipe-right-content", | ||
ref: this.bindContentRight | ||
}, swipeRight.content), /*#__PURE__*/React__default.createElement("div", { | ||
className: styles$1.content, | ||
"data-testid": "content" | ||
"data-testid": "content", | ||
ref: this.bindListElement | ||
}, children)); | ||
@@ -582,2 +681,3 @@ } | ||
exports.ActionAnimations = ActionAnimations; | ||
exports.SwipeableList = SwipeableList; | ||
@@ -584,0 +684,0 @@ exports.SwipeableListItem = SwipeableListItem; |
{ | ||
"name": "@sandstreamdev/react-swipeable-list", | ||
"description": "Swipeable list component for React", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"author": { | ||
@@ -30,35 +30,34 @@ "name": "Sandstream Development", | ||
"devDependencies": { | ||
"@babel/core": "7.8.3", | ||
"@babel/core": "7.9.0", | ||
"@babel/plugin-proposal-class-properties": "7.8.3", | ||
"@babel/plugin-transform-modules-commonjs": "7.8.3", | ||
"@babel/preset-env": "7.8.3", | ||
"@babel/preset-react": "7.8.3", | ||
"@rollup/plugin-commonjs": "11.0.2", | ||
"@rollup/plugin-node-resolve": "7.1.1", | ||
"@testing-library/jest-dom": "5.1.1", | ||
"@testing-library/react": "9.4.0", | ||
"autoprefixer": "9.7.4", | ||
"babel-eslint": "10.0.3", | ||
"@babel/plugin-transform-modules-commonjs": "7.9.0", | ||
"@babel/preset-env": "7.9.5", | ||
"@babel/preset-react": "7.9.4", | ||
"@rollup/plugin-commonjs": "11.1.0", | ||
"@rollup/plugin-node-resolve": "7.1.3", | ||
"@testing-library/jest-dom": "5.5.0", | ||
"@testing-library/react": "10.0.2", | ||
"autoprefixer": "9.7.6", | ||
"babel-eslint": "10.1.0", | ||
"eslint": "6.8.0", | ||
"eslint-config-prettier": "6.10.0", | ||
"eslint-plugin-prettier": "3.1.2", | ||
"eslint-plugin-react": "7.18.3", | ||
"eslint-plugin-react-hooks": "2.3.0", | ||
"husky": "4.2.1", | ||
"eslint-config-prettier": "6.10.1", | ||
"eslint-plugin-prettier": "3.1.3", | ||
"eslint-plugin-react": "7.19.0", | ||
"eslint-plugin-react-hooks": "3.0.0", | ||
"husky": "4.2.5", | ||
"identity-obj-proxy": "3.0.0", | ||
"jest": "25.1.0", | ||
"jest-transform-css": "2.0.0", | ||
"lint-staged": "10.0.7", | ||
"prettier": "1.19.1", | ||
"prop-types": "^15.7.2", | ||
"react": "^16.12.0", | ||
"react-dom": "^16.12.0", | ||
"rollup": "1.31.0", | ||
"rollup-plugin-babel": "4.3.3", | ||
"jest": "25.3.0", | ||
"lint-staged": "10.1.3", | ||
"prettier": "2.0.4", | ||
"prop-types": "15.7.2", | ||
"react": "16.13.1", | ||
"react-dom": "16.13.1", | ||
"rollup": "2.6.1", | ||
"rollup-plugin-babel": "4.4.0", | ||
"rollup-plugin-copy": "3.3.0", | ||
"rollup-plugin-local-resolve": "1.0.7", | ||
"rollup-plugin-peer-deps-external": "2.2.2", | ||
"rollup-plugin-postcss": "2.0.6", | ||
"stylelint": "13.0.0", | ||
"stylelint-config-standard": "19.0.0" | ||
"rollup-plugin-postcss": "2.6.4", | ||
"stylelint": "13.3.2", | ||
"stylelint-config-standard": "20.0.0" | ||
}, | ||
@@ -87,7 +86,4 @@ "scripts": { | ||
"jest --bail --findRelatedTests" | ||
], | ||
"*.css": [ | ||
"stylelint --fix" | ||
] | ||
} | ||
} |
@@ -20,3 +20,3 @@ <h1 align="center">react-swipeable-list</h1> | ||
![GitHub Release Date](https://img.shields.io/github/release-date/sandstreamdev/react-swipeable-list) | ||
[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors) | ||
[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) | ||
@@ -64,2 +64,26 @@ ## React Swipeable List component | ||
or use function as children pattern if other container is needed (check animation and styled container examples). Note that in this case you need to provide list wrapper and pass default `className` props to have same behaviour. Default `SwipeableList` styles are passed in `className` prop. | ||
```jsx | ||
<SwipeableList> | ||
{({ className, ...rest }) => ( | ||
<div className={className}> | ||
<SwipeableListItem | ||
swipeLeft={{ | ||
content: <div>Revealed content during swipe</div>, | ||
action: () => console.info('swipe action triggered') | ||
}} | ||
swipeRight={{ | ||
content: <div>Revealed content during swipe</div>, | ||
action: () => console.info('swipe action triggered') | ||
}} | ||
{...rest} | ||
> | ||
<div>Item name</div> | ||
</SwipeableListItem> | ||
</div> | ||
)} | ||
</SwipeableList> | ||
``` | ||
## SwipeableList Props | ||
@@ -69,3 +93,3 @@ | ||
Type: `number` (default: `10`) | ||
Type: `number` (optional, default: `10`) | ||
@@ -78,3 +102,3 @@ How far in pixels scroll needs to be done to block swiping. After scrolling is started and goes beyond the threshold, swiping is blocked. | ||
Type: `number` (default: `10`) | ||
Type: `number` (optional, default: `10`) | ||
@@ -87,3 +111,3 @@ How far in pixels swipe needs to be done to start swiping on list item. After a swipe is started and goes beyond the threshold, scrolling is blocked. | ||
Type: `number` (default: `0.5`) | ||
Type: `number` (optional, default: `0.5`) | ||
@@ -98,3 +122,3 @@ How far swipe needs to be done to trigger attached action. `0.5` means that item needs to be swiped to half of its width, `0.25` - one-quarter of width. | ||
Type: `boolean` (default: `false`) | ||
Type: `boolean` (optional, default: `false`) | ||
@@ -105,3 +129,3 @@ If set to `true` all defined swipe actions are blocked. | ||
Type: `Object` | ||
Type: `Object` (optional) | ||
@@ -113,2 +137,3 @@ Data for defining left swipe action and rendering content after item is swiped. The object requires following structure: | ||
action, // required: swipe action (function) | ||
actionAnimation, // optional: type of animation | ||
content, // required: HTML or React component | ||
@@ -118,2 +143,21 @@ } | ||
#### action | ||
Type: `function` (required) | ||
Callback function that should be run when swipe is done beyond threshold. | ||
#### actionAnimation | ||
Type: `ActionAnimations (RETURN | REMOVE | NONE)` (optional, default: `RETURN`) | ||
Animation type to be played swipe is done beyond threshold. | ||
#### content | ||
Type: `Anything that can be rendered` (required) | ||
Content that is revealed when swiping. | ||
### swipeRight | ||
@@ -129,2 +173,4 @@ | ||
How far in pixels scroll needs to be done to block swiping. After scrolling is started and goes beyond the threshold, swiping is blocked. | ||
It can be set for the whole list or for every item. See `scrollStartThreshold` for `SwipeableList`. Value from the `SwipeableListItem` takes precedence. | ||
@@ -144,2 +190,4 @@ | ||
How far swipe needs to be done to trigger attached action. `0.5` means that item needs to be swiped to half of its width, `0.25` - one-quarter of width. | ||
It can be set for the whole list or for every item. See `threshold` for `SwipeableList`. Value from the `SwipeableListItem` takes precedence. | ||
@@ -186,2 +234,5 @@ | ||
<td align="center"><a href="https://github.com/Iliyaz1995"><img src="https://avatars0.githubusercontent.com/u/31325754?v=4" width="100px;" alt=""/><br /><sub><b>Iliyaz syed</b></sub></a><br /><a href="https://github.com/sandstreamdev/react-swipeable-list/issues?q=author%3AIliyaz1995" title="Bug reports">🐛</a></td> | ||
<td align="center"><a href="https://twitter.com/jamescuenod"><img src="https://avatars2.githubusercontent.com/u/4253884?v=4" width="100px;" alt=""/><br /><sub><b>James Cuénod</b></sub></a><br /><a href="#ideas-jcuenod" title="Ideas, Planning, & Feedback">🤔</a></td> | ||
<td align="center"><a href="https://github.com/akshar07"><img src="https://avatars2.githubusercontent.com/u/11475137?v=4" width="100px;" alt=""/><br /><sub><b>Akshar Takle</b></sub></a><br /><a href="#ideas-akshar07" title="Ideas, Planning, & Feedback">🤔</a></td> | ||
<td align="center"><a href="http://mohammedfaragallah.herokuapp.com"><img src="https://avatars0.githubusercontent.com/u/14910456?v=4" width="100px;" alt=""/><br /><sub><b>Mohammed Faragallah</b></sub></a><br /><a href="#ideas-MohammedFaragallah" title="Ideas, Planning, & Feedback">🤔</a></td> | ||
</tr> | ||
@@ -188,0 +239,0 @@ </table> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
87766
32
1815
234