Skip to content

Commit 729eb5c

Browse files
author
Horcrux
committed
init project
1 parent 1633e49 commit 729eb5c

8 files changed

Lines changed: 313 additions & 47 deletions

File tree

.editorconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# EditorConfig is awesome: http://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
# Unix-style newlines with a newline ending every file
7+
[*]
8+
charset = utf-8
9+
end_of_line = lf
10+
indent_style = space
11+
indent_size = 4
12+
trim_trailing_whitespace = true
13+
insert_final_newline = true

.gitignore

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,2 @@
1-
# Windows image file caches
2-
Thumbs.db
3-
ehthumbs.db
4-
5-
# Folder config file
6-
Desktop.ini
7-
8-
# Recycle Bin used on file shares
9-
$RECYCLE.BIN/
10-
11-
# Windows Installer files
12-
*.cab
13-
*.msi
14-
*.msm
15-
*.msp
16-
17-
# Windows shortcuts
18-
*.lnk
19-
20-
# =========================
21-
# Operating System Files
22-
# =========================
23-
24-
# OSX
25-
# =========================
26-
27-
.DS_Store
28-
.AppleDouble
29-
.LSOverride
30-
31-
# Thumbnails
32-
._*
33-
34-
# Files that might appear in the root of a volume
35-
.DocumentRevisions-V100
36-
.fseventsd
37-
.Spotlight-V100
38-
.TemporaryItems
39-
.Trashes
40-
.VolumeIcon.icns
41-
42-
# Directories potentially created on remote AFP share
43-
.AppleDB
44-
.AppleDesktop
45-
Network Trash Folder
46-
Temporary Items
47-
.apdisk
1+
/node_modules
2+
.idea/

