diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000..959e169 --- /dev/null +++ b/.bowerrc @@ -0,0 +1,4 @@ +{ + "directory": "bower_components", + "analytics": false +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5d5dea4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,33 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.js] +indent_style = space +indent_size = 2 + +[*.hbs] +indent_style = space +indent_size = 2 + +[*.css] +indent_style = space +indent_size = 2 + +[*.html] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.ember-cli b/.ember-cli new file mode 100644 index 0000000..ee64cfe --- /dev/null +++ b/.ember-cli @@ -0,0 +1,9 @@ +{ + /** + Ember CLI sends analytics information by default. The data is completely + anonymous, but there are times when you might want to disable this behavior. + + Setting `disableAnalytics` to true will prevent any data from being sent. + */ + "disableAnalytics": false +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86fceae --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp + +# dependencies +/node_modules +/bower_components + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..08096ef --- /dev/null +++ b/.jshintrc @@ -0,0 +1,32 @@ +{ + "predef": [ + "document", + "window", + "-Promise" + ], + "browser": true, + "boss": true, + "curly": true, + "debug": false, + "devel": true, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esnext": true, + "unused": true +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cf23938 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +--- +language: node_js + +sudo: false + +cache: + directories: + - node_modules + +before_install: + - "npm config set spin false" + - "npm install -g npm@^2" + +install: + - npm install -g bower + - npm install + - bower install + +script: + - npm test diff --git a/Brocfile.js b/Brocfile.js new file mode 100644 index 0000000..a0c97ed --- /dev/null +++ b/Brocfile.js @@ -0,0 +1,33 @@ +/* jshint node: true */ +/* global require, module */ + +var EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); +var mergeTrees = require('broccoli-merge-trees'); +var pickFiles = require('broccoli-static-compiler'); + +var app = new EmberAddon(); + +// Use `app.import` to add additional libraries to the generated +// output files. +// +// If you need to use different assets in different +// environments, specify an object as the first parameter. That +// object's keys should be the environment name and the values +// should be the asset to use in that environment. +// +// If the library that you are including contains AMD or ES6 +// modules that you would like to import into your application +// please specify an object with the list of modules as keys +// along with the exports of each module as its value. +app.import('bower_components/bootstrap/dist/css/bootstrap.css'); +app.import('bower_components/fontawesome/css/font-awesome.min.css'); +app.import('bower_components/highlightjs/highlight.pack.js'); +app.import('bower_components/highlightjs/styles/tomorrow.css'); + +var extraAssets = pickFiles('bower_components/fontawesome', { + srcDir: '/', + files: ['**/*.woff', '**/*.eot', '**/*.svg', '**/*.ttf'], + destDir: '/' +}); + +module.exports = mergeTrees([app.toTree(), extraAssets]) \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..6df5a22 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2014 Indexia Technologies, ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f132c48 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Ember-idx-accordion + +ember-idx-accordion is a multi panels defined with 1 single planel selected at a time rendered as an accordion. + +## Installation & Tutorial + +### With Ember-CLI: + +npm install --save-dev ember-idx-accordion + +Please visit the documentation for installation & usage documentations: http://indexiatech.github.io/ember-idx-accordion + +## Plugin Development + +* `git clone` this repository +* `npm install` +* `bower install` + +## Running + +* `ember server` +* Visit your app at http://localhost:4200. + +## Running Tests + +* `ember test` +* `ember test --server` + +## Building + +* `ember build` \ No newline at end of file diff --git a/addon/.gitkeep b/addon/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/addon/accordion-item.js b/addon/accordion-item.js new file mode 100644 index 0000000..5602f0f --- /dev/null +++ b/addon/accordion-item.js @@ -0,0 +1,134 @@ +//(c) 2014 Indexia, Inc. +import Em from 'ember'; +import WithConfigMixin from 'ember-idx-utils/mixin/with-config'; +import StyleBindingsMixin from 'ember-idx-utils/mixin/style-bindings'; +var computed = Em.computed; + +/** + * AccordionItem component + * + * @class AccordionItem + */ +export default Em.Component.extend(WithConfigMixin, { + classNameBindings: ['styleClasses', 'selectedClass'], + accordion: computed.alias('parentView'), + content: Em.computed.alias('accordion.content'), + + /** + * Bind the specified attributes to the DOM element + * + * @property attributeBindings + * @type Array + */ + attributeBindings: ['active'], + selectedClass: (function() { + var _ref; + if (this.get('selected')) { + return (_ref = this.get('config.accordion.itemSelectedClasses')) != null ? _ref.join(" ") : void 0; + } else { + return null; + } + }).property('selected'), + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.accordion.itemClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + panelHeaderClasses: (function() { + var _ref; + return (_ref = this.get('config.accordion.panelHeaderClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + panelTitleClasses: (function() { + var _ref; + return (_ref = this.get('config.accordion.panelTitleClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + panelTogglerClasses: (function() { + var _ref; + return (_ref = this.get('config.accordion.panelTogglerClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + panelBodyContainerClasses: (function() { + var _ref; + return (_ref = this.get('config.accordion.panelBodyContainerClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + panelBodyClasses: (function() { + var _ref; + return (_ref = this.get('config.accordion.panelBodyClasses')) != null ? _ref.join(" ") : void 0; + }).property(), + index: (function() { + return this.get('accordion.items').indexOf(this); + }).property('accordion.items.@each'), + register: (function() { + return this.get('accordion').addItem(this); + }).on('init'), + unregister: (function() { + return this.get('accordion').removeItem(this); + }).on('willDestroyElement'), + + /** + * true if this item is currently selected. + * + * @property selected + * @type Boolean + */ + selected: (function() { + return this.get('accordion.selected') === this; + }).property('accordion.selected'), + active: (function() { + if (this.get('selected')) { + return "true"; + } else { + return null; + } + }).property('selected'), + + /** + * Select this item. + * + * Bound to `click` event. + * + * @method select + */ + select: (function() { + return this.get('accordion').select(this); + }).on('click'), + + /** + * Select this item if it matches the {{#crossLink "Accordiong/select:method"}}selected-idx{{/crossLink}} property set by the Accordion component. + * + * @method selectByAccordionParam + * @private + */ + selectByParam: (function() { + var idx; + if ((this.get('accordion.selected') != null) === this) { + return; + } + idx = parseInt(this.get('accordion.selected-idx', 10)); + if (idx === this.get('index')) { + return this.select(); + } + }).observes('accordion.selected-idx').on('didInsertElement'), + + /** + * Listen to `active` property changes and show / hide the item's content according to its state + * + * We use observes instead of properties as we need to invoke a method instead of calculating classes only + * so in the future we can support a transition animation. + */ + activeDidChange: (function() { + if (this.get('active')) { + return this.show(); + } else { + return this.hide(); + } + }).observes('active'), + hide: function() { + var $accordionBody; + $accordionBody = this.$('.panel-collapse'); + return $accordionBody.removeClass('in'); + }, + show: function() { + var $accordionBody; + $accordionBody = this.$('.panel-collapse'); + return $accordionBody.addClass('in'); + } +}); diff --git a/addon/accordion.js b/addon/accordion.js new file mode 100644 index 0000000..6114a2d --- /dev/null +++ b/addon/accordion.js @@ -0,0 +1,58 @@ +//(c) 2014 Indexia, Inc. +import Em from 'ember'; +import WithConfigMixin from 'ember-idx-utils/mixin/with-config'; +import StyleBindingsMixin from 'ember-idx-utils/mixin/style-bindings'; + +/** + * Accordion component + * + * @class Accordion + */ +export default Em.Component.extend(WithConfigMixin, { + classNameBindings: ['styleClasses'], + styleClasses: (function() { + var _ref; + return (_ref = this.get('config.accordion.classes')) != null ? _ref.join(" ") : void 0; + }).property(), + 'selected-idx': 0, + + /** + * A list of {{#crossLink "AccordionItem"}}accordion-item{{/crossLink}} instances. + */ + items: void 0, + selected: void 0, + initItems: (function() { + return this.set('items', Em.ArrayProxy.create({ + content: [] + })); + }).on('init'), + + /** + * Add the given `AccordionItem` instance. + */ + addItem: function(item) { + return this.get('items').addObject(item); + }, + + /** + * Remove the given `AccordionItem` instance. + */ + removeItem: function(item) { + return this.get('items').removeObject(item); + }, + + /** + * Select the given item. + * + * @method select + * @param {Object} an item instance to select. + */ + select: function(item) { + if (!item) { + return; + } + Em.debug("Selecting item: " + (item.get('index'))); + this.set('selected', item); + return this.set('selected-idx', item.get('index')); + } +}); \ No newline at end of file diff --git a/app/.gitkeep b/app/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/components/em-accordion-item.js b/app/components/em-accordion-item.js new file mode 100644 index 0000000..c731d9a --- /dev/null +++ b/app/components/em-accordion-item.js @@ -0,0 +1,2 @@ +import AccordionItemComponent from 'ember-idx-accordion/accordion-item'; +export default AccordionItemComponent; \ No newline at end of file diff --git a/app/components/em-accordion.js b/app/components/em-accordion.js new file mode 100644 index 0000000..0daa100 --- /dev/null +++ b/app/components/em-accordion.js @@ -0,0 +1,2 @@ +import AccordionComponent from 'ember-idx-accordion/accordion'; +export default AccordionComponent; \ No newline at end of file diff --git a/app/initializers/idx-accordion-config.js b/app/initializers/idx-accordion-config.js new file mode 100644 index 0000000..1b080fc --- /dev/null +++ b/app/initializers/idx-accordion-config.js @@ -0,0 +1,34 @@ +import Em from 'ember'; +import Config from 'ember-idx-utils/config' + +export default { + name: 'ember-idx-tabs', + initialize: function() { + if (!Em.Config) { + Em.Config = Config = Config.create() + } + + var defaultConfig = Config.getConfig('default'); + if (!defaultConfig) { + Config.addConfig('default'); + defaultConfig = Config.getConfig('default'); + } + + //Bootstrap + var bsConfig = Config.getConfig('bs'); + if (!bsConfig) { + Config.addConfig('bs'); + bsConfig = Config.getConfig('bs'); + } + bsConfig['accordion'] = { + classes: ['panel-group'], + itemClasses: ['panel', 'panel-default'], + itemSelectedClasses: ['active'], + panelHeaderClasses: ['panel-heading'], + panelTitleClasses: ['panel-title'], + panelTogglerClasses: ['accordion-toggle'], + panelBodyContainerClasses: ['panel-collapse','collapse'], + panelBodyClasses: ['panel-body'] + } + } +}; \ No newline at end of file diff --git a/app/templates/components/em-accordion-item.hbs b/app/templates/components/em-accordion-item.hbs new file mode 100644 index 0000000..176f744 --- /dev/null +++ b/app/templates/components/em-accordion-item.hbs @@ -0,0 +1,16 @@ + + + + + + +
Please check Ember \{{render}} doc for more info.
+ +
+ \{{#em-accordion configName='bs' selected-idx=1}}
+ \{{#em-accordion-item title="Panel 1"}}
+ \{{render 'c1'}}
+ \{{/em-accordion-item}}
+ \{{#em-accordion-item title="Panel 2"}}
+ \{{render 'c2'}}
+ \{{/em-accordion-item}}
+ \{{/em-accordion}}
+
+
+
+ //c1 controller
+ export default Em.Controller.extend({
+ label: 'Hello from C1 Controller.'
+ })
+ //c2 controller
+ export default Em.Controller.extend({
+ label: 'Hello from C2 Controller.'
+ })
+
++ Ember-Idx-Accordion is a multi panels defined with 1 single planel selected at a time rendered as an accordion. +
+ ++ Ember-Idx-Accordion is an Ember CLI module and can be simply installed by: +
+ ++
npm install --save-dev ember-idx-accordion
+ Want to see some code? check out the {{#link-to 'simple'}}Simple{{/link-to}} page
\ No newline at end of file diff --git a/tests/dummy/app/templates/navbar.hbs b/tests/dummy/app/templates/navbar.hbs new file mode 100644 index 0000000..d69d10a --- /dev/null +++ b/tests/dummy/app/templates/navbar.hbs @@ -0,0 +1,45 @@ + \ No newline at end of file diff --git a/tests/dummy/app/templates/query_params.hbs b/tests/dummy/app/templates/query_params.hbs new file mode 100644 index 0000000..05411cf --- /dev/null +++ b/tests/dummy/app/templates/query_params.hbs @@ -0,0 +1,37 @@ +
+ \{{#em-accordion configName='bs' selected-idx=item_idx}}
+ \{{#em-accordion-item title="Panel 1"}}
+ Content of panel #1
+ \{{/em-accordion-item}}
+ \{{#em-accordion-item title="Panel 2"}}
+ Content of panel #2
+ \{{/em-accordion-item}}
+ \{{#em-accordion-item title="Panel 3"}}
+ Content of panel #3
+ \{{/em-accordion-item}}
+ \{{/em-accordion}}
+
++The simplest form of the accordion component is simply laying down accordion items statically where each item has a title and a block of content. +
+ ++Note: Currently the configuration allows only the bs config name, so bootstrap CSS is required, +it is possible to customize the configuration, for more information, take a look at idx-accordion-config.js file. +
+ +
+ \{{#em-accordion configName='bs' selected-idx=1}}
+ \{{#em-accordion-item title="Panel 1"}}
+ Content of panel #1
+ \{{/em-accordion-item}}
+ \{{#em-accordion-item title="Panel 2"}}
+ Content of panel #2
+ \{{/em-accordion-item}}
+ \{{#em-accordion-item title="Panel 3"}}
+ Content of panel #3
+ \{{/em-accordion-item}}
+ \{{/em-accordion}}
+
+