├── app ├── .gitkeep ├── components │ └── paper-selection-dialog.js ├── helpers │ └── ember-paper-selection-dialog-is-selected.js └── styles │ └── ember-paper-selection-dialog.scss ├── addon ├── .gitkeep ├── helpers │ └── ember-paper-selection-dialog-is-selected.js ├── templates │ └── components │ │ └── paper-selection-dialog.hbs └── components │ └── paper-selection-dialog.js ├── vendor └── .gitkeep ├── tests ├── helpers │ └── .gitkeep ├── unit │ └── .gitkeep ├── integration │ ├── .gitkeep │ └── components │ │ └── paper-selection-dialog-test.js ├── dummy │ ├── app │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── models │ │ │ └── .gitkeep │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ ├── .gitkeep │ │ │ └── application.js │ │ ├── templates │ │ │ ├── components │ │ │ │ └── .gitkeep │ │ │ └── application.hbs │ │ ├── styles │ │ │ └── app.scss │ │ ├── resolver.js │ │ ├── router.js │ │ ├── app.js │ │ └── index.html │ ├── config │ │ ├── optional-features.json │ │ ├── targets.js │ │ └── environment.js │ └── public │ │ └── robots.txt ├── .eslintrc.js ├── test-helper.js └── index.html ├── .watchmanconfig ├── index.js ├── config ├── environment.js └── ember-try.js ├── .template-lintrc.js ├── .ember-cli ├── .eslintignore ├── .editorconfig ├── .gitignore ├── .npmignore ├── ember-cli-build.js ├── testem.js ├── LICENSE.md ├── .eslintrc.js ├── .travis.yml ├── package.json └── README.md /app/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/helpers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/unit/.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/components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/config/optional-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "jquery-integration": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | embertest: true 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.scss: -------------------------------------------------------------------------------- 1 | @import "ember-paper"; 2 | @import "ember-paper-selection-dialog"; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: require('./package').name 5 | }; 6 | -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /app/components/paper-selection-dialog.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-paper-selection-dialog/components/paper-selection-dialog'; -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /.template-lintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: 'recommended', 5 | rules: { 6 | 'attribute-indentation': false 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /app/helpers/ember-paper-selection-dialog-is-selected.js: -------------------------------------------------------------------------------- 1 | export { default, emberPaperSelectionDialogIsSelected } from 'ember-paper-selection-dialog/helpers/ember-paper-selection-dialog-is-selected'; 2 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from '../app'; 2 | import config from '../config/environment'; 3 | import { setApplication } from '@ember/test-helpers'; 4 | import { start } from 'ember-qunit'; 5 | 6 | setApplication(Application.create(config.APP)); 7 | 8 | start(); 9 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from './config/environment'; 3 | 4 | const Router = EmberRouter.extend({ 5 | location: config.locationType, 6 | rootURL: config.rootURL 7 | }); 8 | 9 | Router.map(function() { 10 | }); 11 | 12 | export default Router; 13 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | 17 | # ember-try 18 | /.node_modules.ember-try/ 19 | /bower.json.ember-try 20 | /package.json.ember-try 21 | -------------------------------------------------------------------------------- /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 = !!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 './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /.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 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.hbs] 17 | insert_final_newline = false 18 | 19 | [*.{diff,md}] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.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 | /.sass-cache 13 | /connect.lock 14 | /coverage/ 15 | /libpeerconnection.log 16 | /npm-debug.log* 17 | /testem.log 18 | /yarn-error.log 19 | 20 | # ember-try 21 | /.node_modules.ember-try/ 22 | /bower.json.ember-try 23 | /package.json.ember-try 24 | -------------------------------------------------------------------------------- /.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 | /.eslintignore 13 | /.eslintrc.js 14 | /.gitignore 15 | /.template-lintrc.js 16 | /.travis.yml 17 | /.watchmanconfig 18 | /bower.json 19 | /config/ember-try.js 20 | /ember-cli-build.js 21 | /testem.js 22 | /tests/ 23 | /yarn.lock 24 | .gitkeep 25 | 26 | # ember-try 27 | /.node_modules.ember-try/ 28 | /bower.json.ember-try 29 | /package.json.ember-try 30 | -------------------------------------------------------------------------------- /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 | // Add options here 8 | }); 9 | 10 | /* 11 | This build file specifies the options for the dummy test app of this 12 | addon, located in `/tests/dummy` 13 | This build file does *not* influence how the addon or the app using it 14 | behave. You most likely want to be modifying `./index.js` or app's build file 15 | */ 16 | 17 | return app.toTree(); 18 | }; 19 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_page: 'tests/index.html?hidepassed', 3 | disable_watching: true, 4 | launch_in_ci: [ 5 | 'Chrome' 6 | ], 7 | launch_in_dev: [ 8 | 'Chrome' 9 | ], 10 | browser_args: { 11 | Chrome: { 12 | ci: [ 13 | // --no-sandbox is needed when running Chrome inside a container 14 | process.env.CI ? '--no-sandbox' : null, 15 | '--headless', 16 | '--disable-gpu', 17 | '--disable-dev-shm-usage', 18 | '--disable-software-rasterizer', 19 | '--mute-audio', 20 | '--remote-debugging-port=0', 21 | '--window-size=1440,900' 22 | ].filter(Boolean) 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/application.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | options: Object.freeze([ 5 | 'Portugal', 6 | 'USA', 7 | 'Spain', 8 | 'Canada', 9 | 'Italy', 10 | 'Sweden' 11 | ]), 12 | 13 | people: Object.freeze([ 14 | { 15 | name: 'D. Afonso I', 16 | description: 'Founder of the Kingdom of Portugal' 17 | }, 18 | { 19 | name: 'D. Sancho I', 20 | description: 'Son of Aplphonso I' 21 | }, 22 | { 23 | name: 'D. Afonso II', 24 | description: 'Son of Sancius I' 25 | }, 26 | { 27 | name: 'D. Sancho II', 28 | description: 'Son of Alphonso II' 29 | }, 30 | { 31 | name: 'D. Afonso III', 32 | description: 'Son of Alphonso II' 33 | } 34 | ]) 35 | }); 36 | -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ember-paper-selection-dialog demo 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 | -------------------------------------------------------------------------------- /addon/helpers/ember-paper-selection-dialog-is-selected.js: -------------------------------------------------------------------------------- 1 | import { isEqual } from '@ember/utils'; 2 | import { isArray } from '@ember/array'; 3 | import Helper from '@ember/component/helper'; 4 | import { observer } from '@ember/object'; 5 | 6 | export default Helper.extend({ 7 | compute([option, selected]) { 8 | if (selected === undefined || selected === null) { 9 | return false; 10 | } 11 | if (isArray(selected)) { 12 | this.set('array', selected); 13 | for (let i = 0; i < selected.length; i++) { 14 | if (isEqual(selected[i], option)) { 15 | return true; 16 | } 17 | } 18 | return false; 19 | } else { 20 | return isEqual(option, selected); 21 | } 22 | }, 23 | 24 | arrayContentDidChange: observer('array.[]', function() { 25 | this.recompute(); 26 | }) 27 | }); -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 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/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 | {{content-for "body-footer"}} 31 | {{content-for "test-body-footer"}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | ecmaVersion: 2017, 5 | sourceType: 'module' 6 | }, 7 | plugins: [ 8 | 'ember' 9 | ], 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:ember/recommended' 13 | ], 14 | env: { 15 | browser: true 16 | }, 17 | rules: { 18 | }, 19 | overrides: [ 20 | // node files 21 | { 22 | files: [ 23 | '.eslintrc.js', 24 | '.template-lintrc.js', 25 | 'ember-cli-build.js', 26 | 'index.js', 27 | 'testem.js', 28 | 'blueprints/*/index.js', 29 | 'config/**/*.js', 30 | 'tests/dummy/config/**/*.js' 31 | ], 32 | excludedFiles: [ 33 | 'addon/**', 34 | 'addon-test-support/**', 35 | 'app/**', 36 | 'tests/dummy/app/**' 37 | ], 38 | parserOptions: { 39 | sourceType: 'script', 40 | ecmaVersion: 2015 41 | }, 42 | env: { 43 | browser: false, 44 | node: true 45 | }, 46 | plugins: ['node'], 47 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 48 | // add your custom rules and overrides for node files here 49 | }) 50 | } 51 | ] 52 | }; 53 | -------------------------------------------------------------------------------- /app/styles/ember-paper-selection-dialog.scss: -------------------------------------------------------------------------------- 1 | md-dialog { 2 | @media (max-width: $layout-breakpoint-sm - 1) { 3 | min-width: 80%; 4 | } 5 | 6 | &> .md-title { 7 | margin: 0; 8 | padding: $dialog-padding $dialog-padding 20px $dialog-padding; 9 | } 10 | 11 | md-list { 12 | overflow: auto; 13 | padding: 0; 14 | md-list-item .md-no-style { 15 | padding: 0 $dialog-padding; 16 | } 17 | } 18 | 19 | .md-actions, md-dialog-actions { 20 | @include rtl(padding-right, $baseline-grid, $dialog-padding); 21 | @include rtl(padding-left, $dialog-padding, $baseline-grid); 22 | } 23 | } 24 | 25 | md-list-item > md-radio-button, md-list-item .md-list-item-inner > md-radio-button { 26 | width: 24px; 27 | margin-left: 3px; 28 | margin-right: 29px; 29 | margin-top: 14px; 30 | } 31 | 32 | md-list-item > div.md-primary > md-radio-button, md-list-item > div.md-secondary > md-radio-button, md-list-item > md-radio-button, md-list-item md-radio-button.md-secondary, md-list-item .md-list-item-inner > div.md-primary > md-radio-button, md-list-item .md-list-item-inner > div.md-secondary > md-radio-button, md-list-item .md-list-item-inner > md-radio-button, md-list-item .md-list-item-inner md-radio-button.md-secondary { 33 | align-self: center; 34 | } -------------------------------------------------------------------------------- /.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 | - "6" 7 | 8 | sudo: false 9 | dist: trusty 10 | 11 | addons: 12 | chrome: stable 13 | 14 | cache: 15 | directories: 16 | - $HOME/.npm 17 | 18 | env: 19 | global: 20 | # See https://git.io/vdao3 for details. 21 | - JOBS=1 22 | 23 | jobs: 24 | fail_fast: true 25 | allow_failures: 26 | - env: EMBER_TRY_SCENARIO=ember-canary 27 | 28 | include: 29 | # runs linting and tests with current locked deps 30 | 31 | - stage: "Tests" 32 | name: "Tests" 33 | script: 34 | - npm run lint:hbs 35 | - npm run lint:js 36 | - npm test 37 | 38 | # we recommend new addons test the current and previous LTS 39 | # as well as latest stable release (bonus points to beta/canary) 40 | - stage: "Additional Tests" 41 | env: EMBER_TRY_SCENARIO=ember-lts-2.16 42 | - env: EMBER_TRY_SCENARIO=ember-lts-2.18 43 | - env: EMBER_TRY_SCENARIO=ember-release 44 | - env: EMBER_TRY_SCENARIO=ember-beta 45 | - env: EMBER_TRY_SCENARIO=ember-canary 46 | - env: EMBER_TRY_SCENARIO=ember-default-with-jquery 47 | 48 | before_install: 49 | - npm config set spin false 50 | - npm install -g npm@4 51 | - npm --version 52 | 53 | script: 54 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO 55 | -------------------------------------------------------------------------------- /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. 'with-controller': 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 | 46 | if (environment === 'production') { 47 | ENV.locationType = 'hash'; 48 | ENV.rootURL = '/ember-paper-selection-dialog/'; 49 | 50 | } 51 | 52 | return ENV; 53 | }; 54 | -------------------------------------------------------------------------------- /addon/templates/components/paper-selection-dialog.hbs: -------------------------------------------------------------------------------- 1 | {{#paper-dialog 2 | class=class 3 | clickOutsideToClose=clickOutsideToClose 4 | origin=origin 5 | openFrom=openFrom 6 | closeTo=closeTo 7 | escapeToClose=escapeToClose 8 | focusOnOpen=focusOnOpen 9 | fullscreen=fullscreen 10 | parent=parent 11 | onClose=(action "close")}} 12 | 13 | {{#if title}} 14 |

