├── app ├── .gitkeep ├── components │ ├── paper-expansion-panel.js │ └── paper-expansion-panel │ │ ├── collapsed.js │ │ ├── expanded.js │ │ └── expanded │ │ ├── footer.js │ │ ├── header.js │ │ └── content.js └── styles │ └── ember-paper-expansion-panel.scss ├── addon ├── .gitkeep ├── templates │ └── components │ │ ├── paper-expansion-panel │ │ ├── expanded │ │ │ ├── content.hbs │ │ │ ├── footer.hbs │ │ │ └── header.hbs │ │ ├── collapsed.hbs │ │ └── expanded.hbs │ │ └── paper-expansion-panel.hbs └── components │ ├── paper-expansion-panel │ ├── expanded.js │ ├── collapsed.js │ └── expanded │ │ ├── footer.js │ │ ├── header.js │ │ └── content.js │ └── paper-expansion-panel.js ├── vendor └── .gitkeep ├── tests ├── helpers │ └── .gitkeep ├── unit │ └── .gitkeep ├── integration │ ├── .gitkeep │ └── components │ │ └── paper-expansion-panel-test.js ├── dummy │ ├── app │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── models │ │ │ └── .gitkeep │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ ├── .gitkeep │ │ │ └── application.js │ │ ├── templates │ │ │ ├── components │ │ │ │ └── .gitkeep │ │ │ └── application.hbs │ │ ├── resolver.js │ │ ├── router.js │ │ ├── styles │ │ │ └── app.scss │ │ ├── app.js │ │ └── index.html │ ├── public │ │ └── robots.txt │ └── config │ │ ├── targets.js │ │ └── environment.js ├── test-helper.js └── index.html ├── .watchmanconfig ├── bower.json ├── index.js ├── config ├── environment.js └── ember-try.js ├── .ember-cli ├── .npmignore ├── .gitignore ├── .editorconfig ├── 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 | -------------------------------------------------------------------------------- /addon/templates/components/paper-expansion-panel/expanded/content.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-paper-expansion-panel", 3 | "dependencies": {} 4 | } 5 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: 'ember-paper-expansion-panel' 5 | }; 6 | -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /app/components/paper-expansion-panel.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-paper-expansion-panel/components/paper-expansion-panel'; -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /app/components/paper-expansion-panel/collapsed.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-paper-expansion-panel/components/paper-expansion-panel/collapsed'; -------------------------------------------------------------------------------- /app/components/paper-expansion-panel/expanded.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-paper-expansion-panel/components/paper-expansion-panel/expanded'; -------------------------------------------------------------------------------- /app/components/paper-expansion-panel/expanded/footer.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-paper-expansion-panel/components/paper-expansion-panel/expanded/footer'; -------------------------------------------------------------------------------- /app/components/paper-expansion-panel/expanded/header.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-paper-expansion-panel/components/paper-expansion-panel/expanded/header'; -------------------------------------------------------------------------------- /app/components/paper-expansion-panel/expanded/content.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-paper-expansion-panel/components/paper-expansion-panel/expanded/content'; -------------------------------------------------------------------------------- /addon/templates/components/paper-expansion-panel/expanded/footer.hbs: -------------------------------------------------------------------------------- 1 | {{paper-divider}} 2 | 3 | {{yield}} 4 | -------------------------------------------------------------------------------- /addon/templates/components/paper-expansion-panel/expanded/header.hbs: -------------------------------------------------------------------------------- 1 | {{#paper-item class=class onClick=onClose noink=true as |controls|}} 2 | {{yield controls}} 3 | {{/paper-item}} 4 | -------------------------------------------------------------------------------- /addon/components/paper-expansion-panel/expanded.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import layout from '../../templates/components/paper-expansion-panel/expanded'; 3 | 4 | export default Component.extend({ 5 | layout, 6 | tagName: '' 7 | }); 8 | -------------------------------------------------------------------------------- /addon/components/paper-expansion-panel/collapsed.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import layout from '../../templates/components/paper-expansion-panel/collapsed'; 3 | 4 | export default Component.extend({ 5 | layout, 6 | tagName: '' 7 | }); 8 | -------------------------------------------------------------------------------- /addon/components/paper-expansion-panel/expanded/footer.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import layout from '../../../templates/components/paper-expansion-panel/expanded/footer'; 3 | 4 | export default Component.extend({ 5 | layout, 6 | tagName: '' 7 | }); 8 | -------------------------------------------------------------------------------- /addon/components/paper-expansion-panel/expanded/header.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import layout from '../../../templates/components/paper-expansion-panel/expanded/header'; 3 | 4 | export default Component.extend({ 5 | layout, 6 | tagName: '' 7 | }); 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /addon/templates/components/paper-expansion-panel/collapsed.hbs: -------------------------------------------------------------------------------- 1 | {{#unless expanded}} 2 | {{#paper-item class=class onClick=(action onExpand) 3 | onMouseEnter=onMouseEnter 4 | onMouseLeave=onMouseLeave as |controls|}} 5 | {{yield controls}} 6 | {{/paper-item}} 7 | {{/unless}} -------------------------------------------------------------------------------- /addon/components/paper-expansion-panel/expanded/content.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import layout from '../../../templates/components/paper-expansion-panel/expanded/content'; 3 | 4 | export default Component.extend({ 5 | layout, 6 | tagName: 'md-expansion-panel-content' 7 | }); 8 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/application.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | items: Object.freeze([ 5 | 1, 2, 3, 4, 5 6 | ]), 7 | 8 | actions: { 9 | alert() { 10 | this.set('dialogOpen', true); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /addon/templates/components/paper-expansion-panel/expanded.hbs: -------------------------------------------------------------------------------- 1 | {{#if expanded}} 2 | {{yield (hash 3 | header=(component "paper-expansion-panel/expanded/header" onClose=onClose) 4 | content=(component "paper-expansion-panel/expanded/content") 5 | footer=(component "paper-expansion-panel/expanded/footer") 6 | )}} 7 | {{/if}} -------------------------------------------------------------------------------- /addon/templates/components/paper-expansion-panel.hbs: -------------------------------------------------------------------------------- 1 | {{yield (hash 2 | collapsed=(component "paper-expansion-panel/collapsed" expanded=expanded onExpand=(action expand)) 3 | expanded=(component "paper-expansion-panel/expanded" expanded=expanded onClose=(action collapse)) 4 | collapse=(action collapse) 5 | expand=(action expand) 6 | isExpanded=expanded 7 | )}} 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /bower_components 2 | /config/ember-try.js 3 | /dist 4 | /tests 5 | /tmp 6 | **/.gitkeep 7 | .bowerrc 8 | .editorconfig 9 | .ember-cli 10 | .eslintrc.js 11 | .gitignore 12 | .watchmanconfig 13 | .travis.yml 14 | bower.json 15 | ember-cli-build.js 16 | testem.js 17 | 18 | # ember-try 19 | .node_modules.ember-try/ 20 | bower.json.ember-try 21 | package.json.ember-try 22 | -------------------------------------------------------------------------------- /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/styles/app.scss: -------------------------------------------------------------------------------- 1 | @import "ember-paper"; 2 | @import "ember-paper-expansion-panel"; 3 | 4 | body { 5 | background: #F6F7FC; 6 | padding: 80px; 7 | 8 | @media screen and (max-width: 600px) { 9 | padding: 20px; 10 | } 11 | } 12 | 13 | .md-subheader { 14 | background-color: transparent; 15 | } 16 | 17 | md-expansion-panel .actions { 18 | display: flex; 19 | 20 | .md-button { 21 | margin: 0; 22 | } 23 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log* 17 | yarn-error.log 18 | testem.log 19 | 20 | # ember-try 21 | .node_modules.ember-try/ 22 | bower.json.ember-try 23 | package.json.ember-try 24 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | mode: 'ci', 13 | args: [ 14 | // --no-sandbox is needed when running Chrome inside a container 15 | process.env.TRAVIS ? '--no-sandbox' : null, 16 | 17 | '--disable-gpu', 18 | '--headless', 19 | '--remote-debugging-port=0', 20 | '--window-size=1440,900' 21 | ].filter(Boolean) 22 | } 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ember-paper-expansion-panel 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/components/paper-expansion-panel.js: -------------------------------------------------------------------------------- 1 | import Component from '@ember/component'; 2 | import layout from '../templates/components/paper-expansion-panel'; 3 | 4 | export default Component.extend({ 5 | layout, 6 | tagName: 'md-expansion-panel', 7 | classNameBindings: ['expanded:md-open:md-close'], 8 | 9 | expanded: false, 10 | 11 | expand(event) { 12 | this.set('expanded', true); 13 | if (this.get('onExpandedChange')) { 14 | this.get('onExpandedChange')(true, event); 15 | } 16 | }, 17 | 18 | collapse(event) { 19 | this.set('expanded', false); 20 | if (this.get('onExpandedChange')) { 21 | this.get('onExpandedChange')(false, event); 22 | } 23 | }, 24 | 25 | keyDown(ev) { 26 | switch (ev.keyCode) { 27 | case 13: // enter 28 | this.expand(); 29 | break; 30 | case 27: // escape 31 | this.collapse(); 32 | break; 33 | } 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | 'ember-cli-build.js', 24 | 'index.js', 25 | 'testem.js', 26 | 'config/**/*.js', 27 | 'tests/dummy/config/**/*.js' 28 | ], 29 | excludedFiles: [ 30 | 'addon/**', 31 | 'addon-test-support/**', 32 | 'app/**', 33 | 'tests/dummy/app/**' 34 | ], 35 | parserOptions: { 36 | sourceType: 'script', 37 | ecmaVersion: 2015 38 | }, 39 | env: { 40 | browser: false, 41 | node: true 42 | }, 43 | plugins: ['node'], 44 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 45 | // add your custom rules and overrides for node files here 46 | }) 47 | } 48 | ] 49 | }; 50 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | - "4" 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 | matrix: 23 | # we recommend new addons test the current and previous LTS 24 | # as well as latest stable release (bonus points to beta/canary) 25 | - EMBER_TRY_SCENARIO=ember-lts-2.12 26 | - EMBER_TRY_SCENARIO=ember-lts-2.16 27 | - EMBER_TRY_SCENARIO=ember-lts-2.18 28 | - EMBER_TRY_SCENARIO=ember-release 29 | - EMBER_TRY_SCENARIO=ember-beta 30 | - EMBER_TRY_SCENARIO=ember-canary 31 | - EMBER_TRY_SCENARIO=ember-default 32 | 33 | matrix: 34 | fast_finish: true 35 | allow_failures: 36 | - env: EMBER_TRY_SCENARIO=ember-canary 37 | 38 | before_install: 39 | - npm config set spin false 40 | - npm install -g npm@4 41 | - npm --version 42 | 43 | script: 44 | - npm run lint:js 45 | # Usually, it's ok to finish the test scenario without reverting 46 | # to the addon's original dependency state, skipping "cleanup". 47 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO --skip-cleanup 48 | -------------------------------------------------------------------------------- /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 | // here you can enable a production-specific feature 48 | } 49 | 50 | return ENV; 51 | }; 52 | -------------------------------------------------------------------------------- /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.12', 15 | npm: { 16 | devDependencies: { 17 | 'ember-source': '~2.12.0' 18 | } 19 | } 20 | }, 21 | { 22 | name: 'ember-lts-2.16', 23 | npm: { 24 | devDependencies: { 25 | 'ember-source': '~2.16.0' 26 | } 27 | } 28 | }, 29 | { 30 | name: 'ember-lts-2.18', 31 | npm: { 32 | devDependencies: { 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 | }; 69 | }); 70 | }; 71 | -------------------------------------------------------------------------------- /app/styles/ember-paper-expansion-panel.scss: -------------------------------------------------------------------------------- 1 | md-expansion-panel { 2 | display: block; 3 | position: relative; 4 | outline: none; 5 | margin-top: 0; 6 | margin-bottom: 0; 7 | padding: 0; 8 | background-color: #fff; 9 | box-shadow: 0 -1px 0 #e5e5e5, 10 | 0 0 2px rgba(0,0,0,.12), 11 | 0 2px 4px rgba(0,0,0,.24); 12 | 13 | // first panel only has top round corners 14 | &:first-of-type { 15 | border-top-left-radius: 2px; 16 | border-top-right-radius: 2px; 17 | } 18 | 19 | // last panel only has bottom round corners 20 | &:last-of-type { 21 | border-bottom-left-radius: 2px; 22 | border-bottom-right-radius: 2px; 23 | } 24 | 25 | &.md-open { 26 | margin-top: 16px; 27 | margin-bottom: 16px; 28 | border-radius: 2px; 29 | 30 | &:first-of-type { 31 | margin-top: 0; 32 | } 33 | } 34 | 35 | &:not(.md-no-animation) { 36 | &.md-open { 37 | transition: margin-top 0.12s cubic-bezier(0.25, 0.8, 0.25, 1), 38 | margin-bottom 0.12s cubic-bezier(0.25, 0.8, 0.25, 1); 39 | } 40 | 41 | &.md-close { 42 | transition: margin-top 0.08s cubic-bezier(0.25, 0.8, 0.25, 1), 43 | margin-bottom 0.08s cubic-bezier(0.25, 0.8, 0.25, 1); 44 | } 45 | } 46 | 47 | // paper-item has 16px and not 24px 48 | md-list-item.md-no-proxy, md-list-item .md-no-style { 49 | padding: 0 24px; 50 | } 51 | 52 | .md-panel-title { 53 | flex: 1; 54 | font-size: 16px; 55 | font-weight: 600; 56 | min-width: 80px; 57 | max-width: 184px; 58 | overflow: hidden; 59 | text-overflow: ellipsis; 60 | text-align: left; 61 | white-space: nowrap; 62 | } 63 | 64 | .md-panel-summary { 65 | flex: 1; 66 | font-size: 13px; 67 | overflow: hidden; 68 | text-overflow: ellipsis; 69 | text-align: left; 70 | white-space: nowrap; 71 | } 72 | 73 | md-expansion-panel-content { 74 | display: block; 75 | padding: 16px 24px; 76 | } 77 | 78 | md-expansion-panel-footer { 79 | display: flex; 80 | min-height: 48px; 81 | line-height: 48px; 82 | padding: 10px 8px 10px 24px; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-paper-expansion-panel", 3 | "version": "0.0.4", 4 | "description": "Material expansion panels for ember-paper.", 5 | "keywords": [ 6 | "ember-addon", 7 | "ember-paper", 8 | "ember-paper-expansion-panel", 9 | "expansion panel", 10 | "expandable card", 11 | "material design" 12 | ], 13 | "license": "MIT", 14 | "author": "Miguel Andrade ", 15 | "directories": { 16 | "doc": "doc", 17 | "test": "tests" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/miguelcobain/ember-paper-expansion-panel.git" 22 | }, 23 | "scripts": { 24 | "build": "ember build", 25 | "lint:js": "eslint ./*.js addon addon-test-support app config lib server test-support tests", 26 | "start": "ember serve", 27 | "test": "ember test", 28 | "test:all": "ember try:each" 29 | }, 30 | "dependencies": { 31 | "ember-cli-babel": "^6.6.0", 32 | "ember-cli-htmlbars": "^1.1.1" 33 | }, 34 | "devDependencies": { 35 | "broccoli-asset-rev": "^2.4.5", 36 | "ember-ajax": "^3.0.0", 37 | "ember-cli": "~3.1.1", 38 | "ember-cli-dependency-checker": "^2.0.0", 39 | "ember-cli-eslint": "^4.2.1", 40 | "ember-cli-github-pages": "^0.2.0", 41 | "ember-cli-htmlbars-inline-precompile": "^1.0.0", 42 | "ember-cli-inject-live-reload": "^1.4.1", 43 | "ember-cli-qunit": "^4.1.1", 44 | "ember-cli-sass": "^6.1.2", 45 | "ember-cli-shims": "^1.2.0", 46 | "ember-cli-sri": "^2.1.0", 47 | "ember-cli-uglify": "^2.0.0", 48 | "ember-disable-prototype-extensions": "^1.1.2", 49 | "ember-export-application-global": "^2.0.0", 50 | "ember-load-initializers": "^1.0.0", 51 | "ember-maybe-import-regenerator": "^0.1.6", 52 | "ember-native-dom-helpers": "^0.3.9", 53 | "ember-paper": "^1.0.0-beta.4", 54 | "ember-resolver": "^4.0.0", 55 | "ember-source": "~3.1.0", 56 | "ember-source-channel-url": "^1.0.1", 57 | "ember-truth-helpers": "^2.0.0", 58 | "ember-try": "^0.2.23", 59 | "eslint-plugin-ember": "^5.0.0", 60 | "eslint-plugin-node": "^6.0.1", 61 | "loader.js": "^4.2.3" 62 | }, 63 | "engines": { 64 | "node": "^4.5 || 6.* || >= 7.*" 65 | }, 66 | "ember-addon": { 67 | "configPath": "tests/dummy/config" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

ember-paper-expansion-panel

2 | 3 | {{#paper-list}} 4 | {{#paper-subheader}}Simple example{{/paper-subheader}} 5 | {{#each items as |item|}} 6 | 7 | {{#paper-expansion-panel as |panel|}} 8 | {{#panel.collapsed}} 9 |
Title {{item}}
10 |
Summary
11 | {{paper-icon "keyboard_arrow_down"}} 12 | {{/panel.collapsed}} 13 | 14 | {{#panel.expanded as |expanded|}} 15 | {{#expanded.header}} 16 |
Expanded title
17 |
Expanded summary
18 | {{paper-icon "keyboard_arrow_up"}} 19 | {{/expanded.header}} 20 | 21 | {{#expanded.content}} 22 | Content 23 | {{/expanded.content}} 24 | 25 | {{#expanded.footer}} 26 | 27 | {{#paper-button onClick=(action panel.collapse)}} 28 | Cancel 29 | {{/paper-button}} 30 | {{#paper-button primary=true onClick=(action panel.collapse)}} 31 | Save 32 | {{/paper-button}} 33 | {{/expanded.footer}} 34 | 35 | {{/panel.expanded}} 36 | {{/paper-expansion-panel}} 37 | 38 | {{/each}} 39 | 40 | {{/paper-list}} 41 | 42 | {{#paper-list}} 43 | {{#paper-subheader}}Customized example{{/paper-subheader}} 44 | {{#each items as |item|}} 45 | 46 | {{#paper-expansion-panel as |panel|}} 47 | {{#panel.collapsed}} 48 |
Title {{item}}
49 |
Summary
50 | 51 |
52 | {{#paper-button iconButton=true onClick=(action "alert" "time") bubbles=false}} 53 | {{paper-icon "flash-on"}} 54 | {{/paper-button}} 55 | 56 | {{#paper-button iconButton=true onClick=(action "alert" "time") bubbles=false}} 57 | {{paper-icon "access-time"}} 58 | {{/paper-button}} 59 | 60 | {{#paper-menu position="right target" as |menu|}} 61 | {{#menu.trigger}} 62 | {{#paper-button iconButton=true}} 63 | {{paper-icon "more-vert"}} 64 | {{/paper-button}} 65 | {{/menu.trigger}} 66 | {{#menu.content as |content|}} 67 | {{#content.menu-item onClick=(action "alert")}} 68 | {{paper-icon "phone"}} Action 1 69 | {{/content.menu-item}} 70 | {{#content.menu-item onClick=(action "alert")}} 71 | {{paper-icon "phone"}} Action 2 72 | {{/content.menu-item}} 73 | {{#content.menu-item onClick=(action "alert")}} 74 | {{paper-icon "phone"}} Action 3 75 | {{/content.menu-item}} 76 | {{/menu.content}} 77 | {{/paper-menu}} 78 | 79 | {{paper-icon "keyboard_arrow_down"}} 80 |
81 | {{/panel.collapsed}} 82 | 83 | {{#panel.expanded as |expanded|}} 84 | {{#expanded.header}} 85 |
Expanded title
86 |
Expanded summary
87 | 88 | {{paper-icon "keyboard_arrow_up"}} 89 | {{/expanded.header}} 90 | 91 | {{#expanded.content}} 92 | Content 93 | {{/expanded.content}} 94 | 95 | {{#expanded.footer}} 96 | 97 | {{#paper-button onClick=(action panel.collapse)}} 98 | Cancel 99 | {{/paper-button}} 100 | {{#paper-button primary=true onClick=(action panel.collapse)}} 101 | Save 102 | {{/paper-button}} 103 | {{/expanded.footer}} 104 | 105 | {{/panel.expanded}} 106 | {{/paper-expansion-panel}} 107 | 108 | {{/each}} 109 | 110 | {{/paper-list}} 111 | 112 | {{#if dialogOpen}} 113 | {{#paper-dialog onClose=(action (mut dialogOpen) false)}} 114 | {{#paper-dialog-content}} 115 |

Action

116 |

This is an example action.

117 | {{/paper-dialog-content}} 118 | 119 | {{#paper-dialog-actions class="layout-row"}} 120 | 121 | {{#paper-button primary=true onClick=(action (mut dialogOpen) false)}}OK{{/paper-button}} 122 | {{/paper-dialog-actions}} 123 | {{/paper-dialog}} 124 | {{/if}} 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-paper-expansion-panel [![Build Status](https://travis-ci.org/miguelcobain/ember-paper-expansion-panel.svg?branch=master)](https://travis-ci.org/miguelcobain/ember-paper-expansion-panel) [![Ember Observer Score](http://emberobserver.com/badges/ember-paper-expansion-panel.svg)](http://emberobserver.com/addons/ember-paper-expansion-panel) 2 | 3 | This is an [ember-paper](https://github.com/miguelcobain/ember-paper) addon that provides an implementation of [material expansion panels](https://material.io/guidelines/components/expansion-panels.html). 4 | 5 | ## Usage 6 | 7 | An example usage: 8 | 9 | ```hbs 10 | {{#paper-expansion-panel as |panel|}} 11 | {{#panel.collapsed}} 12 |
Title {{item}}
13 |
Summary
14 | {{paper-icon "keyboard_arrow_down"}} 15 | {{/panel.collapsed}} 16 | 17 | {{#panel.expanded as |expanded|}} 18 | {{#expanded.header}} 19 |
Expanded title
20 |
Expanded summary
21 | {{paper-icon "keyboard_arrow_up"}} 22 | {{/expanded.header}} 23 | 24 | {{#expanded.content}} 25 | Content 26 | {{/expanded.content}} 27 | 28 | {{#expanded.footer}} 29 | 30 | {{#paper-button onClick=(action panel.collapse)}} 31 | Cancel 32 | {{/paper-button}} 33 | {{#paper-button primary=true onClick=(action panel.collapse)}} 34 | Save 35 | {{/paper-button}} 36 | {{/expanded.footer}} 37 | 38 | {{/panel.expanded}} 39 | {{/paper-expansion-panel}} 40 | ``` 41 | 42 | ## Demo 43 | 44 | You can see how this addon looks like at https://miguelcobain.github.io/ember-paper-expansion-panel/ 45 | 46 | ## Installation 47 | 48 | ```bash 49 | ember install ember-paper-expansion-panel 50 | ``` 51 | 52 | Don't forget to import your styles in your `app.scss` **after** importing ember paper styles: 53 | 54 | ```scss 55 | @import "ember-paper"; 56 | @import "ember-paper-expansion-panel"; 57 | ``` 58 | 59 | ## API 60 | 61 | ### `{{#paper-expansion-panel as |panel|}}` 62 | 63 | - `expanded` - defaults to `false` - this toggles the expansion panel between expanded and collapsed modes. 64 | - `onExpandedChange` - an action that is sent when a the panel is expanded or collapsed. You get two arguments, a boolean with the current state of `expanded` and the event object 65 | 66 | This component yields a hash that contains: 67 | - `collapsed` and `expanded` components 68 | - a `collapse` action you can use to collapse the panel (e.g use it with paper-button's onClick) 69 | - an `isExpanded` boolean that tells you the current state of the panel 70 | 71 | ### `{{#panel.collapsed}}` 72 | 73 | Use this component to render what shows up in the collapsed state. 74 | Its API is just like a `{{#paper-item}}`. It also yields a `controls` hash. 75 | 76 | 77 | ### `{{#panel.expanded as |expanded|}}` 78 | 79 | This component yields a hash that contains the `header`, `content` and `footer` components. 80 | 81 | ### `{{#expanded.header}}` 82 | 83 | Use this component to render what goes into the expanded header state. 84 | Again, this component will behave like `{{#paper-item}}`. It also yields a `controls` hash. 85 | 86 | ### `{{#expanded.content}}` 87 | 88 | Use this component to render what goes inside the expanded content area. 89 | 90 | ### `{{#expanded.footer}}` 91 | 92 | Use this component to render what goes inside the expanded footer area. 93 | 94 | 95 | Contributing 96 | ------------------------------------------------------------------------------ 97 | 98 | ### Installation 99 | 100 | * `git clone ` 101 | * `cd my-addon` 102 | * `npm install` 103 | 104 | ### Linting 105 | 106 | * `npm run lint:js` 107 | * `npm run lint:js -- --fix` 108 | 109 | ### Running tests 110 | 111 | * `ember test` – Runs the test suite on the current Ember version 112 | * `ember test --server` – Runs the test suite in "watch mode" 113 | * `ember try:each` – Runs the test suite against multiple Ember versions 114 | 115 | ### Running the dummy application 116 | 117 | * `ember serve` 118 | * Visit the dummy application at [http://localhost:4200](http://localhost:4200). 119 | 120 | For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/). 121 | 122 | License 123 | ------------------------------------------------------------------------------ 124 | 125 | This project is licensed under the [MIT License](LICENSE.md). 126 | 127 | -------------------------------------------------------------------------------- /tests/integration/components/paper-expansion-panel-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 { find, click, keyEvent } from 'ember-native-dom-helpers'; 6 | 7 | module('Integration | Component | paper expansion panel', function(hooks) { 8 | setupRenderingTest(hooks); 9 | 10 | test('it renders the collapsed state', async function(assert) { 11 | assert.expect(1); 12 | 13 | await render(hbs` 14 | {{#paper-expansion-panel as |panel|}} 15 | {{#panel.collapsed}} 16 | collapsed content 17 | {{/panel.collapsed}} 18 | {{/paper-expansion-panel}} 19 | `); 20 | 21 | assert.equal(find('.md-button').textContent.trim(), 'collapsed content'); 22 | }); 23 | 24 | test('it renders the expanded state when button is clicked', async function(assert) { 25 | assert.expect(3); 26 | 27 | await render(hbs` 28 | {{#paper-expansion-panel as |panel|}} 29 | {{#panel.collapsed}} 30 | collapsed content 31 | {{/panel.collapsed}} 32 | 33 | {{#panel.expanded as |expanded|}} 34 | {{#expanded.header}} 35 | expanded header 36 | {{/expanded.header}} 37 | 38 | {{#expanded.content}} 39 | expanded content 40 | {{/expanded.content}} 41 | 42 | {{#expanded.footer}} 43 | expanded footer 44 | {{/expanded.footer}} 45 | 46 | {{/panel.expanded}} 47 | {{/paper-expansion-panel}} 48 | `); 49 | 50 | await click('button.md-button'); 51 | 52 | assert.equal(find('md-list-item').textContent.trim(), 'expanded header'); 53 | assert.equal(find('md-expansion-panel-content').textContent.trim(), 'expanded content'); 54 | assert.equal(find('md-expansion-panel-footer').textContent.trim(), 'expanded footer'); 55 | }); 56 | 57 | test('it renders the expanded state when expanded=true', async function(assert) { 58 | assert.expect(3); 59 | 60 | await render(hbs` 61 | {{#paper-expansion-panel expanded=true as |panel|}} 62 | {{#panel.collapsed}} 63 | collapsed content 64 | {{/panel.collapsed}} 65 | 66 | {{#panel.expanded as |expanded|}} 67 | {{#expanded.header}} 68 | expanded header 69 | {{/expanded.header}} 70 | 71 | {{#expanded.content}} 72 | expanded content 73 | {{/expanded.content}} 74 | 75 | {{#expanded.footer}} 76 | expanded footer 77 | {{/expanded.footer}} 78 | 79 | {{/panel.expanded}} 80 | {{/paper-expansion-panel}} 81 | `); 82 | 83 | assert.equal(find('md-list-item').textContent.trim(), 'expanded header'); 84 | assert.equal(find('md-expansion-panel-content').textContent.trim(), 'expanded content'); 85 | assert.equal(find('md-expansion-panel-footer').textContent.trim(), 'expanded footer'); 86 | }); 87 | 88 | test('toggling expanded toggles states', async function(assert) { 89 | assert.expect(4); 90 | 91 | await render(hbs` 92 | {{#paper-expansion-panel expanded=expanded as |panel|}} 93 | {{#panel.collapsed}} 94 | collapsed content 95 | {{/panel.collapsed}} 96 | 97 | {{#panel.expanded as |expanded|}} 98 | {{#expanded.header}} 99 | expanded header 100 | {{/expanded.header}} 101 | 102 | {{#expanded.content}} 103 | expanded content 104 | {{/expanded.content}} 105 | 106 | {{#expanded.footer}} 107 | expanded footer 108 | {{/expanded.footer}} 109 | 110 | {{/panel.expanded}} 111 | {{/paper-expansion-panel}} 112 | `); 113 | 114 | assert.equal(find('.md-button').textContent.trim(), 'collapsed content'); 115 | 116 | this.set('expanded', true); 117 | 118 | assert.equal(find('md-list-item').textContent.trim(), 'expanded header'); 119 | assert.equal(find('md-expansion-panel-content').textContent.trim(), 'expanded content'); 120 | assert.equal(find('md-expansion-panel-footer').textContent.trim(), 'expanded footer'); 121 | }); 122 | 123 | test('yielded expand/collapse actions work', async function(assert) { 124 | assert.expect(3); 125 | 126 | await render(hbs` 127 | {{#paper-expansion-panel as |panel|}} 128 | {{#panel.collapsed}} 129 | collapsed content 130 |
131 | {{/panel.collapsed}} 132 | 133 | {{#panel.expanded as |expanded|}} 134 | {{#expanded.header}} 135 | expanded header 136 | {{/expanded.header}} 137 | 138 | {{#expanded.content}} 139 | expanded content 140 |
141 | {{/expanded.content}} 142 | 143 | {{#expanded.footer}} 144 | expanded footer 145 | {{/expanded.footer}} 146 | 147 | {{/panel.expanded}} 148 | {{/paper-expansion-panel}} 149 | `); 150 | 151 | assert.ok(find('md-expansion-panel').classList.contains('md-close')); 152 | 153 | await click('.expand'); 154 | assert.ok(find('md-expansion-panel').classList.contains('md-open')); 155 | 156 | await click('.collapse'); 157 | assert.ok(find('md-expansion-panel').classList.contains('md-close')); 158 | }); 159 | 160 | test('onExpandedChange is sent on expand/collapse', async function(assert) { 161 | assert.expect(2); 162 | 163 | this.set('onExpandedChange', (state) => { 164 | assert.ok(state, 'action was sent with true'); 165 | }); 166 | 167 | await render(hbs` 168 | {{#paper-expansion-panel onExpandedChange=(action onExpandedChange) as |panel|}} 169 | {{#panel.collapsed}} 170 | collapsed content 171 | {{/panel.collapsed}} 172 | 173 | {{#panel.expanded as |expanded|}} 174 | {{#expanded.header}} 175 | expanded header 176 | {{/expanded.header}} 177 | 178 | {{#expanded.content}} 179 | expanded content 180 | {{/expanded.content}} 181 | 182 | {{#expanded.footer}} 183 | expanded footer 184 | {{/expanded.footer}} 185 | 186 | {{/panel.expanded}} 187 | {{/paper-expansion-panel}} 188 | `); 189 | 190 | await click('button.md-button'); 191 | 192 | this.set('onExpandedChange', (state) => { 193 | assert.notOk(state, 'action was sent with false'); 194 | }); 195 | 196 | await click('button.md-button'); 197 | }); 198 | 199 | test('pressing enter/escape expands/collapses', async function(assert) { 200 | assert.expect(2); 201 | 202 | await render(hbs` 203 | {{#paper-expansion-panel as |panel|}} 204 | {{#panel.collapsed}} 205 | collapsed content 206 | {{/panel.collapsed}} 207 | 208 | {{#panel.expanded as |expanded|}} 209 | {{#expanded.header}} 210 | expanded header 211 | {{/expanded.header}} 212 | 213 | {{#expanded.content}} 214 | expanded content 215 | {{/expanded.content}} 216 | 217 | {{#expanded.footer}} 218 | expanded footer 219 | {{/expanded.footer}} 220 | 221 | {{/panel.expanded}} 222 | {{/paper-expansion-panel}} 223 | `); 224 | 225 | await keyEvent('.md-button', 'keydown', 13); 226 | assert.ok(find('md-expansion-panel').classList.contains('md-open')); 227 | 228 | await keyEvent('.md-button', 'keydown', 27); 229 | assert.ok(find('md-expansion-panel').classList.contains('md-close')); 230 | }); 231 | }); 232 | --------------------------------------------------------------------------------