react-simple-pull-to-refresh 1.2.4 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/package.json +1 -1
- package/build/components/pull-to-refresh.d.ts +0 -18
- package/build/components/pulling-content.d.ts +0 -2
- package/build/components/refreshing-content.d.ts +0 -3
- package/build/index.cjs.js +0 -293
- package/build/index.d.ts +0 -2
- package/build/index.esm.js +0 -288
- package/build/isScrollable.d.ts +0 -5
- package/build/types.d.ts +0 -4
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ return (
|
|
|
72
72
|
| onRefresh | () => Promise<any> | true | | Function called when Refresh Event has been trigerred |
|
|
73
73
|
| pullDownThreshold | number | false | 67 | Distance in pixel to pull to trigger a Refresh Event |
|
|
74
74
|
| maxPullDownDistance | number | false | 95 | Maximum transitionY applied to Children when dragging |
|
|
75
|
+
| resistance | number | false | 1 | Scale of difficulty to pull down |
|
|
75
76
|
| refreshingContent | JSX.Element or string | false | <RefreshingContent /> | Content displayed when Pulling or Fetch more has been trigerred |
|
|
76
77
|
| pullingContent | JSX.Element or string | false | <PullingContent /> | Content displayed when Pulling |
|
|
77
78
|
| canFetchMore | boolean | false | false | Enable or disable fetching more feature |
|
|
@@ -82,6 +83,12 @@ return (
|
|
|
82
83
|
|
|
83
84
|
## Changelog
|
|
84
85
|
|
|
86
|
+
1.3.1: Fix issue preventing fixed elements to work properly - (From: [@ManuDoni](https://github.com/ManuDoni))
|
|
87
|
+
|
|
88
|
+
1.3.0: Add a _resistance_ prop, that allows to adjust the pull down difficulty - (From: [@joshuahiggins](https://github.com/joshuahiggins))
|
|
89
|
+
|
|
90
|
+
1.2.5: Fix event listenter leaks - (From: [@d-s-x](https://github.com/d-s-x))
|
|
91
|
+
|
|
85
92
|
1.2.4: Fix overscroll on iOS Safari - (From: [@d-s-x](https://github.com/d-s-x))
|
|
86
93
|
|
|
87
94
|
1.2.3: Add React 17+ as valid peer dependencies - (From: [@Felixmosh](https://github.com/felixmosh))
|
package/package.json
CHANGED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import '../styles/main.scss';
|
|
3
|
-
interface PullToRefreshProps {
|
|
4
|
-
isPullable?: boolean;
|
|
5
|
-
canFetchMore?: boolean;
|
|
6
|
-
onRefresh: () => Promise<any>;
|
|
7
|
-
onFetchMore?: () => Promise<any>;
|
|
8
|
-
refreshingContent?: JSX.Element | string;
|
|
9
|
-
pullingContent?: JSX.Element | string;
|
|
10
|
-
children: JSX.Element;
|
|
11
|
-
pullDownThreshold?: number;
|
|
12
|
-
fetchMoreThreshold?: number;
|
|
13
|
-
maxPullDownDistance?: number;
|
|
14
|
-
backgroundColor?: string;
|
|
15
|
-
className?: string;
|
|
16
|
-
}
|
|
17
|
-
declare const PullToRefresh: React.FC<PullToRefreshProps>;
|
|
18
|
-
export default PullToRefresh;
|
package/build/index.cjs.js
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
4
|
-
|
|
5
|
-
var React = require('react');
|
|
6
|
-
var React__default = _interopDefault(React);
|
|
7
|
-
|
|
8
|
-
var DIRECTION;
|
|
9
|
-
(function (DIRECTION) {
|
|
10
|
-
DIRECTION[DIRECTION["UP"] = -1] = "UP";
|
|
11
|
-
DIRECTION[DIRECTION["DOWN"] = 1] = "DOWN";
|
|
12
|
-
})(DIRECTION || (DIRECTION = {}));
|
|
13
|
-
|
|
14
|
-
function isOverflowScrollable(element) {
|
|
15
|
-
var overflowType = getComputedStyle(element).overflowY;
|
|
16
|
-
if (element === document.scrollingElement && overflowType === 'visible') {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
if (overflowType !== 'scroll' && overflowType !== 'auto') {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
function isScrollable(element, direction) {
|
|
25
|
-
if (!isOverflowScrollable(element)) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
if (direction === DIRECTION.DOWN) {
|
|
29
|
-
var bottomScroll = element.scrollTop + element.clientHeight;
|
|
30
|
-
return bottomScroll < element.scrollHeight;
|
|
31
|
-
}
|
|
32
|
-
if (direction === DIRECTION.UP) {
|
|
33
|
-
return element.scrollTop > 0;
|
|
34
|
-
}
|
|
35
|
-
throw new Error('unsupported direction');
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Returns whether a given element or any of its ancestors (up to rootElement) is scrollable in a given direction.
|
|
39
|
-
*/
|
|
40
|
-
function isTreeScrollable(element, direction) {
|
|
41
|
-
if (isScrollable(element, direction)) {
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
if (element.parentElement == null) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
return isTreeScrollable(element.parentElement, direction);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function styleInject(css, ref) {
|
|
51
|
-
if ( ref === void 0 ) ref = {};
|
|
52
|
-
var insertAt = ref.insertAt;
|
|
53
|
-
|
|
54
|
-
if (!css || typeof document === 'undefined') { return; }
|
|
55
|
-
|
|
56
|
-
var head = document.head || document.getElementsByTagName('head')[0];
|
|
57
|
-
var style = document.createElement('style');
|
|
58
|
-
style.type = 'text/css';
|
|
59
|
-
|
|
60
|
-
if (insertAt === 'top') {
|
|
61
|
-
if (head.firstChild) {
|
|
62
|
-
head.insertBefore(style, head.firstChild);
|
|
63
|
-
} else {
|
|
64
|
-
head.appendChild(style);
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
head.appendChild(style);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (style.styleSheet) {
|
|
71
|
-
style.styleSheet.cssText = css;
|
|
72
|
-
} else {
|
|
73
|
-
style.appendChild(document.createTextNode(css));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
var css = ".lds-ellipsis {\n display: inline-block;\n position: relative;\n width: 64px;\n height: 64px; }\n\n.lds-ellipsis div {\n position: absolute;\n top: 27px;\n width: 11px;\n height: 11px;\n border-radius: 50%;\n background: #363636;\n animation-timing-function: cubic-bezier(0, 1, 1, 0); }\n\n.lds-ellipsis div:nth-child(1) {\n left: 6px;\n animation: lds-ellipsis1 0.6s infinite; }\n\n.lds-ellipsis div:nth-child(2) {\n left: 6px;\n animation: lds-ellipsis2 0.6s infinite; }\n\n.lds-ellipsis div:nth-child(3) {\n left: 26px;\n animation: lds-ellipsis2 0.6s infinite; }\n\n.lds-ellipsis div:nth-child(4) {\n left: 45px;\n animation: lds-ellipsis3 0.6s infinite; }\n\n@keyframes lds-ellipsis1 {\n 0% {\n transform: scale(0); }\n 100% {\n transform: scale(1); } }\n\n@keyframes lds-ellipsis3 {\n 0% {\n transform: scale(1); }\n 100% {\n transform: scale(0); } }\n\n@keyframes lds-ellipsis2 {\n 0% {\n transform: translate(0, 0); }\n 100% {\n transform: translate(19px, 0); } }\n";
|
|
78
|
-
styleInject(css);
|
|
79
|
-
|
|
80
|
-
// Source: https://loading.io/css/
|
|
81
|
-
var RefreshingContent = function () {
|
|
82
|
-
return (React__default.createElement("div", { className: "lds-ellipsis" },
|
|
83
|
-
React__default.createElement("div", null),
|
|
84
|
-
React__default.createElement("div", null),
|
|
85
|
-
React__default.createElement("div", null),
|
|
86
|
-
React__default.createElement("div", null)));
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
var PullingContent = function () {
|
|
90
|
-
return (React__default.createElement("div", null,
|
|
91
|
-
React__default.createElement("p", null, "\u21A7\u00A0\u00A0pull to refresh\u00A0\u00A0\u21A7")));
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
var css$1 = ".ptr,\n.ptr__children {\n height: 100%;\n width: 100%;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n position: relative; }\n\n.ptr.ptr--fetch-more-treshold-breached .ptr__fetch-more {\n display: block; }\n\n.ptr__fetch-more {\n display: none; }\n\n/**\n * Pull down transition \n */\n.ptr__children,\n.ptr__pull-down {\n transition: transform 0.2s cubic-bezier(0, 0, 0.31, 1); }\n\n.ptr__pull-down {\n position: absolute;\n overflow: hidden;\n left: 0;\n right: 0;\n top: 0;\n visibility: hidden; }\n .ptr__pull-down > div {\n display: none; }\n\n.ptr--dragging {\n /**\n * Hide PullMore content is treshold breached\n */\n /**\n * Otherwize, display content\n */ }\n .ptr--dragging.ptr--pull-down-treshold-breached .ptr__pull-down--pull-more {\n display: none; }\n .ptr--dragging .ptr__pull-down--pull-more {\n display: block; }\n\n.ptr--pull-down-treshold-breached {\n /**\n * Force opacity to 1 is pull down trashold breached\n */\n /**\n * And display loader\n */ }\n .ptr--pull-down-treshold-breached .ptr__pull-down {\n opacity: 1 !important; }\n .ptr--pull-down-treshold-breached .ptr__pull-down--loading {\n display: block; }\n\n.ptr__loader {\n margin: 0 auto;\n text-align: center; }\n";
|
|
95
|
-
styleInject(css$1);
|
|
96
|
-
|
|
97
|
-
var PullToRefresh = function (_a) {
|
|
98
|
-
var _b = _a.isPullable, isPullable = _b === void 0 ? true : _b, _c = _a.canFetchMore, canFetchMore = _c === void 0 ? false : _c, onRefresh = _a.onRefresh, onFetchMore = _a.onFetchMore, _d = _a.refreshingContent, refreshingContent = _d === void 0 ? React__default.createElement(RefreshingContent, null) : _d, _e = _a.pullingContent, pullingContent = _e === void 0 ? React__default.createElement(PullingContent, null) : _e, children = _a.children, _f = _a.pullDownThreshold, pullDownThreshold = _f === void 0 ? 67 : _f, _g = _a.fetchMoreThreshold, fetchMoreThreshold = _g === void 0 ? 100 : _g, _h = _a.maxPullDownDistance, maxPullDownDistance = _h === void 0 ? 95 : _h, // max distance to scroll to trigger refresh
|
|
99
|
-
backgroundColor = _a.backgroundColor, _j = _a.className, className = _j === void 0 ? '' : _j;
|
|
100
|
-
var containerRef = React.useRef(null);
|
|
101
|
-
var childrenRef = React.useRef(null);
|
|
102
|
-
var pullDownRef = React.useRef(null);
|
|
103
|
-
var fetchMoreRef = React.useRef(null);
|
|
104
|
-
var pullToRefreshThresholdBreached = false;
|
|
105
|
-
var fetchMoreTresholdBreached = false; // if true, fetchMore loader is displayed
|
|
106
|
-
var isDragging = false;
|
|
107
|
-
var startY = 0;
|
|
108
|
-
var currentY = 0;
|
|
109
|
-
React.useEffect(function () {
|
|
110
|
-
if (!isPullable || !childrenRef || !childrenRef.current)
|
|
111
|
-
return;
|
|
112
|
-
childrenRef.current.addEventListener('touchstart', onTouchStart, { passive: true });
|
|
113
|
-
childrenRef.current.addEventListener('mousedown', onTouchStart);
|
|
114
|
-
childrenRef.current.addEventListener('touchmove', onTouchMove, { passive: false });
|
|
115
|
-
childrenRef.current.addEventListener('mousemove', onTouchMove);
|
|
116
|
-
window.addEventListener('scroll', onScroll);
|
|
117
|
-
childrenRef.current.addEventListener('touchend', onEnd);
|
|
118
|
-
childrenRef.current.addEventListener('mouseup', onEnd);
|
|
119
|
-
document.body.addEventListener('mouseleave', onEnd);
|
|
120
|
-
return function () {
|
|
121
|
-
if (!isPullable || !childrenRef || !childrenRef.current)
|
|
122
|
-
return;
|
|
123
|
-
childrenRef.current.removeEventListener('touchstart', onTouchStart);
|
|
124
|
-
childrenRef.current.removeEventListener('mousedown', onTouchStart);
|
|
125
|
-
childrenRef.current.removeEventListener('touchmove', onTouchMove);
|
|
126
|
-
childrenRef.current.removeEventListener('mousemove', onTouchMove);
|
|
127
|
-
window.removeEventListener('scroll', onScroll);
|
|
128
|
-
childrenRef.current.removeEventListener('touchend', onEnd);
|
|
129
|
-
childrenRef.current.removeEventListener('mouseup', onEnd);
|
|
130
|
-
document.body.removeEventListener('mouseleave', onEnd);
|
|
131
|
-
};
|
|
132
|
-
}, [
|
|
133
|
-
children,
|
|
134
|
-
isPullable,
|
|
135
|
-
onRefresh,
|
|
136
|
-
pullDownThreshold,
|
|
137
|
-
maxPullDownDistance,
|
|
138
|
-
canFetchMore,
|
|
139
|
-
fetchMoreThreshold,
|
|
140
|
-
]);
|
|
141
|
-
/**
|
|
142
|
-
* Check onMount / canFetchMore becomes true
|
|
143
|
-
* if fetchMoreThreshold is already breached
|
|
144
|
-
*/
|
|
145
|
-
React.useEffect(function () {
|
|
146
|
-
var _a;
|
|
147
|
-
/**
|
|
148
|
-
* Check if it is already in fetching more state
|
|
149
|
-
*/
|
|
150
|
-
if (!((_a = containerRef) === null || _a === void 0 ? void 0 : _a.current))
|
|
151
|
-
return;
|
|
152
|
-
var isAlreadyFetchingMore = containerRef.current.classList.contains('ptr--fetch-more-treshold-breached');
|
|
153
|
-
if (isAlreadyFetchingMore)
|
|
154
|
-
return;
|
|
155
|
-
/**
|
|
156
|
-
* Proceed
|
|
157
|
-
*/
|
|
158
|
-
if (canFetchMore && getScrollToBottomValue() < fetchMoreThreshold && onFetchMore) {
|
|
159
|
-
containerRef.current.classList.add('ptr--fetch-more-treshold-breached');
|
|
160
|
-
fetchMoreTresholdBreached = true;
|
|
161
|
-
onFetchMore().then(initContainer).catch(initContainer);
|
|
162
|
-
}
|
|
163
|
-
}, [canFetchMore, children]);
|
|
164
|
-
/**
|
|
165
|
-
* Returns distance to bottom of the container
|
|
166
|
-
*/
|
|
167
|
-
var getScrollToBottomValue = function () {
|
|
168
|
-
if (!childrenRef || !childrenRef.current)
|
|
169
|
-
return -1;
|
|
170
|
-
var scrollTop = window.scrollY; // is the pixels hidden in top due to the scroll. With no scroll its value is 0.
|
|
171
|
-
var scrollHeight = childrenRef.current.scrollHeight; // is the pixels of the whole container
|
|
172
|
-
return scrollHeight - scrollTop - window.innerHeight;
|
|
173
|
-
};
|
|
174
|
-
var initContainer = function () {
|
|
175
|
-
requestAnimationFrame(function () {
|
|
176
|
-
/**
|
|
177
|
-
* Reset Styles
|
|
178
|
-
*/
|
|
179
|
-
if (childrenRef.current) {
|
|
180
|
-
childrenRef.current.style.overflowX = 'hidden';
|
|
181
|
-
childrenRef.current.style.overflowY = 'auto';
|
|
182
|
-
childrenRef.current.style.transform = "translate(0px, 0px)";
|
|
183
|
-
}
|
|
184
|
-
if (pullDownRef.current) {
|
|
185
|
-
pullDownRef.current.style.opacity = '0';
|
|
186
|
-
}
|
|
187
|
-
if (containerRef.current) {
|
|
188
|
-
containerRef.current.classList.remove('ptr--pull-down-treshold-breached');
|
|
189
|
-
containerRef.current.classList.remove('ptr--dragging');
|
|
190
|
-
containerRef.current.classList.remove('ptr--fetch-more-treshold-breached');
|
|
191
|
-
}
|
|
192
|
-
if (pullToRefreshThresholdBreached)
|
|
193
|
-
pullToRefreshThresholdBreached = false;
|
|
194
|
-
if (fetchMoreTresholdBreached)
|
|
195
|
-
fetchMoreTresholdBreached = false;
|
|
196
|
-
});
|
|
197
|
-
};
|
|
198
|
-
var onTouchStart = function (e) {
|
|
199
|
-
isDragging = false;
|
|
200
|
-
if (e instanceof MouseEvent) {
|
|
201
|
-
startY = e.pageY;
|
|
202
|
-
}
|
|
203
|
-
if (window.TouchEvent && e instanceof TouchEvent) {
|
|
204
|
-
startY = e.touches[0].pageY;
|
|
205
|
-
}
|
|
206
|
-
currentY = startY;
|
|
207
|
-
// Check if element can be scrolled
|
|
208
|
-
if (e.type === 'touchstart' && isTreeScrollable(e.target, DIRECTION.UP)) {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
// Top non visible so cancel
|
|
212
|
-
if (childrenRef.current.getBoundingClientRect().top < 0) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
isDragging = true;
|
|
216
|
-
};
|
|
217
|
-
var onTouchMove = function (e) {
|
|
218
|
-
if (!isDragging) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
if (window.TouchEvent && e instanceof TouchEvent) {
|
|
222
|
-
currentY = e.touches[0].pageY;
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
currentY = e.pageY;
|
|
226
|
-
}
|
|
227
|
-
containerRef.current.classList.add('ptr--dragging');
|
|
228
|
-
if (currentY < startY) {
|
|
229
|
-
isDragging = false;
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
if (e.cancelable) {
|
|
233
|
-
e.preventDefault();
|
|
234
|
-
}
|
|
235
|
-
// Limit to trigger refresh has been breached
|
|
236
|
-
if (currentY - startY >= pullDownThreshold) {
|
|
237
|
-
isDragging = true;
|
|
238
|
-
pullToRefreshThresholdBreached = true;
|
|
239
|
-
containerRef.current.classList.remove('ptr--dragging');
|
|
240
|
-
containerRef.current.classList.add('ptr--pull-down-treshold-breached');
|
|
241
|
-
}
|
|
242
|
-
// maxPullDownDistance breached, stop the animation
|
|
243
|
-
if (currentY - startY > maxPullDownDistance) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
pullDownRef.current.style.opacity = ((currentY - startY) / 65).toString();
|
|
247
|
-
childrenRef.current.style.overflow = 'visible';
|
|
248
|
-
childrenRef.current.style.transform = "translate(0px, " + (currentY - startY) + "px)";
|
|
249
|
-
pullDownRef.current.style.visibility = 'visible';
|
|
250
|
-
};
|
|
251
|
-
var onScroll = function (e) {
|
|
252
|
-
/**
|
|
253
|
-
* Check if component has already called onFetchMore
|
|
254
|
-
*/
|
|
255
|
-
if (fetchMoreTresholdBreached)
|
|
256
|
-
return;
|
|
257
|
-
/**
|
|
258
|
-
* Check if user breached fetchMoreThreshold
|
|
259
|
-
*/
|
|
260
|
-
if (canFetchMore && getScrollToBottomValue() < fetchMoreThreshold && onFetchMore) {
|
|
261
|
-
fetchMoreTresholdBreached = true;
|
|
262
|
-
containerRef.current.classList.add('ptr--fetch-more-treshold-breached');
|
|
263
|
-
onFetchMore().then(initContainer).catch(initContainer);
|
|
264
|
-
}
|
|
265
|
-
};
|
|
266
|
-
var onEnd = function () {
|
|
267
|
-
isDragging = false;
|
|
268
|
-
startY = 0;
|
|
269
|
-
currentY = 0;
|
|
270
|
-
// Container has not been dragged enough, put it back to it's initial state
|
|
271
|
-
if (!pullToRefreshThresholdBreached) {
|
|
272
|
-
if (pullDownRef.current)
|
|
273
|
-
pullDownRef.current.style.visibility = 'hidden';
|
|
274
|
-
initContainer();
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
if (childrenRef.current) {
|
|
278
|
-
childrenRef.current.style.overflow = 'visible';
|
|
279
|
-
childrenRef.current.style.transform = "translate(0px, " + pullDownThreshold + "px)";
|
|
280
|
-
}
|
|
281
|
-
onRefresh().then(initContainer).catch(initContainer);
|
|
282
|
-
};
|
|
283
|
-
return (React__default.createElement("div", { className: "ptr " + className, style: { backgroundColor: backgroundColor }, ref: containerRef },
|
|
284
|
-
React__default.createElement("div", { className: "ptr__pull-down", ref: pullDownRef },
|
|
285
|
-
React__default.createElement("div", { className: "ptr__loader ptr__pull-down--loading" }, refreshingContent),
|
|
286
|
-
React__default.createElement("div", { className: "ptr__pull-down--pull-more" }, pullingContent)),
|
|
287
|
-
React__default.createElement("div", { className: "ptr__children", ref: childrenRef },
|
|
288
|
-
children,
|
|
289
|
-
React__default.createElement("div", { className: "ptr__fetch-more", ref: fetchMoreRef },
|
|
290
|
-
React__default.createElement("div", { className: "ptr__loader ptr__fetch-more--loading" }, refreshingContent)))));
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
module.exports = PullToRefresh;
|
package/build/index.d.ts
DELETED
package/build/index.esm.js
DELETED
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
import React, { useRef, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
var DIRECTION;
|
|
4
|
-
(function (DIRECTION) {
|
|
5
|
-
DIRECTION[DIRECTION["UP"] = -1] = "UP";
|
|
6
|
-
DIRECTION[DIRECTION["DOWN"] = 1] = "DOWN";
|
|
7
|
-
})(DIRECTION || (DIRECTION = {}));
|
|
8
|
-
|
|
9
|
-
function isOverflowScrollable(element) {
|
|
10
|
-
var overflowType = getComputedStyle(element).overflowY;
|
|
11
|
-
if (element === document.scrollingElement && overflowType === 'visible') {
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
14
|
-
if (overflowType !== 'scroll' && overflowType !== 'auto') {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
function isScrollable(element, direction) {
|
|
20
|
-
if (!isOverflowScrollable(element)) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
if (direction === DIRECTION.DOWN) {
|
|
24
|
-
var bottomScroll = element.scrollTop + element.clientHeight;
|
|
25
|
-
return bottomScroll < element.scrollHeight;
|
|
26
|
-
}
|
|
27
|
-
if (direction === DIRECTION.UP) {
|
|
28
|
-
return element.scrollTop > 0;
|
|
29
|
-
}
|
|
30
|
-
throw new Error('unsupported direction');
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Returns whether a given element or any of its ancestors (up to rootElement) is scrollable in a given direction.
|
|
34
|
-
*/
|
|
35
|
-
function isTreeScrollable(element, direction) {
|
|
36
|
-
if (isScrollable(element, direction)) {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
if (element.parentElement == null) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
return isTreeScrollable(element.parentElement, direction);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function styleInject(css, ref) {
|
|
46
|
-
if ( ref === void 0 ) ref = {};
|
|
47
|
-
var insertAt = ref.insertAt;
|
|
48
|
-
|
|
49
|
-
if (!css || typeof document === 'undefined') { return; }
|
|
50
|
-
|
|
51
|
-
var head = document.head || document.getElementsByTagName('head')[0];
|
|
52
|
-
var style = document.createElement('style');
|
|
53
|
-
style.type = 'text/css';
|
|
54
|
-
|
|
55
|
-
if (insertAt === 'top') {
|
|
56
|
-
if (head.firstChild) {
|
|
57
|
-
head.insertBefore(style, head.firstChild);
|
|
58
|
-
} else {
|
|
59
|
-
head.appendChild(style);
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
head.appendChild(style);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (style.styleSheet) {
|
|
66
|
-
style.styleSheet.cssText = css;
|
|
67
|
-
} else {
|
|
68
|
-
style.appendChild(document.createTextNode(css));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
var css = ".lds-ellipsis {\n display: inline-block;\n position: relative;\n width: 64px;\n height: 64px; }\n\n.lds-ellipsis div {\n position: absolute;\n top: 27px;\n width: 11px;\n height: 11px;\n border-radius: 50%;\n background: #363636;\n animation-timing-function: cubic-bezier(0, 1, 1, 0); }\n\n.lds-ellipsis div:nth-child(1) {\n left: 6px;\n animation: lds-ellipsis1 0.6s infinite; }\n\n.lds-ellipsis div:nth-child(2) {\n left: 6px;\n animation: lds-ellipsis2 0.6s infinite; }\n\n.lds-ellipsis div:nth-child(3) {\n left: 26px;\n animation: lds-ellipsis2 0.6s infinite; }\n\n.lds-ellipsis div:nth-child(4) {\n left: 45px;\n animation: lds-ellipsis3 0.6s infinite; }\n\n@keyframes lds-ellipsis1 {\n 0% {\n transform: scale(0); }\n 100% {\n transform: scale(1); } }\n\n@keyframes lds-ellipsis3 {\n 0% {\n transform: scale(1); }\n 100% {\n transform: scale(0); } }\n\n@keyframes lds-ellipsis2 {\n 0% {\n transform: translate(0, 0); }\n 100% {\n transform: translate(19px, 0); } }\n";
|
|
73
|
-
styleInject(css);
|
|
74
|
-
|
|
75
|
-
// Source: https://loading.io/css/
|
|
76
|
-
var RefreshingContent = function () {
|
|
77
|
-
return (React.createElement("div", { className: "lds-ellipsis" },
|
|
78
|
-
React.createElement("div", null),
|
|
79
|
-
React.createElement("div", null),
|
|
80
|
-
React.createElement("div", null),
|
|
81
|
-
React.createElement("div", null)));
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
var PullingContent = function () {
|
|
85
|
-
return (React.createElement("div", null,
|
|
86
|
-
React.createElement("p", null, "\u21A7\u00A0\u00A0pull to refresh\u00A0\u00A0\u21A7")));
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
var css$1 = ".ptr,\n.ptr__children {\n height: 100%;\n width: 100%;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n position: relative; }\n\n.ptr.ptr--fetch-more-treshold-breached .ptr__fetch-more {\n display: block; }\n\n.ptr__fetch-more {\n display: none; }\n\n/**\n * Pull down transition \n */\n.ptr__children,\n.ptr__pull-down {\n transition: transform 0.2s cubic-bezier(0, 0, 0.31, 1); }\n\n.ptr__pull-down {\n position: absolute;\n overflow: hidden;\n left: 0;\n right: 0;\n top: 0;\n visibility: hidden; }\n .ptr__pull-down > div {\n display: none; }\n\n.ptr--dragging {\n /**\n * Hide PullMore content is treshold breached\n */\n /**\n * Otherwize, display content\n */ }\n .ptr--dragging.ptr--pull-down-treshold-breached .ptr__pull-down--pull-more {\n display: none; }\n .ptr--dragging .ptr__pull-down--pull-more {\n display: block; }\n\n.ptr--pull-down-treshold-breached {\n /**\n * Force opacity to 1 is pull down trashold breached\n */\n /**\n * And display loader\n */ }\n .ptr--pull-down-treshold-breached .ptr__pull-down {\n opacity: 1 !important; }\n .ptr--pull-down-treshold-breached .ptr__pull-down--loading {\n display: block; }\n\n.ptr__loader {\n margin: 0 auto;\n text-align: center; }\n";
|
|
90
|
-
styleInject(css$1);
|
|
91
|
-
|
|
92
|
-
var PullToRefresh = function (_a) {
|
|
93
|
-
var _b = _a.isPullable, isPullable = _b === void 0 ? true : _b, _c = _a.canFetchMore, canFetchMore = _c === void 0 ? false : _c, onRefresh = _a.onRefresh, onFetchMore = _a.onFetchMore, _d = _a.refreshingContent, refreshingContent = _d === void 0 ? React.createElement(RefreshingContent, null) : _d, _e = _a.pullingContent, pullingContent = _e === void 0 ? React.createElement(PullingContent, null) : _e, children = _a.children, _f = _a.pullDownThreshold, pullDownThreshold = _f === void 0 ? 67 : _f, _g = _a.fetchMoreThreshold, fetchMoreThreshold = _g === void 0 ? 100 : _g, _h = _a.maxPullDownDistance, maxPullDownDistance = _h === void 0 ? 95 : _h, // max distance to scroll to trigger refresh
|
|
94
|
-
backgroundColor = _a.backgroundColor, _j = _a.className, className = _j === void 0 ? '' : _j;
|
|
95
|
-
var containerRef = useRef(null);
|
|
96
|
-
var childrenRef = useRef(null);
|
|
97
|
-
var pullDownRef = useRef(null);
|
|
98
|
-
var fetchMoreRef = useRef(null);
|
|
99
|
-
var pullToRefreshThresholdBreached = false;
|
|
100
|
-
var fetchMoreTresholdBreached = false; // if true, fetchMore loader is displayed
|
|
101
|
-
var isDragging = false;
|
|
102
|
-
var startY = 0;
|
|
103
|
-
var currentY = 0;
|
|
104
|
-
useEffect(function () {
|
|
105
|
-
if (!isPullable || !childrenRef || !childrenRef.current)
|
|
106
|
-
return;
|
|
107
|
-
childrenRef.current.addEventListener('touchstart', onTouchStart, { passive: true });
|
|
108
|
-
childrenRef.current.addEventListener('mousedown', onTouchStart);
|
|
109
|
-
childrenRef.current.addEventListener('touchmove', onTouchMove, { passive: false });
|
|
110
|
-
childrenRef.current.addEventListener('mousemove', onTouchMove);
|
|
111
|
-
window.addEventListener('scroll', onScroll);
|
|
112
|
-
childrenRef.current.addEventListener('touchend', onEnd);
|
|
113
|
-
childrenRef.current.addEventListener('mouseup', onEnd);
|
|
114
|
-
document.body.addEventListener('mouseleave', onEnd);
|
|
115
|
-
return function () {
|
|
116
|
-
if (!isPullable || !childrenRef || !childrenRef.current)
|
|
117
|
-
return;
|
|
118
|
-
childrenRef.current.removeEventListener('touchstart', onTouchStart);
|
|
119
|
-
childrenRef.current.removeEventListener('mousedown', onTouchStart);
|
|
120
|
-
childrenRef.current.removeEventListener('touchmove', onTouchMove);
|
|
121
|
-
childrenRef.current.removeEventListener('mousemove', onTouchMove);
|
|
122
|
-
window.removeEventListener('scroll', onScroll);
|
|
123
|
-
childrenRef.current.removeEventListener('touchend', onEnd);
|
|
124
|
-
childrenRef.current.removeEventListener('mouseup', onEnd);
|
|
125
|
-
document.body.removeEventListener('mouseleave', onEnd);
|
|
126
|
-
};
|
|
127
|
-
}, [
|
|
128
|
-
children,
|
|
129
|
-
isPullable,
|
|
130
|
-
onRefresh,
|
|
131
|
-
pullDownThreshold,
|
|
132
|
-
maxPullDownDistance,
|
|
133
|
-
canFetchMore,
|
|
134
|
-
fetchMoreThreshold,
|
|
135
|
-
]);
|
|
136
|
-
/**
|
|
137
|
-
* Check onMount / canFetchMore becomes true
|
|
138
|
-
* if fetchMoreThreshold is already breached
|
|
139
|
-
*/
|
|
140
|
-
useEffect(function () {
|
|
141
|
-
var _a;
|
|
142
|
-
/**
|
|
143
|
-
* Check if it is already in fetching more state
|
|
144
|
-
*/
|
|
145
|
-
if (!((_a = containerRef) === null || _a === void 0 ? void 0 : _a.current))
|
|
146
|
-
return;
|
|
147
|
-
var isAlreadyFetchingMore = containerRef.current.classList.contains('ptr--fetch-more-treshold-breached');
|
|
148
|
-
if (isAlreadyFetchingMore)
|
|
149
|
-
return;
|
|
150
|
-
/**
|
|
151
|
-
* Proceed
|
|
152
|
-
*/
|
|
153
|
-
if (canFetchMore && getScrollToBottomValue() < fetchMoreThreshold && onFetchMore) {
|
|
154
|
-
containerRef.current.classList.add('ptr--fetch-more-treshold-breached');
|
|
155
|
-
fetchMoreTresholdBreached = true;
|
|
156
|
-
onFetchMore().then(initContainer).catch(initContainer);
|
|
157
|
-
}
|
|
158
|
-
}, [canFetchMore, children]);
|
|
159
|
-
/**
|
|
160
|
-
* Returns distance to bottom of the container
|
|
161
|
-
*/
|
|
162
|
-
var getScrollToBottomValue = function () {
|
|
163
|
-
if (!childrenRef || !childrenRef.current)
|
|
164
|
-
return -1;
|
|
165
|
-
var scrollTop = window.scrollY; // is the pixels hidden in top due to the scroll. With no scroll its value is 0.
|
|
166
|
-
var scrollHeight = childrenRef.current.scrollHeight; // is the pixels of the whole container
|
|
167
|
-
return scrollHeight - scrollTop - window.innerHeight;
|
|
168
|
-
};
|
|
169
|
-
var initContainer = function () {
|
|
170
|
-
requestAnimationFrame(function () {
|
|
171
|
-
/**
|
|
172
|
-
* Reset Styles
|
|
173
|
-
*/
|
|
174
|
-
if (childrenRef.current) {
|
|
175
|
-
childrenRef.current.style.overflowX = 'hidden';
|
|
176
|
-
childrenRef.current.style.overflowY = 'auto';
|
|
177
|
-
childrenRef.current.style.transform = "translate(0px, 0px)";
|
|
178
|
-
}
|
|
179
|
-
if (pullDownRef.current) {
|
|
180
|
-
pullDownRef.current.style.opacity = '0';
|
|
181
|
-
}
|
|
182
|
-
if (containerRef.current) {
|
|
183
|
-
containerRef.current.classList.remove('ptr--pull-down-treshold-breached');
|
|
184
|
-
containerRef.current.classList.remove('ptr--dragging');
|
|
185
|
-
containerRef.current.classList.remove('ptr--fetch-more-treshold-breached');
|
|
186
|
-
}
|
|
187
|
-
if (pullToRefreshThresholdBreached)
|
|
188
|
-
pullToRefreshThresholdBreached = false;
|
|
189
|
-
if (fetchMoreTresholdBreached)
|
|
190
|
-
fetchMoreTresholdBreached = false;
|
|
191
|
-
});
|
|
192
|
-
};
|
|
193
|
-
var onTouchStart = function (e) {
|
|
194
|
-
isDragging = false;
|
|
195
|
-
if (e instanceof MouseEvent) {
|
|
196
|
-
startY = e.pageY;
|
|
197
|
-
}
|
|
198
|
-
if (window.TouchEvent && e instanceof TouchEvent) {
|
|
199
|
-
startY = e.touches[0].pageY;
|
|
200
|
-
}
|
|
201
|
-
currentY = startY;
|
|
202
|
-
// Check if element can be scrolled
|
|
203
|
-
if (e.type === 'touchstart' && isTreeScrollable(e.target, DIRECTION.UP)) {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
// Top non visible so cancel
|
|
207
|
-
if (childrenRef.current.getBoundingClientRect().top < 0) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
isDragging = true;
|
|
211
|
-
};
|
|
212
|
-
var onTouchMove = function (e) {
|
|
213
|
-
if (!isDragging) {
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
if (window.TouchEvent && e instanceof TouchEvent) {
|
|
217
|
-
currentY = e.touches[0].pageY;
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
currentY = e.pageY;
|
|
221
|
-
}
|
|
222
|
-
containerRef.current.classList.add('ptr--dragging');
|
|
223
|
-
if (currentY < startY) {
|
|
224
|
-
isDragging = false;
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
if (e.cancelable) {
|
|
228
|
-
e.preventDefault();
|
|
229
|
-
}
|
|
230
|
-
// Limit to trigger refresh has been breached
|
|
231
|
-
if (currentY - startY >= pullDownThreshold) {
|
|
232
|
-
isDragging = true;
|
|
233
|
-
pullToRefreshThresholdBreached = true;
|
|
234
|
-
containerRef.current.classList.remove('ptr--dragging');
|
|
235
|
-
containerRef.current.classList.add('ptr--pull-down-treshold-breached');
|
|
236
|
-
}
|
|
237
|
-
// maxPullDownDistance breached, stop the animation
|
|
238
|
-
if (currentY - startY > maxPullDownDistance) {
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
pullDownRef.current.style.opacity = ((currentY - startY) / 65).toString();
|
|
242
|
-
childrenRef.current.style.overflow = 'visible';
|
|
243
|
-
childrenRef.current.style.transform = "translate(0px, " + (currentY - startY) + "px)";
|
|
244
|
-
pullDownRef.current.style.visibility = 'visible';
|
|
245
|
-
};
|
|
246
|
-
var onScroll = function (e) {
|
|
247
|
-
/**
|
|
248
|
-
* Check if component has already called onFetchMore
|
|
249
|
-
*/
|
|
250
|
-
if (fetchMoreTresholdBreached)
|
|
251
|
-
return;
|
|
252
|
-
/**
|
|
253
|
-
* Check if user breached fetchMoreThreshold
|
|
254
|
-
*/
|
|
255
|
-
if (canFetchMore && getScrollToBottomValue() < fetchMoreThreshold && onFetchMore) {
|
|
256
|
-
fetchMoreTresholdBreached = true;
|
|
257
|
-
containerRef.current.classList.add('ptr--fetch-more-treshold-breached');
|
|
258
|
-
onFetchMore().then(initContainer).catch(initContainer);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
var onEnd = function () {
|
|
262
|
-
isDragging = false;
|
|
263
|
-
startY = 0;
|
|
264
|
-
currentY = 0;
|
|
265
|
-
// Container has not been dragged enough, put it back to it's initial state
|
|
266
|
-
if (!pullToRefreshThresholdBreached) {
|
|
267
|
-
if (pullDownRef.current)
|
|
268
|
-
pullDownRef.current.style.visibility = 'hidden';
|
|
269
|
-
initContainer();
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
if (childrenRef.current) {
|
|
273
|
-
childrenRef.current.style.overflow = 'visible';
|
|
274
|
-
childrenRef.current.style.transform = "translate(0px, " + pullDownThreshold + "px)";
|
|
275
|
-
}
|
|
276
|
-
onRefresh().then(initContainer).catch(initContainer);
|
|
277
|
-
};
|
|
278
|
-
return (React.createElement("div", { className: "ptr " + className, style: { backgroundColor: backgroundColor }, ref: containerRef },
|
|
279
|
-
React.createElement("div", { className: "ptr__pull-down", ref: pullDownRef },
|
|
280
|
-
React.createElement("div", { className: "ptr__loader ptr__pull-down--loading" }, refreshingContent),
|
|
281
|
-
React.createElement("div", { className: "ptr__pull-down--pull-more" }, pullingContent)),
|
|
282
|
-
React.createElement("div", { className: "ptr__children", ref: childrenRef },
|
|
283
|
-
children,
|
|
284
|
-
React.createElement("div", { className: "ptr__fetch-more", ref: fetchMoreRef },
|
|
285
|
-
React.createElement("div", { className: "ptr__loader ptr__fetch-more--loading" }, refreshingContent)))));
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
export default PullToRefresh;
|
package/build/isScrollable.d.ts
DELETED
package/build/types.d.ts
DELETED