{{title}}

15 | {{/if}} 16 | 17 | {{#if loading}} 18 |
19 | {{paper-progress-circular diameter=130}} 20 |
21 | {{else}} 22 | {{#paper-list class="flex"}} 23 | {{#each _options as |option index|}} 24 | {{#paper-item class=itemClass as |controls|}} 25 | {{#if multiple}} 26 | {{controls.checkbox 27 | value=(ember-paper-selection-dialog-is-selected option _selected) 28 | onChange=(action "updateSelected" option)}} 29 | {{else}} 30 | {{controls.radio 31 | value=option 32 | groupValue=_selected 33 | onChange=(action (mut _selected option))}} 34 | {{/if}} 35 |
36 | {{yield option (ember-paper-selection-dialog-is-selected option _selected) index}} 37 |
38 | {{/paper-item}} 39 | {{else}} 40 | {{#paper-item class="selection-dialog--no-options"}} 41 | {{noOptionsMessage}} 42 | {{/paper-item}} 43 | {{/each}} 44 | {{/paper-list}} 45 | {{/if}} 46 | 47 | {{#paper-dialog-actions class="layout-row"}} 48 | {{#paper-button onClick=(action "close")}} 49 | {{cancelLabel}} 50 | {{/paper-button}} 51 | {{#paper-button primary=true onClick=(action "confirm")}} 52 | {{confirmLabel}} 53 | {{/paper-button}} 54 | {{/paper-dialog-actions}} 55 | 56 | {{/paper-dialog}} -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = function() { 6 | return Promise.all([ 7 | getChannelURL('release'), 8 | getChannelURL('beta'), 9 | getChannelURL('canary') 10 | ]).then((urls) => { 11 | return { 12 | scenarios: [ 13 | { 14 | name: 'ember-lts-2.16', 15 | env: { 16 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }), 17 | }, 18 | npm: { 19 | devDependencies: { 20 | '@ember/jquery': '^0.5.1', 21 | 'ember-source': '~2.16.0' 22 | } 23 | } 24 | }, 25 | { 26 | name: 'ember-lts-2.18', 27 | env: { 28 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }), 29 | }, 30 | npm: { 31 | devDependencies: { 32 | '@ember/jquery': '^0.5.1', 33 | 'ember-source': '~2.18.0' 34 | } 35 | } 36 | }, 37 | { 38 | name: 'ember-release', 39 | npm: { 40 | devDependencies: { 41 | 'ember-source': urls[0] 42 | } 43 | } 44 | }, 45 | { 46 | name: 'ember-beta', 47 | npm: { 48 | devDependencies: { 49 | 'ember-source': urls[1] 50 | } 51 | } 52 | }, 53 | { 54 | name: 'ember-canary', 55 | npm: { 56 | devDependencies: { 57 | 'ember-source': urls[2] 58 | } 59 | } 60 | }, 61 | { 62 | name: 'ember-default', 63 | npm: { 64 | devDependencies: {} 65 | } 66 | }, 67 | { 68 | name: 'ember-default-with-jquery', 69 | env: { 70 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 71 | 'jquery-integration': true 72 | }) 73 | }, 74 | npm: { 75 | devDependencies: { 76 | '@ember/jquery': '^0.5.1' 77 | } 78 | } 79 | } 80 | ] 81 | }; 82 | }); 83 | }; 84 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-paper-selection-dialog", 3 | "version": "0.0.5", 4 | "description": "The default blueprint for ember-cli addons.", 5 | "keywords": [ 6 | "ember-addon" 7 | ], 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/CoachLogix/ember-paper-selection-dialog.git" 11 | }, 12 | "license": "MIT", 13 | "author": "Miguel Andrade ", 14 | "directories": { 15 | "doc": "doc", 16 | "test": "tests" 17 | }, 18 | "scripts": { 19 | "build": "ember build", 20 | "lint:hbs": "ember-template-lint .", 21 | "lint:js": "eslint .", 22 | "start": "ember serve", 23 | "test": "ember test", 24 | "test:all": "ember try:each" 25 | }, 26 | "dependencies": { 27 | "ember-cli-babel": "^6.16.0", 28 | "ember-cli-htmlbars": "^3.0.0" 29 | }, 30 | "devDependencies": { 31 | "@ember/jquery": "^0.5.2", 32 | "@ember/optional-features": "^0.6.3", 33 | "broccoli-asset-rev": "^2.7.0", 34 | "ember-ajax": "^3.1.0", 35 | "ember-cli": "~3.5.0", 36 | "ember-cli-dependency-checker": "^3.0.0", 37 | "ember-cli-eslint": "^4.2.3", 38 | "ember-cli-github-pages": "^0.2.0", 39 | "ember-cli-htmlbars-inline-precompile": "^1.0.3", 40 | "ember-cli-inject-live-reload": "^1.8.2", 41 | "ember-cli-sass": "^6.1.1", 42 | "ember-cli-sri": "^2.1.1", 43 | "ember-cli-template-lint": "^1.0.0-beta.1", 44 | "ember-cli-uglify": "^2.1.0", 45 | "ember-disable-prototype-extensions": "^1.1.3", 46 | "ember-export-application-global": "^2.0.0", 47 | "ember-load-initializers": "^1.1.0", 48 | "ember-maybe-import-regenerator": "^0.1.6", 49 | "ember-paper": "^1.0.0-beta.18", 50 | "ember-qunit": "^3.4.1", 51 | "ember-resolver": "^5.0.1", 52 | "ember-source": "~3.5.0", 53 | "ember-source-channel-url": "^1.1.0", 54 | "ember-try": "^1.0.0", 55 | "eslint-plugin-ember": "^5.2.0", 56 | "eslint-plugin-ember-suave": "^1.0.0", 57 | "eslint-plugin-node": "^7.0.1", 58 | "loader.js": "^4.7.0", 59 | "qunit-dom": "^0.8.0" 60 | }, 61 | "engines": { 62 | "node": "6.* || 8.* || >= 10.*" 63 | }, 64 | "ember-addon": { 65 | "configPath": "tests/dummy/config", 66 | "demoURL": "https://coachlogix.github.io/ember-paper-selection-dialog/" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /addon/components/paper-selection-dialog.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import RSVP from 'rsvp'; 3 | import layout from '../templates/components/paper-selection-dialog'; 4 | 5 | export default Component.extend({ 6 | layout, 7 | tagName: '', 8 | 9 | // paper dialog truthy defaults 10 | focusOnOpen: true, 11 | escapeToClose: true, 12 | 13 | multiple: false, 14 | closeOnConfirm: true, 15 | 16 | itemClass: '', 17 | 18 | cancelLabel: 'Cancel', 19 | confirmLabel: 'OK', 20 | noOptionsMessage: 'No options.', 21 | 22 | didReceiveAttrs() { 23 | let promises = []; 24 | 25 | let options = this.get('options') || []; 26 | if (options && options.then) { 27 | this.set('loading', true); 28 | let optPromise = options.then((resolvedOptions) => { 29 | this.updateOptions(resolvedOptions); 30 | }); 31 | promises.push(optPromise); 32 | } else { 33 | this.updateOptions(options); 34 | } 35 | 36 | let selected = this.get('selected'); 37 | if (selected && selected.then) { 38 | this.set('loading', true); 39 | let selPromise = selected.then((resolvedSelected) => { 40 | this.updateSelection(resolvedSelected); 41 | }); 42 | promises.push(selPromise); 43 | } else { 44 | this.updateSelection(selected); 45 | } 46 | 47 | RSVP.all(promises).then(() => { 48 | this.set('loading', false); 49 | }); 50 | }, 51 | 52 | updateOptions(options) { 53 | this.set('_options', options); 54 | }, 55 | 56 | updateSelection(selected) { 57 | let newSelection; 58 | if (this.get('multiple')) { 59 | newSelection = (selected || []).slice(0); 60 | } else { 61 | newSelection = selected; 62 | } 63 | this.set('_selected', newSelection); 64 | }, 65 | 66 | buildSelection(option, selected) { 67 | let newSelection = (selected || []).slice(0); 68 | let idx = newSelection.indexOf(option); 69 | if (idx > -1) { 70 | newSelection.splice(idx, 1); 71 | } else { 72 | newSelection.push(option); 73 | } 74 | return newSelection; 75 | }, 76 | 77 | actions: { 78 | updateSelected(option) { 79 | let newSelection = this.buildSelection(option, this.get('_selected')); 80 | this.set('_selected', newSelection); 81 | }, 82 | 83 | confirm() { 84 | if (this.get('onSelect')) { 85 | this.get('onSelect')(this.get('_selected')); 86 | } 87 | if (this.get('closeOnConfirm')) { 88 | if (this.get('onClose')) { 89 | this.get('onClose')(); 90 | } 91 | } 92 | }, 93 | 94 | close() { 95 | if (this.get('onClose')) { 96 | this.get('onClose')(); 97 | } 98 | } 99 | } 100 | }); 101 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 | {{#if showSingle}} 2 | {{#paper-selection-dialog 3 | title="Country" origin=".single-button" class="flex-gt-sm-30" 4 | options=options selected=singleSelected 5 | onSelect=(action (mut singleSelected)) onClose=(action (mut showSingle) false) as |option|}} 6 | {{option}} 7 | {{/paper-selection-dialog}} 8 | {{/if}} 9 | 10 | {{#if showMultiple}} 11 | {{#paper-selection-dialog 12 | title="Countries" origin=".multiple-button" class="flex-gt-sm-30" 13 | options=options selected=multipleSelected multiple=true 14 | onSelect=(action (mut multipleSelected)) onClose=(action (mut showMultiple) false) as |option|}} 15 | {{option}} 16 | {{/paper-selection-dialog}} 17 | {{/if}} 18 | 19 | {{#if showCustom}} 20 | {{#paper-selection-dialog 21 | title="People" origin=".custom-button" class="flex-gt-sm-30" itemClass="md-2-line" 22 | options=people selected=customSelected 23 | onSelect=(action (mut customSelected)) onClose=(action (mut showCustom) false) as |option|}} 24 |

{{option.name}}

25 |

{{option.description}}

26 | {{/paper-selection-dialog}} 27 | {{/if}} 28 | 29 |
30 | 31 |

paper selection dialog demo

32 | 33 |
34 | 35 |
36 | {{#paper-button class="single-button" primary=true raised=true onClick=(action (mut showSingle) true)}} 37 | Show single selection dialog 38 | {{/paper-button}} 39 | 40 |

41 | {{#if singleSelected}} 42 | You selected {{singleSelected}}. 43 | {{else}} 44 | No country was selected. Click the button above. 45 | {{/if}} 46 |

47 |
48 | 49 |
50 | {{#paper-button class="multiple-button" primary=true raised=true onClick=(action (mut showMultiple) true)}} 51 | Show multiple selection dialog 52 | {{/paper-button}} 53 | 54 | {{if multipleSelected "You selected:"}} 55 | 56 |
    57 | {{#each multipleSelected as |country|}} 58 |
  • {{country}}
  • 59 | {{else}} 60 |
  • No countries were selected. Click the button above.
  • 61 | {{/each}} 62 |
63 | 64 |
65 | 66 |
67 | {{#paper-button class="custom-button" primary=true raised=true onClick=(action (mut showCustom) true)}} 68 | Show custom selection dialog 69 | {{/paper-button}} 70 | 71 |

72 | {{#if customSelected}} 73 | You selected {{customSelected.name}}. 74 | {{else}} 75 | No country was selected. Click the button above. 76 | {{/if}} 77 |

78 | 79 |
80 |
81 | 82 |
83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-paper-selection-dialog [![Build Status](https://travis-ci.org/CoachLogix/ember-paper-selection-dialog.svg?branch=master)](https://travis-ci.org/CoachLogix/ember-paper-selection-dialog) [![Ember Observer Score](http://emberobserver.com/badges/ember-paper-selection-dialog.svg)](http://emberobserver.com/addons/ember-paper-selection-dialog) 2 | 3 | This is an [ember-paper](https://github.com/miguelcobain/ember-paper) addon that provides dialogs for selections. Think of it as a select component, but using dialogs. 4 | 5 | ## Usage 6 | 7 | An example usage: 8 | 9 | ```hbs 10 | {{#paper-selection-dialog 11 | title="Select a country" class="flex-50" fullscreen=true 12 | options=options selected=singleSelected 13 | onSelect=(action (mut singleSelected)) onClose=(action (mut showSingle) false) as |option index selected|}} 14 | {{option}} {{if selected "Yay, I'm selected"}} #{{index}} 15 | {{/paper-selection-dialog}} 16 | ``` 17 | 18 | The component is promise friendly, meaning that it accepts promises in `options` or `selected` properties and will display a `{{paper-circular-progress}}` until both are resolved. 19 | 20 | You must specify how you want to render each item in the component's block. Each option is yielded to the block, along with its index. A boolean is also yielded to let you know if that option is currently selected or not. 21 | 22 | ## Demo 23 | 24 | You can see how this addon looks like at https://coachlogix.github.io/ember-paper-selection-dialog/ 25 | 26 | ## Installation 27 | 28 | Run: 29 | 30 | ```bash 31 | ember install ember-paper-selection-dialog 32 | ``` 33 | 34 | Don't forget to import your styles in your `app.scss` **after** importing ember paper styles: 35 | 36 | ```scss 37 | @import "ember-paper"; 38 | @import "ember-paper-selection-dialog"; 39 | ``` 40 | 41 | ## API 42 | 43 | - All the properties that `paper-dialog` supports. 44 | - `multiple` - defaults to `false` - set it to `true` to support multiple selections. 45 | - `options` - an array or promise that resolves to an array that contains the possible options to choose from. 46 | - `selected` - the currently selected items. Can also be a promise. 47 | - `onSelect` - an action sent when the user clicks the confirm button. Will contain an option on single mode and an array of options on multiple mode. 48 | - `onClose` - an action sent when the cancel or close button are pressed (also sent every time `paper-dialog` sends it) 49 | - `cancelLabel` - defaults to `'Cancel'` - you can specify an alternate text for the cancel button 50 | - `confirmLabel` - defaults to `'Confirm'` - you can specify an alternate text for the confirm button 51 | - `title` - the displayed title of the dialog 52 | - `closeOnConfirm` - defaults to `true` - by default the component will also send the `onClose` action when you click the confirm button 53 | - `noOptionsMessage` - defaults to `'No options.'` - you can specify a message to show when `options` is or resolves to a falsy value 54 | 55 | Contributing 56 | ------------------------------------------------------------------------------ 57 | 58 | ### Installation 59 | 60 | * `git clone ` 61 | * `cd my-addon` 62 | * `npm install` 63 | 64 | ### Linting 65 | 66 | * `npm run lint:hbs` 67 | * `npm run lint:js` 68 | * `npm run lint:js -- --fix` 69 | 70 | ### Running tests 71 | 72 | * `ember test` – Runs the test suite on the current Ember version 73 | * `ember test --server` – Runs the test suite in "watch mode" 74 | * `ember try:each` – Runs the test suite against multiple Ember versions 75 | 76 | ### Running the dummy application 77 | 78 | * `ember serve` 79 | * Visit the dummy application at [http://localhost:4200](http://localhost:4200). 80 | 81 | For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/). 82 | 83 | License 84 | ------------------------------------------------------------------------------ 85 | 86 | This project is licensed under the [MIT License](LICENSE.md). 87 | -------------------------------------------------------------------------------- /tests/integration/components/paper-selection-dialog-test.js: -------------------------------------------------------------------------------- 1 | import RSVP from 'rsvp'; 2 | import { module, test } from 'qunit'; 3 | import { setupRenderingTest } from 'ember-qunit'; 4 | import { render, settled, click, findAll } from '@ember/test-helpers'; 5 | import hbs from 'htmlbars-inline-precompile'; 6 | 7 | module('Integration | Component | paper selection dialog', function(hooks) { 8 | setupRenderingTest(hooks); 9 | 10 | test('it renders the correct title', async function(assert) { 11 | assert.expect(1); 12 | 13 | await render(hbs` 14 | {{paper-selection-dialog title="some title"}} 15 | `); 16 | 17 | return settled().then(() => { 18 | assert.dom('h2').hasText('some title', 'rendered correct title'); 19 | }); 20 | }); 21 | 22 | test('it renders `cancelLabel` if provided', async function(assert) { 23 | assert.expect(1); 24 | 25 | await render(hbs` 26 | {{paper-selection-dialog cancelLabel="a cancel label"}} 27 | `); 28 | 29 | 30 | assert.dom('.md-button:nth-child(1)').hasText('a cancel label', 'rendered cancel label'); 31 | }); 32 | 33 | test('it renders `confirmLabel` if provided', async function(assert) { 34 | assert.expect(1); 35 | 36 | await render(hbs` 37 | {{paper-selection-dialog confirmLabel="a confirm label"}} 38 | `); 39 | 40 | assert.dom('.md-button:nth-child(2)').hasText('a confirm label', 'rendered confirm label'); 41 | }); 42 | 43 | let numbers = [1, 2, 3]; 44 | 45 | test('it renders the correct options (single mode)', async function(assert) { 46 | assert.expect(5); 47 | 48 | this.options = numbers; 49 | 50 | await render(hbs` 51 | {{#paper-selection-dialog options=options as |option|}} 52 | {{option}} 53 | {{/paper-selection-dialog}} 54 | `); 55 | 56 | assert.dom('md-list-item').exists({ count: 3 }, 'rendered 3 options'); 57 | assert.dom('md-radio-button').exists({ count: 3 }, 'rendered 3 radio buttons'); 58 | 59 | numbers.forEach((item, i) => { 60 | assert.dom(`md-list-item:nth-child(${i + 1})`).hasText(`${item}`, `rendered the correct text for option ${item}`); 61 | }); 62 | }); 63 | 64 | test('it renders the correct options (multiple mode)', async function(assert) { 65 | assert.expect(5); 66 | 67 | this.options = numbers; 68 | 69 | await render(hbs` 70 | {{#paper-selection-dialog multiple=true options=options as |option|}} 71 | {{option}} 72 | {{/paper-selection-dialog}} 73 | `); 74 | 75 | assert.dom('md-list-item').exists({ count: 3 }, 'rendered 3 options'); 76 | assert.dom('md-checkbox').exists({ count: 3 }, 'rendered 3 radio buttons'); 77 | 78 | numbers.forEach((item, i) => { 79 | assert.dom(`md-list-item:nth-child(${i + 1})`).hasText(`${item}`, `rendered the correct text for option ${item}`); 80 | }); 81 | }); 82 | 83 | test('it supports promises as options', async function(assert) { 84 | assert.expect(4); 85 | 86 | this.options = RSVP.Promise.resolve(numbers); 87 | 88 | await render(hbs` 89 | {{#paper-selection-dialog options=options as |option|}} 90 | {{option}} 91 | {{/paper-selection-dialog}} 92 | `); 93 | 94 | assert.dom('md-list-item').exists({ count: 3 }, 'rendered 3 options'); 95 | 96 | numbers.forEach((item, i) => { 97 | assert.dom(`md-list-item:nth-child(${i + 1})`).hasText(`${item}`, `rendered the correct text for option ${item}`); 98 | }); 99 | }); 100 | 101 | test('it displays a loading indicator while options promise doesn\'t resolve', async function(assert) { 102 | assert.expect(2); 103 | 104 | this.options = new RSVP.Promise(() => { }); 105 | 106 | await render(hbs` 107 | {{#paper-selection-dialog options=options as |option|}} 108 | {{option}} 109 | {{/paper-selection-dialog}} 110 | `); 111 | 112 | assert.dom('md-list-item').doesNotExist('no options were rendered'); 113 | assert.dom('md-progress-circular').exists({ count: 1 }, 'a progress circular was rendered'); 114 | }); 115 | 116 | test('it displays a loading indicator while selected promise doesn\'t resolve', async function(assert) { 117 | assert.expect(2); 118 | 119 | this.options = numbers; 120 | this.selected = new RSVP.Promise(() => { }); 121 | 122 | await render(hbs` 123 | {{#paper-selection-dialog selected=selected options=options as |option|}} 124 | {{option}} 125 | {{/paper-selection-dialog}} 126 | `); 127 | 128 | assert.dom('md-list-item').doesNotExist('no options were rendered'); 129 | assert.dom('md-progress-circular').exists({ count: 1 }, 'a progress circular was rendered'); 130 | }); 131 | 132 | test('selecting an option doesn\'t mutate the `selected` property (single mode)', async function(assert) { 133 | assert.expect(2); 134 | 135 | this.options = numbers; 136 | this.selected = 3; 137 | 138 | await render(hbs` 139 | {{#paper-selection-dialog selected=selected options=options as |option|}} 140 | {{option}} 141 | {{/paper-selection-dialog}} 142 | `); 143 | 144 | assert.equal(this.selected, 3, 'selected is 3'); 145 | 146 | // click option 1 147 | await click(findAll('md-radio-button')[0]); 148 | assert.equal(this.selected, 3, 'selected didn\'t change (is still 3)'); 149 | }); 150 | 151 | test('selecting an option doesn\'t mutate the `selected` property (multiple mode)', async function(assert) { 152 | assert.expect(2); 153 | 154 | this.options = numbers; 155 | this.selected = [3]; 156 | 157 | await render(hbs` 158 | {{#paper-selection-dialog multiple=true selected=selected options=options as |option|}} 159 | {{option}} 160 | {{/paper-selection-dialog}} 161 | `); 162 | 163 | assert.deepEqual(this.selected, [3], 'selected is [3]'); 164 | 165 | // click option 1 166 | await click(findAll('md-checkbox')[0]); 167 | assert.deepEqual(this.selected, [3], 'selected didn\'t change (is still [3])'); 168 | }); 169 | 170 | test('selecting an option and pressing confirm button triggers an action with the new selection (single mode)', async function(assert) { 171 | assert.expect(1); 172 | 173 | this.options = numbers; 174 | this.onSelect = (selection) => { 175 | assert.equal(selection, 1, 'selection is 1'); 176 | }; 177 | 178 | await render(hbs` 179 | {{#paper-selection-dialog selected=selected options=options onSelect=(action onSelect) as |option|}} 180 | {{option}} 181 | {{/paper-selection-dialog}} 182 | `); 183 | 184 | // click option 1 185 | await click(findAll('md-radio-button')[0]); 186 | 187 | // click confirm button 188 | await click(findAll('.md-button')[1]); 189 | }); 190 | 191 | test('selecting an option and pressing confirm button sends an action with the new selection (multiple mode)', async function(assert) { 192 | assert.expect(1); 193 | 194 | this.options = numbers; 195 | this.onSelect = (selection) => { 196 | assert.deepEqual(selection, [1, 2], 'selection is [1, 2]'); 197 | }; 198 | 199 | await render(hbs` 200 | {{#paper-selection-dialog multiple=true selected=selected options=options onSelect=(action onSelect) as |option|}} 201 | {{option}} 202 | {{/paper-selection-dialog}} 203 | `); 204 | 205 | // click option 1 and 2 206 | await click(findAll('md-checkbox')[0]); 207 | await click(findAll('md-checkbox')[1]); 208 | 209 | // click confirm button 210 | await click(findAll('.md-button')[1]); 211 | }); 212 | 213 | test('shows correct option selected (single mode)', async function(assert) { 214 | assert.expect(2); 215 | 216 | this.options = numbers; 217 | this.selected = 3; 218 | 219 | await render(hbs` 220 | {{#paper-selection-dialog selected=selected options=options as |option|}} 221 | {{option}} 222 | {{/paper-selection-dialog}} 223 | `); 224 | 225 | assert.dom('md-radio-button.md-checked').exists({ count: 1 }, 'one radio button is checked'); 226 | assert.dom(findAll('md-radio-button.md-checked')[0].parentNode).hasText('3', 'and it is the correct one'); 227 | }); 228 | 229 | test('shows correct options selected (multiple mode)', async function(assert) { 230 | assert.expect(3); 231 | 232 | this.options = numbers; 233 | this.selected = [2, 3]; 234 | 235 | await render(hbs` 236 | {{#paper-selection-dialog multiple=true selected=selected options=options as |option|}} 237 | {{option}} 238 | {{/paper-selection-dialog}} 239 | `); 240 | 241 | assert.dom('md-checkbox.md-checked').exists({ count: 2 }, 'two checkboxes are checked'); 242 | 243 | this.selected.forEach((item, i) => { 244 | assert.dom(findAll('md-checkbox.md-checked')[i].parentNode).hasText(`${item}`, `${item} is selected`); 245 | }); 246 | }); 247 | 248 | test('pressing cancel button sends `onClose` action', async function(assert) { 249 | assert.expect(1); 250 | 251 | this.options = numbers; 252 | this.onClose = () => { 253 | assert.ok(true); 254 | }; 255 | 256 | await render(hbs` 257 | {{#paper-selection-dialog onClose=(action onClose) as |option|}} 258 | {{option}} 259 | {{/paper-selection-dialog}} 260 | `); 261 | 262 | click('.md-button'); 263 | }); 264 | 265 | test('can specify paper-item class using `itemClass` property', async function(assert) { 266 | assert.expect(1); 267 | 268 | this.options = numbers; 269 | 270 | await render(hbs` 271 | {{#paper-selection-dialog options=options itemClass="some-class" as |option|}} 272 | {{option}} 273 | {{/paper-selection-dialog}} 274 | `); 275 | 276 | assert.dom('.some-class').exists({ count: 3 }, 'rendered 3 options with custom class'); 277 | }); 278 | 279 | test('it renders a default message if options are empty', async function(assert) { 280 | assert.expect(3); 281 | 282 | this.options = []; 283 | 284 | await render(hbs` 285 | {{#paper-selection-dialog options=options as |option|}} 286 | {{option}} 287 | {{/paper-selection-dialog}} 288 | `); 289 | 290 | assert.dom('md-list-item').exists({ count: 1 }, 'rendered 1 item'); 291 | assert.dom('md-radio-button').doesNotExist('rendered 0 radio buttons'); 292 | assert.dom('.selection-dialog--no-options').hasText('No options.'); 293 | }); 294 | 295 | test('it renders a custom message if options are empty', async function(assert) { 296 | assert.expect(3); 297 | 298 | this.options = []; 299 | 300 | await render(hbs` 301 | {{#paper-selection-dialog options=options noOptionsMessage="no options, mate" as |option|}} 302 | {{option}} 303 | {{/paper-selection-dialog}} 304 | `); 305 | 306 | assert.dom('md-list-item').exists({ count: 1 }, 'rendered 1 item'); 307 | assert.dom('md-radio-button').doesNotExist('rendered 0 radio buttons'); 308 | assert.dom('.selection-dialog--no-options').hasText('no options, mate'); 309 | }); 310 | }); 311 | --------------------------------------------------------------------------------