├── tests ├── helpers │ ├── .gitkeep │ └── resolver.js ├── integration │ ├── .gitkeep │ └── components │ │ └── sweet-alert-test.js ├── dummy │ ├── app │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── models │ │ │ └── .gitkeep │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── styles │ │ │ └── app.css │ │ ├── components │ │ │ └── .gitkeep │ │ ├── router.js │ │ ├── app.js │ │ ├── index.html │ │ ├── templates │ │ │ └── application.hbs │ │ └── controllers │ │ │ └── application.js │ ├── public │ │ ├── robots.txt │ │ └── crossdomain.xml │ └── config │ │ ├── optional-features.json │ │ ├── targets.js │ │ ├── ember-cli-update.json │ │ └── environment.js ├── test-helper.js ├── unit │ └── services │ │ └── swal-test.js ├── acceptance │ └── sweetalert-test.js ├── .jshintrc └── index.html ├── .jscsrc ├── .watchmanconfig ├── app ├── services │ └── swal.js └── components │ └── sweet-alert.js ├── .bowerrc ├── .prettierrc.js ├── .template-lintrc.js ├── index.js ├── config ├── environment.js └── ember-try.js ├── addon ├── components │ ├── sweet-alert.hbs │ └── sweet-alert.js └── services │ └── swal.js ├── .ember-cli ├── .eslintignore ├── .prettierignore ├── .editorconfig ├── .gitignore ├── .npmignore ├── ember-cli-build.js ├── .jshintrc ├── testem.js ├── CONTRIBUTING.md ├── LICENSE.md ├── .eslintrc.js ├── .travis.yml ├── addon-test-support └── index.js ├── package.json ├── CODE_OF_CONDUCT.md ├── CHANGELOG.md └── README.md /tests/helpers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/integration/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ember-suave" 3 | } 4 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /app/services/swal.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-sweetalert/services/swal'; 2 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | singleQuote: true, 5 | }; 6 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /.template-lintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: 'octane', 5 | }; 6 | -------------------------------------------------------------------------------- /app/components/sweet-alert.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-sweetalert/components/sweet-alert'; 2 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: require('./package').name, 5 | }; 6 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (/* environment, appConfig */) { 4 | return {}; 5 | }; 6 | -------------------------------------------------------------------------------- /addon/components/sweet-alert.hbs: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /tests/dummy/config/optional-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "application-template-wrapper": false, 3 | "default-async-observers": true, 4 | "jquery-integration": false, 5 | "template-only-glimmer-components": true 6 | } 7 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from 'dummy/config/environment'; 3 | 4 | export default class Router extends EmberRouter { 5 | location = config.locationType; 6 | rootURL = config.rootURL; 7 | } 8 | 9 | Router.map(function () {}); 10 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from '../../resolver'; 2 | import config from '../../config/environment'; 3 | 4 | const resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # unconventional js 2 | /blueprints/*/files/ 3 | /vendor/ 4 | 5 | # compiled output 6 | /dist/ 7 | /tmp/ 8 | 9 | # dependencies 10 | /bower_components/ 11 | /node_modules/ 12 | 13 | # misc 14 | /coverage/ 15 | !.* 16 | .eslintcache 17 | 18 | # ember-try 19 | /.node_modules.ember-try/ 20 | /bower.json.ember-try 21 | /package.json.ember-try 22 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # unconventional js 2 | /blueprints/*/files/ 3 | /vendor/ 4 | 5 | # compiled output 6 | /dist/ 7 | /tmp/ 8 | 9 | # dependencies 10 | /bower_components/ 11 | /node_modules/ 12 | 13 | # misc 14 | /coverage/ 15 | !.* 16 | .eslintcache 17 | 18 | # ember-try 19 | /.node_modules.ember-try/ 20 | /bower.json.ember-try 21 | /package.json.ember-try 22 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from 'dummy/app'; 2 | import config from 'dummy/config/environment'; 3 | import * as QUnit from 'qunit'; 4 | import { setApplication } from '@ember/test-helpers'; 5 | import { setup } from 'qunit-dom'; 6 | import { start } from 'ember-qunit'; 7 | 8 | setApplication(Application.create(config.APP)); 9 | 10 | setup(QUnit.assert); 11 | 12 | start(); 13 | -------------------------------------------------------------------------------- /tests/unit/services/swal-test.js: -------------------------------------------------------------------------------- 1 | import { module, test } from 'qunit'; 2 | import { setupTest } from 'ember-qunit'; 3 | 4 | module('Unit | Service | swal', function (hooks) { 5 | setupTest(hooks); 6 | 7 | // Replace this with your real tests. 8 | test('it exists', function (assert) { 9 | let service = this.owner.lookup('service:swal'); 10 | assert.ok(service); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const browsers = [ 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions', 7 | ]; 8 | 9 | const isCI = Boolean(process.env.CI); 10 | const isProduction = process.env.EMBER_ENV === 'production'; 11 | 12 | if (isCI || isProduction) { 13 | browsers.push('ie 11'); 14 | } 15 | 16 | module.exports = { 17 | browsers, 18 | }; 19 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from 'ember-resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from 'dummy/config/environment'; 5 | 6 | export default class App extends Application { 7 | modulePrefix = config.modulePrefix; 8 | podModulePrefix = config.podModulePrefix; 9 | Resolver = Resolver; 10 | } 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.hbs] 16 | insert_final_newline = false 17 | 18 | [*.{diff,md}] 19 | trim_trailing_whitespace = false 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist/ 5 | /tmp/ 6 | 7 | # dependencies 8 | /bower_components/ 9 | /node_modules/ 10 | 11 | # misc 12 | /.env* 13 | /.pnp* 14 | /.sass-cache 15 | /.eslintcache 16 | /connect.lock 17 | /coverage/ 18 | /libpeerconnection.log 19 | /npm-debug.log* 20 | /testem.log 21 | /yarn-error.log 22 | 23 | # ember-try 24 | /.node_modules.ember-try/ 25 | /bower.json.ember-try 26 | /package.json.ember-try 27 | -------------------------------------------------------------------------------- /tests/dummy/config/ember-cli-update.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "1.0.0", 3 | "packages": [ 4 | { 5 | "name": "ember-cli", 6 | "version": "3.24.0", 7 | "blueprints": [ 8 | { 9 | "name": "addon", 10 | "outputRepo": "https://github.com/ember-cli/ember-addon-output", 11 | "codemodsSource": "ember-addon-codemods-manifest@1", 12 | "isBaseBlueprint": true, 13 | "options": [ 14 | "--yarn", 15 | "--no-welcome" 16 | ] 17 | } 18 | ] 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /bower_components/ 7 | 8 | # misc 9 | /.bowerrc 10 | /.editorconfig 11 | /.ember-cli 12 | /.env* 13 | /.eslintcache 14 | /.eslintignore 15 | /.eslintrc.js 16 | /.git/ 17 | /.gitignore 18 | /.template-lintrc.js 19 | /.travis.yml 20 | /.watchmanconfig 21 | /bower.json 22 | /config/ember-try.js 23 | /CONTRIBUTING.md 24 | /ember-cli-build.js 25 | /testem.js 26 | /tests/ 27 | /yarn.lock 28 | .gitkeep 29 | 30 | # ember-try 31 | /.node_modules.ember-try/ 32 | /bower.json.ember-try 33 | /package.json.ember-try 34 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | 5 | module.exports = function (defaults) { 6 | let app = new EmberAddon(defaults, { 7 | // 'ember-cli-babel': { 8 | // includePolyfill: true, 9 | // }, 10 | }); 11 | 12 | /* 13 | This build file specifies the options for the dummy test app of this 14 | addon, located in `/tests/dummy` 15 | This build file does *not* influence how the addon or the app using it 16 | behave. You most likely want to be modifying `./index.js` or app's build file 17 | */ 18 | 19 | return app.toTree(); 20 | }; 21 | -------------------------------------------------------------------------------- /tests/dummy/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise", 6 | "Sweetalert2" 7 | ], 8 | "browser": true, 9 | "boss": true, 10 | "curly": true, 11 | "debug": false, 12 | "devel": true, 13 | "eqeqeq": true, 14 | "evil": true, 15 | "forin": false, 16 | "immed": false, 17 | "laxbreak": false, 18 | "newcap": true, 19 | "noarg": true, 20 | "noempty": false, 21 | "nonew": false, 22 | "nomen": false, 23 | "onevar": false, 24 | "plusplus": false, 25 | "regexp": false, 26 | "undef": true, 27 | "sub": true, 28 | "strict": false, 29 | "white": false, 30 | "eqnull": true, 31 | "esnext": true, 32 | "unused": true 33 | } 34 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | test_page: 'tests/index.html?hidepassed', 5 | disable_watching: true, 6 | launch_in_ci: ['Chrome'], 7 | launch_in_dev: ['Chrome'], 8 | browser_start_timeout: 120, 9 | browser_args: { 10 | Chrome: { 11 | ci: [ 12 | // --no-sandbox is needed when running Chrome inside a container 13 | process.env.CI ? '--no-sandbox' : null, 14 | '--headless', 15 | '--disable-dev-shm-usage', 16 | '--disable-software-rasterizer', 17 | '--mute-audio', 18 | '--remote-debugging-port=0', 19 | '--window-size=1440,900', 20 | ].filter(Boolean), 21 | }, 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How To Contribute 2 | 3 | ## Installation 4 | 5 | * `git clone ` 6 | * `cd my-addon` 7 | * `npm install` 8 | 9 | ## Linting 10 | 11 | * `npm run lint:hbs` 12 | * `npm run lint:js` 13 | * `npm run lint:js -- --fix` 14 | 15 | ## Running tests 16 | 17 | * `ember test` – Runs the test suite on the current Ember version 18 | * `ember test --server` – Runs the test suite in "watch mode" 19 | * `ember try:each` – Runs the test suite against multiple Ember versions 20 | 21 | ## Running the dummy application 22 | 23 | * `ember serve` 24 | * Visit the dummy application at [http://localhost:4200](http://localhost:4200). 25 | 26 | For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/). 27 | -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | 12 | 13 | 14 | 15 | {{content-for "head-footer"}} 16 | 17 | 18 | {{content-for "body"}} 19 | 20 | 21 | 22 | 23 | {{content-for "body-footer"}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/acceptance/sweetalert-test.js: -------------------------------------------------------------------------------- 1 | import { module, test } from 'qunit'; 2 | import { visit, fillIn } from '@ember/test-helpers'; 3 | import { setupApplicationTest } from 'ember-qunit'; 4 | import { open, confirm, confirmAndClose } from 'ember-sweetalert/test-support'; 5 | 6 | module('Acceptance | sweetalert', function (hooks) { 7 | setupApplicationTest(hooks); 8 | 9 | test('it can submit an email', async function (assert) { 10 | await visit('/'); 11 | await open('.toggle1'); 12 | 13 | assert.dom('.swal2-title').hasText('Ember Sweet Alert'); 14 | 15 | await confirm(); 16 | await fillIn('input[type="email"]', 'foo@example.com'); 17 | await confirmAndClose(); 18 | 19 | assert.dom('.email').hasText('Email: foo@example.com'); 20 | }); 21 | 22 | test('it can be opened via import', async function (assert) { 23 | await visit('/'); 24 | await open('.toggle2'); 25 | 26 | assert.dom('.swal2-container').exists(); 27 | 28 | await confirmAndClose(); 29 | 30 | assert.dom('.swal2-container').doesNotExist(); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "define", 10 | "console", 11 | "visit", 12 | "exists", 13 | "fillIn", 14 | "click", 15 | "keyEvent", 16 | "triggerEvent", 17 | "find", 18 | "findWithAssert", 19 | "wait", 20 | "DS", 21 | "andThen", 22 | "currentURL", 23 | "currentPath", 24 | "currentRouteName", 25 | "sinon" 26 | ], 27 | "node": false, 28 | "browser": false, 29 | "boss": true, 30 | "curly": true, 31 | "debug": false, 32 | "devel": false, 33 | "eqeqeq": true, 34 | "evil": true, 35 | "forin": false, 36 | "immed": false, 37 | "laxbreak": false, 38 | "newcap": true, 39 | "noarg": true, 40 | "noempty": false, 41 | "nonew": false, 42 | "nomen": false, 43 | "onevar": false, 44 | "plusplus": false, 45 | "regexp": false, 46 | "undef": true, 47 | "sub": true, 48 | "strict": false, 49 | "white": false, 50 | "eqnull": true, 51 | "esnext": true, 52 | "unused": true 53 | } 54 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

