Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 36 additions & 107 deletions AppIntro.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
Platform,
} from 'react-native';
import Swiper from 'react-native-swiper';
import DoneButton from './components/DoneButton';
import SkipButton from './components/SkipButton';
import RenderDots from './components/Dots';

const windowsWidth = Dimensions.get('window').width;
const windowsHeight = Dimensions.get('window').height;

Expand Down Expand Up @@ -62,13 +66,6 @@ const defaulStyles = {
},
activeDotStyle: {
backgroundColor: '#fff',
width: 13,
height: 13,
borderRadius: 7,
marginLeft: 7,
marginRight: 7,
marginTop: 7,
marginBottom: 7,
},
paginationContainer: {
position: 'absolute',
Expand Down Expand Up @@ -189,21 +186,6 @@ export default class AppIntro extends Component {
}

renderPagination = (index, total, context) => {
const { activeDotColor, dotColor, rightTextColor, leftTextColor } = this.props;
const ActiveDot = (
<View
style={[this.styles.activeDotStyle, { backgroundColor: activeDotColor }]}
/>
);
const Dot = <View style={[this.styles.dotStyle, { backgroundColor: dotColor }]} />;
let dots = [];
for (let i = 0; i < total; i++) {
dots.push(i === index ?
React.cloneElement(ActiveDot, { key: i })
:
React.cloneElement(Dot, { key: i })
);
}
let isDoneBtnShow;
let isSkipBtnShow;
if (index === total - 1) {
Expand All @@ -219,91 +201,27 @@ export default class AppIntro extends Component {
isDoneBtnShow = false;
isSkipBtnShow = true;
}
let controllBts;
if (Platform.OS === 'ios') {
controllBts = (
<View style={this.styles.paginationContainer}>
<Animated.View style={[this.styles.btnContainer, {
opacity: this.state.skipFadeOpacity,
transform: [{
translateX: this.state.skipFadeOpacity.interpolate({
inputRange: [0, 1],
outputRange: [0, 15],
}),
}],
}]}
>
<TouchableOpacity
style={this.styles.full}
onPress={isSkipBtnShow ? () => this.props.onSkipBtnClick(index) : null}
>
<Text style={[this.styles.controllText, { color: leftTextColor }]}>{this.props.skipBtnLabel}</Text>
</TouchableOpacity>
</Animated.View>
<View style={this.styles.dotContainer}>
{dots}
</View>
<View style={this.styles.btnContainer}>
<Animated.View style={[this.styles.full, { height: 0 }, {
opacity: this.state.doneFadeOpacity,
transform: [{
translateX: this.state.skipFadeOpacity.interpolate({
inputRange: [0, 1],
outputRange: [0, 20],
}),
}],
}]}
>
<View style={this.styles.full}>
<Text style={[this.styles.controllText, {
color: rightTextColor, paddingRight: 30,
}]}
>{this.props.doneBtnLabel}</Text>
</View>
</Animated.View>
<Animated.View style={[this.styles.full, { height: 0 }, { opacity: this.state.nextOpacity }]}>
<TouchableOpacity style={this.styles.full}
onPress={ isDoneBtnShow ?
this.props.onDoneBtnClick : this.onNextBtnClick.bind(this, context)}
>
<Text style={[this.styles.nextButtonText, { color: rightTextColor }]}>{this.props.nextBtnLabel}</Text>
</TouchableOpacity>
</Animated.View>
</View>
</View>
);
} else {
controllBts = (
<View style={this.styles.paginationContainer}>
<View style={[this.styles.btnContainer, {
paddingBottom: 5,
opacity: isSkipBtnShow ? 1 : 0,
}]}
>
<TouchableOpacity
style={this.styles.full}
onPress={isSkipBtnShow ? () => this.props.onSkipBtnClick(index) : null}
>
<Text style={[this.styles.controllText, { color: leftTextColor }]}>{this.props.skipBtnLabel}</Text>
</TouchableOpacity>
</View>
<View style={this.styles.dotContainer}>
{dots}
</View>
<View style={[this.styles.btnContainer, { height: 0, paddingBottom: 5 }]}>
<TouchableOpacity style={this.styles.full}
onPress={ isDoneBtnShow ?
this.props.onDoneBtnClick : this.onNextBtnClick.bind(this, context)}
>
<Text style={[this.styles.nextButtonText, { color: rightTextColor }]}>
{isDoneBtnShow ? this.props.doneBtnLabel : this.props.nextBtnLabel}
</Text>
</TouchableOpacity>
</View>
</View>
);
}
return controllBts;
return (
<View style={[this.styles.paginationContainer]}>
{this.props.showSkipButton && <SkipButton
{...this.props}
{...this.state}
isSkipBtnShow={isSkipBtnShow}
styles={this.styles}
onSkipBtnClick={() => this.props.onSkipBtnClick(index)} />}
{this.props.showDots && RenderDots(index, total, {
...this.props,
styles: this.styles
})}
{this.props.showDoneButton && <DoneButton
{...this.props}
{...this.state}
isDoneBtnShow={isDoneBtnShow}
styles={this.styles}
onNextBtnClick={this.onNextBtnClick.bind(this, context)}
onDoneBtnClick={this.props.onDoneBtnClick} />}
</View>
);
}

renderBasicSlidePage = (index, {
Expand Down Expand Up @@ -396,6 +314,7 @@ export default class AppIntro extends Component {
{androidPages}
<Swiper
loop={false}
index={this.props.defaultIndex}
renderPagination={this.renderPagination}
onMomentumScrollEnd={(e, state) => {
this.props.onSlideChange(state.index, state.total);
Expand Down Expand Up @@ -434,6 +353,12 @@ AppIntro.propTypes = {
PropTypes.element,
]),
customStyles: PropTypes.object,
defaultIndex: PropTypes.number,
showSkipButton: PropTypes.bool,
showDoneButton: PropTypes.bool,
showDots: PropTypes.bool,
renderDoneButton: PropTypes.element,
renderSkipButton: PropTypes.element
};

AppIntro.defaultProps = {
Expand All @@ -449,4 +374,8 @@ AppIntro.defaultProps = {
doneBtnLabel: 'Done',
skipBtnLabel: 'Skip',
nextBtnLabel: '›',
defaultIndex: 0,
showSkipButton: true,
showDoneButton: true,
showDots: true
};
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ And in Android, image inside view component, view need width、height.
| skipBtnLabel | string、Text element | Skip | The bottom left custom Text label |
| nextBtnLabel | string、Text element | › | The bottom left custom Text label |
| pageArray | array | | In the basic usage, you can input object array to render basic view example: ```[[{title: 'Page 1', description: 'Description 1', img: 'https://goo.gl/uwzs0C', imgStyle: {height: 80 * 2.5, width: 109 * 2.5 }, backgroundColor: '#fa931d', fontColor: '#fff', level: 10 }]``` , level is parallax effect level ,if you use pageArray you can't use custom view |
| defaultIndex | number | 0 | number of the index of the initial index |
| renderSkipButton | bool | true | a boolean defining if we should render the skip button |
| renderDoneButton | bool | true | a boolean that defines if we should render the done button |

##### **Children View Properties**
| Prop | PropType | Default Value | Description |
Expand Down
26 changes: 26 additions & 0 deletions components/DoneButton.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import {
Text,
View,
TouchableOpacity,
} from 'react-native';

export const DoneButton = ({
styles, onDoneBtnClick, onNextBtnClick,
rightTextColor, isDoneBtnShow,
doneBtnLabel, nextBtnLabel,
}) => {
return (
<View style={[styles.btnContainer, { height: 0, paddingBottom: 5 }]}>
<TouchableOpacity style={styles.full}
onPress={ isDoneBtnShow ? onDoneBtnClick : onNextBtnClick}
>
<Text style={[styles.nextButtonText, { color: rightTextColor }]}>
{isDoneBtnShow ? doneBtnLabel : nextBtnLabel}
</Text>
</TouchableOpacity>
</View>
)
}

export default DoneButton
48 changes: 48 additions & 0 deletions components/DoneButton.ios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react'
import {
Text,
View,
TouchableOpacity,
Animated
} from 'react-native';

export const DoneButton = ({
styles, onDoneBtnClick, onNextBtnClick,
rightTextColor, isDoneBtnShow,
doneBtnLabel, nextBtnLabel,
doneFadeOpacity, skipFadeOpacity, nextOpacity
}) => {
return (
<View style={styles.btnContainer}>
<Animated.View style={[styles.full, { height: 0 }, {
opacity: doneFadeOpacity,
transform: [{
translateX: skipFadeOpacity.interpolate({
inputRange: [0, 1],
outputRange: [0, 20],
}),
}],
}]}
>
<View style={styles.full}>
<Text style={[styles.controllText, {
color: rightTextColor, paddingRight: 30,
}]}>
{doneBtnLabel}
</Text>
</View>
</Animated.View>
<Animated.View style={[styles.full, { height: 0 }, { opacity: nextOpacity }]}>
<TouchableOpacity style={styles.full}
onPress={ isDoneBtnShow ? onDoneBtnClick : onNextBtnClick}>
<Text style={[styles.nextButtonText, { color: rightTextColor }]}>
{nextBtnLabel}
</Text>
</TouchableOpacity>
</Animated.View>
</View>
)
}

export default DoneButton

40 changes: 40 additions & 0 deletions components/Dots.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import {
Text,
View
} from 'react-native';

export const Dot = ({
styles, dotColor, activeDotColor, active
}) => {
if (active) {
return (
<View
style={[styles.dotStyle, styles.activeDotStyle, {
backgroundColor: activeDotColor
}]}
/>
);
} else {
return (
<View
style={[styles.dotStyle, {
backgroundColor: dotColor
}]} />
);
}
}

export const RenderDots = (index, total, props) => {
let dots = [];
for (let i = 0; i < total; i++) {
dots.push(React.createElement(Dot, {
...props,
key: i,
active: i === index
}));
}
return dots;
}

export default RenderDots;
31 changes: 31 additions & 0 deletions components/SkipButton.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react'
import {
Text,
View,
TouchableOpacity,
Animated
} from 'react-native';

export const SkipButton = ({
styles, onSkipBtnClick, isSkipBtnShow,
leftTextColor,
skipBtnLabel,
skipFadeOpacity
}) => {
return (
<View style={[styles.btnContainer, {
paddingBottom: 5,
opacity: isSkipBtnShow ? 1 : 0,
}]}>
<TouchableOpacity
style={styles.full}
onPress={isSkipBtnShow ? () => onSkipBtnClick(index) : null}>
<Text style={[styles.controllText, { color: leftTextColor }]}>
{skipBtnLabel}
</Text>
</TouchableOpacity>
</View>
)
}

export default SkipButton
37 changes: 37 additions & 0 deletions components/SkipButton.ios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import {
Text,
View,
TouchableOpacity,
Animated
} from 'react-native';

export const SkipButton = ({
styles, onSkipBtnClick, isSkipBtnShow,
rightTextColor,
skipBtnLabel,
skipFadeOpacity
}) => {
return (
<Animated.View style={[styles.btnContainer, {
opacity: skipFadeOpacity,
transform: [{
translateX: skipFadeOpacity.interpolate({
inputRange: [0, 1],
outputRange: [0, 15],
}),
}],
}]}
>
<TouchableOpacity
style={styles.full}
onPress={isSkipBtnShow ? () => onSkipBtnClick(index) : null}>
<Text style={[styles.controllText, { color: rightTextColor }]}>
{skipBtnLabel}
</Text>
</TouchableOpacity>
</Animated.View>
)
}

export default SkipButton