├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .release.json ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── config ├── webpack.config.dev.js └── webpack.config.prod.js ├── css ├── index.css └── index.min.css ├── example ├── example.scss ├── sample.bundle.js └── sample.js ├── index.html ├── package.json ├── postcss.config.js ├── rollup.config.js ├── src ├── css │ └── index.scss └── index.js ├── webpack.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", {"modules": false}], 4 | "stage-2" 5 | ], 6 | "env": { 7 | "test": { 8 | "presets": [ 9 | ["es2015", {"loose": true}], 10 | "stage-2" 11 | ], 12 | "plugins": [ 13 | ["add-module-exports", "transform-object-rest-spread"] 14 | ] 15 | }, 16 | "cjs": { 17 | "presets": [ 18 | ["es2015", {"loose": true}], 19 | "stage-2" 20 | ], 21 | "plugins": [ 22 | ["add-module-exports", "transform-object-rest-spread"] 23 | ] 24 | }, 25 | "es": { 26 | "presets": [ 27 | ["es2015", {"loose": true, "modules": false}], 28 | "stage-2" 29 | ] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | cjs 2 | es 3 | dist 4 | coverage 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "standard-extended" 3 | } 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Do you want to request a feature or report a bug?** 2 | 3 | 4 | 5 | **Feature:** 6 | 7 | **If this is a feature request, what is motivation or use case for changing the behavior?**: 8 | 9 | **Bug:** 10 | 11 | **What is the current behavior?**: 12 | 13 | **What is the expected behavior?**: 14 | 15 | **Please provide the steps to reproduce or a link (repository) to a [Short, Self Contained, Correct (Compilable), Example (SSCE)](http://sscce.org/)**: 16 | 17 | **Please mention other relevant information**: 18 | 19 | **Browser Version: 20 |
Node.js Version: 21 |
Operating System:** 22 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **What kind of change does this PR introduce?**: 2 | 3 | **Did you add tests for your changes?**: 4 | 5 | **Summary**: 6 | 7 | **Does this PR introduce a breaking change?**: 8 | 9 | **Other**: 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | es 2 | cjs 3 | dist 4 | node_modules 5 | coverage 6 | *.log 7 | -------------------------------------------------------------------------------- /.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "commitMessage": ":bookmark: v%s", 3 | "tagName": "v%s", 4 | "prereleaseId": "beta", 5 | "tagAnnotation": "Version %s", 6 | "changelogCommand": "git log --pretty=format:'* %s (%h)' v[REV_RANGE]" 7 | } 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4" 4 | - "5" 5 | - "6" 6 | - "7" 7 | script: 8 | - npm run lint:test 9 | cache: 10 | yarn: true 11 | directories: 12 | - node_modules 13 | after_success: 'npm run coveralls' 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to 'is-loading' 2 | 3 | ## Support / Questions 4 | 5 | For **support or usage questions** like "How do I do X with is-loading." and "My code doesn't work.", please search and ask on **StackOverflow** with a **'is-loading' tag** first. 6 | 7 | ## Bugs 8 | 9 | > The ideal GitHub issue (and even some feature requests) is not an issue, it's a PR with a failing test case. 10 |
[@rauchg](https://twitter.com/rauchg/status/810589655532007424) 11 | 12 | **Before filing an issue please [search the issue tracker](https://github.com/hekigan/is-loading/issues); your issue may have already been discussed or fixed in `master`.** 13 | 14 | **If you want your issue to get priority, submit it as a PR instead** 15 | 16 | **Fill in the template** provided by the issue tracker, try to be as **clear** and **complete** as possible, providing a **[Short, Self Contained, Correct (Compilable), Example (SSCE)](http://sscce.org/)** (**link** to a **repository**) helps a lot . 17 | 18 | ## Feature / Enhancement Requests 19 | 20 | Feature or enhancement requests should be **submitted** in the 21 | [issue tracker](https://github.com/hekigan/is-loading/issues), with a **description** (follow the template) of the expected behavior & use case, where they’ll remain until **approval** by the **lead maintainer(s) and/or enough interest** from the **community**. 22 | 23 | You can **request** a feature by **writing a pull request**, but this is **no guarantee** it will be **merged**. 24 | 25 | ## 'help wanted' label 26 | 27 | There are issues marked with the **['help wanted'](https://github.com/hekigan/is-loading/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)** label.
This is a perfect start if you want to help out with the further development of is-loading. 28 | 29 | ## Pull Requests (PR) 30 | 31 | In general, the contribution workflow looks like this: 32 | 33 | 1. **Fork** the repo. 34 | 2. **Clone** the repo. `git clone https://github.com/your-username/is-loading.git`. 35 | 3. Create a **new branch** based off the master branch, provide a **descriptive name**
(ex. '**feat**-add-better-logging', '**bug**-removed-double-method', '**enh**-bumped-eslint') 36 | 4. Before running the code you’ll need to **install** the **dependencies** (`npm install` or `yarn`). 37 | 5. **Implement** your feature / bugfix (using the **watch scripts**), you should **only need to modify `/src`**. Don’t worry about regenerating the build folders (`/cjs`, `/es`, `/dist`), they are **built** in the **prepublish** phase. 38 | 6. Make sure **all tests pass**, **coverage is 100%** and there are **no linting errors**. 39 | 7. Submit a **PR**, referencing what it addresses. 40 | 8. Please try to keep your **PR focused in scope and avoid including unrelated commits**. 41 | 42 | After you have submitted your PR, we'll try to **get back to you as soon as possible**.
We will **review** your PR and might **request changes**. 43 | 44 | ## Development / Watch mode 45 | 46 | You can **run the watch scripts** 47 | 48 | ```console 49 | npm run build:watch 50 | ``` 51 | 52 | and 53 | 54 | ```console 55 | npm run test:watch 56 | ``` 57 | 58 | to make development easier. 59 | 60 | ## Coding Guidelines 61 | 62 | Please **follow** the **conventions** already established in the code. 63 | 64 | Guidelines are enforced using **[ESLint](http://eslint.org/)**. 65 | 66 | 67 | You can **run the linting script** by using 68 | 69 | ```console 70 | $ npm run lint 71 | ``` 72 | 73 | 74 | ## Testing 75 | 76 | Include updated (or add new) tests in the `__tests__` directory as part of your PR. 77 | 78 | You can **run the test script** by using 79 | 80 | ```console 81 | $ npm run test 82 | ``` 83 | 84 | or with coverage 85 | 86 | ```console 87 | $ npm run test:coverage 88 | ``` 89 | 90 | Aim for **100% [coverage](https://en.wikipedia.org/wiki/Code_coverage)**. 91 | 92 | ## Hooks 93 | 94 | We added **pre-commit** and **pre-push** **hooks** to make sure you **don't commit non-working code.** 95 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Laurent Blanes 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # is-loading 2 | 3 | ![Node](https://img.shields.io/node/v/is-loading.svg?style=flat-square) 4 | [![NPM](https://img.shields.io/npm/v/is-loading.svg?style=flat-square)](https://www.npmjs.com/package/is-loading) 5 | [![Travis](https://img.shields.io/travis/hekigan/is-loading/master.svg?style=flat-square)](https://travis-ci.org/hekigan/is-loading) 6 | [![David](https://img.shields.io/david/hekigan/is-loading.svg?style=flat-square)](https://david-dm.org/hekigan/is-loading) 7 | [![Coverage Status](https://img.shields.io/coveralls/hekigan/is-loading.svg?style=flat-square)](https://coveralls.io/github/hekigan/is-loading) 8 | ![Downloads](https://img.shields.io/npm/dm/is-loading.svg) 9 | 10 | [![NPM](https://nodei.co/npm/is-loading.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/is-loading/) 11 | 12 | > Simple script to show visual feedback when loading data or any action that would take time. 13 | > Vanilla script built with ES2015. 14 | > Exported as CommonJS, ES2015 and UMD. So it should work everywhere. 15 | 16 | ### Usage 17 | 18 | Vanilla javascript 19 | 20 | ```js 21 | import isLoading from 'is-loading'; 22 | 23 | ``` 24 | 25 | ### Examples and Demo 26 | 27 | http://hekigan.github.io/is-loading/ 28 | 29 | ### Installation 30 | 31 | Install via [yarn](https://github.com/yarnpkg/yarn) 32 | 33 | yarn add is-loading 34 | 35 | or npm 36 | 37 | npm install is-loading 38 | 39 | 40 | ### configuration 41 | 42 | You can pass in extra options as a configuration 43 | 44 | *Parameters:* 45 | 46 | By default all modes accept a DOM element as the first parameter, and an `option` object as the second. 47 | 48 | ```js 49 | isLoading(targetElement, options); 50 | ``` 51 | 52 | Full overlay mode is an exception with either *no parameters* or 1 parameter for the `option` object. 53 | 54 | ```js 55 | isLoading(options); 56 | ``` 57 | 58 | ```js 59 | import isLoading from 'is-loading'; 60 | ``` 61 | 62 | ➖ **targetElement** ( DOMElement ) 63 |
📝 The first parameter is expected to be a DOMElement. 64 |
💡 example 65 | 66 | ```js 67 | import isLoading from 'is-loading'; 68 | 69 | const $elt = document.querySelector('input[type="submit"]'); 70 | 71 | // Start the script 72 | isLoading($elt).loading(); 73 | 74 | // Stop the script 75 | isLoading($elt).remove(); 76 | ``` 77 | ➖ **options** ( Object ) 78 |
📝 The second parameter is an Object to set options. 79 |
💡 default 80 | ```js 81 | const optionsDefault = { 82 | 'type': 'switch', // switch | replace | full-overlay | overlay 83 | 'text': 'loading', // Text to display in the loader 84 | 'disableSource': true, // true | false 85 | 'disableList': [] 86 | }; 87 | ``` 88 |
💡 example 89 | 90 | ```js 91 | import isLoading from 'is-loading'; 92 | 93 | // Assuming that we have a login form 94 | const $button = document.querySelector('input[type="submit"]'); 95 | const $username = document.querySelector('#username'); 96 | const $password = document.querySelector('#password'); 97 | 98 | options = { 99 | 'type': 'switch', // switch | replace | full-overlay | overlay 100 | 'text': 'login...', // Text to display in the loader 101 | 'disableSource': true, // true | false 102 | 'disableList': [$username, $password] 103 | }; 104 | 105 | // using a variable 106 | const loader = isLoading($button, options); 107 | loader.loading(); // Start the script 108 | loader.remove(); // Stop the script 109 | 110 | // no variable 111 | isLoading($button, options).loading(); // Start the script 112 | isLoading($button, options).remove(); // Stop the script 113 | ``` 114 | 115 | ### methods 116 | 117 | #### #loading 118 | 119 | Show the loader 120 | 121 | ```js 122 | const loader = isLoading($elt, options); 123 | loader.loading(); 124 | 125 | // or 126 | 127 | isLoading($elt, options).loading(); 128 | ``` 129 | 130 | #### #remove 131 | 132 | Remove the loader 133 | 134 | ```js 135 | const loader = isLoading($elt, options); 136 | loader.remove(); 137 | 138 | // or 139 | 140 | isLoading($elt, options).remove(); 141 | ``` 142 | 143 | ### Builds 144 | 145 | If you don't use a package manager, you can [access `is-loading` via unpkg (CDN)](https://unpkg.com/is-loading/), download the source, or point your package manager to the url. 146 | 147 | `is-loading` is compiled as a collection of [CommonJS](http://webpack.github.io/docs/commonjs.html) modules & [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html) for bundlers that support the `jsnext:main` or `module` field in package.json (Rollup, Webpack 2) 148 | 149 | The `is-loading` package includes precompiled production and development [UMD](https://github.com/umdjs/umd) builds in the [`dist` folder](https://unpkg.com/is-loading/dist/). They can be used directly without a bundler and are thus compatible with many popular JavaScript module loaders and environments. You can drop a UMD build as a [` 466 | 467 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "is-loading", 3 | "version": "2.0.4", 4 | "description": "Small helper to give the user a visual feedback that something is happening ", 5 | "main": "cjs/index.js", 6 | "browser": "dist/isLoading.js", 7 | "module": "es/index.js", 8 | "jsxnext:main": "es/index.js", 9 | "style": "css/index.css", 10 | "files": [ 11 | "dist", 12 | "cjs", 13 | "es", 14 | "src", 15 | "css" 16 | ], 17 | "engines": { 18 | "node": ">=4.0.0" 19 | }, 20 | "scripts": { 21 | "start": "npm run dev", 22 | "prepublish": "npm run build", 23 | "precommit": "npm run lint:test", 24 | "prepush": "npm run lint:test", 25 | "release": "release-it", 26 | "coveralls": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls", 27 | "lint": "npm run lint:eslint", 28 | "lint:eslint": "eslint src/*.js", 29 | "test": "clear && jest", 30 | "test:coverage": "jest --coverage ", 31 | "test:watch": "clear && jest --watch", 32 | "lint:test": "npm run lint && npm run test:coverage", 33 | "prebuild:sass": "node-sass src/css --output-style=compressed -o ./css", 34 | "build:sass": "postcss --use autoprefixer -b 'last 2 versions' < ./css/index.css | postcss --use cssnano > ./css/index.min.css", 35 | "build:sass:watch": "node-sass -w src/css -o ./css --source-map=true --source-map-contents --error-bell", 36 | "build": "clear && npm run lint:test && npm run build:cjs && npm run build:es && npm run build:umd && npm run build:sass && npm run build:example", 37 | "build:watch": "clear && rimraf cjs && cross-env BABEL_ENV=cjs babel -w src --out-dir cjs & npm run build:sass:watch", 38 | "build:es": "rimraf es && cross-env BABEL_ENV=es babel src --out-dir es", 39 | "build:cjs": "rimraf cjs && cross-env BABEL_ENV=cjs babel src --out-dir cjs", 40 | "build:umd": "rimraf dist && cross-env BABEL_ENV=es rollup -c & cross-env BABEL_ENV=es NODE_ENV=production rollup -c", 41 | "build:example": "webpack -p --env=prod", 42 | "dev": "webpack-dev-server --env=dev" 43 | }, 44 | "keywords": [ 45 | "isloading", 46 | "loader", 47 | "loading" 48 | ], 49 | "author": "Laurent Blanes (laurent.blanes@gmail.com)", 50 | "license": "MIT", 51 | "repository": "hekigan/is-loading", 52 | "devDependencies": { 53 | "autoprefixer": "^6.7.2", 54 | "babel-cli": "^6.18.0", 55 | "babel-core": "^6.17.0", 56 | "babel-loader": "^6.3.0", 57 | "babel-plugin-add-module-exports": "^0.2.1", 58 | "babel-plugin-transform-object-rest-spread": "^6.22.0", 59 | "babel-plugin-transform-runtime": "^6.23.0", 60 | "babel-preset-es2015": "^6.16.0", 61 | "babel-preset-stage-0": "^6.22.0", 62 | "babel-preset-stage-1": "^6.22.0", 63 | "babel-preset-stage-2": "^6.22.0", 64 | "babel-runtime": "^6.23.0", 65 | "coveralls": "^2.11.15", 66 | "cross-env": "^3.1.3", 67 | "css-loader": "^0.26.1", 68 | "cssnano": "^3.10.0", 69 | "eslint": "^3.12.0", 70 | "eslint-config-standard-extended": "^1.0.1", 71 | "eslint-plugin-babel": "^4.0.0", 72 | "husky": "^0.12.0", 73 | "jest": "^18.1.0", 74 | "node-sass": "^4.5.0", 75 | "postcss": "^5.2.12", 76 | "postcss-cli": "^2.6.0", 77 | "postcss-cssnext": "^2.9.0", 78 | "postcss-loader": "^1.3.0", 79 | "release-it": "^2.5.1", 80 | "rimraf": "^2.5.4", 81 | "rollup": "^0.39.2", 82 | "rollup-plugin-babel": "^2.6.1", 83 | "rollup-plugin-bundle-size": "^1.0.1", 84 | "rollup-plugin-commonjs": "^7.0.0", 85 | "rollup-plugin-node-resolve": "^2.0.0", 86 | "rollup-plugin-uglify": "^1.0.1", 87 | "sass-loader": "^6.0.0", 88 | "style-loader": "^0.13.1", 89 | "webpack": "^2.2.1", 90 | "webpack-dev-server": "^2.3.0", 91 | "webpack-merge": "^3.0.0" 92 | }, 93 | "dependencies": { 94 | "babel-polyfill": "^6.23.0", 95 | "dom-create-element-query-selector": "^1.0.5" 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | "postcss-cssnext": { 4 | browsers: ['last 2 versions', '> 5%'] 5 | } 6 | } 7 | }; -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel'; 2 | import nodeResolve from 'rollup-plugin-node-resolve'; 3 | import uglify from 'rollup-plugin-uglify'; 4 | import bundleSize from 'rollup-plugin-bundle-size'; 5 | import commonjs from 'rollup-plugin-commonjs'; 6 | 7 | const name = `isLoading`; 8 | 9 | const plugins = [ 10 | babel(), 11 | nodeResolve({ 12 | module: false, 13 | jsnext: true 14 | }), 15 | commonjs({ 16 | include: `node_modules/**` 17 | }), 18 | bundleSize() 19 | ]; 20 | 21 | const isProd = process.env.NODE_ENV === `production`; 22 | if (isProd) plugins.push(uglify()); 23 | 24 | const isExample = process.env.NODE_ENV === `example`; 25 | 26 | let config = { 27 | entry: `src/index.js`, 28 | plugins, 29 | dest: `dist/${name}${isProd ? `.min` : ``}.js`, 30 | moduleName: name, 31 | format: `umd` 32 | }; 33 | 34 | if (isExample) { 35 | Object.assign(config, { 36 | entry: `example/sample.js`, 37 | dest: `example/sample.bundle.js`, 38 | plugins 39 | }); 40 | } 41 | 42 | export default config; 43 | -------------------------------------------------------------------------------- /src/css/index.scss: -------------------------------------------------------------------------------- 1 | $is-loading-overlay-bg: rgba(#000, .5); 2 | $is-loading-overlay-text-color: #444; 3 | $is-loading-overlay-wrapper-bg: #FFF; 4 | $is-loading-overlay-animation-color: #0BB; 5 | 6 | .is-loading-text-wrapper { 7 | background: $is-loading-overlay-wrapper-bg; 8 | border-radius: 2px; 9 | color: $is-loading-overlay-text-color; 10 | display: inline-block; 11 | padding: 10px 20px; 12 | position: absolute; 13 | left: 50%; 14 | top: 50%; 15 | transform: translate(-50%, -50%); 16 | 17 | &:after { 18 | animation-name: is-loading-anim; 19 | animation-duration: 1s; 20 | animation-iteration-count: infinite; 21 | animation-direction: alternate; 22 | content: ''; 23 | display: inline-block; 24 | background: $is-loading-overlay-animation-color; 25 | height: 2px; 26 | position: absolute; 27 | left: 50%; 28 | bottom: 1px; 29 | transform: translate(-50%, 0%); 30 | vertical-align: middle; 31 | width: 1px; 32 | z-index: 2; 33 | } 34 | } 35 | 36 | #is-loading-full-overlay, 37 | .is-loading-element-overlay { 38 | background: $is-loading-overlay-bg; 39 | position: relative; 40 | top: 0; 41 | bottom: 0; 42 | left: 0; 43 | right: 0; 44 | z-index: 99999; 45 | } 46 | 47 | #is-loading-full-overlay { 48 | position: fixed; 49 | } 50 | 51 | .is-loading-element-overlay { 52 | position: absolute; 53 | } 54 | 55 | .is-loading-element-overlay-target { 56 | position: relative; 57 | 58 | .is-loading-text-wrapper { 59 | padding-bottom: 4px; 60 | padding-top: 0px; 61 | } 62 | } 63 | 64 | @keyframes is-loading-anim { 65 | 0% { width: 1px; } 66 | 100% { width: 98%; } 67 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import createElement from 'dom-create-element-query-selector'; 2 | 3 | export default (...params) => { 4 | return new IsLoading(params); 5 | }; 6 | 7 | const formElements = ['form', 'input', 'textarea', 'label', 'fieldset', 'select', 'button']; 8 | 9 | const optionsDefault = { 10 | 'type': 'switch', // switch | replace | full-overlay | overlay 11 | 'text': 'loading', // Text to display in the loader 12 | 'disableSource': true, // true | false 13 | 'disableList': [] 14 | }; 15 | 16 | class IsLoading { 17 | constructor (params) { 18 | let options = {}; 19 | if (params.length === 0 || (params.length === 1 && !params[0].nodeType)) { 20 | this._target = null; 21 | options = {...params[0], type: 'full-overlay'}; 22 | } else { 23 | this._target = params[0]; 24 | options = params[1]; 25 | } 26 | this._options = {...optionsDefault, ...options}; 27 | this._fullOverlayId = 'is-loading-full-overlay'; 28 | } 29 | 30 | loading () { 31 | switch (this._options.type) { 32 | case 'replace': this._onReplaceType(); break; 33 | case 'full-overlay': this._onFullOverlayType(); break; 34 | case 'overlay': this._onElementOverlayType(); break; 35 | default: this._onSwitchType(); break; 36 | } 37 | } 38 | 39 | get targetContent () { 40 | if (this.isTargetValue) { 41 | return this._target.value; 42 | } else { 43 | return this._target.textContent; 44 | } 45 | } 46 | 47 | set targetContent (val) { 48 | if (this.isTargetValue) { 49 | this._target.value = val; 50 | } else { 51 | this._target.textContent = val; 52 | } 53 | } 54 | 55 | get isTargetValue () { 56 | const node = this._target.nodeName.toLowerCase(); 57 | const type = this._target.attributes.type; 58 | 59 | return (node === 'input' && type && (type.value.toLowerCase() === 'button' || type.value.toLowerCase() === 'submit')); 60 | } 61 | 62 | restoreContent () { 63 | const content = this._target.getAttribute('data-is-loading-content'); 64 | if (this.isTargetValue) { 65 | this._target.value = content; 66 | } else { 67 | this._target.textContent = content; 68 | } 69 | } 70 | 71 | _onSwitchType () { 72 | this._toggleElements(false); 73 | this._target.setAttribute('data-is-loading-content', this.targetContent); 74 | this.targetContent = this._options.text; 75 | } 76 | 77 | _onReplaceType () { 78 | this._toggleElements(false); 79 | this._target.setAttribute('data-is-loading-content', this.targetContent); 80 | this._target.innerHTML = ''; 81 | this._target.appendChild(createElement('span.is-loading.is-loading-target', this._options.text)); 82 | } 83 | 84 | _onElementOverlayType () { 85 | this._toggleElements(false); 86 | const overlayWrapperClass = '.is-loading-element-overlay'; 87 | 88 | if (this._prop('position') === 'static') { 89 | this._target.setAttribute('data-is-loading-position', 'static'); 90 | this._target.classList.add('is-loading-element-overlay-target'); 91 | } 92 | 93 | if (!this._target.querySelector(overlayWrapperClass)) { 94 | const overlay = createElement(overlayWrapperClass, 95 | createElement('.is-loading-text-wrapper', this._options.text) 96 | ); 97 | overlay.style.borderRadius = this._prop('border-radius'); 98 | this._target.appendChild(overlay); 99 | } 100 | } 101 | 102 | _onFullOverlayType () { 103 | this._toggleElements(false); 104 | this._showFullOverlay(); 105 | } 106 | 107 | _showFullOverlay () { 108 | let overlay = document.querySelector(this._fullOverlayId); 109 | 110 | if (!overlay) { 111 | overlay = createElement(`#${this._fullOverlayId}`, 112 | createElement('.is-loading-text-wrapper', this._options.text) 113 | ); 114 | document.querySelector('body').appendChild(overlay); 115 | } 116 | } 117 | 118 | _prop (prop) { 119 | return window.getComputedStyle(this._target).getPropertyValue(prop); 120 | } 121 | 122 | _toggleElements (status = true) { 123 | let list = [...this._options.disableList]; 124 | if (this._target && this._options.disableSource === true) { 125 | list.unshift(this._target); 126 | } 127 | list.forEach(item => { 128 | if (formElements.includes(item.tagName.toLowerCase())) { 129 | if (status === true) { 130 | item.removeAttribute('disabled'); 131 | } else { 132 | item.setAttribute('disabled', 'disabled'); 133 | } 134 | } 135 | if (status === true) { 136 | item.classList.remove('disabled'); 137 | } else { 138 | item.classList.add('disabled'); 139 | } 140 | }); 141 | } 142 | 143 | remove () { 144 | this._toggleElements(true); 145 | if (this._options.type === 'switch') { 146 | this.restoreContent(); 147 | } 148 | if (this._target) { 149 | this._target.removeAttribute('data-is-loading-content'); 150 | } 151 | if (this._options.type === 'full-overlay') { 152 | let overlay = document.getElementById(this._fullOverlayId); 153 | if (overlay) { 154 | document.querySelector('body').removeChild(overlay); 155 | } 156 | } 157 | if (this._target && this._target.getAttribute('data-is-loading-position')) { 158 | this._target.classList.remove('is-loading-element-overlay-target'); 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require('path'); 2 | const webpackMerge = require('webpack-merge'); 3 | 4 | function buildConfig (env) { 5 | return require('./config/webpack.config.' + env + '.js')({ env: env }); 6 | } 7 | 8 | var base = function () { 9 | return { 10 | entry: [ 11 | 'babel-polyfill', 12 | './example/sample.js' 13 | ], 14 | output: { 15 | filename: './example/sample.bundle.js', 16 | path: resolve(__dirname, '.'), 17 | publicPath: '/' 18 | }, 19 | context: resolve(__dirname, '.'), 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.js$/, 24 | use: [ 25 | 'babel-loader' 26 | ], 27 | exclude: /node_modules/ 28 | }, 29 | { 30 | test: /\.css|\.scss$/, 31 | use: [ 32 | 'style-loader', 33 | 'css-loader', 34 | 'postcss-loader', 35 | 'sass-loader' 36 | ] 37 | } 38 | ] 39 | } 40 | }; 41 | }; 42 | 43 | module.exports = function (env) { 44 | return webpackMerge(base(), buildConfig(env)); 45 | }; --------------------------------------------------------------------------------