Welcome to Ember Sweet Alert!

2 | 3 |
4 | 5 | Toggle 6 | 7 | 16 | 17 | 29 | 30 | {{#if this.cancellation}} 31 |

Cancelled: {{this.cancellation}}

32 | {{/if}} 33 | 34 | {{#if this.email}} 35 | 36 | {{/if}} 37 | 38 |
39 | 40 | Open via Import 41 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'module', 9 | ecmaFeatures: { 10 | legacyDecorators: true, 11 | }, 12 | }, 13 | plugins: ['ember'], 14 | extends: [ 15 | 'eslint:recommended', 16 | 'plugin:ember/recommended', 17 | 'plugin:prettier/recommended', 18 | ], 19 | env: { 20 | browser: true, 21 | }, 22 | rules: {}, 23 | overrides: [ 24 | // node files 25 | { 26 | files: [ 27 | '.eslintrc.js', 28 | '.prettierrc.js', 29 | '.template-lintrc.js', 30 | 'ember-cli-build.js', 31 | 'index.js', 32 | 'testem.js', 33 | 'blueprints/*/index.js', 34 | 'config/**/*.js', 35 | 'tests/dummy/config/**/*.js', 36 | ], 37 | excludedFiles: [ 38 | 'addon/**', 39 | 'addon-test-support/**', 40 | 'app/**', 41 | 'tests/dummy/app/**', 42 | ], 43 | parserOptions: { 44 | sourceType: 'script', 45 | }, 46 | env: { 47 | browser: false, 48 | node: true, 49 | }, 50 | plugins: ['node'], 51 | extends: ['plugin:node/recommended'], 52 | }, 53 | ], 54 | }; 55 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | {{content-for "test-head"}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for "head-footer"}} 18 | {{content-for "test-head-footer"}} 19 | 20 | 21 | {{content-for "body"}} 22 | {{content-for "test-body"}} 23 | 24 |
25 |
26 |
27 |
28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {{content-for "body-footer"}} 38 | {{content-for "test-body-footer"}} 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (environment) { 4 | let ENV = { 5 | modulePrefix: 'dummy', 6 | environment, 7 | rootURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true 13 | }, 14 | EXTEND_PROTOTYPES: { 15 | // Prevent Ember Data from overriding Date.parse. 16 | Date: false, 17 | }, 18 | }, 19 | 20 | APP: { 21 | // Here you can pass flags/options to your application instance 22 | // when it is created 23 | }, 24 | }; 25 | 26 | if (environment === 'development') { 27 | // ENV.APP.LOG_RESOLVER = true; 28 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 29 | // ENV.APP.LOG_TRANSITIONS = true; 30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 31 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 32 | } 33 | 34 | if (environment === 'test') { 35 | // Testem prefers this... 36 | ENV.locationType = 'none'; 37 | 38 | // keep test console output quieter 39 | ENV.APP.LOG_ACTIVE_GENERATION = false; 40 | ENV.APP.LOG_VIEW_LOOKUPS = false; 41 | 42 | ENV.APP.rootElement = '#ember-testing'; 43 | ENV.APP.autoboot = false; 44 | 45 | ENV['ember-sweetalert'] = { target: ENV.APP.rootElement }; 46 | } 47 | 48 | if (environment === 'production') { 49 | // here you can enable a production-specific feature 50 | } 51 | 52 | return ENV; 53 | }; 54 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/application.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | import { inject as service } from '@ember/service'; 3 | import { tracked } from '@glimmer/tracking'; 4 | import { action } from '@ember/object'; 5 | import { later, next } from '@ember/runloop'; 6 | import { Promise } from 'rsvp'; 7 | import config from '../config/environment'; 8 | 9 | const TESTING = 'test' === config.environment; 10 | 11 | export default class ApplicationController extends Controller { 12 | @service swal; 13 | @tracked toggleModal = false; 14 | @tracked enterEmail = false; 15 | @tracked cancellation = null; 16 | @tracked email = null; 17 | 18 | @action 19 | reset() { 20 | this.cancellation = null; 21 | this.email = null; 22 | } 23 | 24 | @action 25 | loading() { 26 | return new Promise((resolve) => { 27 | this.swal.showLoading(); 28 | TESTING ? next(null, resolve) : later(resolve, 2000); 29 | }); 30 | } 31 | 32 | @action 33 | cancelled({ dismiss }) { 34 | this.cancellation = dismiss; 35 | } 36 | 37 | @action 38 | openModal() { 39 | this.toggleModal = true; 40 | } 41 | 42 | @action 43 | closeModal() { 44 | this.toggleModal = false; 45 | } 46 | 47 | @action 48 | openEmail() { 49 | this.enterEmail = true; 50 | } 51 | 52 | @action 53 | closeEmail() { 54 | this.enterEmail = false; 55 | } 56 | 57 | @action 58 | updateEmail({ value }) { 59 | this.email = value; 60 | } 61 | 62 | @action 63 | open() { 64 | this.swal.fire({ title: 'Hello World!' }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | # we recommend testing addons with the same minimum supported node version as Ember CLI 5 | # so that your addon works for all apps 6 | - "10" 7 | 8 | dist: xenial 9 | 10 | addons: 11 | chrome: stable 12 | 13 | cache: 14 | yarn: true 15 | 16 | env: 17 | global: 18 | # See https://git.io/vdao3 for details. 19 | - JOBS=1 20 | 21 | branches: 22 | only: 23 | - master 24 | - develop 25 | # npm version tags 26 | - /^v\d+\.\d+\.\d+/ 27 | 28 | jobs: 29 | fast_finish: true 30 | allow_failures: 31 | - env: EMBER_TRY_SCENARIO=ember-canary 32 | 33 | include: 34 | # runs linting and tests with current locked deps 35 | - stage: "Tests" 36 | name: "Tests" 37 | script: 38 | - yarn lint 39 | - yarn test:ember 40 | 41 | - stage: "Additional Tests" 42 | name: "Floating Dependencies" 43 | install: 44 | - yarn install --no-lockfile --non-interactive 45 | script: 46 | - yarn test:ember 47 | 48 | # we recommend new addons test the current and previous LTS 49 | # as well as latest stable release (bonus points to beta/canary) 50 | - env: EMBER_TRY_SCENARIO=ember-lts-3.16 51 | - env: EMBER_TRY_SCENARIO=ember-lts-3.20 52 | - env: EMBER_TRY_SCENARIO=ember-release 53 | - env: EMBER_TRY_SCENARIO=ember-beta 54 | - env: EMBER_TRY_SCENARIO=ember-canary 55 | - env: EMBER_TRY_SCENARIO=ember-default-with-jquery 56 | - env: EMBER_TRY_SCENARIO=ember-classic 57 | 58 | before_install: 59 | - curl -o- -L https://yarnpkg.com/install.sh | bash 60 | - export PATH=$HOME/.yarn/bin:$PATH 61 | 62 | script: 63 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO 64 | -------------------------------------------------------------------------------- /addon-test-support/index.js: -------------------------------------------------------------------------------- 1 | import { find, click, waitUntil, waitFor } from '@ember/test-helpers'; 2 | 3 | const SWAL_CONTAINER = '.swal2-container'; 4 | const SWAL_CONFIRM = '.swal2-confirm'; 5 | const SWAL_CANCEL = '.swal2-cancel'; 6 | 7 | /** 8 | * Wait for Sweet Alert to open. 9 | * 10 | * @public 11 | * @return {Promise} resolves when settled. 12 | */ 13 | export async function waitForOpen() { 14 | await waitFor(SWAL_CONTAINER); 15 | } 16 | 17 | /** 18 | * Wait for Sweet Alert to close. 19 | * 20 | * @public 21 | * @return {Promise} resolves when settled. 22 | */ 23 | export async function waitForClose() { 24 | await waitUntil(() => false === Boolean(find(SWAL_CONTAINER))); 25 | } 26 | 27 | /** 28 | * Click the specified target and wait for Sweet Alert to open. 29 | * 30 | * @public 31 | * @param {string|Element} target the element or selector to click on. 32 | * @return {Promise} resolves when settled. 33 | */ 34 | export async function open(target) { 35 | await click(target); 36 | await waitForOpen(); 37 | } 38 | 39 | /** 40 | * Click the Sweet Alert confirm element. 41 | * 42 | * @public 43 | * @return {Promise} resolves when settled. 44 | */ 45 | export async function confirm() { 46 | await click(SWAL_CONFIRM); 47 | } 48 | 49 | /** 50 | * Click the Sweet Alert confirm element and wait for Sweet Alert to close. 51 | * 52 | * @public 53 | * @return {Promise} resolves when settled. 54 | */ 55 | export async function confirmAndClose() { 56 | await confirm(); 57 | await waitForClose(); 58 | } 59 | 60 | /** 61 | * Click the Sweet Alert cancel element. 62 | * 63 | * @public 64 | * @return {Promise} resolves when settled. 65 | */ 66 | export async function cancel() { 67 | await click(SWAL_CANCEL); 68 | } 69 | 70 | /** 71 | * Click the Sweet Alert cancel element and wait for Sweet Alert to close. 72 | * 73 | * @public 74 | * @return {Promise} resolves when settled. 75 | */ 76 | export async function cancelAndClose() { 77 | await cancel(); 78 | await waitForClose(); 79 | } 80 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = async function () { 6 | return { 7 | useYarn: true, 8 | scenarios: [ 9 | { 10 | name: 'ember-lts-3.16', 11 | npm: { 12 | devDependencies: { 13 | 'ember-source': '~3.16.0', 14 | }, 15 | }, 16 | }, 17 | { 18 | name: 'ember-lts-3.20', 19 | npm: { 20 | devDependencies: { 21 | 'ember-source': '~3.20.5', 22 | }, 23 | }, 24 | }, 25 | { 26 | name: 'ember-release', 27 | npm: { 28 | devDependencies: { 29 | 'ember-source': await getChannelURL('release'), 30 | }, 31 | }, 32 | }, 33 | { 34 | name: 'ember-beta', 35 | npm: { 36 | devDependencies: { 37 | 'ember-source': await getChannelURL('beta'), 38 | }, 39 | }, 40 | }, 41 | { 42 | name: 'ember-canary', 43 | allowedToFail: true, 44 | npm: { 45 | devDependencies: { 46 | 'ember-source': await getChannelURL('canary'), 47 | }, 48 | }, 49 | }, 50 | { 51 | name: 'ember-default-with-jquery', 52 | env: { 53 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 54 | 'jquery-integration': true, 55 | }), 56 | }, 57 | npm: { 58 | devDependencies: { 59 | '@ember/jquery': '^1.1.0', 60 | }, 61 | }, 62 | }, 63 | { 64 | name: 'ember-classic', 65 | env: { 66 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 67 | 'application-template-wrapper': true, 68 | 'default-async-observers': false, 69 | 'template-only-glimmer-components': false, 70 | }), 71 | }, 72 | npm: { 73 | ember: { 74 | edition: 'classic', 75 | }, 76 | }, 77 | }, 78 | ], 79 | }; 80 | }; 81 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-sweetalert", 3 | "version": "3.1.0", 4 | "description": "Ember Sweet Alerts with SweetAlert2", 5 | "scripts": { 6 | "build": "ember build --environment=production", 7 | "lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'", 8 | "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix", 9 | "lint:hbs": "ember-template-lint .", 10 | "lint:hbs:fix": "ember-template-lint . --fix", 11 | "lint:js": "eslint . --cache", 12 | "lint:js:fix": "eslint . --fix", 13 | "start": "ember serve", 14 | "test": "npm-run-all lint test:*", 15 | "test:ember": "ember test", 16 | "test:ember-compatibility": "ember try:each" 17 | }, 18 | "dependencies": { 19 | "@ember/render-modifiers": "^1.0.2", 20 | "ember-auto-import": "^1.10.1", 21 | "ember-cli-babel": "^7.23.0", 22 | "ember-cli-htmlbars": "^5.3.1", 23 | "sweetalert2": "^10.14.1" 24 | }, 25 | "maintainers": [ 26 | "Leo Correa ", 27 | "Guillaume Gérard ", 28 | "Christopher Gammie " 29 | ], 30 | "devDependencies": { 31 | "@ember/optional-features": "^2.0.0", 32 | "@ember/test-helpers": "^2.1.4", 33 | "@glimmer/component": "^1.0.3", 34 | "@glimmer/tracking": "^1.0.3", 35 | "babel-eslint": "^10.1.0", 36 | "broccoli-asset-rev": "^3.0.0", 37 | "ember-cli": "~3.24.0", 38 | "ember-cli-dependency-checker": "^3.2.0", 39 | "ember-cli-inject-live-reload": "^2.0.2", 40 | "ember-cli-sri": "^2.1.1", 41 | "ember-cli-terser": "^4.0.1", 42 | "ember-disable-prototype-extensions": "^1.1.3", 43 | "ember-export-application-global": "^2.0.1", 44 | "ember-load-initializers": "^2.1.2", 45 | "ember-maybe-import-regenerator": "^0.1.6", 46 | "ember-page-title": "^6.0.3", 47 | "ember-qunit": "^5.1.1", 48 | "ember-resolver": "^8.0.2", 49 | "ember-source": "~3.24.0", 50 | "ember-source-channel-url": "^3.0.0", 51 | "ember-template-lint": "^2.15.0", 52 | "ember-try": "^1.4.0", 53 | "eslint": "^7.17.0", 54 | "eslint-config-prettier": "^7.1.0", 55 | "eslint-plugin-ember": "^10.1.1", 56 | "eslint-plugin-node": "^11.1.0", 57 | "eslint-plugin-prettier": "^3.3.1", 58 | "loader.js": "^4.7.0", 59 | "npm-run-all": "^4.1.5", 60 | "prettier": "^2.2.1", 61 | "qunit": "^2.13.0", 62 | "qunit-dom": "^1.6.0" 63 | }, 64 | "keywords": [ 65 | "ember-addon", 66 | "sweetalert", 67 | "sweetalert2", 68 | "modal", 69 | "alert", 70 | "swal", 71 | "sweet" 72 | ], 73 | "repository": "https://github.com/Tonkpils/ember-sweetalert", 74 | "license": "MIT", 75 | "directories": { 76 | "doc": "doc", 77 | "test": "tests" 78 | }, 79 | "engines": { 80 | "node": "10.* || >= 12" 81 | }, 82 | "ember": { 83 | "edition": "octane" 84 | }, 85 | "ember-addon": { 86 | "configPath": "tests/dummy/config" 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at lcorr005@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /addon/components/sweet-alert.js: -------------------------------------------------------------------------------- 1 | import Component from '@glimmer/component'; 2 | import { inject as service } from '@ember/service'; 3 | import { action } from '@ember/object'; 4 | import { A } from '@ember/array'; 5 | 6 | const CONFIGURATION = [ 7 | 'title', 8 | 'titleText', 9 | 'html', 10 | 'text', 11 | 'icon', 12 | 'iconColor', 13 | 'iconHtml', 14 | 'showClass', 15 | 'hideClass', 16 | 'footer', 17 | 'backdrop', 18 | 'toast', 19 | 'target', 20 | 'input', 21 | 'width', 22 | 'padding', 23 | 'background', 24 | 'position', 25 | 'grow', 26 | 'customClass', 27 | 'timer', 28 | 'timerProgressBar', 29 | 'animation', 30 | 'heightAuto', 31 | 'allowOutsideClick', 32 | 'allowEscapeKey', 33 | 'allowEnterKey', 34 | 'stopKeydownPropagation', 35 | 'keydownListenerCapture', 36 | 'showConfirmButton', 37 | 'showDenyButton', 38 | 'showCancelButton', 39 | 'confirmButtonText', 40 | 'denyButtonText', 41 | 'cancelButtonText', 42 | 'confirmButtonColor', 43 | 'denyButtonColor', 44 | 'cancelButtonColor', 45 | 'confirmButtonAriaLabel', 46 | 'denyButtonAriaLabel', 47 | 'cancelButtonAriaLabel', 48 | 'buttonsStyling', 49 | 'reverseButtons', 50 | 'focusConfirm', 51 | 'focusDeny', 52 | 'focusCancel', 53 | 'showCloseButton', 54 | 'closeButtonHtml', 55 | 'closeButtonAriaLabel', 56 | 'loaderHtml', 57 | 'showLoaderOnConfirm', 58 | 'showLoaderOnDeny', 59 | 'scrollbarPadding', 60 | 'preConfirm', 61 | 'preDeny', 62 | 'returnInputValueOnDeny', 63 | 'imageUrl', 64 | 'imageWidth', 65 | 'imageHeight', 66 | 'imageAlt', 67 | 'imageLabel', 68 | 'inputPlaceholder', 69 | 'inputValue', 70 | 'inputOptions', 71 | 'inputAutoTrim', 72 | 'inputAttributes', 73 | 'inputValidator', 74 | 'validationMessage', 75 | 'progressSteps', 76 | 'currentProgressStep', 77 | 'progressStepsDistance', 78 | ]; 79 | 80 | const EVENTS = [ 81 | 'willOpen', 82 | 'onBeforeOpen', // deprecated, use willOpen 83 | 'didOpen', 84 | 'onOpen', // deprecated, use didOpen 85 | 'didRender', 86 | 'onRender', // deprecated, use didRender 87 | 'willClose', 88 | 'onClose', // deprecated, use willClose 89 | 'didClose', 90 | 'onAfterClose', // deprecated, use didClose, 91 | 'didDestroy', 92 | 'onDestroy', // deprecated, use didDestroy 93 | ]; 94 | 95 | export default class SweetAlertComponent extends Component { 96 | @service swal; 97 | 98 | get isOpen() { 99 | if (undefined === this.args.show) { 100 | return true; 101 | } 102 | 103 | return this.args.show; 104 | } 105 | 106 | @action 107 | async fire(element, [open]) { 108 | if (open) { 109 | let result = await this.swal.fire(this._values()); 110 | 111 | if (result.value) { 112 | this._call('onConfirm', result); 113 | return; 114 | } 115 | 116 | this._call('onCancel', result); 117 | } 118 | } 119 | 120 | _call(method, ...args) { 121 | if (!this.isDestroying && this.args[method]) { 122 | this.args[method](...args); 123 | } 124 | } 125 | 126 | _values() { 127 | let props = {}; 128 | 129 | A(CONFIGURATION).forEach((key) => { 130 | let value = this.args[key]; 131 | 132 | if (undefined !== value) { 133 | props[key] = value; 134 | } 135 | }); 136 | 137 | A(EVENTS).forEach((key) => { 138 | if (undefined !== this.args[key]) { 139 | props[key] = () => this._call(key, ...arguments); 140 | } 141 | }); 142 | 143 | return props; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. This 4 | project adheres to [Semantic Versioning](http://semver.org/) and 5 | [this changelog format](http://keepachangelog.com/). 6 | 7 | ## [3.1.0] - 2021-02-15 8 | 9 | ### Added 10 | - Upgraded to Sweet Alert `10.14`, adding the `showLoaderOnDeny` configuration 11 | parameter. 12 | 13 | ## [3.0.0] - 2021-01-15 14 | 15 | ### Changed 16 | - **BREAKING** Upgrade SweetAlert from `9.17` to `10.13`. Refer to the 17 | [Sweet Alert v10 release notes.](https://github.com/sweetalert2/sweetalert2/releases/tag/v10.0.0) 18 | - The `` component previously rendered a `` tag within a 19 | `
` tag. This has been changed so that just a `` tag is now used. 20 | This is unlikely to be a breaking change, unless you were relying on 21 | the elements for page layout and/or CSS. 22 | 23 | ### Removed 24 | - **BREAKING** The previously deprecated `open` method on the SweetAlert 25 | service has been removed. Use the `fire` method instead. 26 | 27 | ## [2.0.1] - 2021-01-14 28 | 29 | ### Fixed 30 | - Fixed JS linting issues. 31 | 32 | ## [2.0.0] - 2021-01-14 33 | 34 | ### Changed 35 | - Upgraded addon to Ember 3.24 (from 3.19). 36 | - Minimum supported Ember version is now 3.16 LTS. 37 | 38 | ### Fixed 39 | - Import test helpers from `@ember/test-helpers` rather than `ember-test-helpers`. 40 | 41 | ## [2.0.0-alpha.1] - 2020-07-22 42 | 43 | ### Changed 44 | - **BREAKING:** Upgrade Sweet Alert to from `7.33` to `9.17`. 45 | - [v8 to v9 Upgrade Guide](https://github.com/sweetalert2/sweetalert2/releases/tag/v9.0.0) 46 | - [v7 to v8 Upgrade Guide](https://github.com/sweetalert2/sweetalert2/releases/tag/v8.0.0) 47 | - **BREAKING:** Sweet Alert component no longer supports positional parameters. 48 | - **BREAKING:** The Sweet Alert component now follows the DDAU pattern. This means 49 | that the `onClose` action must be used in conjunction with the `show` attribute 50 | to ensure the show value is toggled between true/false. There is an 51 | [example in the readme document](./README.md#Opening). 52 | - Minimum Ember version is now `3.16`. 53 | 54 | ### Deprecated 55 | - The `SweetAlertService.open()` method is deprecated in favour of 56 | `SweetAlertService.fire()`, and will be removed in `3.0`. 57 | 58 | ## [1.1.0] - 2020-07-22 59 | 60 | ### Added 61 | - Updated list of configuration keys on the component to match those available 62 | in Sweet Alert. Added the following: 63 | - `customContainerClass` 64 | - `keydownListenerCapture` 65 | - `cancelButtonColor` 66 | - `showCloseButton` 67 | - `validationMessage` 68 | - `onAfterClose` 69 | - Update the list of methods available on the Sweet Alert service to match 70 | those available on Sweet Alert. Added the following: 71 | - `getButtonWrapper` 72 | - `stopTimer` 73 | - `resumeTimer` 74 | - `toggleTimer` 75 | - `isTimerRunning` 76 | - `increaseTimer` 77 | - `showValidationMessage` (use instead of `showValidationError`) 78 | - `resetValidationMessage` (use instead of `resetValidationError`) 79 | - `getValidationMessage` 80 | 81 | ## [1.0.0] - 2020-07-22 82 | 83 | ### Changed 84 | - Upgraded package to Ember CLI `3.19`, requiring at least Node 10. 85 | - Minimum supported Ember version is now `3.8`. 86 | 87 | ## [1.0.0-rc.1] - 2019-03-28 88 | 89 | ### Added 90 | - Now supports default configuration for all alerts. 91 | - Execute callbacks on the Ember run loop. 92 | - Provide test helpers. 93 | - Added package tests. 94 | - New Sweet Alert service to trigger alerts from controllers, routes etc. 95 | 96 | ### Changed 97 | - Upgraded to SweetAlert2 v7 98 | - Install SweetAlert2 via NPM instead of Bower. 99 | -------------------------------------------------------------------------------- /addon/services/swal.js: -------------------------------------------------------------------------------- 1 | import Service from '@ember/service'; 2 | import { getOwner } from '@ember/application'; 3 | import { scheduleOnce } from '@ember/runloop'; 4 | import { Promise } from 'rsvp'; 5 | import Swal from 'sweetalert2'; 6 | 7 | export default class SweetAlertService extends Service { 8 | sweetAlert; 9 | 10 | constructor() { 11 | super(...arguments); 12 | let config = getOwner(this).resolveRegistration('config:environment') || {}; 13 | this.sweetAlert = Swal.mixin(config['ember-sweetalert'] || {}); 14 | } 15 | 16 | fire(...args) { 17 | return new Promise((resolve, reject) => { 18 | this.sweetAlert.fire(...args).then(resolve, reject); 19 | }); 20 | } 21 | 22 | isVisible() { 23 | return this.sweetAlert.isVisible(); 24 | } 25 | 26 | mixin(params) { 27 | return this.sweetAlert.mixin(params); 28 | } 29 | 30 | update(params) { 31 | return this.sweetAlert.update(params); 32 | } 33 | 34 | close() { 35 | this._run('close'); 36 | } 37 | 38 | getContainer() { 39 | return this.sweetAlert.getContainer(); 40 | } 41 | 42 | getHeader() { 43 | return this.sweetAlert.getHeader(); 44 | } 45 | 46 | getTitle() { 47 | return this.sweetAlert.getTitle(); 48 | } 49 | 50 | getProgressSteps() { 51 | return this.sweetAlert.getProgressSteps(); 52 | } 53 | 54 | getCloseButton() { 55 | return this.sweetAlert.getCloseButton(); 56 | } 57 | 58 | getContent() { 59 | return this.sweetAlert.getContent(); 60 | } 61 | 62 | getImage() { 63 | return this.sweetAlert.getImage(); 64 | } 65 | 66 | getActions() { 67 | return this.sweetAlert.getActions(); 68 | } 69 | 70 | getFooter() { 71 | return this.sweetAlert.getFooter(); 72 | } 73 | 74 | getFocusableElements() { 75 | return this.sweetAlert.getFocusableElements(); 76 | } 77 | 78 | getConfirmButton() { 79 | return this.sweetAlert.getConfirmButton(); 80 | } 81 | 82 | getDenyButton() { 83 | return this.sweetAlert.getDenyButton(); 84 | } 85 | 86 | getCancelButton() { 87 | return this.sweetAlert.getCancelButton(); 88 | } 89 | 90 | enableButtons() { 91 | this._run('enableButtons'); 92 | } 93 | 94 | disableButtons() { 95 | this._run('disableButtons'); 96 | } 97 | 98 | showLoading() { 99 | this._run('showLoading'); 100 | } 101 | 102 | hideLoading() { 103 | this._run('hideLoading'); 104 | } 105 | 106 | isLoading() { 107 | return this.sweetAlert.isLoading(); 108 | } 109 | 110 | getTimerLeft() { 111 | return this.sweetAlert.getTimerLeft(); 112 | } 113 | 114 | stopTimer() { 115 | return this.sweetAlert.stopTimer(); 116 | } 117 | 118 | resumeTimer() { 119 | return this.sweetAlert.resumeTimer(); 120 | } 121 | 122 | toggleTimer() { 123 | return this.sweetAlert.toggleTimer(); 124 | } 125 | 126 | isTimerRunning() { 127 | return this.sweetAlert.isTimerRunning(); 128 | } 129 | 130 | increaseTimer(n) { 131 | return this.sweetAlert.increaseTimer(n); 132 | } 133 | 134 | clickConfirm() { 135 | this._run('clickConfirm'); 136 | } 137 | 138 | clickDeny() { 139 | this._run('clickDeny'); 140 | } 141 | 142 | clickCancel() { 143 | this._run('clickCancel'); 144 | } 145 | 146 | getInput() { 147 | return this.sweetAlert.getInput(); 148 | } 149 | 150 | disableInput() { 151 | this._run('disableInput'); 152 | } 153 | 154 | enableInput() { 155 | this._run('enableInput'); 156 | } 157 | 158 | showValidationMessage(error) { 159 | this._run('showValidationMessage', error); 160 | } 161 | 162 | resetValidationMessage() { 163 | this._run('resetValidationMessage'); 164 | } 165 | 166 | getValidationMessage() { 167 | return this.getValidationMessage(); 168 | } 169 | 170 | queue() { 171 | this._run('queue', ...arguments); 172 | } 173 | 174 | getQueueStep() { 175 | return this.sweetAlert.getQueueStep(); 176 | } 177 | 178 | insertQueueStep() { 179 | this._run('insertQueueStep', ...arguments); 180 | } 181 | 182 | deleteQueueStep(index) { 183 | this._run('deleteQueueStep', index); 184 | } 185 | 186 | isValidParameter(param) { 187 | return this.sweetAlert.isValidParameter(param); 188 | } 189 | 190 | isUpdatableParameter(param) { 191 | return this.sweetAlert.isUpdatableParameter(param); 192 | } 193 | 194 | _run(method, ...args) { 195 | scheduleOnce('afterRender', this.sweetAlert, method, ...args); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /tests/integration/components/sweet-alert-test.js: -------------------------------------------------------------------------------- 1 | import { module, test } from 'qunit'; 2 | import { setupRenderingTest } from 'ember-qunit'; 3 | import { render } from '@ember/test-helpers'; 4 | import hbs from 'htmlbars-inline-precompile'; 5 | import { 6 | open, 7 | confirmAndClose, 8 | cancelAndClose, 9 | } from 'ember-sweetalert/test-support'; 10 | 11 | module('Integration | Component | sweet-alert', function (hooks) { 12 | setupRenderingTest(hooks); 13 | 14 | test('it renders', async function (assert) { 15 | await render(hbs` 16 | 20 | `); 21 | 22 | assert 23 | .dom('[data-test-swal]') 24 | .hasTagName('span') 25 | .hasAttribute('aria-hidden', 'true'); 26 | 27 | assert.dom('.swal2-title').hasText('Any fool can use a computer'); 28 | 29 | await confirmAndClose(); 30 | 31 | assert.dom('.swal2-container').doesNotExist(); 32 | }); 33 | 34 | test('it has params', async function (assert) { 35 | await render(hbs` 36 | 41 | `); 42 | 43 | assert.dom('.swal2-title').hasText('The Internet?', 'title'); 44 | assert 45 | .dom('.swal2-content') 46 | .hasText('That thing is still around?', 'content'); 47 | assert.dom('.swal2-icon.swal2-question').hasClass('swal2-icon-show'); 48 | 49 | await confirmAndClose(); 50 | 51 | assert.dom('.swal2-container').doesNotExist(); 52 | }); 53 | 54 | test('it can be toggled', async function (assert) { 55 | this.set('isOpen', false); 56 | 57 | await render(hbs` 58 | 65 | 66 | 67 | `); 68 | 69 | assert.dom('.swal2-container').doesNotExist(); 70 | 71 | await open('button'); 72 | 73 | assert.strictEqual(this.isOpen, true); 74 | assert.dom('.swal2-title').hasText('The Internet?', 'title'); 75 | 76 | await confirmAndClose(); 77 | 78 | assert.dom('.swal2-container').doesNotExist(); 79 | assert.strictEqual(this.isOpen, false); 80 | 81 | await open('button'); 82 | 83 | assert.strictEqual(this.isOpen, true); 84 | assert.dom('.swal2-container').exists('it can be opened a second time'); 85 | 86 | await confirmAndClose(); 87 | 88 | assert.strictEqual(this.isOpen, false); 89 | }); 90 | 91 | /** 92 | * The `onClose` action is deprecated and will be removed in the next 93 | * major release of SweetAlert2 94 | */ 95 | test('it can be toggled using on-close', async function (assert) { 96 | this.set('isOpen', false); 97 | 98 | await render(hbs` 99 | 106 | 107 | 108 | `); 109 | 110 | assert.dom('.swal2-container').doesNotExist(); 111 | await open('button'); 112 | assert.dom('.swal2-title').hasText('The Internet?', 'title'); 113 | await confirmAndClose(); 114 | assert.dom('.swal2-container').doesNotExist(); 115 | await open('button'); 116 | assert.dom('.swal2-container').exists('it can be opened a second time'); 117 | }); 118 | 119 | test('it has a confirm action', async function (assert) { 120 | assert.expect(1); 121 | this.set('confirmed', ({ value }) => assert.ok(value, 'it was confirmed')); 122 | this.set('cancelled', () => assert.ok(false, 'it was cancelled')); 123 | 124 | await render(hbs` 125 | 133 | `); 134 | 135 | await confirmAndClose(); 136 | }); 137 | 138 | test('it has a cancel action', async function (assert) { 139 | this.set('confirmed', () => assert.ok(false, 'it was confirmed')); 140 | this.set('cancel', ({ dismiss }) => this.set('cancellation', dismiss)); 141 | 142 | await render(hbs` 143 | 151 | `); 152 | 153 | await cancelAndClose(); 154 | 155 | assert.equal(this.cancellation, 'cancel'); 156 | }); 157 | }); 158 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ember Sweet Alert 2 | ============================================================================== 3 | 4 | An [ember-cli](http://www.ember-cli.com/) addon for using 5 | [SweetAlert2](https://sweetalert2.github.io/) in Ember applications. 6 | 7 | Compatibility 8 | ------------------------------------------------------------------------------ 9 | 10 | * Ember.js v3.16 or above 11 | * Ember CLI v2.13 or above 12 | * Node.js v10 or above 13 | 14 | Installation 15 | ------------------------------------------------------------------------------ 16 | 17 | ``` 18 | ember install ember-sweetalert 19 | ``` 20 | 21 | IE11 requires the Babel polyfill to be present, otherwise you'll get a 22 | `Promise is undefined` error. 23 | [As per this comment](https://github.com/babel/ember-cli-babel/issues/40#issuecomment-268952820) 24 | you can add it via your `ember-cli-build.js` file as follows: 25 | 26 | ```js 27 | // ember-cli-build.js 28 | let app = new EmberApp(defaults, { 29 | 'ember-cli-babel': { 30 | includePolyfill: true 31 | } 32 | }); 33 | ``` 34 | 35 | 36 | Usage 37 | ------------------------------------------------------------------------------ 38 | 39 | ### In your templates 40 | 41 | #### Basic Usage 42 | 43 | The `sweet-alert` component allows setting SweetAlert's attributes. 44 | 45 | ```hbs 46 | 47 | ``` 48 | 49 | By default the alert will be open as soon as the template is rendered. See below 50 | for controlling whether the alert is open. 51 | 52 | #### Configuration 53 | 54 | All Sweet Alert options [Sweet Alert configuration options](https://sweetalert2.github.io/#configuration) 55 | can also be passed in as arguments: 56 | 57 | ```hbs 58 | 65 | ``` 66 | 67 | If there are defaults that you want to set for every alert, you can set these 68 | in your environment config, e.g.: 69 | 70 | ```js 71 | ENV['ember-sweetalert'] = { 72 | target: '#my-sweetalert', 73 | allowOutsideClick: false 74 | }; 75 | ``` 76 | 77 | #### Opening 78 | 79 | By default the alert will be open when the component is rendered. To control 80 | this behaviour, use the `show` attribute. For example to open the alert when 81 | a button is clicked: 82 | 83 | ```hbs 84 | {{! sayHello === false to start }} 85 | 91 | 92 | 93 | ``` 94 | 95 | The Sweet Alert component follows the Data-Down, Action Up (DDAU) pattern. 96 | This means in the example above, the alert will only show once, as `sayHello` 97 | will remain `true` once the alert is closed. To allow an alert to be 98 | open/closed any number of times, use an action to set the show variable back 99 | to `false` once the alert is closed. For example: 100 | 101 | ```hbs 102 | {{! sayHello === false to start }} 103 | 110 | 111 | 112 | ``` 113 | 114 | #### Actions 115 | 116 | The component supports all the Sweet Alert actions allowed via configuration: 117 | - `willOpen` 118 | - `didOpen` 119 | - `didRender` 120 | - `willClose` 121 | - `didClose` 122 | - `didDestroy` 123 | 124 | In addition, the component also supports the following two actions: 125 | - `onConfirm`: invoked if the user clicks the confirm button within the alert. 126 | - `onCancel`: invoked if the user closes the alert without confirmation. 127 | 128 | Both actions receive the return value from Sweet Alert. 129 | 130 | The following example collects an email from a user, giving them a different 131 | message based on whether they provided the email or cancelled: 132 | 133 | ```js 134 | import Component from '@glimmer/component'; 135 | import { tracked } from '@glimmer/tracking'; 136 | import { action } from '@ember/object'; 137 | 138 | export default class JoinMailingListComponent extends Component { 139 | @tracked enterEmail = false; 140 | @tracked email; 141 | @tracked sayThankYou = false; 142 | @tracked didNotJoin = false; 143 | 144 | @action 145 | collectEmail() { 146 | this.enterEmail = true; 147 | } 148 | 149 | @action 150 | join({ value }) { 151 | this.email = value; 152 | this.enterEmail = false; 153 | this.sayThankYou = true; 154 | } 155 | 156 | @action 157 | didCancel() { 158 | this.enterEmail = false; 159 | this.didNotJoin = true; 160 | } 161 | 162 | @action 163 | reset() { 164 | this.enterEmail = false; 165 | this.email = null; 166 | this.sayThankYou = false; 167 | this.didNotJoin = false; 168 | } 169 | } 170 | ``` 171 | 172 | ```hbs 173 | 174 | 175 | 184 | 185 | 192 | 193 | 199 | ``` 200 | 201 | ### In your code 202 | 203 | #### Service 204 | 205 | The recommended way to use SweetAlert in your code is to inject the `swal` 206 | service and use the `fire` method. The service ensures your default 207 | SweetAlert config is used, plus integrates with the Ember run loop. 208 | 209 | Here is an example: 210 | 211 | ```js 212 | import Component from '@ember/component'; 213 | import { inject as service } from '@ember/service'; 214 | import { action } from '@ember/object'; 215 | 216 | export default class DeleteModelComponent extends Component { 217 | @service swal; 218 | 219 | @action 220 | async confirm() { 221 | let { value } = await this.swal.fire({ 222 | title: 'Are you sure?', 223 | showCancelButton: true 224 | }); 225 | 226 | if (value) { 227 | this.args.model.destroyRecord(); 228 | } 229 | } 230 | } 231 | ``` 232 | 233 | The service also exposes the [SweetAlert methods](https://sweetalert2.github.io/#methods), 234 | scheduling any action methods on the Ember run loop. 235 | 236 | #### Import it 237 | 238 | If you really need to you can import SweetAlert easily with: 239 | 240 | ```js 241 | import Swal from 'sweetalert2'; 242 | ``` 243 | 244 | > Using SweetAlert directly as an import will not have your default settings 245 | and will not be run-loop aware. 246 | 247 | ### In your tests 248 | 249 | #### Setup 250 | 251 | You will need to set the target for Sweet Alert to the Ember testing `div`. 252 | Add the following to your environment config: 253 | 254 | ```js 255 | if (environment === 'test') { 256 | ENV.APP.rootElement = '#ember-testing'; 257 | // ... 258 | ENV['ember-sweetalert'] = { target: ENV.APP.rootElement }; 259 | } 260 | ``` 261 | 262 | #### Test Helpers 263 | 264 | This addon provides a number of test helpers that can be used in acceptance or 265 | rendering tests. 266 | 267 | Test helpers can be imported from `ember-sweetalert/test-support`. The 268 | available helpers are: 269 | 270 | | Helper | Description | 271 | | :--- | :--- | 272 | | `open(target)` | Clicks the specified target and waits for Sweet Alert to open. | 273 | | `confirm` | Clicks the Sweet Alert confirm button. | 274 | | `confirmAndClose` | Clicks the Sweet Alert confirm button and waits for it to close. | 275 | | `cancel` | Clicks the Sweet Alert cancel button. | 276 | | `cancelAndClose` | Clicks the Sweet Alert cancel button and waits for it to close. | 277 | | `waitForOpen` | Wait for Sweet Alert to open. | 278 | | `waitForClose` | Wait for Sweet Alert to close. | 279 | 280 | An example acceptance test: 281 | 282 | ```js 283 | import { module, test } from 'qunit'; 284 | import { visit, fillIn } from '@ember/test-helpers'; 285 | import { setupApplicationTest } from 'ember-qunit'; 286 | import { open, confirmAndClose } from 'ember-sweetalert/test-support'; 287 | 288 | module('Acceptance | join mailing list', function(hooks) { 289 | setupApplicationTest(hooks); 290 | 291 | test('user can join mailing list', async function(assert) { 292 | await visit('/'); 293 | await open('button.join'); 294 | await fillIn('input[type="email"]', 'foo@example.com'); 295 | await confirmAndClose(); 296 | 297 | assert.dom('.email').hasText('Your email is: foo@example.com'); 298 | }); 299 | }); 300 | ``` 301 | 302 | Contributing 303 | ------------------------------------------------------------------------------ 304 | 305 | See the [Contributing](CONTRIBUTING.md) guide for details. 306 | 307 | 308 | License 309 | ------------------------------------------------------------------------------ 310 | 311 | This project is licensed under the [MIT License](LICENSE.md). 312 | --------------------------------------------------------------------------------