README.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
### react-native-root-siblings
2+
---
3+
4+
Add sibling elements to your app root
5+
6+
7+
### Add it to your project
8+
9+
1. Run `npm install react-native-root-siblings --save`
10+
2. Import library **before** `AppRegistry.registerComponent`
11+
12+
```javascript
13+
...do something there
14+
**import 'react-native-root-siblings';**
15+
...do something else
16+
17+
*AppRegistry.registerComponent('MyApp', () => MyApp);*
18+
19+
```
20+
21+
### USAGE
22+
23+
```
24+
'use strict';
25+
import React, {
26+
AppRegistry,
27+
View,
28+
View,
29+
Component,
30+
TouchableHighlight,
31+
Text
32+
} from 'react-native';
33+
import Dimensions from 'Dimensions';
34+
35+
// Import library there,it will wrap everything registered by AppRegistry.registerComponent
36+
// And add or remove other elements after the root component
37+
**import RootSiblings from 'react-native-root-siblings';**
38+
39+
var id = 0;
40+
var elements = [];
41+
class SiblingsExample extends Component{
42+
addSibling = () {
43+
let sibling = new RootSiblings(<View
44+
style={[styles.sibling, {top: id * 20}]}
45+
>
46+
<Text>I`m No.{id}</Text>
47+
</View>);
48+
id++;
49+
elements.push(sibling);
50+
};
51+
52+
destroySibling = () {
53+
let lastSibling = elements.pop();
54+
lastSibling.destroy();
55+
};
56+
57+
updateSibling = () {
58+
59+
};
60+
61+
render() {
62+
return <View style={styles.container}>
63+
<TouchableHighlight
64+
style={styles.button}
65+
onPress={this.addSibling}
66+
>
67+
<Text style={styles.buttonText}>Add element</Text>
68+
</TouchableHighlight>
69+
<TouchableHighlight
70+
style={styles.button}
71+
onPress={this.destroySibling}
72+
>
73+
<Text style={styles.buttonText}>Destroy element</Text>
74+
</TouchableHighlight>
75+
<TouchableHighlight
76+
style={styles.button}
77+
onPress={this.updateSibling}
78+
>
79+
<Text style={styles.buttonText}>Update element</Text>
80+
</TouchableHighlight>
81+
</View>;
82+
}
83+
}
84+
85+
AppRegistry.registerComponent('SiblingsExample', () => SiblingsExample);
86+
87+
var styles = StyleSheet.create({
88+
container: {
89+
flex: 1,
90+
alignItems: 'center',
91+
justifyContent: 'center',
92+
backgroundColor: 'green',
93+
},
94+
button: {
95+
borderRadius: 4,
96+
padding: 10,
97+
marginLeft: 10,
98+
marginRight: 10,
99+
backgroundColor: '#ccc',
100+
borderColor: '#333',
101+
borderWidth: 1,
102+
},
103+
buttonText: {
104+
color: '#000'
105+
},
106+
sibling: {
107+
left: 0,
108+
height: 20,
109+
width: Dimensions.get('window').width / 2,
110+
backgroundColor: 'blue'
111+
}
112+
});
113+
114+
```
115+

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import RootDecorators from './lib/RootSiblings';
2+
export default RootDecorators;

lib/RootSiblings.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, {
2+
StyleSheet,
3+
Component,
4+
View,
5+
AppRegistry,
6+
StaticContainer
7+
} from 'react-native';
8+
9+
import _ from 'lodash';
10+
import SiblingsManager from './SiblingsManager';
11+
import SiblingContainer from './SiblingContainer';
12+
13+
let styles = StyleSheet.create({
14+
container: {
15+
flex: 1,
16+
position: 'relative'
17+
}
18+
});
19+
20+
// inject modals into app entry component
21+
let originRegister = AppRegistry.registerComponent;
22+
AppRegistry.registerComponent = function (appKey, getComponentFunc) {
23+
return originRegister(appKey, () => {
24+
let Origin = getComponentFunc();
25+
return React.createClass({
26+
displayName: `Root(${appKey})`,
27+
getInitialState() {
28+
return {
29+
siblings: {}
30+
};
31+
},
32+
33+
componentWillMount() {
34+
SiblingsManager.addListener('set', this.onSet);
35+
SiblingsManager.addListener('update', (props, prevProps, id) =>
36+
this.onSet(props, id)
37+
);
38+
SiblingsManager.addListener('destroy', this.onDestroy);
39+
},
40+
41+
onSet(element, id) {
42+
this.state.siblings[id] = element;
43+
this.forceUpdate();
44+
},
45+
46+
onDestroy(destroyed, id) {
47+
delete this.state.siblings[id];
48+
this.forceUpdate();
49+
},
50+
51+
getSiblings() {
52+
return _.map(this.state.siblings, (sibling, id) => <SiblingContainer
53+
key={`sibling-${id}`}
54+
>
55+
{sibling}
56+
</SiblingContainer>);
57+
},
58+
59+
render() {
60+
return <View style={styles.container}>
61+
<StaticContainer shouldUpdate={false}>
62+
<Origin {...this.props} />
63+
</StaticContainer>
64+
{this.getSiblings()}
65+
</View>;
66+
}
67+
});
68+
});
69+
};
70+
71+
export default SiblingsManager;

lib/SiblingContainer.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React, {
2+
StyleSheet,
3+
Component,
4+
View,
5+
cloneElement
6+
} from 'react-native';
7+
8+
import onlyChild from 'onlyChild';
9+
10+
let styles = StyleSheet.create({
11+
offStream: {
12+
position: 'absolute'
13+
}
14+
});
15+
16+
class SiblingContainer extends Component {
17+
static displayName = 'SiblingContainer';
18+
19+
static propTypes = {
20+
...View.propTypes
21+
};
22+
23+
shouldComponentUpdate = () => false;
24+
25+
render() {
26+
return cloneElement(onlyChild(this.props.children), {
27+
style: [this.props.children.props.style, styles.offStream]
28+
});
29+
}
30+
}
31+
32+
export default SiblingContainer;

lib/SiblingsManager.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import callbacks from 'jquery-callbacks';
2+
let decorators = {};
3+
let decoratorUid = 0;
4+
let setCallbacks = callbacks();
5+
let updateCallbacks = callbacks();
6+
let destroyCallbacks = callbacks();
7+
8+
class SiblingsManager {
9+
constructor(element) {
10+
decoratorUid++;
11+
decorators[decoratorUid] = element;
12+
this.id = decoratorUid;
13+
setCallbacks.fire(element, decoratorUid);
14+
}
15+
16+
static addListener = (event, cb) => {
17+
switch (event) {
18+
case 'set':
19+
setCallbacks.add(cb);
20+
break;
21+
case 'update':
22+
updateCallbacks.add(cb);
23+
break;
24+
case 'destroy':
25+
destroyCallbacks.add(cb);
26+
break;
27+
default:
28+
console.warn(`SiblingsManager.addListener: Unexpected event \`${event}\`.\nEvent must be one of the ['set','update','destroy']`);
29+
}
30+
};
31+
32+
static removeListener = (event, cb) => {
33+
switch (event) {
34+
case 'set':
35+
setCallbacks.remove(cb);
36+
break;
37+
case 'update':
38+
updateCallbacks.remove(cb);
39+
break;
40+
case 'destroy':
41+
destroyCallbacks.remove(cb);
42+
break;
43+
default:
44+
console.warn(`SiblingsManager.removeListener: Unexpected event \`${event}\`.\nEvent must be one of the ['set','update','destroy']`);
45+
}
46+
};
47+
48+
update = element => {
49+
updateCallbacks.fire(element, decorators[this.id], this.id);
50+
decorators[this.id] = element;
51+
};
52+
53+
destroy = () => {
54+
destroyCallbacks.fire(decorators[this.id], this.id);
55+
delete decorators[this.id];
56+
};
57+
}
58+
59+
export default SiblingsManager;

package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "react-native-root-siblings",
3+
"repository": {
4+
"type": "git",
5+
"url": "git@github.com:magicismight/react-native-root-siblings.git"
6+
},
7+
"version": "1.0.0",
8+
"main": "./index.js",
9+
"description": "react native root sibling elements manager",
10+
"dependencies": {
11+
"jquery-callbacks": "^0.0.1"
12+
},
13+
"keywords": [
14+
"react-component",
15+
"react-native",
16+
"ios",
17+
"android"
18+
]
19+
}

0 commit comments

Comments
 (0)