├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── Toast.js
├── constants.js
├── note.md
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | *.[aod]
2 | *.DS_Store
3 | .DS_Store
4 | *Thumbs.db
5 | *.iml
6 | .gradle
7 | .idea
8 | node_modules
9 | npm-debug.log
10 | /android/build
11 | /ios/**/*xcuserdata*
12 | /ios/**/*xcshareddata*
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.[aod]
2 | *.DS_Store
3 | .DS_Store
4 | *Thumbs.db
5 | *.iml
6 | .gradle
7 | .idea
8 | node_modules
9 | npm-debug.log
10 | /android/build
11 | /ios/**/*xcuserdata*
12 | /ios/**/*xcshareddata*
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-smart-toast
2 |
3 | [](https://www.npmjs.com/package/react-native-smart-toast)
4 | [](https://www.npmjs.com/package/react-native-smart-toast)
5 | [](https://www.npmjs.com/package/react-native-smart-toast)
6 | [](https://github.com/react-native-component/react-native-smart-toast/blob/master/LICENSE)
7 |
8 | A android like toast for react-native apps, written in JS for cross-platform support.
9 | It works on iOS and Android.
10 |
11 | This component is compatible with React Native 0.25 and newer.
12 |
13 | ## Preview
14 |
15 | ![react-native-smart-toast-preview-ios][1]
16 | ![react-native-smart-toast-preview-android][2]
17 |
18 | ## Installation
19 |
20 | ```
21 | npm install react-native-smart-toast --save
22 | ```
23 |
24 | ## Full Demo
25 |
26 | see [ReactNativeComponentDemos][0]
27 |
28 | ## Usage
29 |
30 | Install the toast from npm with `npm install react-native-smart-toast --save`.
31 | Then, require it from your app's JavaScript files with `import toast from 'react-native-smart-toast'`.
32 |
33 | ```js
34 |
35 | import React, {
36 | Component,
37 | } from 'react'
38 | import {
39 | View,
40 | } from 'react-native'
41 |
42 | import Button from 'react-native-smart-button'
43 | import TimerEnhance from 'react-native-smart-timer-enhance'
44 | import Toast from 'react-native-smart-toast'
45 |
46 | class LoadingToast extends Component {
47 |
48 | constructor(props) {
49 | super(props)
50 | this.state = {}
51 | }
52 |
53 | render() {
54 | return (
55 |
56 |
64 |
65 |
74 |
75 |
84 |
91 |
98 |
105 |
112 |
113 | this._toast = component }
115 | marginTop={64}>
116 | Unable to connect to apple store
117 |
118 |
119 | )
120 | }
121 |
122 | _showTopToast = () => {
123 | this._toast.show({
124 | position: Toast.constants.gravity.top,
125 | })
126 | }
127 |
128 | _showCenterToast = () => {
129 | this._toast.show({
130 | position: Toast.constants.gravity.center,
131 | children: Unalbe to download now
132 | })
133 | }
134 |
135 | _showBottomToast = () => {
136 | this._toast.show({
137 | position: Toast.constants.gravity.bottom,
138 | children: 'Unalbe to upload now'
139 | })
140 | }
141 |
142 | _showFastToast = () => {
143 | this._toast.show({
144 | position: Toast.constants.gravity.center,
145 | duration: 255,
146 | children: 'Unable to connect to apple store'
147 | })
148 | }
149 |
150 | _showFastToastAndAnimatedHide = () => {
151 | this._toast.show({
152 | position: Toast.constants.gravity.center,
153 | duration: 255,
154 | children: 'Unable to connect to google store',
155 | animationEnd : () => {
156 | this._toast._toastAnimationToggle = this.setTimeout( () => {
157 | this._toast.hide({
158 | duration: 0,
159 | animationEnd: () => {
160 | //do sth...
161 | }
162 | })
163 | }, 3000)
164 | }
165 | })
166 | }
167 |
168 | _showImmediateToast = () => {
169 | this._toast.show({
170 | position: Toast.constants.gravity.center,
171 | duration: 0,
172 | children: 'Unable to connect to wifi',
173 | })
174 | }
175 | _showImmediateToastAndAnimatedHide = () => {
176 | this._toast.show({
177 | position: Toast.constants.gravity.center,
178 | duration: 0,
179 | children: 'Unable to connect to wlan',
180 | animationEnd : () => {
181 | this._toast._toastAnimationToggle = this.setTimeout( () => {
182 | this._toast.hide({
183 | animationEnd: () => {
184 | //do sth...
185 | }
186 | })
187 | }, 3000)
188 | }
189 | })
190 | }
191 |
192 | }
193 |
194 |
195 | export default TimerEnhance(LoadingToast)
196 | ```
197 |
198 | ## Props
199 |
200 | Prop | Type | Optional | Default | Description
201 | ---------------- | ------ | -------- | ---------------- | -----------
202 | style | style | Yes | | see [react-native documents][3]
203 | textStyle | style | Yes | | see [react-native documents][4]
204 | spacing | number | Yes | 30 | determine the top or bottom spacing when the position is on the top or bottom
205 | position | style | Yes | constants.bottom | determine the position of toast
206 | duration | number | Yes | 3000 | determine the residence duration after toast is shown
207 | animatedDuration | number | Yes | 510 | determine the duration of toast animation
208 | delay | number | Yes | 0 | determine the delay of toast animation
209 | marginTop | number | Yes | 0 | determine the marginTop of the root container view, it is used when toast's position is constants.top
210 |
211 | ## Method
212 |
213 | * show({children, position, duration, easing, delay, animationEnd,})
214 |
215 | * children: determine the children of toast
216 | * position: determine the position of toast. enum(gravity.bottom, gravity.top, gravity.center)
217 | * duration: determine the duration of animation
218 | * easing: determine the easing of animation
219 | * delay: determine the delay of animation
220 | * animationEnd: determine the callback when animation is end
221 |
222 | * hide({duration, easing, delay, animationEnd,})
223 |
224 | * duration: determine the duration of animation
225 | * easing: determine the easing of animation
226 | * delay: determine the delay of animation
227 | * animationEnd: determine the callback when animation is end
228 |
229 | [0]: https://github.com/cyqresig/ReactNativeComponentDemos
230 | [1]: http://cyqresig.github.io/img/react-native-smart-toast-preview-ios-v1.0.0.gif
231 | [2]: http://cyqresig.github.io/img/react-native-smart-toast-preview-android-v1.0.0.gif
232 | [3]: https://facebook.github.io/react-native/docs/style.html
233 | [4]: http://facebook.github.io/react-native/docs/text.html#style
234 |
235 |
--------------------------------------------------------------------------------
/Toast.js:
--------------------------------------------------------------------------------
1 | /*
2 | * A android like toast for android and ios, written in JS
3 | * https://github.com/react-native-component/react-native-smart-toast/
4 | * Released under the MIT license
5 | * Copyright (c) 2016 react-native-component
6 | */
7 |
8 | import React, {
9 | Component,
10 | PropTypes,
11 | } from 'react'
12 | import {
13 | View,
14 | Text,
15 | StyleSheet,
16 | Animated,
17 | Easing,
18 | Dimensions,
19 | } from 'react-native'
20 |
21 | import TimerEnhance from 'react-native-smart-timer-enhance'
22 | import constants, { gravity } from './constants'
23 |
24 | const {width: deviceWidth, height: deviceHeight,} = Dimensions.get('window')
25 | const styles = StyleSheet.create({
26 | container: {
27 | backgroundColor: 'rgba(0, 0, 0, 0.8)',
28 | position: 'absolute',
29 | borderRadius: 8,
30 | padding: 8,
31 | left: -9999,
32 | top: -9999,
33 | zIndex: 999,
34 | },
35 | text: {
36 | fontFamily: '.HelveticaNeueInterface-MediumP4',
37 | fontSize: 14,
38 | color: '#fff'
39 | }
40 | })
41 |
42 | class Toast extends Component {
43 |
44 | static constants = constants
45 |
46 | static defaultProps = {
47 | spacing: 30,
48 | position: gravity.bottom,
49 | duration: 3000,
50 | animatedDuration: 510,
51 | delay: 0,
52 | marginTop: 0,
53 | }
54 |
55 | static propTypes = {
56 | style: View.propTypes.style,
57 | textStyle: Text.propTypes.style,
58 | spacing: PropTypes.number,
59 | position: PropTypes.oneOf([gravity.top, gravity.bottom, gravity.center,]),
60 | duration: PropTypes.number,
61 | animatedDuration: PropTypes.number,
62 | delay: PropTypes.number,
63 | marginTop: PropTypes.number,
64 | }
65 |
66 | constructor(props) {
67 | super(props)
68 | this.state = {
69 | position: props.position,
70 | visible: false,
71 | opacity: new Animated.Value(0),
72 | children: props.children,
73 | }
74 | this._toastWidth = null
75 | this._toastHeight = null
76 | this._toastShowAnimation = null
77 | this._toastHideAnimation = null
78 | this._toastAnimationToggle = null
79 | }
80 |
81 | render() {
82 | let children = React.Children.map(this.state.children, (child) => {
83 | if (!React.isValidElement(child)) {
84 | return (
85 |
87 | {child}
88 |
89 | )
90 | }
91 | return child
92 | })
93 | return (
94 | this.state.visible ?
95 | this._container = component }
97 | onLayout={this._onToastLayout}
98 | style={[styles.container, this.props.style, {opacity:this.state.opacity, }]}>
99 | {children}
100 | : null
101 | )
102 | }
103 |
104 | show({children = this.state.children, position = this.state.position, duration = this.props.animatedDuration, easing = Easing.linear, delay = this.props.delay, animationEnd,}
105 | = {children: this.state.children, position: this.state.position, duration: this.props.animatedDuration, easing: Easing.linear, delay: this.props.delay,}) {
106 |
107 | this._toastShowAnimation && this._toastShowAnimation.stop()
108 | this._toastHideAnimation && this._toastHideAnimation.stop()
109 | this._toastAnimationToggle && this.clearTimeout(this._toastAnimationToggle)
110 |
111 | if(this.state.visible) {
112 | this._setToastPosition(position)
113 | }
114 |
115 | this.setState({
116 | children,
117 | position,
118 | visible: true,
119 | })
120 |
121 | this._toastShowAnimation = Animated.timing(
122 | this.state.opacity,
123 | {
124 | toValue: 1,
125 | duration,
126 | easing,
127 | delay,
128 | }
129 | )
130 | this._toastShowAnimation.start(() => {
131 | this._toastShowAnimation = null
132 | if(!animationEnd) {
133 | this._toastAnimationToggle = this.setTimeout( () => {
134 | this.hide({duration, easing, delay})
135 | this._toastAnimationToggle = null
136 | }, this.props.duration)
137 | }
138 | else {
139 | animationEnd()
140 | }
141 | })
142 | }
143 |
144 | hide({duration = this.props.animatedDuration, easing = Easing.linear, delay = this.props.delay, animationEnd,}
145 | = {duration: this.props.animatedDuration, easing: Easing.linear, delay: this.props.delay,}) {
146 |
147 | this._toastShowAnimation && this._toastShowAnimation.stop()
148 | this._toastHideAnimation && this._toastHideAnimation.stop()
149 | this.clearTimeout(this._toastAnimationToggle)
150 |
151 | this._toastHideAnimation = Animated.timing(
152 | this.state.opacity,
153 | {
154 | toValue: 0,
155 | duration,
156 | easing,
157 | delay,
158 | }
159 | )
160 | this._toastHideAnimation.start( () => {
161 | this._toastHideAnimation = null
162 | this.setState({
163 | visible: false,
164 | })
165 | animationEnd && animationEnd()
166 | })
167 | }
168 |
169 | _onToastLayout = (e) => {
170 | this._toastWidth = e.nativeEvent.layout.width
171 | this._toastHeight = e.nativeEvent.layout.height
172 | this._setToastPosition()
173 | }
174 |
175 | _setToastPosition(position = this.state.position) {
176 | if(!this._toastWidth || !this._toastHeight) {
177 | return
178 | }
179 | let { spacing, marginTop, } = this.props
180 | let left = (deviceWidth - this._toastWidth) / 2
181 | let top = position == gravity.top ? spacing + marginTop:
182 | position == gravity.center ? (deviceHeight - this._toastHeight) / 2 : null
183 | let bottom = position == gravity.bottom ? spacing : null
184 | this._container.setNativeProps({
185 | style: {
186 | left,
187 | top,
188 | bottom,
189 | }
190 | })
191 | }
192 |
193 | }
194 |
195 | export default TimerEnhance(Toast)
--------------------------------------------------------------------------------
/constants.js:
--------------------------------------------------------------------------------
1 |
2 | export const gravity = {
3 | bottom: 0,
4 | top: 1,
5 | center: 2,
6 | }
7 |
8 | export default {
9 | gravity,
10 | }
--------------------------------------------------------------------------------
/note.md:
--------------------------------------------------------------------------------
1 | * 需要保证组件为单例, 在显示/隐藏期间再次调用显示/隐藏时, 不会产生冲突
2 | * 需要支持上, 中, 下三种显示位置
3 | * 需要保证上述三种类型, 加载指示器区域显示时相对屏幕进行定位显示
4 | * 需要支持帮助信息区域及内容可自定义样式和内容
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@react-native-component/react-native-smart-toast",
3 | "version": "1.1.1",
4 | "description": "A android like toast for react-native apps",
5 | "main": "Toast.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/react-native-component/react-native-smart-toast.git"
12 | },
13 | "keywords": [
14 | "react-native",
15 | "smart",
16 | "toast",
17 | "component"
18 | ],
19 | "author": "HISAME SHIZUMARU",
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/react-native-component/react-native-smart-toast/issues"
23 | },
24 | "homepage": "https://github.com/react-native-component/react-native-smart-toast#readme",
25 | "dependencies": {
26 | "react-native-smart-timer-enhance": "^1.0.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------