Skip to content

Commit

Permalink
Fix navigators for new core, add tab navigator. Bump to 0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Zotov committed Jan 29, 2020
1 parent de648a1 commit dfb0eac
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 26 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@navigationjs/react",
"version": "0.2.0",
"version": "0.3.0",
"description": "Small and well-tested React navigation",
"main": "dist/index.js",
"author": "Ivan Zotov <me@ivanzotov.com> (http://ivanzotov.com/)",
Expand Down
16 changes: 11 additions & 5 deletions src/Modal/Navigator.js
@@ -1,27 +1,33 @@
import { History } from '@navigationjs/core';

export default class Navigator {
constructor(name) {
this.name = name;
this.scenes = {};
this.history = [];
this.history = new History(this.name);
}

addScenes = (...scenes) => {
scenes.forEach(it => (this.scenes[it.name] = it));
};

current = () => this.history[this.history.length - 1];
removeScenes = (...scenes) => {
scenes.forEach(it => delete this.scenes[it]);
};

current = () => this.history.current();

go = async (name, duration) => {
const scene = this.scenes[name];
if (!scene) return Promise.reject();
const alreadyInHistory = this.history.includes(name);
const alreadyInHistory = this.history.current() === name;
if (alreadyInHistory) return Promise.resolve();
await scene.show(duration);
this.history.push(name);
};

back = async duration => {
if (this.history.length === 0) return Promise.resolve();
if (this.history.isEmpty()) return Promise.resolve();
const name = this.current();
const scene = this.scenes[name];
if (!scene) return Promise.reject();
Expand All @@ -33,6 +39,6 @@ export default class Navigator {
await Promise.all(
Object.keys(this.scenes).map(key => this.scenes[key].hide(0))
);
this.history = [];
this.history = new History(this.name);
};
}
24 changes: 15 additions & 9 deletions src/Stack/Navigator.js
@@ -1,24 +1,30 @@
import { History } from '@navigationjs/core';

export default class Navigator {
constructor(name) {
this.name = name;
this.scenes = {};
this.history = [];
this.history = new History(this.name);
}

addScenes = (...scenes) => {
scenes.forEach(it => (this.scenes[it.name] = it));
};

removeScenes = (...scenes) => {
scenes.forEach(it => delete this.scenes[it]);
};

go = async (name, duration) => {
const scene = this.scenes[name];
if (!scene) return Promise.reject();

const alreadyInHistory = this.history.includes(name);
const alreadyInHistory = this.history.current() === name;
if (alreadyInHistory) return Promise.resolve();

const promises = this.history.map((sceneName, index) => {
const promises = this.history.chain.map((sceneName, index) => {
const scene = this.scenes[sceneName];
const level = this.history.length - index - 1;
const level = this.history.chain.length - index - 1;
return scene.dive(level + 1, duration);
});

Expand All @@ -28,10 +34,10 @@ export default class Navigator {
this.history.push(name);
};

current = () => this.history[this.history.length - 1];
current = () => this.history.current();

back = async duration => {
if (this.history.length === 0) return Promise.resolve();
if (this.history.isEmpty()) return Promise.resolve();

const promises = [];

Expand All @@ -41,9 +47,9 @@ export default class Navigator {

promises.push(scene.hide(duration));

this.history.forEach((sceneName, index) => {
this.history.chain.forEach((sceneName, index) => {
const scene = this.scenes[sceneName];
const level = this.history.length - index - 1;
const level = this.history.chain.length - index - 1;
promises.push(scene.dive(level - 1, duration));
});

Expand All @@ -55,6 +61,6 @@ export default class Navigator {
await Promise.all(
Object.keys(this.scenes).map(key => this.scenes[key].hide(0))
);
this.history = [];
this.history = new History(this.name);
};
}
52 changes: 52 additions & 0 deletions src/Tab/Navigator.js
@@ -0,0 +1,52 @@
import { History } from '@navigationjs/core';

export default class Navigator {
constructor(name) {
this.name = name;
this.scenes = {};
this.history = new History(this.name);
}

addScenes = (...scenes) => {
scenes.forEach(it => (this.scenes[it.name] = it));
};

removeScenes = (...scenes) => {
scenes.forEach(it => delete this.scenes[it]);
};

go = async (name, duration) => {
const scene = this.scenes[name];
if (!scene) return Promise.reject();
const promises = [];
Object.values(this.scenes).forEach(it => {
promises.push(it.name === name ? it.show(duration) : it.hide(duration));
});
await Promise.all(promises);
this.history.push(name);
};

current = () => this.history.current();

back = async duration => {
if (this.history.isEmpty()) return Promise.resolve();
const name = this.current();
const scene = this.scenes[name];
if (!scene) return Promise.reject();
const promises = [];
promises.push(scene.hide(duration));
const newSceneName = this.history.chain[this.history.chain.length - 2];
const newScene = this.scenes[newSceneName];
if (!newScene) return Promise.reject();
promises.push(newScene.show(duration));
await Promise.all(promises);
this.history.pop();
};

reset = async () => {
await Promise.all(
Object.keys(this.scenes).map(key => this.scenes[key].hide(0))
);
this.history = new History(this.name);
};
}
11 changes: 11 additions & 0 deletions src/Tab/Scene.js
@@ -0,0 +1,11 @@
import Value from '../Value';

export default class Scene {
constructor(name) {
this.name = name;
this.active = new Value('active', 0, 0);
}

show = duration => this.active.to(1, duration);
hide = duration => this.active.to(0, duration);
}
69 changes: 69 additions & 0 deletions src/Tab/Wrap.js
@@ -0,0 +1,69 @@
import React, { Component } from 'react';
import navigation, { toId } from '@navigationjs/core';

export default class Wrap extends Component {
onValue = () => {
const eventNames = [
'transitionend',
'webkitTransitionEnd',
'oTransitionEnd',
'otransitionend',
'MSTransitionEnd',
];
const callback = () => {
eventNames.forEach(eventName =>
this.element.removeEventListener(eventName, callback, false)
);
};
eventNames.forEach(eventName => {
this.element.addEventListener(eventName, callback, false);
});
this.forceUpdate();
};

componentDidMount() {
const { navigator: navigatorName, scene: sceneName } = this.props;
const navigator = navigation.navigators[navigatorName];
const scene = navigator.scenes[sceneName];
scene.active.on('value', this.onValue);
}

componentWillUnmount() {
const { navigator: navigatorName, scene: sceneName } = this.props;
const navigator = navigation.navigators[navigatorName];
const scene = navigator.scenes[sceneName];
scene.active.off('value', this.onValue);
}

render() {
const { navigator: navigatorName, scene: sceneName, children } = this.props;

const id = toId(navigatorName, sceneName);
const pass = { id };

const navigator = navigation.navigators[navigatorName];
const scene = navigator.scenes[sceneName];

return (
<div
ref={ref => {
this.element = ref;
}}
style={{
transform: `translateY(${(1 - scene.active.value) * 100}%)`,
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
transitionProperty: 'transform',
transitionDuration: '300ms',
overflowY: 'auto',
backgroundColor: 'white',
}}
>
{typeof children === 'function' ? children(pass) : children}
</div>
);
}
}
9 changes: 9 additions & 0 deletions src/Tab/index.js
@@ -0,0 +1,9 @@
import Navigator from './Navigator';
import Scene from './Scene';
import Wrap from './Wrap';

export default {
Navigator,
Scene,
Wrap,
};
18 changes: 7 additions & 11 deletions src/index.js
@@ -1,13 +1,9 @@
import navigation, {
Navigation,
Base,
Value,
toId,
fromId,
} from '@navigationjs/core';
import Modal from './Modal';
import Stack from './Stack';
import Wrap from './Wrap';
import navigation, { Navigation, toId, fromId } from '@navigationjs/core';
import Stack from './src/Stack';
import Tab from './src/Tab';
import Modal from './src/Modal';
import Value from './src/Value';
import Wrap from './src/Wrap';

export { Navigation, Base, Modal, Stack, Wrap, Value, toId, fromId };
export { Navigation, Stack, Tab, Modal, Value, Wrap, toId, fromId };
export default navigation;

0 comments on commit dfb0eac

Please sign in to comment.