Skip to content

Commit 74af51e

Browse files
committed
add dialog component
1 parent 932f555 commit 74af51e

File tree

8 files changed

+186
-34
lines changed

8 files changed

+186
-34
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ or
2929

3030
`$ npm install react-native-common --save`
3131

32+
## Native Dependencies
33+
Some of the components are using these native dependencies, they are not a requirement but will allow you to create
34+
better lookings apps :)
35+
36+
* react-native-animatable
37+
* react-native-blur
38+
3239
## Usage
3340

3441
```javascript
@@ -44,6 +51,7 @@ import { Button } from 'react-native-common';
4451

4552
## Components Included
4653

54+
- [x] Theming & Default Styles of the Components
4755
- [x] Badge
4856
- [x] Button
4957
- [x] Carousel
@@ -67,7 +75,6 @@ import { Button } from 'react-native-common';
6775
- [x] SettingsList.Item
6876
- [x] StyleSheet
6977
- [x] ViewPager
70-
- [ ] Checkboxes
7178

7279
## Documentation
7380

@@ -79,7 +86,6 @@ import { Button } from 'react-native-common';
7986
Look for the label `Good First Task` on the issues. Click [here](https://github.com/rghorbani/react-native-common/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+First+Task%22) to see them.
8087

8188
#### NOT STARTED
82-
- [ ] Add Theming & Default Styles to all of the Components
8389
- [ ] Add Image Component which supports parallax
8490
- [ ] Compatibility with react-native-windows
8591
- [ ] Something you's like to see? Submit an [issue](https://github.com/rghorbani/react-native-common/issues/new) or a [pull request](https://github.com/rghorbani/react-native-common/pulls)

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-common",
3-
"version": "1.2.2",
3+
"version": "1.3.0",
44
"description": "UI Toolset & Components and API Library for React Native.",
55
"main": "src/index.js",
66
"scripts": {
@@ -73,9 +73,8 @@
7373
"react-native": "0.51.0"
7474
},
7575
"peerDependencies": {
76-
"react": "*",
77-
"react-native": "*",
78-
"react-native-vector-icons": "^4.5.0"
76+
"react": "^16.0.0",
77+
"react-native": "^0.51.0"
7978
},
8079
"prettier": {
8180
"requirePragma": true,

src/commons/BaseComponent.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,14 @@ class BaseComponent extends React.Component {
131131
}
132132

133133
extractBorderRadiusValue() {
134+
const borderRadiusPropsKeys = _.chain(this.props)
135+
.keys(this.props)
136+
.filter(key => BorderRadiuses.getKeysPattern().test(key))
137+
.value();
134138
let borderRadius;
135-
_.forEach(BorderRadiuses, (value, key) => {
139+
_.forEach(borderRadiusPropsKeys, (key) => {
136140
if (this.props[key] === true) {
137-
borderRadius = value;
141+
borderRadius = BorderRadiuses[key];
138142
}
139143
});
140144

src/components/dialog/index.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
const React = require('react');
2+
const PropTypes = require('prop-types');
3+
const _ = require('lodash');
4+
const Animatable = require('react-native-animatable');
5+
const { StyleSheet } = require('react-native');
6+
7+
const View = require('../view');
8+
const Modal = require('../../screensComponents/modal');
9+
const { BaseComponent } = require('../../commons');
10+
const { Colors } = require('../../style');
11+
12+
/*eslint-disable*/
13+
/**
14+
* @description: Dialog component for displaying custom content inside a popup dialog
15+
* @notes: Use alignment modifiers to control the dialog positon (top, bottom, centerV, centerH, etc... by default the dialog is align to center)
16+
* @modifiers: alignment
17+
*/
18+
/*eslint-enable*/
19+
class Dialog extends BaseComponent {
20+
static displayName = 'Dialog'
21+
22+
static propTypes = {
23+
/**
24+
* Control visibility of the dialog
25+
*/
26+
visible: PropTypes.bool,
27+
/**
28+
* dismiss callback for when clicking on the background
29+
*/
30+
onDismiss: PropTypes.func,
31+
/**
32+
* The color of the overlay background
33+
*/
34+
overlayBackgroundColor: PropTypes.string,
35+
/**
36+
* The dialog width (default: 90%)
37+
*/
38+
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
39+
/**
40+
* The dialog height (default: 70%)
41+
*/
42+
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
43+
/**
44+
* the animation configuration to pass to the dialog (based on react-native-animatable,
45+
* ex. {animation, duration, easing,..})
46+
*/
47+
animationConfig: PropTypes.object,
48+
/**
49+
* The dialog container style
50+
*/
51+
containerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]),
52+
};
53+
54+
static defaultProps = {
55+
overlayBackgroundColor: Colors.rgba(Colors.dark10, 0.6),
56+
width: '90%',
57+
height: '70%',
58+
};
59+
60+
generateStyles() {
61+
this.styles = createStyles(this.props);
62+
}
63+
64+
getAnimationConfig() {
65+
const {animationConfig} = this.props;
66+
return {
67+
animation: 'slideInUp',
68+
duration: 400,
69+
useNativeDriver: true,
70+
...animationConfig,
71+
};
72+
}
73+
74+
render() {
75+
const {visible, overlayBackgroundColor, onDismiss} = this.getThemeProps();
76+
const {alignments} = this.state;
77+
const centerByDefault = _.isEmpty(alignments);
78+
79+
return (
80+
<Modal
81+
transparent
82+
visible={visible}
83+
animationType={'fade'}
84+
onBackgroundPress={onDismiss}
85+
onRequestClose={onDismiss}
86+
overlayBackgroundColor={overlayBackgroundColor}
87+
>
88+
<View center={centerByDefault} style={[this.styles.overlay, alignments]} pointerEvents="box-none">
89+
<Animatable.View style={this.styles.dialogContainer} {...this.getAnimationConfig()}>
90+
{this.props.children}
91+
</Animatable.View>
92+
</View>
93+
</Modal>
94+
);
95+
}
96+
}
97+
98+
function createStyles({width, height}) {
99+
return StyleSheet.create({
100+
overlay: {
101+
flex: 1,
102+
},
103+
dialogContainer: {
104+
width,
105+
height,
106+
},
107+
});
108+
}
109+
110+
module.exports = Dialog;

src/components/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module.exports = {
2323
get Badge() { return require('./badge'); },
2424
get Button() { return require('./button'); },
2525
get ConnectionStatusBar() { return require('./connection'); },
26+
get Dialog() { return require('./dialog'); },
2627
get Header() { return require('./header'); },
2728
get KeyboardSpacer() { return require('./KeyboardSpacer'); },
2829
get LoadingView() { return require('./loading'); },

src/components/picker/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ class Picker extends TextInput {
171171
}
172172

173173
renderExpandableInput() {
174+
const {style} = this.props;
174175
const typography = this.getTypography();
175176
const minHeight = typography.lineHeight;
176177
const color = this.extractColorValue() || Colors.dark10;
@@ -183,6 +184,7 @@ class Picker extends TextInput {
183184
typography,
184185
{minHeight},
185186
{color},
187+
style
186188
]}
187189
numberOfLines={3}
188190
onPress={this.handlePickerOnPress}

src/screen-components/modal/index.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88

99
const React = require('react');
1010
const PropTypes = require('prop-types');
11+
const _ = require('lodash');
1112
const RNModal = require('react-native').Modal;
12-
const { View } = require('react-native');
13+
const { StyleSheet, TouchableWithoutFeedback } = require('react-native');
1314
const { BlurView } = require('react-native-blur');
1415

1516
const TopBar = require('./TopBar');
17+
const View = require('../../components/view');
1618
const { BaseComponent } = require('../../commons');
1719
const { Constants } = require('../../helpers');
1820

@@ -24,21 +26,49 @@ class Modal extends BaseComponent {
2426
* Blurs the modal background when transparent (iOS only)
2527
*/
2628
enableModalBlur: PropTypes.bool,
29+
/**
30+
* allow dismissing a modal when clicking on its background
31+
*/
32+
onBackgroundPress: PropTypes.func,
33+
/**
34+
* the background color of the overlay
35+
*/
36+
overlayBackgroundColor: PropTypes.string,
2737
};
2838

39+
renderTouchableOverlay() {
40+
const {overlayBackgroundColor, onBackgroundPress} = this.props;
41+
if (_.isFunction(onBackgroundPress) || !!overlayBackgroundColor) {
42+
return (
43+
<View style={[styles.touchableOverlay, {backgroundColor: overlayBackgroundColor}]}>
44+
<TouchableWithoutFeedback onPress={onBackgroundPress}>
45+
<View flex />
46+
</TouchableWithoutFeedback>
47+
</View>
48+
);
49+
}
50+
}
51+
2952
render() {
3053
const {enableModalBlur, ...props} = this.props;
3154
const Container = enableModalBlur && Constants.isIOS ? BlurView : View;
3255
return (
3356
<RNModal {...props}>
3457
<Container style={{flex: 1}} blurType="light">
58+
{this.renderTouchableOverlay()}
3559
{this.props.children}
3660
</Container>
3761
</RNModal>
3862
);
3963
}
4064
}
4165

66+
const styles = StyleSheet.create({
67+
touchableOverlay: {
68+
...StyleSheet.absoluteFillObject,
69+
},
70+
});
71+
4272
Modal.TopBar = TopBar;
4373

4474
module.exports = Modal;

src/style/BorderRadiuses.js

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,30 @@
66

77
'use strict';
88

9-
const { Platform } = require('react-native');
9+
const _ = require('lodash');
1010

11-
if (Platform.OS === 'ios') {
12-
module.exports = {
13-
br0: 0,
14-
br10: 3,
15-
br20: 6,
16-
br30: 9,
17-
br40: 12,
18-
br50: 15,
19-
br60: 20,
20-
br100: 999,
21-
};
22-
} else if (Platform.OS === 'android') {
23-
module.exports = {
24-
br0: 0,
25-
br10: 2,
26-
br20: 6,
27-
br30: 8,
28-
br40: 12,
29-
br50: 16,
30-
br60: 20,
31-
br100: 999,
32-
};
33-
} else {
34-
throw 'BorderRadiuses: Unknown platform';
11+
const { Constants } = require('../helpers');
12+
13+
class BorderRadiuses {
14+
br0 = 0;
15+
br10 = Constants.isIOS ? 3 : 2;
16+
br20 = 6;
17+
br30 = Constants.isIOS ? 9 : 8;
18+
br40 = 12;
19+
br50 = Constants.isIOS ? 15 : 16;
20+
br60 = 20;
21+
br100 = 999;
22+
23+
getKeysPattern() {
24+
return new RegExp(
25+
_.chain(this)
26+
.keys()
27+
.map(key => [`${key}`])
28+
.flatten()
29+
.join('|')
30+
.value(),
31+
);
32+
}
3533
}
34+
35+
module.exports = new BorderRadiuses();

0 commit comments

Comments
 (0)