Skip to content

Commit

Permalink
feat: support shards
Browse files Browse the repository at this point in the history
  • Loading branch information
theKashey committed Mar 10, 2019
1 parent 12d61fb commit 67519f3
Showing 1 changed file with 45 additions and 13 deletions.
58 changes: 45 additions & 13 deletions src/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,35 @@ import {aggressive} from './aggresiveCapture';

export const getTouchY = (event: TouchEvent) => event.changedTouches ? event.changedTouches[0].clientY : 0;

export interface RemoveScrollProps {
export interface IRemoveScrollProps {
noIsolation?: boolean;
forwardProps?: boolean;
enabled?: boolean;
className?: string;
removeScrollBar?: boolean;

shards?: Array<React.RefObject<any>>;
}

const classNames = {
fullWidth: fullWidthClassName,
zeroRight: zeroRightClassName,
};

export class RemoveScroll extends React.Component<RemoveScrollProps> {
private shouldPreventQueue: Array<{ name: string, delta: number, target: any, should: boolean }> = [];
private touchStart = 0;
private ref = React.createRef<HTMLDivElement>();

export class RemoveScroll extends React.Component<IRemoveScrollProps> {
public static classNames = classNames;
public static stack: Array<RemoveScroll> = [];

static defaultProps = {
public static defaultProps = {
enabled: true,
removeScrollBar: true,
};

private static stack: RemoveScroll[] = [];

private shouldPreventQueue: Array<{ name: string, delta: number, target: any, should: boolean }> = [];
private touchStart = 0;
private ref = React.createRef<HTMLDivElement>();

componentDidMount() {
RemoveScroll.stack.push(this);
this.componentDidUpdate({enabled: false})
Expand All @@ -56,16 +59,29 @@ export class RemoveScroll extends React.Component<RemoveScrollProps> {
if (typeof document !== 'undefined') {
document.addEventListener('wheel', this.shouldPrevent, aggressive);
document.addEventListener('touchmove', this.shouldPrevent, aggressive);
document.addEventListener('touchstart', this.scrollTouchStart, aggressive);
}
}

disable() {
if (typeof window !== 'undefined') {
document.removeEventListener('wheel', this.shouldPrevent, aggressive as any);
document.removeEventListener('touchmove', this.shouldPrevent, aggressive as any);
document.removeEventListener('touchstart', this.scrollTouchStart, aggressive as any);
}
}

shouldCancelEvent(event: any, parent: HTMLElement) {
switch (event.type) {
case 'wheel':
case 'scroll':
return handleScroll(parent, event, event.deltaY)
case 'touchmove':
return handleScroll(parent, event, this.touchStart - getTouchY(event));
}
return false;
};

shouldPrevent = (event: any) => {
const stack = RemoveScroll.stack.filter(el => el.props.enabled);
if (!stack.length || stack[stack.length - 1] !== this) {
Expand All @@ -76,8 +92,25 @@ export class RemoveScroll extends React.Component<RemoveScrollProps> {
const sourceEvent = this.shouldPreventQueue.filter(
(e: any) => e.name === event.type && e.delta === delta && e.target === event.target
)[0];
if ((!sourceEvent && !this.props.noIsolation) || (sourceEvent && sourceEvent.should)) {
// self event, and should be canceled
if (sourceEvent && sourceEvent.should) {
event.preventDefault();
return;
}
// outside or shard event
if (!sourceEvent) {
const shardNodes = (this.props.shards || [])
.map(({current}) => current)
.filter(Boolean)
.filter(node => node.contains(event.target));

const shouldStop = shardNodes.length > 0
? this.shouldCancelEvent(event, shardNodes[0])
: !this.props.noIsolation

if (shouldStop) {
event.preventDefault();
}
}
};

Expand All @@ -89,16 +122,16 @@ export class RemoveScroll extends React.Component<RemoveScrollProps> {
}, 1);
};

scrollTouchStart = (event: TouchEvent<HTMLDivElement>) => {
scrollTouchStart = (event: any) => {
this.touchStart = getTouchY(event);
};

scrollWheel = (event: any) => {
this.shouldCancel(event.type, event.deltaY, event.target, handleScroll(this.ref.current as any, event, event.deltaY));
this.shouldCancel(event.type, event.deltaY, event.target, this.shouldCancelEvent(event, this.ref.current as any));
};

scrollTouchMove = (event: TouchEvent<HTMLDivElement>) => {
this.shouldCancel(event.type, getTouchY(event), event.target, handleScroll(this.ref.current as any, event, this.touchStart - getTouchY(event)));
this.shouldCancel(event.type, getTouchY(event), event.target, this.shouldCancelEvent(event, this.ref.current as any));
};

render() {
Expand All @@ -108,7 +141,6 @@ export class RemoveScroll extends React.Component<RemoveScrollProps> {
ref: this.ref,
onScrollCapture: this.scrollWheel,
onWheelCapture: this.scrollWheel,
onTouchStartCapture: this.scrollTouchStart,
onTouchMoveCapture: this.scrollTouchMove,
};
return (
Expand Down

0 comments on commit 67519f3

Please sign in to comment.