@player-ui/auto-scroll-manager-plugin-react 0.4.0-next.7 → 0.4.0-next.9
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/dist/index.cjs.js +19 -9
- package/dist/index.d.ts +13 -1
- package/dist/index.esm.js +19 -8
- package/package.json +11 -3
- package/src/hooks.tsx +8 -5
- package/src/plugin.tsx +20 -2
- package/src/scrollIntoViewWithOffset.ts +22 -0
package/dist/index.cjs.js
CHANGED
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
-
var
|
|
6
|
+
var seamlessScrollPolyfill = require('seamless-scroll-polyfill');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
9
|
|
|
10
10
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
var scrollIntoViewWithOffset = (node, baseElement, offset) => {
|
|
13
|
+
seamlessScrollPolyfill.scrollTo(window, {
|
|
14
|
+
behavior: "smooth",
|
|
15
|
+
top: node.getBoundingClientRect().top - baseElement.getBoundingClientRect().top - offset
|
|
16
|
+
});
|
|
17
|
+
};
|
|
12
18
|
|
|
13
19
|
const AutoScrollManagerContext = React__default["default"].createContext({ register: () => {
|
|
14
20
|
} });
|
|
@@ -18,6 +24,8 @@ const useRegisterAsScrollable = () => {
|
|
|
18
24
|
};
|
|
19
25
|
const AutoScrollProvider = ({
|
|
20
26
|
getElementToScrollTo,
|
|
27
|
+
getBaseElement,
|
|
28
|
+
offset,
|
|
21
29
|
children
|
|
22
30
|
}) => {
|
|
23
31
|
const [scrollableMap, setScrollableMap] = React.useState(new Map());
|
|
@@ -38,10 +46,7 @@ const AutoScrollProvider = ({
|
|
|
38
46
|
React.useEffect(() => {
|
|
39
47
|
const node = document.getElementById(getElementToScrollTo(scrollableMap));
|
|
40
48
|
if (node) {
|
|
41
|
-
|
|
42
|
-
block: "center",
|
|
43
|
-
inline: "center"
|
|
44
|
-
});
|
|
49
|
+
scrollIntoViewWithOffset(node, getBaseElement() || document.body, offset);
|
|
45
50
|
}
|
|
46
51
|
});
|
|
47
52
|
return /* @__PURE__ */ React__default["default"].createElement(AutoScrollManagerContext.Provider, {
|
|
@@ -58,9 +63,11 @@ exports.ScrollType = void 0;
|
|
|
58
63
|
class AutoScrollManagerPlugin {
|
|
59
64
|
constructor(config) {
|
|
60
65
|
this.name = "auto-scroll-manager";
|
|
61
|
-
var _a, _b;
|
|
66
|
+
var _a, _b, _c, _d;
|
|
62
67
|
this.autoScrollOnLoad = (_a = config.autoScrollOnLoad) != null ? _a : false;
|
|
63
68
|
this.autoFocusOnErrorField = (_b = config.autoFocusOnErrorField) != null ? _b : false;
|
|
69
|
+
this.getBaseElement = (_c = config.getBaseElement) != null ? _c : () => null;
|
|
70
|
+
this.offset = (_d = config.offset) != null ? _d : 0;
|
|
64
71
|
this.initialRender = false;
|
|
65
72
|
this.failedNavigation = false;
|
|
66
73
|
this.alreadyScrolledTo = [];
|
|
@@ -118,6 +125,7 @@ class AutoScrollManagerPlugin {
|
|
|
118
125
|
this.initialRender = true;
|
|
119
126
|
this.failedNavigation = false;
|
|
120
127
|
this.alreadyScrolledTo = [];
|
|
128
|
+
window.scroll(0, 0);
|
|
121
129
|
});
|
|
122
130
|
flow.hooks.skipTransition.intercept({
|
|
123
131
|
call: () => {
|
|
@@ -130,9 +138,11 @@ class AutoScrollManagerPlugin {
|
|
|
130
138
|
applyReact(reactPlayer) {
|
|
131
139
|
reactPlayer.hooks.webComponent.tap(this.name, (Comp) => {
|
|
132
140
|
return () => {
|
|
133
|
-
const { scrollFn } = this;
|
|
141
|
+
const { scrollFn, getBaseElement, offset } = this;
|
|
134
142
|
return /* @__PURE__ */ React__default["default"].createElement(AutoScrollProvider, {
|
|
135
|
-
getElementToScrollTo: scrollFn
|
|
143
|
+
getElementToScrollTo: scrollFn,
|
|
144
|
+
getBaseElement,
|
|
145
|
+
offset
|
|
136
146
|
}, /* @__PURE__ */ React__default["default"].createElement(Comp, null));
|
|
137
147
|
};
|
|
138
148
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ import { Player } from '@player-ui/player';
|
|
|
5
5
|
interface AutoScrollProviderProps {
|
|
6
6
|
/** Return the element to scroll to based on the registered types */
|
|
7
7
|
getElementToScrollTo: (scrollableElements: Map<ScrollType, Set<string>>) => string;
|
|
8
|
+
/** Optional function to get container element, which is used for calculating offset (default: document.body) */
|
|
9
|
+
getBaseElement: () => HTMLElement | undefined | null;
|
|
10
|
+
/** Additional offset to be used (default: 0) */
|
|
11
|
+
offset: number;
|
|
8
12
|
}
|
|
9
13
|
interface RegisterData {
|
|
10
14
|
/** when to scroll to the target */
|
|
@@ -20,7 +24,7 @@ declare const AutoScrollManagerContext: React.Context<{
|
|
|
20
24
|
/** hook to register as a scroll target */
|
|
21
25
|
declare const useRegisterAsScrollable: () => ScrollFunction;
|
|
22
26
|
/** Component to handle scrolling */
|
|
23
|
-
declare const AutoScrollProvider: ({ getElementToScrollTo, children, }: PropsWithChildren<AutoScrollProviderProps>) => JSX.Element;
|
|
27
|
+
declare const AutoScrollProvider: ({ getElementToScrollTo, getBaseElement, offset, children, }: PropsWithChildren<AutoScrollProviderProps>) => JSX.Element;
|
|
24
28
|
|
|
25
29
|
declare enum ScrollType {
|
|
26
30
|
ValidationError = 0,
|
|
@@ -32,6 +36,10 @@ interface AutoScrollManagerConfig {
|
|
|
32
36
|
autoScrollOnLoad?: boolean;
|
|
33
37
|
/** Config to auto-focus on an error */
|
|
34
38
|
autoFocusOnErrorField?: boolean;
|
|
39
|
+
/** Optional function to get container element, which is used for calculating offset (default: document.body) */
|
|
40
|
+
getBaseElement?: () => HTMLElement | undefined | null;
|
|
41
|
+
/** Additional offset to be used (default: 0) */
|
|
42
|
+
offset?: number;
|
|
35
43
|
}
|
|
36
44
|
/** A plugin to manage scrolling behavior */
|
|
37
45
|
declare class AutoScrollManagerPlugin implements ReactPlayerPlugin {
|
|
@@ -44,6 +52,10 @@ declare class AutoScrollManagerPlugin implements ReactPlayerPlugin {
|
|
|
44
52
|
private initialRender;
|
|
45
53
|
/** tracks if the navigation failed */
|
|
46
54
|
private failedNavigation;
|
|
55
|
+
/** function to return the base of the scrollable area */
|
|
56
|
+
private getBaseElement;
|
|
57
|
+
/** static offset */
|
|
58
|
+
private offset;
|
|
47
59
|
/** map of scroll type to set of ids that are registered under that type */
|
|
48
60
|
private alreadyScrolledTo;
|
|
49
61
|
private scrollFn;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { scrollTo } from 'seamless-scroll-polyfill';
|
|
3
|
+
|
|
4
|
+
var scrollIntoViewWithOffset = (node, baseElement, offset) => {
|
|
5
|
+
scrollTo(window, {
|
|
6
|
+
behavior: "smooth",
|
|
7
|
+
top: node.getBoundingClientRect().top - baseElement.getBoundingClientRect().top - offset
|
|
8
|
+
});
|
|
9
|
+
};
|
|
3
10
|
|
|
4
11
|
const AutoScrollManagerContext = React.createContext({ register: () => {
|
|
5
12
|
} });
|
|
@@ -9,6 +16,8 @@ const useRegisterAsScrollable = () => {
|
|
|
9
16
|
};
|
|
10
17
|
const AutoScrollProvider = ({
|
|
11
18
|
getElementToScrollTo,
|
|
19
|
+
getBaseElement,
|
|
20
|
+
offset,
|
|
12
21
|
children
|
|
13
22
|
}) => {
|
|
14
23
|
const [scrollableMap, setScrollableMap] = useState(new Map());
|
|
@@ -29,10 +38,7 @@ const AutoScrollProvider = ({
|
|
|
29
38
|
useEffect(() => {
|
|
30
39
|
const node = document.getElementById(getElementToScrollTo(scrollableMap));
|
|
31
40
|
if (node) {
|
|
32
|
-
|
|
33
|
-
block: "center",
|
|
34
|
-
inline: "center"
|
|
35
|
-
});
|
|
41
|
+
scrollIntoViewWithOffset(node, getBaseElement() || document.body, offset);
|
|
36
42
|
}
|
|
37
43
|
});
|
|
38
44
|
return /* @__PURE__ */ React.createElement(AutoScrollManagerContext.Provider, {
|
|
@@ -49,9 +55,11 @@ var ScrollType;
|
|
|
49
55
|
class AutoScrollManagerPlugin {
|
|
50
56
|
constructor(config) {
|
|
51
57
|
this.name = "auto-scroll-manager";
|
|
52
|
-
var _a, _b;
|
|
58
|
+
var _a, _b, _c, _d;
|
|
53
59
|
this.autoScrollOnLoad = (_a = config.autoScrollOnLoad) != null ? _a : false;
|
|
54
60
|
this.autoFocusOnErrorField = (_b = config.autoFocusOnErrorField) != null ? _b : false;
|
|
61
|
+
this.getBaseElement = (_c = config.getBaseElement) != null ? _c : () => null;
|
|
62
|
+
this.offset = (_d = config.offset) != null ? _d : 0;
|
|
55
63
|
this.initialRender = false;
|
|
56
64
|
this.failedNavigation = false;
|
|
57
65
|
this.alreadyScrolledTo = [];
|
|
@@ -109,6 +117,7 @@ class AutoScrollManagerPlugin {
|
|
|
109
117
|
this.initialRender = true;
|
|
110
118
|
this.failedNavigation = false;
|
|
111
119
|
this.alreadyScrolledTo = [];
|
|
120
|
+
window.scroll(0, 0);
|
|
112
121
|
});
|
|
113
122
|
flow.hooks.skipTransition.intercept({
|
|
114
123
|
call: () => {
|
|
@@ -121,9 +130,11 @@ class AutoScrollManagerPlugin {
|
|
|
121
130
|
applyReact(reactPlayer) {
|
|
122
131
|
reactPlayer.hooks.webComponent.tap(this.name, (Comp) => {
|
|
123
132
|
return () => {
|
|
124
|
-
const { scrollFn } = this;
|
|
133
|
+
const { scrollFn, getBaseElement, offset } = this;
|
|
125
134
|
return /* @__PURE__ */ React.createElement(AutoScrollProvider, {
|
|
126
|
-
getElementToScrollTo: scrollFn
|
|
135
|
+
getElementToScrollTo: scrollFn,
|
|
136
|
+
getBaseElement,
|
|
137
|
+
offset
|
|
127
138
|
}, /* @__PURE__ */ React.createElement(Comp, null));
|
|
128
139
|
};
|
|
129
140
|
});
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@player-ui/auto-scroll-manager-plugin-react",
|
|
3
|
-
"version": "0.4.0-next.
|
|
3
|
+
"version": "0.4.0-next.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org"
|
|
7
7
|
},
|
|
8
8
|
"peerDependencies": {
|
|
9
|
-
"@player-ui/react": "0.4.0-next.
|
|
9
|
+
"@player-ui/react": "0.4.0-next.9"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"
|
|
12
|
+
"seamless-scroll-polyfill": "2.3.3",
|
|
13
13
|
"@babel/runtime": "7.15.4"
|
|
14
14
|
},
|
|
15
15
|
"main": "dist/index.cjs.js",
|
|
@@ -53,6 +53,14 @@
|
|
|
53
53
|
{
|
|
54
54
|
"name": "Kelly Harrop",
|
|
55
55
|
"url": "https://github.com/kharrop"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "Alejandro Fimbres",
|
|
59
|
+
"url": "https://github.com/lexfm"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "Rafael Campos",
|
|
63
|
+
"url": "https://github.com/rafbcampos"
|
|
56
64
|
}
|
|
57
65
|
]
|
|
58
66
|
}
|
package/src/hooks.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PropsWithChildren } from 'react';
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
|
-
import
|
|
3
|
+
import scrollIntoViewWithOffset from './scrollIntoViewWithOffset';
|
|
4
4
|
import type { ScrollType } from './index';
|
|
5
5
|
|
|
6
6
|
export interface AutoScrollProviderProps {
|
|
@@ -8,6 +8,10 @@ export interface AutoScrollProviderProps {
|
|
|
8
8
|
getElementToScrollTo: (
|
|
9
9
|
scrollableElements: Map<ScrollType, Set<string>>
|
|
10
10
|
) => string;
|
|
11
|
+
/** Optional function to get container element, which is used for calculating offset (default: document.body) */
|
|
12
|
+
getBaseElement: () => HTMLElement | undefined | null;
|
|
13
|
+
/** Additional offset to be used (default: 0) */
|
|
14
|
+
offset: number;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
export interface RegisterData {
|
|
@@ -35,6 +39,8 @@ export const useRegisterAsScrollable = (): ScrollFunction => {
|
|
|
35
39
|
/** Component to handle scrolling */
|
|
36
40
|
export const AutoScrollProvider = ({
|
|
37
41
|
getElementToScrollTo,
|
|
42
|
+
getBaseElement,
|
|
43
|
+
offset,
|
|
38
44
|
children,
|
|
39
45
|
}: PropsWithChildren<AutoScrollProviderProps>) => {
|
|
40
46
|
// Tracker for what elements are registered to be scroll targets
|
|
@@ -68,10 +74,7 @@ export const AutoScrollProvider = ({
|
|
|
68
74
|
const node = document.getElementById(getElementToScrollTo(scrollableMap));
|
|
69
75
|
|
|
70
76
|
if (node) {
|
|
71
|
-
|
|
72
|
-
block: 'center',
|
|
73
|
-
inline: 'center',
|
|
74
|
-
});
|
|
77
|
+
scrollIntoViewWithOffset(node, getBaseElement() || document.body, offset);
|
|
75
78
|
}
|
|
76
79
|
});
|
|
77
80
|
|
package/src/plugin.tsx
CHANGED
|
@@ -14,6 +14,10 @@ export interface AutoScrollManagerConfig {
|
|
|
14
14
|
autoScrollOnLoad?: boolean;
|
|
15
15
|
/** Config to auto-focus on an error */
|
|
16
16
|
autoFocusOnErrorField?: boolean;
|
|
17
|
+
/** Optional function to get container element, which is used for calculating offset (default: document.body) */
|
|
18
|
+
getBaseElement?: () => HTMLElement | undefined | null;
|
|
19
|
+
/** Additional offset to be used (default: 0) */
|
|
20
|
+
offset?: number;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
/** A plugin to manage scrolling behavior */
|
|
@@ -32,6 +36,12 @@ export class AutoScrollManagerPlugin implements ReactPlayerPlugin {
|
|
|
32
36
|
/** tracks if the navigation failed */
|
|
33
37
|
private failedNavigation: boolean;
|
|
34
38
|
|
|
39
|
+
/** function to return the base of the scrollable area */
|
|
40
|
+
private getBaseElement: () => HTMLElement | undefined | null;
|
|
41
|
+
|
|
42
|
+
/** static offset */
|
|
43
|
+
private offset: number;
|
|
44
|
+
|
|
35
45
|
/** map of scroll type to set of ids that are registered under that type */
|
|
36
46
|
private alreadyScrolledTo: Array<string>;
|
|
37
47
|
private scrollFn: (
|
|
@@ -41,6 +51,8 @@ export class AutoScrollManagerPlugin implements ReactPlayerPlugin {
|
|
|
41
51
|
constructor(config: AutoScrollManagerConfig) {
|
|
42
52
|
this.autoScrollOnLoad = config.autoScrollOnLoad ?? false;
|
|
43
53
|
this.autoFocusOnErrorField = config.autoFocusOnErrorField ?? false;
|
|
54
|
+
this.getBaseElement = config.getBaseElement ?? (() => null);
|
|
55
|
+
this.offset = config.offset ?? 0;
|
|
44
56
|
this.initialRender = false;
|
|
45
57
|
this.failedNavigation = false;
|
|
46
58
|
this.alreadyScrolledTo = [];
|
|
@@ -123,6 +135,8 @@ export class AutoScrollManagerPlugin implements ReactPlayerPlugin {
|
|
|
123
135
|
this.initialRender = true;
|
|
124
136
|
this.failedNavigation = false;
|
|
125
137
|
this.alreadyScrolledTo = [];
|
|
138
|
+
// Reset scroll position for new view
|
|
139
|
+
window.scroll(0, 0);
|
|
126
140
|
});
|
|
127
141
|
flow.hooks.skipTransition.intercept({
|
|
128
142
|
call: () => {
|
|
@@ -136,9 +150,13 @@ export class AutoScrollManagerPlugin implements ReactPlayerPlugin {
|
|
|
136
150
|
applyReact(reactPlayer: ReactPlayer) {
|
|
137
151
|
reactPlayer.hooks.webComponent.tap(this.name, (Comp) => {
|
|
138
152
|
return () => {
|
|
139
|
-
const { scrollFn } = this;
|
|
153
|
+
const { scrollFn, getBaseElement, offset } = this;
|
|
140
154
|
return (
|
|
141
|
-
<AutoScrollProvider
|
|
155
|
+
<AutoScrollProvider
|
|
156
|
+
getElementToScrollTo={scrollFn}
|
|
157
|
+
getBaseElement={getBaseElement}
|
|
158
|
+
offset={offset}
|
|
159
|
+
>
|
|
142
160
|
<Comp />
|
|
143
161
|
</AutoScrollProvider>
|
|
144
162
|
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scroll to the given element
|
|
3
|
+
-* @param node Element to scroll to
|
|
4
|
+
-* @param baseElement Container element used to calculate offset
|
|
5
|
+
-* @param offset Additional offset
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { scrollTo } from 'seamless-scroll-polyfill';
|
|
9
|
+
|
|
10
|
+
export default (
|
|
11
|
+
node: HTMLElement,
|
|
12
|
+
baseElement: HTMLElement,
|
|
13
|
+
offset: number
|
|
14
|
+
) => {
|
|
15
|
+
scrollTo(window, {
|
|
16
|
+
behavior: 'smooth',
|
|
17
|
+
top:
|
|
18
|
+
node.getBoundingClientRect().top -
|
|
19
|
+
baseElement.getBoundingClientRect().top -
|
|
20
|
+
offset,
|
|
21
|
+
});
|
|
22
|
+
};
|