@dhis2-ui/intersection-detector 9.11.0 → 9.11.1-beta.10
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/build/cjs/features/Visibility_notification/index.js +10 -9
- package/build/cjs/index.js +0 -1
- package/build/cjs/{intersection-detector.stories.e2e.js → intersection-detector.e2e.stories.js} +3 -13
- package/build/cjs/intersection-detector.js +13 -22
- package/build/cjs/{intersection-detector.stories.js → intersection-detector.prod.stories.js} +22 -27
- package/build/es/features/Visibility_notification/index.js +10 -8
- package/build/es/intersection-detector.js +10 -11
- package/build/es/{intersection-detector.stories.js → intersection-detector.prod.stories.js} +17 -11
- package/package.json +5 -5
- /package/build/es/{intersection-detector.stories.e2e.js → intersection-detector.e2e.stories.js} +0 -0
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _cypressCucumberPreprocessor = require("@badeball/cypress-cucumber-preprocessor");
|
|
4
|
-
|
|
5
4
|
(0, _cypressCucumberPreprocessor.Given)('the detector is not intersecting with the root', () => {
|
|
6
5
|
cy.visitStory('IntersectionDetector', 'Out Of View');
|
|
7
|
-
cy.window().
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
cy.window().should(win => expect(win.onChange).to.not.be.undefined);
|
|
7
|
+
cy.window().its('onChange').as('onChangeStub', {
|
|
8
|
+
static: true
|
|
9
|
+
}).should('be.calledOnce').should('be.calledWith', {
|
|
10
|
+
isIntersecting: false
|
|
11
11
|
});
|
|
12
12
|
});
|
|
13
13
|
(0, _cypressCucumberPreprocessor.Given)('the detector is intersecting with the root', () => {
|
|
14
14
|
cy.visitStory('IntersectionDetector', 'In View');
|
|
15
|
-
cy.window().
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
cy.window().should(win => expect(win.onChange).to.not.be.undefined);
|
|
16
|
+
cy.window().its('onChange').as('onChangeStub', {
|
|
17
|
+
static: true
|
|
18
|
+
}).should('be.calledOnce').should('be.calledWith', {
|
|
19
|
+
isIntersecting: true
|
|
19
20
|
});
|
|
20
21
|
});
|
|
21
22
|
(0, _cypressCucumberPreprocessor.When)('the user scrolls the detector into view', () => {
|
package/build/cjs/index.js
CHANGED
package/build/cjs/{intersection-detector.stories.e2e.js → intersection-detector.e2e.stories.js}
RENAMED
|
@@ -4,21 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.OutOfView = exports.InView = void 0;
|
|
7
|
-
|
|
8
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
-
|
|
10
8
|
var _intersectionDetector = require("./intersection-detector.js");
|
|
11
|
-
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
|
-
|
|
9
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
10
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
16
11
|
window.onChange = window.Cypress ? window.Cypress.cy.stub() : () => null;
|
|
17
|
-
var _default = {
|
|
12
|
+
var _default = exports.default = {
|
|
18
13
|
title: 'IntersectionDetector'
|
|
19
14
|
};
|
|
20
|
-
exports.default = _default;
|
|
21
|
-
|
|
22
15
|
const OutOfView = () => {
|
|
23
16
|
const rootRef = (0, _react.useRef)();
|
|
24
17
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -47,9 +40,7 @@ const OutOfView = () => {
|
|
|
47
40
|
}
|
|
48
41
|
})));
|
|
49
42
|
};
|
|
50
|
-
|
|
51
43
|
exports.OutOfView = OutOfView;
|
|
52
|
-
|
|
53
44
|
const InView = () => {
|
|
54
45
|
const rootRef = (0, _react.useRef)();
|
|
55
46
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -78,5 +69,4 @@ const InView = () => {
|
|
|
78
69
|
}
|
|
79
70
|
}));
|
|
80
71
|
};
|
|
81
|
-
|
|
82
72
|
exports.InView = InView;
|
|
@@ -4,19 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.IntersectionDetector = void 0;
|
|
7
|
-
|
|
8
7
|
var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
9
|
-
|
|
10
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
-
|
|
12
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
|
-
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
17
|
-
|
|
18
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
-
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
13
|
const IntersectionDetector = _ref => {
|
|
21
14
|
let {
|
|
22
15
|
threshold,
|
|
@@ -31,25 +24,26 @@ const IntersectionDetector = _ref => {
|
|
|
31
24
|
// so there's no need for re-rendering the (potentially computational
|
|
32
25
|
// heavy) children. Also: If the parent re-renders (e. g. due to a state
|
|
33
26
|
// change), then this component will re-render as well.
|
|
27
|
+
|
|
34
28
|
// @var {Object}
|
|
35
29
|
// @prop {bool} current
|
|
36
|
-
const isIntersecting = (0, _react.useRef)();
|
|
37
|
-
// @prop {HTMLElement} current
|
|
30
|
+
const isIntersecting = (0, _react.useRef)();
|
|
38
31
|
|
|
32
|
+
// @var {Object}
|
|
33
|
+
// @prop {HTMLElement} current
|
|
39
34
|
const intersectionRef = (0, _react.useRef)();
|
|
40
35
|
(0, _react.useEffect)(() => {
|
|
41
36
|
const rootEl = rootRef.current;
|
|
42
37
|
const intersectionEl = intersectionRef.current;
|
|
43
|
-
|
|
44
38
|
if (rootEl && intersectionEl) {
|
|
45
39
|
const onIntersection = entries => {
|
|
46
40
|
// Currently there's no way to supply multiple thresholds,
|
|
47
41
|
// so a single entry can be assumed safely
|
|
48
|
-
const [entry] = entries;
|
|
49
|
-
// if there is no change
|
|
42
|
+
const [entry] = entries;
|
|
50
43
|
|
|
44
|
+
// Make sure the callback is not called multiple times
|
|
45
|
+
// if there is no change
|
|
51
46
|
const intersectionChange = entry.isIntersecting !== isIntersecting.current;
|
|
52
|
-
|
|
53
47
|
if (intersectionChange) {
|
|
54
48
|
isIntersecting.current = entry.isIntersecting;
|
|
55
49
|
onChange({
|
|
@@ -57,16 +51,16 @@ const IntersectionDetector = _ref => {
|
|
|
57
51
|
});
|
|
58
52
|
}
|
|
59
53
|
};
|
|
60
|
-
|
|
61
54
|
const observerOptions = {
|
|
62
55
|
root: rootEl,
|
|
63
56
|
threshold
|
|
64
57
|
};
|
|
65
58
|
const intersectionObserver = new IntersectionObserver(onIntersection, observerOptions);
|
|
66
|
-
intersectionObserver.observe(intersectionEl);
|
|
59
|
+
intersectionObserver.observe(intersectionEl);
|
|
60
|
+
|
|
61
|
+
// Make sure to clean up everything when un-mounting.
|
|
67
62
|
// Using an arrow function instead of just returning
|
|
68
63
|
// the disconnect function for better readability.
|
|
69
|
-
|
|
70
64
|
return () => intersectionObserver.disconnect();
|
|
71
65
|
}
|
|
72
66
|
}, [rootRef.current, intersectionRef.current]);
|
|
@@ -78,7 +72,6 @@ const IntersectionDetector = _ref => {
|
|
|
78
72
|
id: "2829611397"
|
|
79
73
|
}, ["div.jsx-2829611397{height:100%;}"]));
|
|
80
74
|
};
|
|
81
|
-
|
|
82
75
|
exports.IntersectionDetector = IntersectionDetector;
|
|
83
76
|
IntersectionDetector.defaultProps = {
|
|
84
77
|
threshold: 0,
|
|
@@ -90,13 +83,11 @@ IntersectionDetector.propTypes = {
|
|
|
90
83
|
// not required so `current` can be `null`
|
|
91
84
|
current: _propTypes.default.instanceOf(HTMLElement)
|
|
92
85
|
}).isRequired,
|
|
93
|
-
|
|
94
86
|
/** Called with signature `({ isIntersecting: bool })` */
|
|
95
87
|
onChange: _propTypes.default.func.isRequired,
|
|
96
88
|
children: _propTypes.default.any,
|
|
97
89
|
className: _propTypes.default.string,
|
|
98
90
|
dataTest: _propTypes.default.string,
|
|
99
|
-
|
|
100
91
|
/** The [threshold](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options) value: a value from 0.0 to 1.0 that controls the point at which an intersecting component is considered 'intersected' or 'visible' and the onChange callback triggers */
|
|
101
92
|
threshold: _propTypes.default.number
|
|
102
93
|
};
|
package/build/cjs/{intersection-detector.stories.js → intersection-detector.prod.stories.js}
RENAMED
|
@@ -4,25 +4,24 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.BottomArea = exports.AbsoluteTopArea = exports.AbsoluteBottomArea = void 0;
|
|
7
|
-
|
|
8
7
|
var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
9
|
-
|
|
10
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
-
|
|
12
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
|
-
|
|
14
10
|
var _intersectionDetector = require("./intersection-detector.js");
|
|
11
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
12
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
15
|
+
const description = `
|
|
16
|
+
A tool to performantly detect when two components intersect, which is often better to use than scroll listeners. A common use case is to detect when a child component is in view inside a scrolling parent. Uses an [\`IntersectionObserver\`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) object internally.
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
18
|
+
See the code examples below for examples on how to implement it.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
var _default = {
|
|
20
|
+
\`\`\`js
|
|
21
|
+
import { IntersectionDetector } from '@dhis2/ui'
|
|
22
|
+
\`\`\`
|
|
23
|
+
`;
|
|
24
|
+
var _default = exports.default = {
|
|
26
25
|
title: 'Intersection Observer',
|
|
27
26
|
component: _intersectionDetector.IntersectionDetector,
|
|
28
27
|
parameters: {
|
|
@@ -44,14 +43,11 @@ var _default = {
|
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
};
|
|
47
|
-
exports.default = _default;
|
|
48
|
-
|
|
49
46
|
const Text = () => /*#__PURE__*/_react.default.createElement("p", {
|
|
50
47
|
className: "jsx-3862390236"
|
|
51
48
|
}, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tempor venenatis hendrerit. Donec dictum sed ligula id efficitur. Suspendisse feugiat, elit in dictum imperdiet, mi tellus euismod nibh, vitae hendrerit turpis odio ut mauris. Vestibulum rhoncus interdum nunc eu eleifend. Aenean viverra nibh hendrerit nulla iaculis, vitae tincidunt erat ullamcorper. Donec tempus mattis faucibus. Donec nec lacus vitae elit aliquet pharetra. Cras vitae odio eu lorem euismod malesuada. Nunc eu rhoncus mauris. Nullam vehicula elit id vehicula maximus. Phasellus gravida tincidunt mauris, vitae laoreet erat commodo id. Nullam vitae erat ante. Proin id ultricies risus, in ultricies mauris. Vivamus lectus enim, ultricies vel egestas nec, tempor a magna. Nam sed fermentum ipsum, a ullamcorper felis. Aenean finibus erat elit, at eleifend nulla rutrum at.", /*#__PURE__*/_react.default.createElement(_style.default, {
|
|
52
49
|
id: "3862390236"
|
|
53
50
|
}, ["p.jsx-3862390236{margin:0;}"]));
|
|
54
|
-
|
|
55
51
|
const Template = _ref => {
|
|
56
52
|
let {
|
|
57
53
|
containerStyles,
|
|
@@ -63,7 +59,7 @@ const Template = _ref => {
|
|
|
63
59
|
className: "jsx-2697878418" + " " + "container"
|
|
64
60
|
}, /*#__PURE__*/_react.default.createElement("p", {
|
|
65
61
|
className: "jsx-2697878418"
|
|
66
|
-
}, "Is intersecting: ",
|
|
62
|
+
}, "Is intersecting: ", ` ${isIntersecting}`), /*#__PURE__*/_react.default.createElement("div", {
|
|
67
63
|
ref: rootRef,
|
|
68
64
|
className: "jsx-2697878418" + " " + "scrollContainer"
|
|
69
65
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -83,7 +79,6 @@ const Template = _ref => {
|
|
|
83
79
|
id: "2697878418"
|
|
84
80
|
}, [".scrollContainer.jsx-2697878418{width:200px;height:300px;overflow:hidden;overflow-y:auto;}", ".contentContainer.jsx-2697878418{position:relative;}"]));
|
|
85
81
|
};
|
|
86
|
-
|
|
87
82
|
Template.propTypes = {
|
|
88
83
|
containerStyles: _propTypes.default.shape({})
|
|
89
84
|
};
|
|
@@ -94,27 +89,27 @@ const boxStyles = {
|
|
|
94
89
|
width: '100%',
|
|
95
90
|
height: '100px'
|
|
96
91
|
};
|
|
97
|
-
const AbsoluteBottomArea = Template.bind({});
|
|
98
|
-
exports.AbsoluteBottomArea = AbsoluteBottomArea;
|
|
92
|
+
const AbsoluteBottomArea = exports.AbsoluteBottomArea = Template.bind({});
|
|
99
93
|
AbsoluteBottomArea.args = {
|
|
100
|
-
containerStyles: {
|
|
94
|
+
containerStyles: {
|
|
95
|
+
...boxStyles,
|
|
101
96
|
position: 'absolute',
|
|
102
97
|
bottom: '0',
|
|
103
98
|
left: '0'
|
|
104
99
|
}
|
|
105
100
|
};
|
|
106
|
-
const AbsoluteTopArea = Template.bind({});
|
|
107
|
-
exports.AbsoluteTopArea = AbsoluteTopArea;
|
|
101
|
+
const AbsoluteTopArea = exports.AbsoluteTopArea = Template.bind({});
|
|
108
102
|
AbsoluteTopArea.args = {
|
|
109
|
-
containerStyles: {
|
|
103
|
+
containerStyles: {
|
|
104
|
+
...boxStyles,
|
|
110
105
|
position: 'absolute',
|
|
111
106
|
top: '0',
|
|
112
107
|
left: '0'
|
|
113
108
|
}
|
|
114
109
|
};
|
|
115
|
-
const BottomArea = Template.bind({});
|
|
116
|
-
exports.BottomArea = BottomArea;
|
|
110
|
+
const BottomArea = exports.BottomArea = Template.bind({});
|
|
117
111
|
BottomArea.args = {
|
|
118
|
-
containerStyles: {
|
|
112
|
+
containerStyles: {
|
|
113
|
+
...boxStyles
|
|
119
114
|
}
|
|
120
115
|
};
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor';
|
|
2
2
|
Given('the detector is not intersecting with the root', () => {
|
|
3
3
|
cy.visitStory('IntersectionDetector', 'Out Of View');
|
|
4
|
-
cy.window().
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
cy.window().should(win => expect(win.onChange).to.not.be.undefined);
|
|
5
|
+
cy.window().its('onChange').as('onChangeStub', {
|
|
6
|
+
static: true
|
|
7
|
+
}).should('be.calledOnce').should('be.calledWith', {
|
|
8
|
+
isIntersecting: false
|
|
8
9
|
});
|
|
9
10
|
});
|
|
10
11
|
Given('the detector is intersecting with the root', () => {
|
|
11
12
|
cy.visitStory('IntersectionDetector', 'In View');
|
|
12
|
-
cy.window().
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
cy.window().should(win => expect(win.onChange).to.not.be.undefined);
|
|
14
|
+
cy.window().its('onChange').as('onChangeStub', {
|
|
15
|
+
static: true
|
|
16
|
+
}).should('be.calledOnce').should('be.calledWith', {
|
|
17
|
+
isIntersecting: true
|
|
16
18
|
});
|
|
17
19
|
});
|
|
18
20
|
When('the user scrolls the detector into view', () => {
|
|
@@ -15,25 +15,26 @@ export const IntersectionDetector = _ref => {
|
|
|
15
15
|
// so there's no need for re-rendering the (potentially computational
|
|
16
16
|
// heavy) children. Also: If the parent re-renders (e. g. due to a state
|
|
17
17
|
// change), then this component will re-render as well.
|
|
18
|
+
|
|
18
19
|
// @var {Object}
|
|
19
20
|
// @prop {bool} current
|
|
20
|
-
const isIntersecting = useRef();
|
|
21
|
-
// @prop {HTMLElement} current
|
|
21
|
+
const isIntersecting = useRef();
|
|
22
22
|
|
|
23
|
+
// @var {Object}
|
|
24
|
+
// @prop {HTMLElement} current
|
|
23
25
|
const intersectionRef = useRef();
|
|
24
26
|
useEffect(() => {
|
|
25
27
|
const rootEl = rootRef.current;
|
|
26
28
|
const intersectionEl = intersectionRef.current;
|
|
27
|
-
|
|
28
29
|
if (rootEl && intersectionEl) {
|
|
29
30
|
const onIntersection = entries => {
|
|
30
31
|
// Currently there's no way to supply multiple thresholds,
|
|
31
32
|
// so a single entry can be assumed safely
|
|
32
|
-
const [entry] = entries;
|
|
33
|
-
// if there is no change
|
|
33
|
+
const [entry] = entries;
|
|
34
34
|
|
|
35
|
+
// Make sure the callback is not called multiple times
|
|
36
|
+
// if there is no change
|
|
35
37
|
const intersectionChange = entry.isIntersecting !== isIntersecting.current;
|
|
36
|
-
|
|
37
38
|
if (intersectionChange) {
|
|
38
39
|
isIntersecting.current = entry.isIntersecting;
|
|
39
40
|
onChange({
|
|
@@ -41,16 +42,16 @@ export const IntersectionDetector = _ref => {
|
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
|
-
|
|
45
45
|
const observerOptions = {
|
|
46
46
|
root: rootEl,
|
|
47
47
|
threshold
|
|
48
48
|
};
|
|
49
49
|
const intersectionObserver = new IntersectionObserver(onIntersection, observerOptions);
|
|
50
|
-
intersectionObserver.observe(intersectionEl);
|
|
50
|
+
intersectionObserver.observe(intersectionEl);
|
|
51
|
+
|
|
52
|
+
// Make sure to clean up everything when un-mounting.
|
|
51
53
|
// Using an arrow function instead of just returning
|
|
52
54
|
// the disconnect function for better readability.
|
|
53
|
-
|
|
54
55
|
return () => intersectionObserver.disconnect();
|
|
55
56
|
}
|
|
56
57
|
}, [rootRef.current, intersectionRef.current]);
|
|
@@ -72,13 +73,11 @@ IntersectionDetector.propTypes = {
|
|
|
72
73
|
// not required so `current` can be `null`
|
|
73
74
|
current: PropTypes.instanceOf(HTMLElement)
|
|
74
75
|
}).isRequired,
|
|
75
|
-
|
|
76
76
|
/** Called with signature `({ isIntersecting: bool })` */
|
|
77
77
|
onChange: PropTypes.func.isRequired,
|
|
78
78
|
children: PropTypes.any,
|
|
79
79
|
className: PropTypes.string,
|
|
80
80
|
dataTest: PropTypes.string,
|
|
81
|
-
|
|
82
81
|
/** The [threshold](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options) value: a value from 0.0 to 1.0 that controls the point at which an intersecting component is considered 'intersected' or 'visible' and the onChange callback triggers */
|
|
83
82
|
threshold: PropTypes.number
|
|
84
83
|
};
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import _JSXStyle from "styled-jsx/style";
|
|
2
|
-
|
|
3
|
-
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
|
-
|
|
2
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
5
3
|
import PropTypes from 'prop-types';
|
|
6
4
|
import React, { useState, useRef } from 'react';
|
|
7
5
|
import { IntersectionDetector } from './intersection-detector.js';
|
|
8
|
-
const description =
|
|
6
|
+
const description = `
|
|
7
|
+
A tool to performantly detect when two components intersect, which is often better to use than scroll listeners. A common use case is to detect when a child component is in view inside a scrolling parent. Uses an [\`IntersectionObserver\`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) object internally.
|
|
8
|
+
|
|
9
|
+
See the code examples below for examples on how to implement it.
|
|
10
|
+
|
|
11
|
+
\`\`\`js
|
|
12
|
+
import { IntersectionDetector } from '@dhis2/ui'
|
|
13
|
+
\`\`\`
|
|
14
|
+
`;
|
|
9
15
|
export default {
|
|
10
16
|
title: 'Intersection Observer',
|
|
11
17
|
component: IntersectionDetector,
|
|
@@ -28,13 +34,11 @@ export default {
|
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
};
|
|
31
|
-
|
|
32
37
|
const Text = () => /*#__PURE__*/React.createElement("p", {
|
|
33
38
|
className: "jsx-3862390236"
|
|
34
39
|
}, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tempor venenatis hendrerit. Donec dictum sed ligula id efficitur. Suspendisse feugiat, elit in dictum imperdiet, mi tellus euismod nibh, vitae hendrerit turpis odio ut mauris. Vestibulum rhoncus interdum nunc eu eleifend. Aenean viverra nibh hendrerit nulla iaculis, vitae tincidunt erat ullamcorper. Donec tempus mattis faucibus. Donec nec lacus vitae elit aliquet pharetra. Cras vitae odio eu lorem euismod malesuada. Nunc eu rhoncus mauris. Nullam vehicula elit id vehicula maximus. Phasellus gravida tincidunt mauris, vitae laoreet erat commodo id. Nullam vitae erat ante. Proin id ultricies risus, in ultricies mauris. Vivamus lectus enim, ultricies vel egestas nec, tempor a magna. Nam sed fermentum ipsum, a ullamcorper felis. Aenean finibus erat elit, at eleifend nulla rutrum at.", /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
35
40
|
id: "3862390236"
|
|
36
41
|
}, ["p.jsx-3862390236{margin:0;}"]));
|
|
37
|
-
|
|
38
42
|
const Template = _ref => {
|
|
39
43
|
let {
|
|
40
44
|
containerStyles,
|
|
@@ -46,7 +50,7 @@ const Template = _ref => {
|
|
|
46
50
|
className: "jsx-2697878418" + " " + "container"
|
|
47
51
|
}, /*#__PURE__*/React.createElement("p", {
|
|
48
52
|
className: "jsx-2697878418"
|
|
49
|
-
}, "Is intersecting: ",
|
|
53
|
+
}, "Is intersecting: ", ` ${isIntersecting}`), /*#__PURE__*/React.createElement("div", {
|
|
50
54
|
ref: rootRef,
|
|
51
55
|
className: "jsx-2697878418" + " " + "scrollContainer"
|
|
52
56
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -66,7 +70,6 @@ const Template = _ref => {
|
|
|
66
70
|
id: "2697878418"
|
|
67
71
|
}, [".scrollContainer.jsx-2697878418{width:200px;height:300px;overflow:hidden;overflow-y:auto;}", ".contentContainer.jsx-2697878418{position:relative;}"]));
|
|
68
72
|
};
|
|
69
|
-
|
|
70
73
|
Template.propTypes = {
|
|
71
74
|
containerStyles: PropTypes.shape({})
|
|
72
75
|
};
|
|
@@ -79,7 +82,8 @@ const boxStyles = {
|
|
|
79
82
|
};
|
|
80
83
|
export const AbsoluteBottomArea = Template.bind({});
|
|
81
84
|
AbsoluteBottomArea.args = {
|
|
82
|
-
containerStyles: {
|
|
85
|
+
containerStyles: {
|
|
86
|
+
...boxStyles,
|
|
83
87
|
position: 'absolute',
|
|
84
88
|
bottom: '0',
|
|
85
89
|
left: '0'
|
|
@@ -87,7 +91,8 @@ AbsoluteBottomArea.args = {
|
|
|
87
91
|
};
|
|
88
92
|
export const AbsoluteTopArea = Template.bind({});
|
|
89
93
|
AbsoluteTopArea.args = {
|
|
90
|
-
containerStyles: {
|
|
94
|
+
containerStyles: {
|
|
95
|
+
...boxStyles,
|
|
91
96
|
position: 'absolute',
|
|
92
97
|
top: '0',
|
|
93
98
|
left: '0'
|
|
@@ -95,6 +100,7 @@ AbsoluteTopArea.args = {
|
|
|
95
100
|
};
|
|
96
101
|
export const BottomArea = Template.bind({});
|
|
97
102
|
BottomArea.args = {
|
|
98
|
-
containerStyles: {
|
|
103
|
+
containerStyles: {
|
|
104
|
+
...boxStyles
|
|
99
105
|
}
|
|
100
106
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhis2-ui/intersection-detector",
|
|
3
|
-
"version": "9.11.
|
|
3
|
+
"version": "9.11.1-beta.10",
|
|
4
4
|
"description": "UI IntersectionDetector",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,18 +22,18 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
|
-
"start": "
|
|
25
|
+
"start": "storybook dev -c ../../storybook/config --port 5000",
|
|
26
26
|
"build": "d2-app-scripts build",
|
|
27
27
|
"test": "d2-app-scripts test --jestConfig ../../jest.config.shared.js"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"react": "^16.
|
|
31
|
-
"react-dom": "^16.
|
|
30
|
+
"react": "^16.13",
|
|
31
|
+
"react-dom": "^16.13",
|
|
32
32
|
"styled-jsx": "^4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@dhis2/prop-types": "^3.1.2",
|
|
36
|
-
"@dhis2/ui-constants": "9.11.
|
|
36
|
+
"@dhis2/ui-constants": "9.11.1-beta.10",
|
|
37
37
|
"classnames": "^2.3.1",
|
|
38
38
|
"prop-types": "^15.7.2"
|
|
39
39
|
},
|
/package/build/es/{intersection-detector.stories.e2e.js → intersection-detector.e2e.stories.js}
RENAMED
|
File without changes
|