├── .codeclimate.yml ├── .editorconfig ├── .gitignore ├── .travis.yml ├── AUTHORS ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── asset-manifest.json ├── build │ ├── 0.320b8cca.js │ └── bundle.1d11b103.js ├── favicon.ico ├── index.html ├── service-worker.js └── static │ ├── css │ ├── main.d315a98d.css │ └── main.d315a98d.css.map │ ├── js │ ├── main.3027f4fc.js │ └── main.3027f4fc.js.map │ └── media │ ├── background.3ecd8248.jpg │ └── demo.3ecd8248.jpg ├── lib ├── __tests__ │ └── index.test.js ├── components │ ├── ToastContainer.js │ ├── ToastMessage │ │ ├── ToastMessage.js │ │ ├── ToastMessageAnimated.js │ │ └── ToastMessagejQuery.js │ └── __tests__ │ │ └── ToastContainer.test.js └── index.js ├── package.json ├── src ├── __tests__ │ └── index.test.js ├── components │ ├── ToastContainer.jsx │ ├── ToastContainer.md │ ├── ToastMessage │ │ ├── ToastMessage.jsx │ │ ├── ToastMessage.md │ │ ├── ToastMessageAnimated.jsx │ │ └── ToastMessagejQuery.jsx │ ├── __tests__ │ │ ├── ToastContainer.test.js │ │ └── __snapshots__ │ │ │ └── ToastContainer.test.js.snap │ ├── demo.css │ └── demo.jpg ├── docs │ ├── configuration.md │ ├── installation.md │ └── introduction.md └── index.js ├── styleguide ├── styleguide.config.js └── yarn.lock /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | # This is a sample .codeclimate.yml configured for Engine analysis on Code 2 | # Climate Platform. For an overview of the Code Climate Platform, see here: 3 | # http://docs.codeclimate.com/article/300-the-codeclimate-platform 4 | 5 | # Under the engines key, you can configure which engines will analyze your repo. 6 | # Each key is an engine name. For each value, you need to specify enabled: true 7 | # to enable the engine as well as any other engines-specific configuration. 8 | 9 | # For more details, see here: 10 | # http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform 11 | 12 | # For a list of all available engines, see here: 13 | # http://docs.codeclimate.com/article/296-engines-available-engines 14 | 15 | engines: 16 | # to turn on an engine, add it here and set enabled to `true` 17 | # to turn off an engine, set enabled to `false` or remove it 18 | eslint: 19 | enabled: true 20 | 21 | # Engines can analyze files and report issues on them, but you can separately 22 | # decide which files will receive ratings based on those issues. This is 23 | # specified by path patterns under the ratings key. 24 | 25 | # For more details see here: 26 | # http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform 27 | 28 | ratings: 29 | paths: 30 | - src/** 31 | 32 | # You can globally exclude files from being analyzed by any engine using the 33 | # exclude_paths key. 34 | 35 | exclude_paths: 36 | - lib/** 37 | - public/** 38 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 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 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # Matches multiple files with brace expansion notation 12 | # Set default charset 13 | [*.{js,py}] 14 | charset = utf-8 15 | 16 | # 4 space indentation 17 | [*.py] 18 | indent_style = space 19 | indent_size = 4 20 | 21 | # Tab indentation (no size specified) 22 | [Makefile] 23 | indent_style = tab 24 | 25 | # Indentation override for all JS under lib directory 26 | [*.js] 27 | indent_style = space 28 | indent_size = 2 29 | 30 | # Matches the exact files either package.json or .travis.yml 31 | [{package.json,.travis.yml}] 32 | indent_style = space 33 | indent_size = 2 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by http://www.gitignore.io 2 | 3 | ### Editor 4 | *.swp 5 | 6 | ### Node ### 7 | # Logs 8 | logs 9 | *.log 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | 16 | # OSX 17 | .DS_Store 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Compiled binary addons (http://nodejs.org/api/addons.html) 29 | build/Release 30 | 31 | # Dependency directory 32 | # Commenting this out is preferred by some people, see 33 | # https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 34 | node_modules 35 | 36 | # Users Environment Variables 37 | .lock-wscript 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: required 3 | language: node_js 4 | node_js: 5 | - '6' 6 | - '8' 7 | before_script: 8 | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter 9 | - chmod +x ./cc-test-reporter 10 | - "./cc-test-reporter before-build" 11 | script: 12 | - npm test -- --coverage 13 | after_script: 14 | - if [[ "$TRAVIS_PULL_REQUEST" == "false" && `node --version` == *v8* ]]; then ./cc-test-reporter 15 | after-build --exit-code $TRAVIS_TEST_RESULT; fi 16 | env: 17 | global: 18 | secure: JpQFPCk6B08i5qtG/useKoDuY/ig/4bEkWtl7esPdvwBi8YjkkxRu+E9lOqiV9FudzogYls3mZRPIeBO41BjGzFqkhaQMUDnB9Gd8kGgUFaU4XmOHgJ46gPLwQLOia/+y6DOeN7fv4t2RGABf+F/hpnumJ3GXqbAQW5W2gfXJEs= 19 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | tomchentw (https://github.com/tomchentw) 2 | yfxie (http://www.json.tw) 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | 6 | # [3.0.0](https://github.com/tomchentw/react-toastr/compare/v2.9.5...v3.0.0) (2017-10-28) 7 | 8 | 9 | ### Features 10 | 11 | * **index.js:** export components ([b702c2a](https://github.com/tomchentw/react-toastr/commit/b702c2a)) 12 | * **package.json:** add `dom-helpers` to dependencies ([66cb57f](https://github.com/tomchentw/react-toastr/commit/66cb57f)) 13 | * **package.json:** drop support for `react@^0.14` ([e5fa767](https://github.com/tomchentw/react-toastr/commit/e5fa767)) 14 | * **package.json:** remove unused dependencies ([fbe75e1](https://github.com/tomchentw/react-toastr/commit/fbe75e1)) 15 | * **ToastContainer:** rewrite ([a3cd015](https://github.com/tomchentw/react-toastr/commit/a3cd015)) 16 | * **ToastMessage:** rewrite ([b8a3b29](https://github.com/tomchentw/react-toastr/commit/b8a3b29)) 17 | * **ToastMessageAnimated:** rewrite ([9469454](https://github.com/tomchentw/react-toastr/commit/9469454)) 18 | * **ToastMessagejQuery:** rewrite ([f239dee](https://github.com/tomchentw/react-toastr/commit/f239dee)) 19 | 20 | 21 | ### BREAKING CHANGES 22 | 23 | * **index.js:** named exports changes for ToastMessage 24 | 25 | Before: 26 | 27 | ```js 28 | import { ToastContainer, ToastMessage } from "react-toastr" 29 | 30 | const ToastMessageFactory = React.createFactory(ToastMessage.animation); 31 | const jQueryFactory = React.createFactory(ToastMessage.jQuery); 32 | 33 | 34 | 35 | ``` 36 | 37 | After: 38 | 39 | ```js 40 | import { ToastContainer, ToastMessageAnimated } from "react-toastr" 41 | import ToastMessagejQuery from "react-toastr/lib/components/ToastMessage/ToastMessagejQuery"; 42 | 43 | const ToastMessageFactory = React.createFactory(ToastMessageAnimated); 44 | const jQueryFactory = React.createFactory(ToastMessagejQuery); 45 | 46 | 47 | 48 | ``` 49 | 50 | 51 | 52 | 53 | ## [2.9.5](https://github.com/tomchentw/react-toastr/compare/v2.9.4...v2.9.5) (2017-10-06) 54 | 55 | 56 | ### Bug Fixes 57 | 58 | * **package.json:** keep peerDependencies for `react@^0.14.0` ([eecf97f](https://github.com/tomchentw/react-toastr/commit/eecf97f)) 59 | 60 | 61 | 62 | 63 | ## [2.9.4](https://github.com/tomchentw/react-toastr/compare/v2.9.3...v2.9.4) (2017-09-30) 64 | 65 | 66 | ### Bug Fixes 67 | 68 | * **package.json:** move react-dom to peerDependencies ([#119](https://github.com/tomchentw/react-toastr/issues/119)) ([ebb9e90](https://github.com/tomchentw/react-toastr/commit/ebb9e90)) 69 | 70 | 71 | 72 | 73 | ## [2.9.3](https://github.com/tomchentw/react-toastr/compare/v2.9.2...v2.9.3) (2017-08-23) 74 | 75 | 76 | 77 | 78 | ## [2.9.2](https://github.com/tomchentw/react-toastr/compare/v2.9.1...v2.9.2) (2017-08-21) 79 | 80 | 81 | ### Bug Fixes 82 | 83 | * **ToastContainer:** replace _.omit with object rest ([bc1a397](https://github.com/tomchentw/react-toastr/commit/bc1a397)), closes [#105](https://github.com/tomchentw/react-toastr/issues/105) [#104](https://github.com/tomchentw/react-toastr/issues/104) 84 | 85 | 86 | 87 | 88 | ## [2.9.1](https://github.com/tomchentw/react-toastr/compare/v2.9.0...v2.9.1) (2017-08-21) 89 | 90 | 91 | ### Bug Fixes 92 | 93 | * **ToastMessage:** switch to hosted ReactTransitionEvents ([b3423a9](https://github.com/tomchentw/react-toastr/commit/b3423a9)), closes [#108](https://github.com/tomchentw/react-toastr/issues/108) [#86](https://github.com/tomchentw/react-toastr/issues/86) 94 | 95 | 96 | 97 | 98 | # [2.9.0](https://github.com/tomchentw/react-toastr/compare/v2.8.2...v2.9.0) (2017-08-21) 99 | 100 | 101 | ### Bug Fixes 102 | 103 | * eslint warnings ([2687c92](https://github.com/tomchentw/react-toastr/commit/2687c92)) 104 | 105 | 106 | ### Features 107 | 108 | * **package.json:** add `prop-types` and `create-react-class` to dependencies ([ee7d307](https://github.com/tomchentw/react-toastr/commit/ee7d307)), closes [#94](https://github.com/tomchentw/react-toastr/issues/94) [#95](https://github.com/tomchentw/react-toastr/issues/95) [#97](https://github.com/tomchentw/react-toastr/issues/97) 109 | * **ToastContainer:** switch to `prop-types` ([1aac987](https://github.com/tomchentw/react-toastr/commit/1aac987)), closes [#94](https://github.com/tomchentw/react-toastr/issues/94) 110 | * **ToastMessage:** switch to `create-react-class` ([49aa141](https://github.com/tomchentw/react-toastr/commit/49aa141)), closes [#95](https://github.com/tomchentw/react-toastr/issues/95) 111 | 112 | 113 | 114 | 115 | ## [2.8.2](https://github.com/tomchentw/react-toastr/compare/v2.8.1...v2.8.2) (2016-11-09) 116 | 117 | 118 | 119 | 120 | ## [2.8.1](https://github.com/tomchentw/react-toastr/compare/v2.8.0...v2.8.1) (2016-09-21) 121 | 122 | 123 | 124 | 125 | # [2.8.0](https://github.com/tomchentw/react-toastr/compare/v2.7.0...v2.8.0) (2016-08-01) 126 | 127 | 128 | ### Bug Fixes 129 | 130 | * **ToastContainer:** warning of unknown props ([766e2b3](https://github.com/tomchentw/react-toastr/commit/766e2b3)), closes [#63](https://github.com/tomchentw/react-toastr/issues/63) [#67](https://github.com/tomchentw/react-toastr/issues/67) [#68](https://github.com/tomchentw/react-toastr/issues/68) [#70](https://github.com/tomchentw/react-toastr/issues/70) 131 | 132 | 133 | ### Features 134 | 135 | * **ToastContainer:** add prevents duplicates functionality ([3a8f772](https://github.com/tomchentw/react-toastr/commit/3a8f772)), closes [#60](https://github.com/tomchentw/react-toastr/issues/60) 136 | 137 | 138 | 139 | 140 | # [2.7.0](https://github.com/tomchentw/react-toastr/compare/v2.6.2...v2.7.0) (2016-06-14) 141 | 142 | 143 | ### Features 144 | 145 | * **ToastContainer:** add props.preventDuplicates suppory ([b8e9bd2](https://github.com/tomchentw/react-toastr/commit/b8e9bd2)), closes [#58](https://github.com/tomchentw/react-toastr/issues/58) [#56](https://github.com/tomchentw/react-toastr/issues/56) [#53](https://github.com/tomchentw/react-toastr/issues/53) 146 | 147 | 148 | 149 | 150 | ## [2.6.2](https://github.com/tomchentw/react-toastr/compare/v2.6.1...v2.6.2) (2016-05-31) 151 | 152 | 153 | 154 | 155 | ## [2.6.1](https://github.com/tomchentw/react-toastr/compare/v2.6.0...v2.6.1) (2016-04-28) 156 | 157 | 158 | ### Bug Fixes 159 | 160 | * **package.json:** make react and react-dom support both @^0.14.0 and @^15.0.0 ([394ef07](https://github.com/tomchentw/react-toastr/commit/394ef07)) 161 | 162 | 163 | 164 | 165 | # (Unpublished) [2.6.0](https://github.com/tomchentw/react-toastr/compare/v2.4.0...v2.6.0) (2016-04-26) 166 | 167 | ### Unpublished due to 168 | 169 | * [#49](https://github.com/tomchentw/react-toastr/issues/49): react@^15.0.0 is required 170 | 171 | ### Features 172 | 173 | * **package.json:** update to react@^15.0.0 ([6d7e8a8](https://github.com/tomchentw/react-toastr/commit/6d7e8a8)) 174 | 175 | 176 | 177 | 178 | # [2.4.0](https://github.com/tomchentw/react-toastr/compare/v2.3.1...v2.4.0) (2016-01-28) 179 | 180 | 181 | ### Features 182 | 183 | * **package.json:** bump dependencies ([d74c217](https://github.com/tomchentw/react-toastr/commit/d74c217)) 184 | * **ToastMessage:** replace fbjs dependency with element-class ([97c171b](https://github.com/tomchentw/react-toastr/commit/97c171b)) 185 | 186 | 187 | 188 | 189 | ## [2.3.1](https://github.com/tomchentw/react-toastr/compare/v2.3.0...v2.3.1) (2016-01-19) 190 | 191 | 192 | 193 | 194 | 195 | # [2.3.0](https://github.com/tomchentw/react-toastr/compare/v2.2.4...v2.3.0) (2016-01-03) 196 | 197 | 198 | ### Features 199 | 200 | * **package.json:** bump fbjs to ^0.6.0 ([ae96bee](https://github.com/tomchentw/react-toastr/commit/ae96bee)) 201 | 202 | 203 | 204 | 205 | ## [2.2.4](https://github.com/tomchentw/react-toastr/compare/v2.2.3...v2.2.4) (2015-12-10) 206 | 207 | 208 | ### Bug Fixes 209 | 210 | * **ToastContainer:** add default value for optionsOverride ([14f953a](https://github.com/tomchentw/react-toastr/commit/14f953a)) 211 | 212 | 213 | 214 | 215 | ## [2.2.3](https://github.com/tomchentw/react-toastr/compare/v2.2.2...v2.2.3) (2015-12-10) 216 | 217 | 218 | ### Features 219 | 220 | * **ToastContainer:** add support for optionsOverride.handleOnClick ([73dc376](https://github.com/tomchentw/react-toastr/commit/73dc376)), closes [#43](https://github.com/tomchentw/react-toastr/issues/43) 221 | 222 | 223 | 224 | 225 | ## [2.2.2](https://github.com/tomchentw/react-toastr/compare/v2.2.1...v2.2.2) (2015-11-02) 226 | 227 | 228 | ### Bug Fixes 229 | 230 | * **src:** Revert breaking changes commits for v2.2.1. Closes #42 ([988112e](https://github.com/tomchentw/react-toastr/commit/988112e)), closes [#42](https://github.com/tomchentw/react-toastr/issues/42) 231 | 232 | 233 | 234 | 235 | ## _UNPLUBISHED FROM NPM_ [2.2.1](https://github.com/tomchentw/react-toastr/compare/v2.2.0...v2.2.1) (2015-11-02) 236 | 237 | This version has been unpublished from npm. The __Bug Fixes__ here still applied but __Features__ are removed. See https://github.com/tomchentw/react-toastr/issues/42. 238 | 239 | ### Bug Fixes 240 | 241 | * **package.json:** added react-dom as dependency ([18c58d0](https://github.com/tomchentw/react-toastr/commit/18c58d0)), closes [#41](https://github.com/tomchentw/react-toastr/issues/41) 242 | * **ToastMessage:** use ReactDOM.findDOMNode instead of this.getDOMNode ([d4f40b3](https://github.com/tomchentw/react-toastr/commit/d4f40b3)) 243 | 244 | ### Features 245 | 246 | * **src:** ES2015 ([96aa073](https://github.com/tomchentw/react-toastr/commit/96aa073)) 247 | * **ToastContainer:** ES2015 ([dce1279](https://github.com/tomchentw/react-toastr/commit/dce1279)) 248 | * **ToastMessage:** ES2015 + props naming convention changed ([69c23db](https://github.com/tomchentw/react-toastr/commit/69c23db)) 249 | * **ToastMessage.animation:** ES2015 ([69dbd7e](https://github.com/tomchentw/react-toastr/commit/69dbd7e)) 250 | * **ToastMessage.jQuery:** ES2015 + require jQuery as dependency ([e0ff62b](https://github.com/tomchentw/react-toastr/commit/e0ff62b)) 251 | * **ToastMessageList:** add pure component to wrap toast list ([db9fee6](https://github.com/tomchentw/react-toastr/commit/db9fee6)) 252 | 253 | 254 | ### BREAKING CHANGES 255 | 256 | * ToastMessage: Props naming convention changed 257 | 258 | Before: type,handleRemove, handleOnClick 259 | 260 | After: toastType, onRemove, onClick 261 | * ToastMessage.jQuery: use ES2015 import statement for jquery 262 | 263 | Previously, we requires you to inject jQuery as global variable ($, jQuery). 264 | However, as people adoping module bundler such as webpack, it's more common 265 | to declare it as dependency. 266 | 267 | 268 | 269 | 270 | # [2.2.0](https://github.com/tomchentw/react-toastr/compare/v2.1.0...v2.2.0) (2015-10-28) 271 | 272 | 273 | ### Bug Fixes 274 | 275 | * **src:** React@0.14 migration, add react-addons-update as a dep ([e8b7152](https://github.com/tomchentw/react-toastr/commit/e8b7152)), closes [#38](https://github.com/tomchentw/react-toastr/issues/38) 276 | 277 | 278 | 279 | 280 | # [2.1.0](https://github.com/tomchentw/react-toastr/compare/v2.0.0...v2.1.0) (2015-10-11) 281 | 282 | 283 | ### Bug Fixes 284 | 285 | * **package.json:** move classnames to dependencies ([9a74e6f](https://github.com/tomchentw/react-toastr/commit/9a74e6f)), closes [#32](https://github.com/tomchentw/react-toastr/issues/32) 286 | 287 | 288 | 289 | 290 | # [2.0.0](https://github.com/tomchentw/react-toastr/compare/v1.5.2...v2.0.0) (2015-10-08) 291 | 292 | 293 | ### Features 294 | 295 | * **package.json:** upgrade to React@^0.14 ([c1cfc28](https://github.com/tomchentw/react-toastr/commit/c1cfc28)) 296 | 297 | 298 | ### BREAKING CHANGES 299 | 300 | * __React@^0.14__: upgrade at peerDependencies 301 | * move __React@^0.14__ and __classnames@^2.1.5__ from dependencies to peerDependencies 302 | * also add __fbjs^0.3.1__ to peerDependencies 303 | 304 | 305 | 306 | 307 | ### 1.5.2 (2015-09-25) 308 | 309 | 310 | #### Bug Fixes 311 | 312 | * **ToastMessage:** need clear setTimeout when component unmount ([e12f025c](https://github.com/tomchentw/react-toastr/commit/e12f025c), closes [#29](https://github.com/tomchentw/react-toastr/issues/29)) 313 | 314 | 315 | 316 | ### 1.5.1 (2015-07-01) 317 | 318 | 319 | 320 | ## 1.5.0 (2015-07-01) 321 | 322 | 323 | #### Bug Fixes 324 | 325 | * **ToastMessage:** × using dangerouslySetInnerHTML ([af7e6059](https://github.com/tomchentw/react-toastr/commit/af7e6059)) 326 | 327 | 328 | #### Features 329 | 330 | * **ToastMessage:** Update React addon classSet to classnames ([528473e9](https://github.com/tomchentw/react-toastr/commit/528473e9), closes [#23](https://github.com/tomchentw/react-toastr/issues/23)) 331 | 332 | 333 | ## 1.4.0 (2015-05-22) 334 | 335 | 336 | ### 1.3.1 (2015-05-21) 337 | 338 | 339 | #### Bug Fixes 340 | 341 | * **package.json:** move react from dependencies to devDependencies ([07e1acf3](https://github.com/tomchentw/react-toastr/commit/07e1acf3cae1052546a3d9a415ae007fd72eff3e)) 342 | 343 | 344 | ## 1.3.0 (2015-05-12) 345 | 346 | 347 | #### Bug Fixes 348 | 349 | * **animationMixin:** misuse typeof ([8f504133](https://github.com/tomchentw/react-toastr/commit/8f504133235e2a4b29992b213b1bb51f9ff22f5b)) 350 | 351 | 352 | #### Features 353 | 354 | * **animationMixin:** animate toasts using css transitions/animations ([ed0d8b07](https://github.com/tomchentw/react-toastr/commit/ed0d8b07cb9ed94148a409945981479adfa0882f)) 355 | 356 | 357 | ## 1.2.0 (2015-04-27) 358 | 359 | 360 | #### Features 361 | 362 | * **package.json:** update to react@0.13 and add peerDependencies ([0e00b836](https://github.com/tomchentw/react-toastr/commit/0e00b836bfa5cfa435d497a78c6fba872aa7cfde)) 363 | 364 | 365 | ### 1.1.2 (2014-11-20) 366 | 367 | 368 | ### 1.1.1 (2014-11-14) 369 | 370 | 371 | #### Bug Fixes 372 | 373 | * **jQueryMixin:** update jQuery calls to use jQuery rather than $ ([d1d858b4](https://github.com/tomchentw/react-toastr/commit/d1d858b4c7df32c5bb88399a1aa9be74a866cde0)) 374 | 375 | 376 | ## 1.1.0 (2014-10-29) 377 | 378 | 379 | #### Features 380 | 381 | * **ToastContainer:** toastMessageClass changed to toastMessageFactory ([bdcbabac](https://github.com/tomchentw/react-toastr/commit/bdcbabacfffea683ababd26a2f6ecb59c66dbda2)) 382 | * **lib:** upgrade React to 0.12 ([5a375ae8](https://github.com/tomchentw/react-toastr/commit/5a375ae8125216eb478feb80cf67402d6bcc647a)) 383 | 384 | 385 | #### Breaking Changes 386 | 387 | * propTypes renamed to toastMessageFactory 388 | 389 | toastMessageFactory now only accepts the result of calling React.createFactory(ReactElementClass). 390 | 391 | ([bdcbabac](https://github.com/tomchentw/react-toastr/commit/bdcbabacfffea683ababd26a2f6ecb59c66dbda2)) 392 | 393 | 394 | ## 1.0.0 (2014-10-19) 395 | 396 | 397 | #### Bug Fixes 398 | 399 | * **.travis.yml:** remove 0.11 target for jest bug ([09c9ab66](https://github.com/tomchentw/react-toastr/commit/09c9ab665cbb5cd385df4abd72c680bcb73bca1b)) 400 | 401 | 402 | #### Features 403 | 404 | * **ToastContainer:** add clear interface ([29bef4c0](https://github.com/tomchentw/react-toastr/commit/29bef4c01908db02a38e9a2a43b0bd05d952ae4a)) 405 | * **ToastMessage:** 406 | * add closeButton props support ([ea53e383](https://github.com/tomchentw/react-toastr/commit/ea53e383343122aeb66ea7a4673851447d937e2b)) 407 | * hookup remove toast from state ([f0a72224](https://github.com/tomchentw/react-toastr/commit/f0a7222439b290b4e445472c114255cfa49cbe33)) 408 | * add handleMouse{Enter/Leave} for internal api ([6f340ffc](https://github.com/tomchentw/react-toastr/commit/6f340ffc828917c414fe003724862dd2b67611a2)) 409 | * hook onClick handler ([312764d2](https://github.com/tomchentw/react-toastr/commit/312764d26e36db373cc1cec678591bdb23d89965)) 410 | * **ToastMessage.jQuery:** with jQueryMixin ([1fc06874](https://github.com/tomchentw/react-toastr/commit/1fc068740ce864a6daac87774d9834b8d5e590a2)) 411 | * **ToastMessage:** 412 | * export ToastContainer and ToastMessage ([ea3d2ea3](https://github.com/tomchentw/react-toastr/commit/ea3d2ea31fb608d392afbda72e321d32cf84164e)) 413 | * add newestOnTop to props ([1d7950d1](https://github.com/tomchentw/react-toastr/commit/1d7950d1f52710e638d30379ae8ba9b0d69ebc43)) 414 | * add onClick handler and hook toast callback ([e71a0058](https://github.com/tomchentw/react-toastr/commit/e71a00585e1d52ec0186bc89e48392a6efbcc2ac)) 415 | * add preventDuplicates props ([c9d548b8](https://github.com/tomchentw/react-toastr/commit/c9d548b82ca14a56dc7214b30d097844f992286d)) 416 | * add default container-id and move to top-right ([30fa8264](https://github.com/tomchentw/react-toastr/commit/30fa8264dab02756b27fd34b63e5e05d7b9bc2bc)) 417 | * add iconClassNames and toastType to props ([3916c2ef](https://github.com/tomchentw/react-toastr/commit/3916c2efcfe8240bb4ead80b0326743e86b4030b)) 418 | * port from jsfiddle.net/tomchentw/x7m8wavf ([bb87f99c](https://github.com/tomchentw/react-toastr/commit/bb87f99c43c26d0558cddc788bff3c025c1dfe5f)) 419 | * **jQueryMixin:** 420 | * hook hover logic into handleMouse{Enter/Leave} ([bc8d8e49](https://github.com/tomchentw/react-toastr/commit/bc8d8e495ba240349d8d69b9745f3357857f6be7)) 421 | * add show props and hook to componentDidMount ([a90a47ce](https://github.com/tomchentw/react-toastr/commit/a90a47ceb6f4365927d6ba42acd4570b9a928c9b)) 422 | * **lib:** compile src to lib ([44f406dd](https://github.com/tomchentw/react-toastr/commit/44f406dd0479c50d94c43cd3b8487a27a7ed5c78)) 423 | * **package.json:** downgrade react to 0.11.0 ([4f105dc7](https://github.com/tomchentw/react-toastr/commit/4f105dc7c29599184d75a31468a32528966649b9)) 424 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to React-Toastr 2 | 3 | ## Convention 4 | 5 | ### `src/lib` contains core library 6 | 7 | * Please add new features/fix bugs here 8 | * They'll be compiled by babel into `lib` folder 9 | * Don't manually modify contents under `lib` folder 10 | 11 | ### `src/app` contains docs app 12 | 13 | * It can be served as local app for core library development 14 | * It'll be released as `gh-pages` into `build` folder 15 | * Don't manually modify contents under `build` folder 16 | 17 | 18 | ## Development 19 | 20 | ```shell 21 | git clone ... 22 | npm install 23 | npm start 24 | ``` 25 | 26 | Now you can develop! 27 | 28 | 29 | ## Contributing 30 | 31 | [![devDependency Status][david-dm-image]][david-dm-url] 32 | 33 | 1. Fork it 34 | 2. Create your feature branch (`git checkout -b my-new-feature`) 35 | 3. Commit your changes (`git commit -am 'Add some feature'`) 36 | 4. Push to the branch (`git push origin my-new-feature`) 37 | 5. Create new pull request 38 | 39 | [david-dm-image]: https://img.shields.io/david/dev/tomchentw/react-toastr.svg?style=flat-square 40 | [david-dm-url]: https://david-dm.org/tomchentw/react-toastr#info=devDependencies 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Tom Chen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-toastr 2 | > React.js toastr component 3 | 4 | [![Version][npm-image]][npm-url] [![Travis CI][travis-image]][travis-url] [![Quality][codeclimate-image]][codeclimate-url] [![Coverage][codeclimate-coverage-image]][codeclimate-coverage-url] [![Dependencies][gemnasium-image]][gemnasium-url] [![Gitter][gitter-image]][gitter-url] 5 | 6 | 7 | ## [Introduction](https://tomchentw.github.io/react-toastr/#introduction) 8 | 9 | 10 | ## [Installation](https://tomchentw.github.io/react-toastr/#installation) 11 | 12 | 13 | ## [Usage & Configuration](https://tomchentw.github.io/react-toastr/#usage--configuration) 14 | 15 | 16 | ## [Changelog][changelog-url] 17 | 18 | The changelog is automatically generated via [standard-version][standard-version] and can be found in project root as well as npm tarball. 19 | 20 | 21 | [npm-image]: https://img.shields.io/npm/v/react-toastr.svg?style=flat-square 22 | [npm-url]: https://www.npmjs.org/package/react-toastr 23 | 24 | [travis-image]: https://img.shields.io/travis/tomchentw/react-toastr.svg?style=flat-square 25 | [travis-url]: https://travis-ci.org/tomchentw/react-toastr 26 | [codeclimate-image]: https://img.shields.io/codeclimate/github/tomchentw/react-toastr.svg?style=flat-square 27 | [codeclimate-url]: https://codeclimate.com/github/tomchentw/react-toastr 28 | [codeclimate-coverage-image]: https://img.shields.io/codeclimate/coverage/github/tomchentw/react-toastr.svg?style=flat-square 29 | [codeclimate-coverage-url]: https://codeclimate.com/github/tomchentw/react-toastr 30 | [gemnasium-image]: https://img.shields.io/gemnasium/tomchentw/react-toastr.svg?style=flat-square 31 | [gemnasium-url]: https://gemnasium.com/tomchentw/react-toastr 32 | [gitter-image]: https://badges.gitter.im/Join%20Chat.svg 33 | [gitter-url]: https://gitter.im/tomchentw/react-toastr?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge 34 | 35 | [changelog-url]: https://github.com/tomchentw/react-toastr/blob/master/CHANGELOG.md 36 | 37 | [standard-version]: https://github.com/conventional-changelog/standard-version 38 | [conventional-commits-specification]: https://conventionalcommits.org/ 39 | -------------------------------------------------------------------------------- /docs/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "main.css": "static/css/main.d315a98d.css", 3 | "main.css.map": "static/css/main.d315a98d.css.map", 4 | "main.js": "static/js/main.3027f4fc.js", 5 | "main.js.map": "static/js/main.3027f4fc.js.map", 6 | "static/media/background.jpg": "static/media/background.3ecd8248.jpg" 7 | } -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomchentw/react-toastr/fcd3b4b7e6031dde7c128921489bffaad85729a9/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Toastr Style Guide 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/service-worker.js: -------------------------------------------------------------------------------- 1 | "use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/react-toastr/index.html","27024685ea45cf23cecd7a97f8953f51"],["/react-toastr/static/css/main.d315a98d.css","30a54fc3030a9ecf812d869759915e5e"],["/react-toastr/static/js/main.3027f4fc.js","76dd24ea3356e3a6058708870fdc22b8"],["/react-toastr/static/media/background.3ecd8248.jpg","3ecd8248d225ee1d187d0160128854ab"]],cacheName="sw-precache-v3-sw-precache-webpack-plugin-"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,/\.\w{8}\./);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));!t&&"navigate"===e.request.mode&&isPathWhitelisted(["^(?!\\/__).*"],e.request.url)&&(n=new URL("/react-toastr/index.html",self.location).toString(),t=urlsToCacheKeys.has(n)),t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); -------------------------------------------------------------------------------- /docs/static/css/main.d315a98d.css: -------------------------------------------------------------------------------- 1 | h1{font-weight:900;font-size:72px;text-align:center;text-shadow:0 1px 3px #555}h1,h1 small{font-family:Lato,sans-serif}h1 small{font-weight:400;display:block;font-size:24px;color:#fff}.github-button-container{margin:20px 0 0;text-align:center}.btn-container{text-align:center}.btn-container button{outline:0;border:none;color:#fff;font-size:18px;font-weight:700;width:140px;height:35px;line-height:35px;text-align:center;margin:10px 5px;background:#1abc9c;display:inline-block;text-decoration:none;border-radius:5px;-webkit-box-shadow:0 3px 0 0 #17a88c;box-shadow:0 3px 0 0 #17a88c;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.btn-container button:hover{background:#01a383;-webkit-box-shadow:0 3px 0 0 #008f73;box-shadow:0 3px 0 0 #008f73}.fadeInOut-enter{opacity:.01;-webkit-transition:opacity .5s linear;-o-transition:opacity .5s linear;transition:opacity .5s linear}.fadeInOut-enter.fadeInOut-enter-active{opacity:.8}.fadeInOut-leave{opacity:.8;-webkit-transition:opacity .5s linear;-o-transition:opacity .5s linear;transition:opacity .5s linear}.fadeInOut-leave.fadeInOut-leave-active{opacity:.01}.rotate-enter{-webkit-transition:-webkit-transform 1s;transition:-webkit-transform 1s;-o-transition:transform 1s;transition:transform 1s;transition:transform 1s,-webkit-transform 1s}.rotate-enter.rotate-enter-active{-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}.rotate-leave{-webkit-transition:-webkit-transform 1s;transition:-webkit-transform 1s;-o-transition:transform 1s;transition:transform 1s;transition:transform 1s,-webkit-transform 1s}.rotate-leave.rotate-leave-active{-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}.scale-enter{-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7);opacity:.01;-webkit-transition:opacity .5s,-webkit-transform .5s;transition:opacity .5s,-webkit-transform .5s;-o-transition:transform .5s,opacity .5s;transition:transform .5s,opacity .5s;transition:transform .5s,opacity .5s,-webkit-transform .5s}.scale-enter.scale-enter-active,.scale-leave{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:.8}.scale-leave{-webkit-transition:opacity .5s,-webkit-transform .5s;transition:opacity .5s,-webkit-transform .5s;-o-transition:transform .5s,opacity .5s;transition:transform .5s,opacity .5s;transition:transform .5s,opacity .5s,-webkit-transform .5s}.scale-leave.scale-leave-active{opacity:.01;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}body,html{height:100%}body{color:#fff;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}body:before{-webkit-filter:blur(10px);-moz-filter:blur(10px);-ms-filter:blur(10px);-o-filter:blur(10px);filter:blur(10px);background-image:url(/react-toastr/static/media/background.3ecd8248.jpg);background-repeat:no-repeat;background-size:cover;display:block;content:"";z-index:-2;position:absolute;left:0;width:100%;top:0;height:100%} 2 | /*# sourceMappingURL=main.d315a98d.css.map*/ -------------------------------------------------------------------------------- /docs/static/css/main.d315a98d.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["app/App.css","index.css"],"names":[],"mappings":"AAAA,GAEE,gBACA,eACA,kBACA,0BAA4B,CAG9B,YAPE,2BAAgC,CAajC,SAJC,gBACA,cACA,eACA,UAAY,CAGd,yBACE,gBACA,iBAAmB,CAGrB,eACE,iBAAmB,CAGrB,sBACE,UACA,YACA,WACA,eACA,gBACA,YACA,YACA,iBACA,kBACA,gBACA,mBACA,qBACA,qBACA,kBACA,qCACQ,6BACR,oCACA,+BACA,2BAA8B,CAGhC,4BACE,mBACA,qCACQ,4BAAoC,CAG9C,iBACE,YACA,sCACA,iCACA,6BAA+B,CAGjC,wCACE,UAAa,CAGf,iBACE,WACA,sCACA,iCACA,6BAA+B,CAGjC,wCACE,WAAc,CAGhB,cACE,wCACA,gCACA,2BACA,wBACA,4CAA+C,CAGjD,kCACE,gCACI,4BACI,uBAA0B,CAGpC,cACE,wCACA,gCACA,2BACA,wBACA,4CAA+C,CAGjD,kCACE,gCACI,4BACI,uBAA0B,CAIpC,aACE,4BACI,wBACI,oBACR,YACA,qDACA,6CACA,wCACA,qCACA,0DAA8D,CAUhE,6CANE,2BACI,uBACI,mBACR,UAAa,CAad,aATC,qDACA,6CACA,wCACA,qCACA,0DAA8D,CAOhE,gCACE,YACA,4BACI,wBACI,mBAAsB,CC3IhC,UACE,WAAa,CAGf,KACE,WACA,oBACA,aACA,sBACA,mBACA,qBACA,sBAAwB,CAG1B,YACE,0BACA,uBACA,sBACA,qBACA,kBACA,+CACA,4BACA,sBACA,cACA,WACA,WACA,kBACA,OACA,WACA,MACA,WAAa,CACd","file":"static/css/main.d315a98d.css","sourcesContent":["h1 {\n font-family: 'Lato', sans-serif;\n font-weight: 900;\n font-size: 72px;\n text-align: center;\n text-shadow: 0 1px 3px #555;\n}\n\nh1 small {\n font-family: 'Lato', sans-serif;\n font-weight: 400;\n display: block;\n font-size: 24px;\n color: #fff;\n}\n\n.github-button-container {\n margin: 20px 0 0 0;\n text-align: center;\n}\n\n.btn-container {\n text-align: center;\n}\n\n.btn-container button {\n outline: 0;\n border: none;\n color: #fff;\n font-size: 18px;\n font-weight: 700;\n width: 140px;\n height: 35px;\n line-height: 35px;\n text-align: center;\n margin: 10px 5px;\n background: #1abc9c;\n display: inline-block;\n text-decoration: none;\n border-radius: 5px;\n -webkit-box-shadow: 0px 3px 0px 0px #17a88c;\n box-shadow: 0px 3px 0px 0px #17a88c;\n -webkit-transition: all 150ms ease-in;\n -o-transition: all 150ms ease-in;\n transition: all 150ms ease-in;\n}\n\n.btn-container button:hover {\n background: #01A383;\n -webkit-box-shadow: 0px 3px 0px 0px #008F73;\n box-shadow: 0px 3px 0px 0px #008F73;\n}\n\n.fadeInOut-enter {\n opacity: 0.01;\n -webkit-transition: opacity .5s linear;\n -o-transition: opacity .5s linear;\n transition: opacity .5s linear;\n}\n\n.fadeInOut-enter.fadeInOut-enter-active {\n opacity: 0.8;\n}\n\n.fadeInOut-leave {\n opacity: 0.8;\n -webkit-transition: opacity .5s linear;\n -o-transition: opacity .5s linear;\n transition: opacity .5s linear;\n}\n\n.fadeInOut-leave.fadeInOut-leave-active {\n opacity: 0.01;\n}\n\n.rotate-enter {\n -webkit-transition: -webkit-transform 1s;\n transition: -webkit-transform 1s;\n -o-transition: transform 1s;\n transition: transform 1s;\n transition: transform 1s, -webkit-transform 1s;\n}\n\n.rotate-enter.rotate-enter-active {\n -webkit-transform: rotate(360deg);\n -ms-transform: rotate(360deg);\n transform: rotate(360deg);\n}\n\n.rotate-leave {\n -webkit-transition: -webkit-transform 1s;\n transition: -webkit-transform 1s;\n -o-transition: transform 1s;\n transition: transform 1s;\n transition: transform 1s, -webkit-transform 1s;\n}\n\n.rotate-leave.rotate-leave-active {\n -webkit-transform: rotate(360deg);\n -ms-transform: rotate(360deg);\n transform: rotate(360deg);\n}\n\n\n.scale-enter {\n -webkit-transform: scale(0.7);\n -ms-transform: scale(0.7);\n transform: scale(0.7);\n opacity: 0.01;\n -webkit-transition: opacity .5s, -webkit-transform .5s;\n transition: opacity .5s, -webkit-transform .5s;\n -o-transition: transform .5s, opacity .5s;\n transition: transform .5s, opacity .5s;\n transition: transform .5s, opacity .5s, -webkit-transform .5s;\n}\n\n.scale-enter.scale-enter-active {\n -webkit-transform: scale(1);\n -ms-transform: scale(1);\n transform: scale(1);\n opacity: 0.8;\n}\n\n.scale-leave {\n -webkit-transition: opacity .5s, -webkit-transform .5s;\n transition: opacity .5s, -webkit-transform .5s;\n -o-transition: transform .5s, opacity .5s;\n transition: transform .5s, opacity .5s;\n transition: transform .5s, opacity .5s, -webkit-transform .5s;\n -webkit-transform: scale(1);\n -ms-transform: scale(1);\n transform: scale(1);\n opacity: 0.8;\n}\n\n.scale-leave.scale-leave-active {\n opacity: 0.01;\n -webkit-transform: scale(0.7);\n -ms-transform: scale(0.7);\n transform: scale(0.7);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/App.css","body, html {\n height: 100%;\n}\n\nbody {\n color: #fff;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\nbody:before {\n -webkit-filter: blur(10px);\n -moz-filter: blur(10px);\n -ms-filter: blur(10px);\n -o-filter: blur(10px);\n filter: blur(10px);\n background-image: url(\"./app/background.jpg\");\n background-repeat: no-repeat;\n background-size: cover;\n display: block;\n content: '';\n z-index: -2;\n position: absolute;\n left: 0;\n width: 100%;\n top: 0;\n height: 100%;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.css"],"sourceRoot":""} -------------------------------------------------------------------------------- /docs/static/media/background.3ecd8248.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomchentw/react-toastr/fcd3b4b7e6031dde7c128921489bffaad85729a9/docs/static/media/background.3ecd8248.jpg -------------------------------------------------------------------------------- /docs/static/media/demo.3ecd8248.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomchentw/react-toastr/fcd3b4b7e6031dde7c128921489bffaad85729a9/docs/static/media/demo.3ecd8248.jpg -------------------------------------------------------------------------------- /lib/__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | var _index = require("../index") 4 | 5 | describe("index module", function() { 6 | it("should be exported as ES2015 module", function() { 7 | expect(_index.ToastContainer).toBeDefined() 8 | expect(_index.ToastMessage).toBeDefined() 9 | expect(_index.ToastMessageAnimated).toBeDefined() 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /lib/components/ToastContainer.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true, 5 | }) 6 | exports.ToastContainer = undefined 7 | 8 | var _toConsumableArray2 = require("babel-runtime/helpers/toConsumableArray") 9 | 10 | var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2) 11 | 12 | var _extends2 = require("babel-runtime/helpers/extends") 13 | 14 | var _extends3 = _interopRequireDefault(_extends2) 15 | 16 | var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of") 17 | 18 | var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf) 19 | 20 | var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck") 21 | 22 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2) 23 | 24 | var _createClass2 = require("babel-runtime/helpers/createClass") 25 | 26 | var _createClass3 = _interopRequireDefault(_createClass2) 27 | 28 | var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn") 29 | 30 | var _possibleConstructorReturn3 = _interopRequireDefault( 31 | _possibleConstructorReturn2 32 | ) 33 | 34 | var _inherits2 = require("babel-runtime/helpers/inherits") 35 | 36 | var _inherits3 = _interopRequireDefault(_inherits2) 37 | 38 | var _keys2 = require("lodash/keys") 39 | 40 | var _keys3 = _interopRequireDefault(_keys2) 41 | 42 | var _omit2 = require("lodash/omit") 43 | 44 | var _omit3 = _interopRequireDefault(_omit2) 45 | 46 | var _reject2 = require("lodash/reject") 47 | 48 | var _reject3 = _interopRequireDefault(_reject2) 49 | 50 | var _bind2 = require("lodash/bind") 51 | 52 | var _bind3 = _interopRequireDefault(_bind2) 53 | 54 | var _isFunction2 = require("lodash/isFunction") 55 | 56 | var _isFunction3 = _interopRequireDefault(_isFunction2) 57 | 58 | var _uniqueId2 = require("lodash/uniqueId") 59 | 60 | var _uniqueId3 = _interopRequireDefault(_uniqueId2) 61 | 62 | var _includes2 = require("lodash/includes") 63 | 64 | var _includes3 = _interopRequireDefault(_includes2) 65 | 66 | var _isObject2 = require("lodash/isObject") 67 | 68 | var _isObject3 = _interopRequireDefault(_isObject2) 69 | 70 | var _forEach2 = require("lodash/forEach") 71 | 72 | var _forEach3 = _interopRequireDefault(_forEach2) 73 | 74 | var _noop2 = require("lodash/noop") 75 | 76 | var _noop3 = _interopRequireDefault(_noop2) 77 | 78 | var _react = require("react") 79 | 80 | var _react2 = _interopRequireDefault(_react) 81 | 82 | var _ToastMessageAnimated = require("./ToastMessage/ToastMessageAnimated") 83 | 84 | var _ToastMessageAnimated2 = _interopRequireDefault(_ToastMessageAnimated) 85 | 86 | function _interopRequireDefault(obj) { 87 | return obj && obj.__esModule ? obj : { default: obj } 88 | } 89 | 90 | /** 91 | * A React container for displaying a list of toast messages. 92 | * It mimics the APIs with the vanilla [toastr.js](https://github.com/CodeSeven/toastr) 93 | * by retaining a [ref][react-ref] to publish a new **toast**. 94 | * 95 | * To display HTML, simply pass JSX instead of strings for title and message. 96 | * 97 | * ```javascript 98 | * this.container.success( 99 | * I am a strong title, 100 | * I am an emphasized message 101 | * }); 102 | * ``` 103 | * 104 | * If you're using Redux for managing states, you might consider using the 105 | * underlying component directly. See [ToastMessageAnimated](#toastmessage) below 106 | */ 107 | var ToastContainer = (exports.ToastContainer = (function(_React$PureComponent) { 108 | ;(0, _inherits3.default)(ToastContainer, _React$PureComponent) 109 | 110 | function ToastContainer() { 111 | var _ref 112 | 113 | var _temp, _this, _ret 114 | 115 | ;(0, _classCallCheck3.default)(this, ToastContainer) 116 | 117 | for ( 118 | var _len = arguments.length, args = Array(_len), _key = 0; 119 | _key < _len; 120 | _key++ 121 | ) { 122 | args[_key] = arguments[_key] 123 | } 124 | 125 | return ( 126 | (_ret = ((_temp = ((_this = (0, _possibleConstructorReturn3.default)( 127 | this, 128 | (_ref = 129 | ToastContainer.__proto__ || 130 | (0, _getPrototypeOf2.default)(ToastContainer)).call.apply( 131 | _ref, 132 | [this].concat(args) 133 | ) 134 | )), 135 | _this)), 136 | (_this.state = { 137 | toastList: [], 138 | }), 139 | (_this.toastMessageRefs = {}), 140 | (_this.handleOnToastClick = function(event) { 141 | _this.props.onClick(event) 142 | if (event.defaultPrevented) { 143 | return 144 | } 145 | event.preventDefault() 146 | event.stopPropagation() 147 | }), 148 | (_this.handleOnToastRemove = function(key) { 149 | _this.setState(function(state) { 150 | return { 151 | toastList: (0, _reject3.default)(state.toastList, { key: key }), 152 | } 153 | }) 154 | }), 155 | _temp)), 156 | (0, _possibleConstructorReturn3.default)(_this, _ret) 157 | ) 158 | } 159 | 160 | ;(0, _createClass3.default)(ToastContainer, [ 161 | { 162 | key: "error", 163 | 164 | /** 165 | * 166 | * @param {any} message 167 | * @param {any} title 168 | * @param {any} optionsOverride 169 | * @public 170 | */ 171 | value: function error(message, title, optionsOverride) { 172 | this.handleNotify( 173 | this.props.toastType.error, 174 | message, 175 | title, 176 | optionsOverride 177 | ) 178 | }, 179 | 180 | /** 181 | * 182 | * @param {any} message 183 | * @param {any} title 184 | * @param {any} optionsOverride 185 | * @public 186 | */ 187 | }, 188 | { 189 | key: "info", 190 | value: function info(message, title, optionsOverride) { 191 | this.handleNotify( 192 | this.props.toastType.info, 193 | message, 194 | title, 195 | optionsOverride 196 | ) 197 | }, 198 | 199 | /** 200 | * 201 | * @param {any} message 202 | * @param {any} title 203 | * @param {any} optionsOverride 204 | * @public 205 | */ 206 | }, 207 | { 208 | key: "success", 209 | value: function success(message, title, optionsOverride) { 210 | this.handleNotify( 211 | this.props.toastType.success, 212 | message, 213 | title, 214 | optionsOverride 215 | ) 216 | }, 217 | 218 | /** 219 | * 220 | * @param {any} message 221 | * @param {any} title 222 | * @param {any} optionsOverride 223 | * @public 224 | */ 225 | }, 226 | { 227 | key: "warning", 228 | value: function warning(message, title, optionsOverride) { 229 | this.handleNotify( 230 | this.props.toastType.warning, 231 | message, 232 | title, 233 | optionsOverride 234 | ) 235 | }, 236 | 237 | /** 238 | * 239 | * @public 240 | */ 241 | }, 242 | { 243 | key: "clear", 244 | value: function clear() { 245 | ;(0, _forEach3.default)(this.toastMessageRefs, function(ref) { 246 | if ((0, _isObject3.default)(ref)) { 247 | ref.handleHide() 248 | } 249 | }) 250 | }, 251 | }, 252 | { 253 | key: "handleNotify", 254 | value: function handleNotify(type, message, title) { 255 | var _this2 = this 256 | 257 | var optionsOverride = 258 | arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {} 259 | 260 | if ( 261 | this.props.preventDuplicates && 262 | (0, _includes3.default)(this.state.toastList, { message: message }) 263 | ) { 264 | return 265 | } 266 | var key = (0, _uniqueId3.default)("toast_") 267 | var nextToast = (0, _extends3.default)({}, optionsOverride, { 268 | key: key, 269 | type: type, 270 | title: title, 271 | message: message, 272 | ref: function ref(_ref2) { 273 | _this2.toastMessageRefs[key] = _ref2 274 | }, 275 | onClick: function onClick(event) { 276 | if ((0, _isFunction3.default)(optionsOverride.handleOnClick)) { 277 | optionsOverride.handleOnClick() 278 | } 279 | _this2.handleOnToastClick(event) 280 | }, 281 | onRemove: (0, _bind3.default)(this.handleOnToastRemove, this, key), 282 | }) 283 | this.setState(function(state) { 284 | return { 285 | toastList: _this2.props.newestOnTop 286 | ? [nextToast].concat( 287 | (0, _toConsumableArray3.default)(state.toastList) 288 | ) 289 | : [].concat((0, _toConsumableArray3.default)(state.toastList), [ 290 | nextToast, 291 | ]), 292 | } 293 | }) 294 | }, 295 | }, 296 | { 297 | key: "render", 298 | value: function render() { 299 | var _this3 = this 300 | 301 | var restProps = (0, _omit3.default)( 302 | this.props, 303 | (0, _keys3.default)(ToastContainer.defaultProps) 304 | ) 305 | return _react2.default.createElement( 306 | "div", 307 | (0, _extends3.default)({}, restProps, { 308 | id: this.props.id, 309 | "aria-live": "polite", 310 | role: "alert", 311 | }), 312 | this.state.toastList.map(function(it) { 313 | return _this3.props.toastMessageFactory(it) 314 | }) 315 | ) 316 | }, 317 | }, 318 | ]) 319 | return ToastContainer 320 | })(_react2.default.PureComponent)) 321 | 322 | ToastContainer.defaultProps = { 323 | toastType: { 324 | error: "error", 325 | info: "info", 326 | success: "success", 327 | warning: "warning", 328 | }, 329 | id: "toast-container", 330 | toastMessageFactory: _react2.default.createFactory( 331 | _ToastMessageAnimated2.default 332 | ), 333 | preventDuplicates: true, 334 | newestOnTop: true, 335 | onClick: _noop3.default, 336 | } 337 | exports.default = ToastContainer 338 | -------------------------------------------------------------------------------- /lib/components/ToastMessage/ToastMessage.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true, 5 | }) 6 | exports.ToastMessage = undefined 7 | 8 | var _extends2 = require("babel-runtime/helpers/extends") 9 | 10 | var _extends3 = _interopRequireDefault(_extends2) 11 | 12 | var _objectWithoutProperties2 = require("babel-runtime/helpers/objectWithoutProperties") 13 | 14 | var _objectWithoutProperties3 = _interopRequireDefault( 15 | _objectWithoutProperties2 16 | ) 17 | 18 | var _noop2 = require("lodash/noop") 19 | 20 | var _noop3 = _interopRequireDefault(_noop2) 21 | 22 | var _classnames = require("classnames") 23 | 24 | var _classnames2 = _interopRequireDefault(_classnames) 25 | 26 | var _react = require("react") 27 | 28 | var _react2 = _interopRequireDefault(_react) 29 | 30 | function _interopRequireDefault(obj) { 31 | return obj && obj.__esModule ? obj : { default: obj } 32 | } 33 | 34 | var defaultIconClassNames = { 35 | error: "toast-error", 36 | info: "toast-info", 37 | success: "toast-success", 38 | warning: "toast-warning", 39 | } 40 | 41 | /** 42 | * Base component for displaying a toast message. 43 | */ 44 | var ToastMessage = function ToastMessage(_ref) { 45 | var _ref$className = _ref.className, 46 | className = _ref$className === undefined ? "toast" : _ref$className, 47 | type = _ref.type, 48 | _ref$iconClassNames = _ref.iconClassNames, 49 | iconClassNames = 50 | _ref$iconClassNames === undefined 51 | ? defaultIconClassNames 52 | : _ref$iconClassNames, 53 | _ref$iconClassName = _ref.iconClassName, 54 | iconClassName = 55 | _ref$iconClassName === undefined 56 | ? iconClassNames[type] 57 | : _ref$iconClassName, 58 | _ref$closeButton = _ref.closeButton, 59 | closeButton = _ref$closeButton === undefined ? false : _ref$closeButton, 60 | _ref$onCloseClick = _ref.onCloseClick, 61 | onCloseClick = 62 | _ref$onCloseClick === undefined ? _noop3.default : _ref$onCloseClick, 63 | _ref$title = _ref.title, 64 | title = _ref$title === undefined ? false : _ref$title, 65 | _ref$titleClassName = _ref.titleClassName, 66 | titleClassName = 67 | _ref$titleClassName === undefined ? "toast-title" : _ref$titleClassName, 68 | _ref$message = _ref.message, 69 | message = _ref$message === undefined ? false : _ref$message, 70 | _ref$messageClassName = _ref.messageClassName, 71 | messageClassName = 72 | _ref$messageClassName === undefined 73 | ? "toast-message" 74 | : _ref$messageClassName, 75 | restProps = (0, _objectWithoutProperties3.default)(_ref, [ 76 | "className", 77 | "type", 78 | "iconClassNames", 79 | "iconClassName", 80 | "closeButton", 81 | "onCloseClick", 82 | "title", 83 | "titleClassName", 84 | "message", 85 | "messageClassName", 86 | ]) 87 | return _react2.default.createElement( 88 | "div", 89 | (0, _extends3.default)({}, restProps, { 90 | className: (0, _classnames2.default)(className, iconClassName), 91 | }), 92 | !!closeButton && 93 | _react2.default.createElement("button", { 94 | className: "toast-close-button", 95 | onClick: onCloseClick, 96 | dangerouslySetInnerHTML: { __html: "×" }, 97 | }), 98 | !!title && 99 | _react2.default.createElement( 100 | "div", 101 | { className: titleClassName }, 102 | title 103 | ), 104 | !!message && 105 | _react2.default.createElement( 106 | "div", 107 | { className: messageClassName }, 108 | message 109 | ) 110 | ) 111 | } 112 | 113 | exports.ToastMessage = ToastMessage 114 | exports.default = ToastMessage 115 | -------------------------------------------------------------------------------- /lib/components/ToastMessage/ToastMessageAnimated.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true, 5 | }) 6 | exports.ToastMessageAnimated = undefined 7 | 8 | var _extends2 = require("babel-runtime/helpers/extends") 9 | 10 | var _extends3 = _interopRequireDefault(_extends2) 11 | 12 | var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of") 13 | 14 | var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf) 15 | 16 | var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck") 17 | 18 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2) 19 | 20 | var _createClass2 = require("babel-runtime/helpers/createClass") 21 | 22 | var _createClass3 = _interopRequireDefault(_createClass2) 23 | 24 | var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn") 25 | 26 | var _possibleConstructorReturn3 = _interopRequireDefault( 27 | _possibleConstructorReturn2 28 | ) 29 | 30 | var _inherits2 = require("babel-runtime/helpers/inherits") 31 | 32 | var _inherits3 = _interopRequireDefault(_inherits2) 33 | 34 | var _keys2 = require("lodash/keys") 35 | 36 | var _keys3 = _interopRequireDefault(_keys2) 37 | 38 | var _omit2 = require("lodash/omit") 39 | 40 | var _omit3 = _interopRequireDefault(_omit2) 41 | 42 | var _isNil2 = require("lodash/isNil") 43 | 44 | var _isNil3 = _interopRequireDefault(_isNil2) 45 | 46 | var _flowRight2 = require("lodash/flowRight") 47 | 48 | var _flowRight3 = _interopRequireDefault(_flowRight2) 49 | 50 | var _isUndefined2 = require("lodash/isUndefined") 51 | 52 | var _isUndefined3 = _interopRequireDefault(_isUndefined2) 53 | 54 | var _noop2 = require("lodash/noop") 55 | 56 | var _noop3 = _interopRequireDefault(_noop2) 57 | 58 | var _classnames = require("classnames") 59 | 60 | var _classnames2 = _interopRequireDefault(_classnames) 61 | 62 | var _react = require("react") 63 | 64 | var _react2 = _interopRequireDefault(_react) 65 | 66 | var _on = require("dom-helpers/events/on") 67 | 68 | var _on2 = _interopRequireDefault(_on) 69 | 70 | var _properties = require("dom-helpers/transition/properties") 71 | 72 | var _ToastMessage = require("./ToastMessage") 73 | 74 | function _interopRequireDefault(obj) { 75 | return obj && obj.__esModule ? obj : { default: obj } 76 | } 77 | 78 | /** 79 | * A decorated component that leverages animate.css for toast showing/hiding. 80 | * 81 | * @see https://daneden.github.io/animate.css/ 82 | */ 83 | var ToastMessageAnimated = (exports.ToastMessageAnimated = (function( 84 | _React$PureComponent 85 | ) { 86 | ;(0, _inherits3.default)(ToastMessageAnimated, _React$PureComponent) 87 | 88 | function ToastMessageAnimated() { 89 | var _ref 90 | 91 | var _temp, _this, _ret 92 | 93 | ;(0, _classCallCheck3.default)(this, ToastMessageAnimated) 94 | 95 | for ( 96 | var _len = arguments.length, args = Array(_len), _key = 0; 97 | _key < _len; 98 | _key++ 99 | ) { 100 | args[_key] = arguments[_key] 101 | } 102 | 103 | return ( 104 | (_ret = ((_temp = ((_this = (0, _possibleConstructorReturn3.default)( 105 | this, 106 | (_ref = 107 | ToastMessageAnimated.__proto__ || 108 | (0, _getPrototypeOf2.default)(ToastMessageAnimated)).call.apply( 109 | _ref, 110 | [this].concat(args) 111 | ) 112 | )), 113 | _this)), 114 | (_this.state = { 115 | hidingTimoutId: undefined, 116 | className: undefined, 117 | }), 118 | (_this.handleMount = function(ref) { 119 | _this.message = ref 120 | }), 121 | (_this.handleMouseEnter = function() { 122 | _this.setState(function(state) { 123 | if (!(0, _isUndefined3.default)(state.hidingTimoutId)) { 124 | clearTimeout(state.hidingTimoutId) 125 | } 126 | return { 127 | hidingTimoutId: undefined, 128 | className: undefined, 129 | } 130 | }) 131 | }), 132 | (_this.handleMouseLeave = function() { 133 | _this.setState(function(state) { 134 | var timeOut = 135 | _this.props.extendedTimeOut !== 0 136 | ? _this.props.extendedTimeOut 137 | : _this.props.timeOut 138 | if ( 139 | (0, _isUndefined3.default)(state.hidingTimoutId) && 140 | timeOut !== 0 141 | ) { 142 | return { 143 | hidingTimoutId: setTimeout(_this.handleHide, timeOut), 144 | } 145 | } 146 | return {} 147 | }) 148 | }), 149 | (_this.handleTransitionEnd = function() { 150 | _this.setState(function() { 151 | return { 152 | className: undefined, 153 | } 154 | }) 155 | }), 156 | (_this.handleHideHookOnEnd = function() { 157 | ;(0, _on2.default)( 158 | _this.message, 159 | _properties.animationEnd, 160 | (0, _flowRight3.default)( 161 | _this.handleRemove, 162 | _this.handleTransitionEnd 163 | ) 164 | ) 165 | }), 166 | (_this.handleHide = function() { 167 | var override = 168 | arguments.length > 0 && arguments[0] !== undefined 169 | ? arguments[0] 170 | : false 171 | 172 | _this.setState(function(state) { 173 | if (override || !(0, _isUndefined3.default)(state.hidingTimoutId)) { 174 | if (!(0, _isNil3.default)(_this.props.hideAnimation)) { 175 | return { 176 | hidingTimoutId: setTimeout(_this.handleHideHookOnEnd, 50), 177 | className: _this.props.hideAnimation, 178 | } 179 | } else { 180 | _this.handleRemove() 181 | return { 182 | hidingTimoutId: undefined, 183 | className: undefined, 184 | } 185 | } 186 | } 187 | }) 188 | }), 189 | (_this.handleRemove = function() { 190 | _this.props.onRemove() 191 | }), 192 | (_this.handleOnClick = function(event) { 193 | _this.props.onClick(event) 194 | if (_this.props.tapToDismiss) { 195 | _this.handleHide(true) 196 | } 197 | }), 198 | (_this.handleOnCloseClick = function(event) { 199 | event.stopPropagation() 200 | _this.props.onCloseClick(event) 201 | _this.handleHide(true) 202 | }), 203 | _temp)), 204 | (0, _possibleConstructorReturn3.default)(_this, _ret) 205 | ) 206 | } 207 | 208 | ;(0, _createClass3.default)(ToastMessageAnimated, [ 209 | { 210 | key: "componentDidMount", 211 | value: function componentDidMount() { 212 | var _this2 = this 213 | 214 | if (!(0, _isUndefined3.default)(this.props.showAnimation)) { 215 | this.setState(function() { 216 | ;(0, 217 | _on2.default)(_this2.message, _properties.animationEnd, _this2.handleTransitionEnd) 218 | return { 219 | className: _this2.props.showAnimation, 220 | } 221 | }) 222 | } 223 | if (this.props.timeOut > 0) { 224 | this.setState(function() { 225 | return { 226 | hidingTimoutId: setTimeout( 227 | _this2.handleHide, 228 | _this2.props.timeOut 229 | ), 230 | } 231 | }) 232 | } 233 | }, 234 | }, 235 | { 236 | key: "componentWillUnmount", 237 | value: function componentWillUnmount() { 238 | if (!(0, _isUndefined3.default)(this.state.hidingTimoutId)) { 239 | clearTimeout(this.state.hidingTimoutId) 240 | } 241 | this.setState = _noop3.default 242 | }, 243 | }, 244 | { 245 | key: "render", 246 | value: function render() { 247 | var restProps = (0, _omit3.default)( 248 | this.props, 249 | (0, _keys3.default)(ToastMessageAnimated.defaultProps) 250 | ) 251 | return (0, _ToastMessage.ToastMessage)( 252 | (0, _extends3.default)({}, restProps, { 253 | ref: this.handleMount, 254 | className: (0, _classnames2.default)( 255 | this.props.className, 256 | this.state.className 257 | ), 258 | onClick: this.handleOnClick, 259 | onMouseEnter: this.handleMouseEnter, 260 | onMouseLeave: this.handleMouseLeave, 261 | onCloseClick: this.handleOnCloseClick, 262 | }) 263 | ) 264 | }, 265 | }, 266 | ]) 267 | return ToastMessageAnimated 268 | })(_react2.default.PureComponent)) 269 | 270 | ToastMessageAnimated.defaultProps = { 271 | className: "toast", 272 | showAnimation: "animated bounceIn", 273 | hideAnimation: "animated bounceOut", 274 | // 275 | timeOut: 5000, 276 | extendedTimeOut: 1000, 277 | // 278 | tapToDismiss: true, 279 | // 280 | onRemove: undefined, 281 | onClick: _noop3.default, 282 | onCloseClick: _noop3.default, 283 | } 284 | exports.default = ToastMessageAnimated 285 | -------------------------------------------------------------------------------- /lib/components/ToastMessage/ToastMessagejQuery.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true, 5 | }) 6 | exports.ToastMessagejQuery = undefined 7 | 8 | var _extends2 = require("babel-runtime/helpers/extends") 9 | 10 | var _extends3 = _interopRequireDefault(_extends2) 11 | 12 | var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of") 13 | 14 | var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf) 15 | 16 | var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck") 17 | 18 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2) 19 | 20 | var _createClass2 = require("babel-runtime/helpers/createClass") 21 | 22 | var _createClass3 = _interopRequireDefault(_createClass2) 23 | 24 | var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn") 25 | 26 | var _possibleConstructorReturn3 = _interopRequireDefault( 27 | _possibleConstructorReturn2 28 | ) 29 | 30 | var _inherits2 = require("babel-runtime/helpers/inherits") 31 | 32 | var _inherits3 = _interopRequireDefault(_inherits2) 33 | 34 | var _keys2 = require("lodash/keys") 35 | 36 | var _keys3 = _interopRequireDefault(_keys2) 37 | 38 | var _omit2 = require("lodash/omit") 39 | 40 | var _omit3 = _interopRequireDefault(_omit2) 41 | 42 | var _isUndefined2 = require("lodash/isUndefined") 43 | 44 | var _isUndefined3 = _interopRequireDefault(_isUndefined2) 45 | 46 | var _noop2 = require("lodash/noop") 47 | 48 | var _noop3 = _interopRequireDefault(_noop2) 49 | 50 | var _react = require("react") 51 | 52 | var _react2 = _interopRequireDefault(_react) 53 | 54 | var _reactDom = require("react-dom") 55 | 56 | var _reactDom2 = _interopRequireDefault(_reactDom) 57 | 58 | var _ToastMessage = require("./ToastMessage") 59 | 60 | var _ToastMessage2 = _interopRequireDefault(_ToastMessage) 61 | 62 | function _interopRequireDefault(obj) { 63 | return obj && obj.__esModule ? obj : { default: obj } 64 | } 65 | 66 | var jQuery = void 0 67 | 68 | /** 69 | * A standalone decorated component that leverages jQuery for toast showing/hiding. 70 | * 71 | * @see https://jquery.com/ 72 | */ 73 | 74 | var ToastMessagejQuery = (exports.ToastMessagejQuery = (function( 75 | _React$PureComponent 76 | ) { 77 | ;(0, _inherits3.default)(ToastMessagejQuery, _React$PureComponent) 78 | 79 | function ToastMessagejQuery() { 80 | var _ref 81 | 82 | var _temp, _this, _ret 83 | 84 | ;(0, _classCallCheck3.default)(this, ToastMessagejQuery) 85 | 86 | for ( 87 | var _len = arguments.length, args = Array(_len), _key = 0; 88 | _key < _len; 89 | _key++ 90 | ) { 91 | args[_key] = arguments[_key] 92 | } 93 | 94 | return ( 95 | (_ret = ((_temp = ((_this = (0, _possibleConstructorReturn3.default)( 96 | this, 97 | (_ref = 98 | ToastMessagejQuery.__proto__ || 99 | (0, _getPrototypeOf2.default)(ToastMessagejQuery)).call.apply( 100 | _ref, 101 | [this].concat(args) 102 | ) 103 | )), 104 | _this)), 105 | (_this.state = { 106 | hidingTimoutId: undefined, 107 | }), 108 | (_this.handleMouseEnter = function() { 109 | _this.setState(function(state) { 110 | if (!(0, _isUndefined3.default)(state.hidingTimoutId)) { 111 | clearTimeout(state.hidingTimoutId) 112 | } 113 | var $node = jQuery(_reactDom2.default.findDOMNode(_this)) 114 | $node.stop(true, true) 115 | $node[_this.props.showMethod]() 116 | return { 117 | hidingTimoutId: undefined, 118 | } 119 | }) 120 | }), 121 | (_this.handleMouseLeave = function() { 122 | _this.setState(function(state) { 123 | var timeOut = 124 | _this.props.extendedTimeOut !== 0 125 | ? _this.props.extendedTimeOut 126 | : _this.props.timeOut 127 | if ( 128 | (0, _isUndefined3.default)(state.hidingTimoutId) && 129 | timeOut !== 0 130 | ) { 131 | return { 132 | hidingTimoutId: setTimeout(_this.handleHide, timeOut), 133 | } 134 | } 135 | return {} 136 | }) 137 | }), 138 | (_this.handleHide = function() { 139 | var override = 140 | arguments.length > 0 && arguments[0] !== undefined 141 | ? arguments[0] 142 | : false 143 | 144 | _this.setState(function(state) { 145 | if (override || !(0, _isUndefined3.default)(state.hidingTimoutId)) { 146 | var $node = jQuery(_reactDom2.default.findDOMNode(_this)) 147 | $node[_this.props.hideMethod]({ 148 | duration: _this.props.hideDuration, 149 | easing: _this.props.hideEasing, 150 | complete: _this.handleRemove, 151 | }) 152 | return { 153 | hidingTimoutId: undefined, 154 | } 155 | } 156 | }) 157 | }), 158 | (_this.handleRemove = function() { 159 | _this.props.onRemove() 160 | }), 161 | (_this.handleOnClick = function(event) { 162 | _this.props.onClick(event) 163 | if (_this.props.tapToDismiss) { 164 | _this.handleHide(true) 165 | } 166 | }), 167 | (_this.handleOnCloseClick = function(event) { 168 | event.stopPropagation() 169 | _this.props.onCloseClick(event) 170 | _this.handleHide(true) 171 | }), 172 | _temp)), 173 | (0, _possibleConstructorReturn3.default)(_this, _ret) 174 | ) 175 | } 176 | 177 | ;(0, _createClass3.default)(ToastMessagejQuery, [ 178 | { 179 | key: "componentDidMount", 180 | value: function componentDidMount() { 181 | var _this2 = this 182 | 183 | jQuery = require("jquery") 184 | var $node = jQuery(_reactDom2.default.findDOMNode(this)) 185 | $node[this.props.showMethod]() 186 | if (this.props.timeOut > 0) { 187 | this.setState(function() { 188 | return { 189 | hidingTimoutId: setTimeout( 190 | _this2.handleHide, 191 | _this2.props.timeOut 192 | ), 193 | } 194 | }) 195 | } 196 | }, 197 | }, 198 | { 199 | key: "componentWillUnmount", 200 | value: function componentWillUnmount() { 201 | if (!(0, _isUndefined3.default)(this.state.hidingTimoutId)) { 202 | clearTimeout(this.state.hidingTimoutId) 203 | } 204 | this.setState = _noop3.default 205 | }, 206 | }, 207 | { 208 | key: "render", 209 | value: function render() { 210 | var restProps = (0, _omit3.default)( 211 | this.props, 212 | (0, _keys3.default)(ToastMessagejQuery.defaultProps) 213 | ) 214 | return _react2.default.createElement( 215 | _ToastMessage2.default, 216 | (0, _extends3.default)({}, restProps, { 217 | onClick: this.handleOnClick, 218 | onMouseEnter: this.handleMouseEnter, 219 | onMouseLeave: this.handleMouseLeave, 220 | onCloseClick: this.handleOnCloseClick, 221 | }) 222 | ) 223 | }, 224 | }, 225 | ]) 226 | return ToastMessagejQuery 227 | })(_react2.default.PureComponent)) 228 | 229 | ToastMessagejQuery.defaultProps = { 230 | style: { 231 | display: "none", 232 | }, 233 | showMethod: "fadeIn", 234 | showDuration: 300, 235 | showEasing: "swing", 236 | hideMethod: "fadeOut", 237 | hideDuration: 1000, 238 | hideEasing: "swing", 239 | // 240 | timeOut: 5000, 241 | extendedTimeOut: 1000, 242 | // 243 | tapToDismiss: true, 244 | // 245 | onRemove: undefined, 246 | onClick: _noop3.default, 247 | onCloseClick: _noop3.default, 248 | } 249 | exports.default = ToastMessagejQuery 250 | -------------------------------------------------------------------------------- /lib/components/__tests__/ToastContainer.test.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | var _react = require("react") 4 | 5 | var _react2 = _interopRequireDefault(_react) 6 | 7 | var _reactDom = require("react-dom") 8 | 9 | var _reactDom2 = _interopRequireDefault(_reactDom) 10 | 11 | var _reactTestRenderer = require("react-test-renderer") 12 | 13 | var _reactTestRenderer2 = _interopRequireDefault(_reactTestRenderer) 14 | 15 | function _interopRequireDefault(obj) { 16 | return obj && obj.__esModule ? obj : { default: obj } 17 | } 18 | 19 | describe("ToastContainer module", function() { 20 | var _require = require("../ToastContainer"), 21 | ToastContainer = _require.ToastContainer 22 | 23 | describe("renders a toast message", function() { 24 | it("exists in the container", function() { 25 | var renderer = _reactTestRenderer2.default.create( 26 | _react2.default.createElement(ToastContainer, null) 27 | ) 28 | expect(renderer).toMatchSnapshot() 29 | 30 | renderer.getInstance().success("yeah,", "cool") 31 | expect(renderer).toMatchSnapshot() 32 | }) 33 | 34 | it("should be closed by clicking on it", function(done) { 35 | var renderer = _reactTestRenderer2.default.create( 36 | _react2.default.createElement(ToastContainer, null) 37 | ) 38 | renderer.getInstance().success("yeah,", "cool", { hideAnimation: null }) 39 | expect(renderer).toMatchSnapshot() 40 | 41 | renderer.toJSON().children[0].props.onClick({ defaultPrevented: true }) 42 | 43 | setTimeout(function() { 44 | expect(renderer).toMatchSnapshot() 45 | done() 46 | }, 100) 47 | }) 48 | }) 49 | 50 | describe("when component function is triggered multiple times", function() { 51 | it("renders a list of toast messages", function() { 52 | var renderer = _reactTestRenderer2.default.create( 53 | _react2.default.createElement(ToastContainer, null) 54 | ) 55 | renderer.getInstance().success("yeah", "cool") 56 | renderer.getInstance().error("blabla", "foobar") 57 | 58 | expect(renderer).toMatchSnapshot() 59 | }) 60 | }) 61 | }) 62 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true, 5 | }) 6 | 7 | var _ToastContainer = require("./components/ToastContainer") 8 | 9 | Object.defineProperty(exports, "ToastContainer", { 10 | enumerable: true, 11 | get: function get() { 12 | return _ToastContainer.ToastContainer 13 | }, 14 | }) 15 | 16 | var _ToastMessage = require("./components/ToastMessage/ToastMessage") 17 | 18 | Object.defineProperty(exports, "ToastMessage", { 19 | enumerable: true, 20 | get: function get() { 21 | return _ToastMessage.ToastMessage 22 | }, 23 | }) 24 | 25 | var _ToastMessageAnimated = require("./components/ToastMessage/ToastMessageAnimated") 26 | 27 | Object.defineProperty(exports, "ToastMessageAnimated", { 28 | enumerable: true, 29 | get: function get() { 30 | return _ToastMessageAnimated.ToastMessageAnimated 31 | }, 32 | }) 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-toastr", 3 | "version": "3.0.0", 4 | "description": "React.js toastr component", 5 | "license": "MIT", 6 | "author": { 7 | "name": "tomchentw", 8 | "email": "developer@tomchentw.com", 9 | "url": "https://github.com/tomchentw" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/tomchentw/react-toastr" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/tomchentw/react-toastr/issues" 17 | }, 18 | "homepage": "https://tomchentw.github.io/react-toastr/", 19 | "main": "lib/index.js", 20 | "files": ["lib/", "src/", "CHANGELOG.md"], 21 | "keywords": [ 22 | "React.js", 23 | "React", 24 | "react-component", 25 | "toastr", 26 | "alert", 27 | "toast", 28 | "message", 29 | "popup", 30 | "jQuery" 31 | ], 32 | "scripts": { 33 | "precommit": "lint-staged", 34 | "styleguide": "styleguidist server", 35 | "styleguide:build": "styleguidist build", 36 | "test": "react-scripts test", 37 | "test:once": "cross-env CI=true npm test", 38 | "prebuild:lib": "rimraf lib", 39 | "build:lib": "cross-env NODE_ENV=production babel src --out-dir lib", 40 | "precommit:lib": "npm run build:lib", 41 | "commit:lib": 42 | "git add -A && git commit -m 'chore(lib): compile from src with `babel`'", 43 | "precommit:docs": "npm run styleguide:build", 44 | "commit:docs": 45 | "git add -A && git commit -m 'docs: compile from src with `styleguidist`'", 46 | "prerelease": "npm run commit:lib && npm run commit:docs", 47 | "release": "standard-version" 48 | }, 49 | "lint-staged": { 50 | "*.{js,jsx,json,css}": ["prettier --write", "git add"] 51 | }, 52 | "babel": { 53 | "plugins": [ 54 | "lodash", 55 | "transform-class-properties", 56 | "transform-object-rest-spread", 57 | "transform-runtime" 58 | ], 59 | "presets": [ 60 | [ 61 | "env", 62 | { 63 | "targets": { 64 | "ie": 9 65 | } 66 | } 67 | ], 68 | "react" 69 | ] 70 | }, 71 | "prettier": { 72 | "semi": false, 73 | "singleQuote": false, 74 | "trailingComma": "es5" 75 | }, 76 | "dependencies": { 77 | "babel-runtime": "^6.26.0", 78 | "classnames": "^2.2.5", 79 | "dom-helpers": "^3.2.1", 80 | "lodash": "^4.17.4" 81 | }, 82 | "peerDependencies": { 83 | "react": "^15.0.0 || ^16.0.0", 84 | "react-dom": "^15.0.0 || ^16.0.0" 85 | }, 86 | "devDependencies": { 87 | "animate.css": "^3.5.2", 88 | "babel-cli": "^6.26.0", 89 | "babel-plugin-lodash": "^3.2.11", 90 | "babel-plugin-transform-class-properties": "^6.24.1", 91 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 92 | "babel-plugin-transform-runtime": "^6.23.0", 93 | "babel-preset-env": "^1.6.0", 94 | "babel-preset-react": "^6.24.1", 95 | "cross-env": "^5.0.5", 96 | "husky": "^0.14.3", 97 | "jquery": "^3.2.1", 98 | "lint-staged": "^4.1.3", 99 | "prettier": "^1.6.1", 100 | "prismjs": "^1.6.0", 101 | "react": "^15.0.0", 102 | "react-dom": "^15.0.0", 103 | "react-scripts": "^1.0.11", 104 | "react-styleguidist": "^6.0.24", 105 | "react-test-renderer": "^15.0.0", 106 | "rimraf": "^2.6.1", 107 | "standard-version": "^4.2.0", 108 | "toastr": "^2.1.2" 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | import { ToastContainer, ToastMessage, ToastMessageAnimated } from "../index" 2 | 3 | describe(`index module`, () => { 4 | it(`should be exported as ES2015 module`, () => { 5 | expect(ToastContainer).toBeDefined() 6 | expect(ToastMessage).toBeDefined() 7 | expect(ToastMessageAnimated).toBeDefined() 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /src/components/ToastContainer.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import _ from "lodash" 3 | import React from "react" 4 | 5 | import ToastMessageAnimated from "./ToastMessage/ToastMessageAnimated" 6 | import type { IconClassNames } from "./ToastMessage/ToastMessage" 7 | 8 | type Props = { 9 | toastType?: IconClassNames, 10 | id?: string, 11 | toastMessageFactory?: func, 12 | /** 13 | * Prevent identical toast messages from displaying. 14 | */ 15 | preventDuplicates?: boolean, 16 | /** 17 | * Display new toast messages at the top or bottom of the queue. 18 | */ 19 | newestOnTop?: boolean, 20 | onClick?: func, 21 | } 22 | 23 | /** 24 | * A React container for displaying a list of toast messages. 25 | * It mimics the APIs with the vanilla [toastr.js](https://github.com/CodeSeven/toastr) 26 | * by retaining a [ref][react-ref] to publish a new **toast**. 27 | * 28 | * To display HTML, simply pass JSX instead of strings for title and message. 29 | * 30 | * ```javascript 31 | * this.container.success( 32 | * I am a strong title, 33 | * I am an emphasized message 34 | * }); 35 | * ``` 36 | * 37 | * If you're using Redux for managing states, you might consider using the 38 | * underlying component directly. See [ToastMessageAnimated](#toastmessage) below 39 | */ 40 | export class ToastContainer extends React.PureComponent { 41 | static defaultProps = { 42 | toastType: { 43 | error: "error", 44 | info: "info", 45 | success: "success", 46 | warning: "warning", 47 | }, 48 | id: "toast-container", 49 | toastMessageFactory: React.createFactory(ToastMessageAnimated), 50 | preventDuplicates: true, 51 | newestOnTop: true, 52 | onClick: _.noop, 53 | } 54 | 55 | state = { 56 | toastList: [], 57 | } 58 | 59 | toastMessageRefs = {} 60 | 61 | /** 62 | * 63 | * @param {any} message 64 | * @param {any} title 65 | * @param {any} optionsOverride 66 | * @public 67 | */ 68 | error(message, title, optionsOverride) { 69 | this.handleNotify( 70 | this.props.toastType.error, 71 | message, 72 | title, 73 | optionsOverride 74 | ) 75 | } 76 | 77 | /** 78 | * 79 | * @param {any} message 80 | * @param {any} title 81 | * @param {any} optionsOverride 82 | * @public 83 | */ 84 | info(message, title, optionsOverride) { 85 | this.handleNotify( 86 | this.props.toastType.info, 87 | message, 88 | title, 89 | optionsOverride 90 | ) 91 | } 92 | 93 | /** 94 | * 95 | * @param {any} message 96 | * @param {any} title 97 | * @param {any} optionsOverride 98 | * @public 99 | */ 100 | success(message, title, optionsOverride) { 101 | this.handleNotify( 102 | this.props.toastType.success, 103 | message, 104 | title, 105 | optionsOverride 106 | ) 107 | } 108 | 109 | /** 110 | * 111 | * @param {any} message 112 | * @param {any} title 113 | * @param {any} optionsOverride 114 | * @public 115 | */ 116 | warning(message, title, optionsOverride) { 117 | this.handleNotify( 118 | this.props.toastType.warning, 119 | message, 120 | title, 121 | optionsOverride 122 | ) 123 | } 124 | 125 | /** 126 | * 127 | * @public 128 | */ 129 | clear() { 130 | _.forEach(this.toastMessageRefs, ref => { 131 | if (_.isObject(ref)) { 132 | ref.handleHide() 133 | } 134 | }) 135 | } 136 | 137 | handleNotify(type, message, title, optionsOverride = {}) { 138 | if ( 139 | this.props.preventDuplicates && 140 | _.includes(this.state.toastList, { message }) 141 | ) { 142 | return 143 | } 144 | const key = _.uniqueId("toast_") 145 | const nextToast = { 146 | ...optionsOverride, 147 | key, 148 | type, 149 | title, 150 | message, 151 | ref: ref => { 152 | this.toastMessageRefs[key] = ref 153 | }, 154 | onClick: event => { 155 | if (_.isFunction(optionsOverride.handleOnClick)) { 156 | optionsOverride.handleOnClick() 157 | } 158 | this.handleOnToastClick(event) 159 | }, 160 | onRemove: _.bind(this.handleOnToastRemove, this, key), 161 | } 162 | this.setState(state => ({ 163 | toastList: this.props.newestOnTop 164 | ? [nextToast, ...state.toastList] 165 | : [...state.toastList, nextToast], 166 | })) 167 | } 168 | 169 | handleOnToastClick = event => { 170 | this.props.onClick(event) 171 | if (event.defaultPrevented) { 172 | return 173 | } 174 | event.preventDefault() 175 | event.stopPropagation() 176 | } 177 | 178 | handleOnToastRemove = key => { 179 | this.setState(state => ({ 180 | toastList: _.reject(state.toastList, { key }), 181 | })) 182 | } 183 | 184 | render() { 185 | const restProps = _.omit(this.props, _.keys(ToastContainer.defaultProps)) 186 | return ( 187 | 190 | ) 191 | } 192 | } 193 | 194 | export default ToastContainer 195 | -------------------------------------------------------------------------------- /src/components/ToastContainer.md: -------------------------------------------------------------------------------- 1 | ### Usage 2 | 3 | ```jsx static 4 | import { ToastContainer } from "react-toastr"; 5 | 6 | ``` 7 | 8 | ### DEMO App 9 | 10 | 11 | ```jsx 12 | require("./demo.css"); 13 | let container; 14 | 15 |
16 | container = ref} 18 | className="toast-top-right" 19 | /> 20 |

21 | React-Toastr 22 | React.js toastr component 23 |

24 |
25 | 35 | 38 |
39 |
40 |