diff --git a/.npmignore b/.npmignore
index 49996f5a..fa8b147a 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,14 +1,16 @@
-bower_components/
-tests/
-tmp/
-dist/
-
+/bower_components
+/config/ember-try.js
+/dist
+/tests
+/tmp
+**/.gitkeep
.bowerrc
.editorconfig
.ember-cli
+.gitignore
+.jshintrc
+.watchmanconfig
.travis.yml
-.npmignore
-**/.gitkeep
bower.json
-Brocfile.js
-testem.json
+ember-cli-build.js
+testem.js
diff --git a/.travis.yml b/.travis.yml
index 36d7bf72..dd54ffde 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,6 +11,7 @@ cache:
env:
- EMBER_TRY_SCENARIO=default
+ - EMBER_TRY_SCENARIO=ember-1-13
- EMBER_TRY_SCENARIO=ember-release
- EMBER_TRY_SCENARIO=ember-beta
- EMBER_TRY_SCENARIO=ember-canary
diff --git a/LICENSE.md b/LICENSE.md
index 6d4bd7fb..e6d06674 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2015 Envy Labs, LLC.
+Copyright (c) 2016 Envy Labs, LLC.
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:
diff --git a/README.md b/README.md
index 78ec5c33..983c4777 100644
--- a/README.md
+++ b/README.md
@@ -8,33 +8,29 @@ Special thanks to [ic-tabs], which this addon is based on.
## Installation
-### As an Ember CLI addon
-
-Use this addon in your ember-cli application:
-
```sh
-npm install --save-dev IvyApp/ivy-tabs
+$ ember install ivy-tabs
```
## Usage
```handlebars
-{{#ivy-tabs}}
- {{#ivy-tab-list}}
- {{#ivy-tab}}Foo{{/ivy-tab}}
- {{#ivy-tab}}Bar{{/ivy-tab}}
- {{#ivy-tab}}Baz{{/ivy-tab}}
+{{#ivy-tabs as |tabsContainer|}}
+ {{#ivy-tab-list tabsContainer=tabsContainer as |tabList|}}
+ {{#ivy-tab tabList=tabList}}Foo{{/ivy-tab}}
+ {{#ivy-tab tabList=tabList}}Bar{{/ivy-tab}}
+ {{#ivy-tab tabList=tabList}}Baz{{/ivy-tab}}
{{/ivy-tab-list}}
- {{#ivy-tab-panel}}
+ {{#ivy-tab-panel tabsContainer=tabsContainer}}
Foo
{{/ivy-tab-panel}}
- {{#ivy-tab-panel}}
+ {{#ivy-tab-panel tabsContainer=tabsContainer}}
Bar
{{/ivy-tab-panel}}
- {{#ivy-tab-panel}}
+ {{#ivy-tab-panel tabsContainer=tabsContainer}}
Baz
{{/ivy-tab-panel}}
{{/ivy-tabs}}
@@ -43,9 +39,9 @@ npm install --save-dev IvyApp/ivy-tabs
Some things to note:
* Associations between tabs and tab-panes are inferred by order.
- * `ivy-tab-list` must be an immediate child of `ivy-tabs`.
- * `ivy-tab` must be an immediate child of `ivy-tab-list`.
- * `ivy-tab-panel` must be an immediate child of `ivy-tabs`.
+ * Both `ivy-tabs` and `ivy-tab-list` yield themselves as a parameter, which
+ should be passed down to their children as `tabsContainer` and `tabList`,
+ respectively.
## Contributing
diff --git a/addon/components/ivy-tab-list.js b/addon/components/ivy-tab-list.js
index 28c4c25a..74f50e48 100644
--- a/addon/components/ivy-tab-list.js
+++ b/addon/components/ivy-tab-list.js
@@ -1,4 +1,5 @@
import Ember from 'ember';
+import layout from '../templates/components/ivy-tab-list';
/**
* @module ivy-tabs
@@ -10,17 +11,19 @@ import Ember from 'ember';
* @extends Ember.Component
*/
export default Ember.Component.extend({
+ layout: layout,
+
tagName: 'ul',
attributeBindings: ['aria-multiselectable', 'role'],
classNames: ['ivy-tab-list'],
- init: function() {
- this._super();
+ init() {
+ this._super(...arguments);
Ember.run.once(this, this._registerWithTabsContainer);
},
- willDestroy: function() {
- this._super();
+ willDestroy() {
+ this._super(...arguments);
Ember.run.once(this, this._unregisterWithTabsContainer);
},
@@ -49,7 +52,7 @@ export default Ember.Component.extend({
*
* @method focusSelectedTab
*/
- focusSelectedTab: function() {
+ focusSelectedTab() {
this.get('selectedTab').$().focus();
},
@@ -85,7 +88,7 @@ export default Ember.Component.extend({
* @method registerTab
* @param {IvyTabs.IvyTabComponent} tab
*/
- registerTab: function(tab) {
+ registerTab(tab) {
this.get('tabs').pushObject(tab);
},
@@ -94,8 +97,8 @@ export default Ember.Component.extend({
*
* @method selectNextTab
*/
- selectNextTab: function() {
- var index = this.get('selected-index') + 1;
+ selectNextTab() {
+ let index = this.get('selected-index') + 1;
if (index === this.get('tabs.length')) { index = 0; }
this.selectTabByIndex(index);
},
@@ -105,8 +108,8 @@ export default Ember.Component.extend({
*
* @method selectPreviousTab
*/
- selectPreviousTab: function() {
- var index = this.get('selected-index') - 1;
+ selectPreviousTab() {
+ let index = this.get('selected-index') - 1;
// Previous from the first tab should select the last tab.
if (index < 0) { index = this.get('tabs.length') - 1; }
@@ -134,7 +137,7 @@ export default Ember.Component.extend({
* @method selectTab
* @param {IvyTabs.IvyTabComponent} tab
*/
- selectTab: function(tab) {
+ selectTab(tab) {
this.selectTabByIndex(this.get('tabs').indexOf(tab));
},
@@ -144,10 +147,22 @@ export default Ember.Component.extend({
* @method selectTabByIndex
* @param {Number} index
*/
- selectTabByIndex: function(index) {
+ selectTabByIndex(index) {
this.set('selected-index', index);
},
+ tabs: Ember.computed(function() {
+ return Ember.A();
+ }).readOnly(),
+
+ _deprecatedParentViewBasedTabsContainer: Ember.computed('parentView', function() {
+ Ember.deprecate('Inferring `tabsContainer` from `parentView` on `{{ivy-tab-list}}` is deprecated. Please assign in an instance of `{{ivy-tabs}}` to the `tabsContainer` property.', false, {
+ id: 'ivy-tabs.ivy-tab-list.tabs-container-missing',
+ until: '2.0.0'
+ });
+ return this.get('parentView');
+ }).readOnly(),
+
/**
* The `ivy-tabs` component.
*
@@ -155,7 +170,7 @@ export default Ember.Component.extend({
* @type IvyTabs.IvyTabsComponent
* @readOnly
*/
- tabsContainer: Ember.computed.alias('parentView').readOnly(),
+ tabsContainer: Ember.computed.oneWay('_deprecatedParentViewBasedTabsContainer'),
/**
* Removes a tab from the `tabs` array.
@@ -163,8 +178,8 @@ export default Ember.Component.extend({
* @method unregisterTab
* @param {IvyTabs.IvyTabComponent} tab
*/
- unregisterTab: function(tab) {
- var index = tab.get('index');
+ unregisterTab(tab) {
+ const index = tab.get('index');
this.get('tabs').removeObject(tab);
if (index < this.get('selected-index')) {
@@ -176,15 +191,11 @@ export default Ember.Component.extend({
}
},
- _initTabs: Ember.on('init', function() {
- this.set('tabs', Ember.A());
- }),
-
- _registerWithTabsContainer: function() {
+ _registerWithTabsContainer() {
this.get('tabsContainer').registerTabList(this);
},
- _unregisterWithTabsContainer: function() {
+ _unregisterWithTabsContainer() {
this.get('tabsContainer').unregisterTabList(this);
}
});
diff --git a/addon/components/ivy-tab-panel.js b/addon/components/ivy-tab-panel.js
index e989066c..9c2bcd0e 100644
--- a/addon/components/ivy-tab-panel.js
+++ b/addon/components/ivy-tab-panel.js
@@ -14,13 +14,13 @@ export default Ember.Component.extend({
classNames: ['ivy-tab-panel'],
classNameBindings: ['active'],
- init: function() {
- this._super();
+ init() {
+ this._super(...arguments);
Ember.run.once(this, this._registerWithTabsContainer);
},
- willDestroy: function() {
- this._super();
+ willDestroy() {
+ this._super(...arguments);
Ember.run.once(this, this._unregisterWithTabsContainer);
},
@@ -102,7 +102,7 @@ export default Ember.Component.extend({
* @type IvyTabs.IvyTabComponent
*/
tab: Ember.computed(function() {
- var tabs = this.get('tabs');
+ const tabs = this.get('tabs');
if (tabs) { return tabs.objectAt(this.get('index')); }
}).property('tabs.[]', 'index'),
@@ -134,6 +134,14 @@ export default Ember.Component.extend({
*/
tabs: Ember.computed.alias('tabList.tabs').readOnly(),
+ _deprecatedParentViewBasedTabsContainer: Ember.computed('parentView', function() {
+ Ember.deprecate('Inferring `tabsContainer` from `parentView` on `{{ivy-tab-panel}}` is deprecated. Please assign in an instance of `{{ivy-tabs}}` to the `tabsContainer` property.', false, {
+ id: 'ivy-tabs.ivy-tab-panel.tabs-container-missing',
+ until: '2.0.0'
+ });
+ return this.get('parentView');
+ }).readOnly(),
+
/**
* The `ivy-tabs` component.
*
@@ -141,13 +149,13 @@ export default Ember.Component.extend({
* @type IvyTabs.IvyTabsComponent
* @readOnly
*/
- tabsContainer: Ember.computed.alias('parentView').readOnly(),
+ tabsContainer: Ember.computed.oneWay('_deprecatedParentViewBasedTabsContainer'),
- _registerWithTabsContainer: function() {
+ _registerWithTabsContainer() {
this.get('tabsContainer').registerTabPanel(this);
},
- _unregisterWithTabsContainer: function() {
+ _unregisterWithTabsContainer() {
this.get('tabsContainer').unregisterTabPanel(this);
}
});
diff --git a/addon/components/ivy-tab.js b/addon/components/ivy-tab.js
index d21d1487..62e4e822 100644
--- a/addon/components/ivy-tab.js
+++ b/addon/components/ivy-tab.js
@@ -15,13 +15,13 @@ export default Ember.Component.extend({
classNames: ['ivy-tab'],
classNameBindings: ['active'],
- init: function() {
- this._super();
+ init() {
+ this._super(...arguments);
Ember.run.once(this, this._registerWithTabList);
},
- willDestroy: function() {
- this._super();
+ willDestroy() {
+ this._super(...arguments);
Ember.run.once(this, this._unregisterWithTabList);
},
@@ -144,6 +144,14 @@ export default Ember.Component.extend({
this.get('tabList').selectTab(this);
}),
+ _deprecatedParentViewBasedTabList: Ember.computed('parentView', function() {
+ Ember.deprecate('Inferring `tabList` from `parentView` on `{{ivy-tab}}` is deprecated. Please assign in an instance of `{{ivy-tab-list}}` to the `tabList` property.', false, {
+ id: 'ivy-tabs.ivy-tab.tab-list-missing',
+ until: '2.0.0'
+ });
+ return this.get('parentView');
+ }).readOnly(),
+
/**
* The `ivy-tab-list` component this tab belongs to.
*
@@ -151,7 +159,7 @@ export default Ember.Component.extend({
* @type IvyTabs.IvyTabListComponent
* @readOnly
*/
- tabList: Ember.computed.alias('parentView').readOnly(),
+ tabList: Ember.computed.oneWay('_deprecatedParentViewBasedTabList'),
/**
* The `ivy-tab-panel` associated with this tab.
@@ -191,11 +199,11 @@ export default Ember.Component.extend({
*/
tabsContainer: Ember.computed.alias('tabList.tabsContainer').readOnly(),
- _registerWithTabList: function() {
+ _registerWithTabList() {
this.get('tabList').registerTab(this);
},
- _unregisterWithTabList: function() {
+ _unregisterWithTabList() {
this.get('tabList').unregisterTab(this);
}
});
diff --git a/addon/components/ivy-tabs.js b/addon/components/ivy-tabs.js
index 8bee516e..cc7cbaa0 100644
--- a/addon/components/ivy-tabs.js
+++ b/addon/components/ivy-tabs.js
@@ -1,4 +1,5 @@
import Ember from 'ember';
+import layout from '../templates/components/ivy-tabs';
/**
* @module ivy-tabs
@@ -10,12 +11,9 @@ import Ember from 'ember';
* @extends Ember.Component
*/
export default Ember.Component.extend({
- classNames: ['ivy-tabs'],
+ layout: layout,
- init: function() {
- this._super();
- this._initTabPanels();
- },
+ classNames: ['ivy-tabs'],
/**
* Set this to the index of the tab you'd like to be selected. Usually it is
@@ -34,7 +32,7 @@ export default Ember.Component.extend({
* @method registerTabList
* @param {IvyTabs.IvyTabListComponent} tabList
*/
- registerTabList: function(tabList) {
+ registerTabList(tabList) {
this.set('tabList', tabList);
Ember.run.once(this, this._selectTabByIndex);
},
@@ -45,17 +43,21 @@ export default Ember.Component.extend({
* @method registerTabPanel
* @param {IvyTabs.IvyTabPanelComponent} tabPanel
*/
- registerTabPanel: function(tabPanel) {
+ registerTabPanel(tabPanel) {
this.get('tabPanels').pushObject(tabPanel);
},
+ tabPanels: Ember.computed(function() {
+ return Ember.A();
+ }).readOnly(),
+
/**
* Removes the `ivy-tab-list` component.
*
* @method unregisterTabList
* @param {IvyTabs.IvyTabListComponent} tabList
*/
- unregisterTabList: function(/* tabList */) {
+ unregisterTabList(/* tabList */) {
this.set('tabList', null);
},
@@ -65,16 +67,12 @@ export default Ember.Component.extend({
* @method unregisterTabPanel
* @param {IvyTabs.IvyTabPanelComponent} tabPanel
*/
- unregisterTabPanel: function(tabPanel) {
+ unregisterTabPanel(tabPanel) {
this.get('tabPanels').removeObject(tabPanel);
},
- _initTabPanels: function() {
- this.set('tabPanels', Ember.A());
- },
-
- _selectTabByIndex: function() {
- var selectedIndex = this.get('selected-index');
+ _selectTabByIndex() {
+ let selectedIndex = this.get('selected-index');
if (Ember.isNone(selectedIndex)) { selectedIndex = 0; }
this.get('tabList').selectTabByIndex(selectedIndex);
}
diff --git a/addon/index.js b/addon/index.js
deleted file mode 100644
index 1c2daedd..00000000
--- a/addon/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import IvyTabComponent from './components/ivy-tab';
-import IvyTabListComponent from './components/ivy-tab-list';
-import IvyTabPanelComponent from './components/ivy-tab-panel';
-import IvyTabsComponent from './components/ivy-tabs';
-
-export {
- IvyTabComponent,
- IvyTabListComponent,
- IvyTabPanelComponent,
- IvyTabsComponent
-};
diff --git a/addon/templates/components/ivy-tab-list.hbs b/addon/templates/components/ivy-tab-list.hbs
new file mode 100644
index 00000000..f4a0b592
--- /dev/null
+++ b/addon/templates/components/ivy-tab-list.hbs
@@ -0,0 +1 @@
+{{yield this}}
diff --git a/addon/templates/components/ivy-tabs.hbs b/addon/templates/components/ivy-tabs.hbs
new file mode 100644
index 00000000..f4a0b592
--- /dev/null
+++ b/addon/templates/components/ivy-tabs.hbs
@@ -0,0 +1 @@
+{{yield this}}
diff --git a/bower.json b/bower.json
index 51b7b54e..67f4e12c 100644
--- a/bower.json
+++ b/bower.json
@@ -1,16 +1,10 @@
{
"name": "ivy-tabs",
"dependencies": {
- "ember": "1.13.11",
- "ember-cli-shims": "0.0.6",
- "ember-cli-test-loader": "0.2.1",
- "ember-load-initializers": "0.1.7",
- "ember-qunit": "0.4.16",
- "ember-qunit-notifications": "0.1.0",
- "ember-resolver": "~0.1.20",
- "jquery": "^1.11.3",
- "loader.js": "ember-cli/loader.js#3.4.0",
"bootstrap": "~3.3.1",
- "qunit": "~1.20.0"
+ "ember": "~2.4.1",
+ "ember-cli-shims": "0.1.0",
+ "ember-cli-test-loader": "0.2.2",
+ "ember-qunit-notifications": "0.1.0"
}
}
diff --git a/config/ember-try.js b/config/ember-try.js
index 3e88bc61..7ded6fc4 100644
--- a/config/ember-try.js
+++ b/config/ember-try.js
@@ -3,33 +3,52 @@ module.exports = {
scenarios: [
{
name: 'default',
- dependencies: { }
+ bower: {
+ dependencies: { }
+ }
+ },
+ {
+ name: 'ember-1-13',
+ bower: {
+ dependencies: {
+ 'ember': '~1.13.0'
+ },
+ resolutions: {
+ 'ember': '~1.13.0'
+ }
+ }
},
{
name: 'ember-release',
- dependencies: {
- 'ember': 'components/ember#release'
- },
- resolutions: {
- 'ember': 'release'
+ bower: {
+ dependencies: {
+ 'ember': 'components/ember#release'
+ },
+ resolutions: {
+ 'ember': 'release'
+ }
}
},
{
name: 'ember-beta',
- dependencies: {
- 'ember': 'components/ember#beta'
- },
- resolutions: {
- 'ember': 'beta'
+ bower: {
+ dependencies: {
+ 'ember': 'components/ember#beta'
+ },
+ resolutions: {
+ 'ember': 'beta'
+ }
}
},
{
name: 'ember-canary',
- dependencies: {
- 'ember': 'components/ember#canary'
- },
- resolutions: {
- 'ember': 'canary'
+ bower: {
+ dependencies: {
+ 'ember': 'components/ember#canary'
+ },
+ resolutions: {
+ 'ember': 'canary'
+ }
}
}
]
diff --git a/ember-cli-build.js b/ember-cli-build.js
index 9f28b983..6f2ffb9b 100644
--- a/ember-cli-build.js
+++ b/ember-cli-build.js
@@ -1,8 +1,6 @@
/*jshint node:true*/
/* global require, module */
var EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
-var Funnel = require('broccoli-funnel');
-var path = require('path');
module.exports = function(defaults) {
var app = new EmberAddon(defaults, {
@@ -10,19 +8,13 @@ module.exports = function(defaults) {
});
/*
- This build file specifes the options for the dummy test app of this
+ This build file specifies the options for the dummy test app of this
addon, located in `/tests/dummy`
This build file does *not* influence how the addon or the app using it
behave. You most likely want to be modifying `./index.js` or app's build file
*/
+ app.import('bower_components/bootstrap/dist/css/bootstrap.css');
+ app.import('bower_components/bootstrap/dist/css/bootstrap.css.map');
- app.import(path.join(app.bowerDirectory, 'ember/ember-template-compiler.js'), {
- type: 'test'
- });
-
- var bootstrapTree = new Funnel(path.join(app.bowerDirectory, 'bootstrap/dist/css'), {
- destDir: '/assets'
- });
-
- return app.toTree([bootstrapTree]);
+ return app.toTree();
};
diff --git a/package.json b/package.json
index c5609632..0bf5206d 100644
--- a/package.json
+++ b/package.json
@@ -7,8 +7,8 @@
"test": "tests"
},
"scripts": {
- "start": "ember server",
"build": "ember build",
+ "start": "ember server",
"test": "ember try:testall"
},
"repository": "https://github.com/IvyApp/ivy-tabs",
@@ -22,23 +22,22 @@
},
"devDependencies": {
"broccoli-asset-rev": "^2.2.0",
- "broccoli-funnel": "^1.0.0",
- "ember-cli": "1.13.13",
+ "ember-cli": "2.4.2",
"ember-cli-app-version": "^1.0.0",
- "ember-cli-content-security-policy": "0.4.0",
- "ember-cli-dependency-checker": "^1.1.0",
- "ember-cli-htmlbars": "^1.0.1",
+ "ember-cli-dependency-checker": "^1.2.0",
"ember-cli-htmlbars-inline-precompile": "^0.3.1",
- "ember-cli-ic-ajax": "0.2.4",
"ember-cli-inject-live-reload": "^1.3.1",
- "ember-cli-qunit": "^1.0.4",
+ "ember-cli-qunit": "^1.2.1",
"ember-cli-release": "0.2.8",
- "ember-cli-sri": "^1.2.0",
+ "ember-cli-sri": "^2.1.0",
"ember-cli-uglify": "^1.2.0",
- "ember-disable-prototype-extensions": "^1.0.0",
+ "ember-disable-prototype-extensions": "^1.1.0",
"ember-disable-proxy-controllers": "^1.0.1",
"ember-export-application-global": "^1.0.4",
- "ember-try": "~0.0.8"
+ "ember-load-initializers": "^0.5.0",
+ "ember-resolver": "^2.0.3",
+ "ember-try": "^0.1.2",
+ "loader.js": "^4.0.0"
},
"keywords": [
"ember",
@@ -46,7 +45,8 @@
"tabs"
],
"dependencies": {
- "ember-cli-babel": "^5.1.5"
+ "ember-cli-babel": "^5.1.5",
+ "ember-cli-htmlbars": "^1.0.1"
},
"ember-addon": {
"configPath": "tests/dummy/config"
diff --git a/testem.json b/testem.js
similarity index 81%
rename from testem.json
rename to testem.js
index 0f35392c..26044b2f 100644
--- a/testem.json
+++ b/testem.js
@@ -1,4 +1,5 @@
-{
+/*jshint node:true*/
+module.exports = {
"framework": "qunit",
"test_page": "tests/index.html?hidepassed",
"disable_watching": true,
@@ -9,4 +10,4 @@
"PhantomJS",
"Chrome"
]
-}
+};
diff --git a/tests/dummy/app/app.js b/tests/dummy/app/app.js
index 8b234d6d..831ad610 100644
--- a/tests/dummy/app/app.js
+++ b/tests/dummy/app/app.js
@@ -1,6 +1,6 @@
import Ember from 'ember';
-import Resolver from 'ember/resolver';
-import loadInitializers from 'ember/load-initializers';
+import Resolver from './resolver';
+import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
let App;
diff --git a/tests/dummy/app/components/ivy-tab.js b/tests/dummy/app/components/ivy-tab.js
index f43466ab..3398f43f 100644
--- a/tests/dummy/app/components/ivy-tab.js
+++ b/tests/dummy/app/components/ivy-tab.js
@@ -5,7 +5,7 @@ export default IvyTabComponent.extend({
tagName: 'li',
actions: {
- select: function() {
+ select() {
this.select();
}
},
diff --git a/tests/dummy/app/index.html b/tests/dummy/app/index.html
index 54cce3c8..5b870941 100644
--- a/tests/dummy/app/index.html
+++ b/tests/dummy/app/index.html
@@ -7,20 +7,19 @@
- {{content-for 'head'}}
+ {{content-for "head"}}
-
- {{content-for 'head-footer'}}
+ {{content-for "head-footer"}}
- {{content-for 'body'}}
+ {{content-for "body"}}
- {{content-for 'body-footer'}}
+ {{content-for "body-footer"}}