diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d5b52fe6..378c8da4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ Contributions and pull requests are always welcome. Contributors may often be fo - [#730](https://github.com/miguelcobain/ember-paper/pull/730) ready for fastboot 1.0 - [#752](https://github.com/miguelcobain/ember-paper/pull/752) Tooltips are now available. Contrasts are now set correctly. - [#750](https://github.com/miguelcobain/ember-paper/pull/750) Toasts are now available. -- [#753](https://github.com/miguelcobain/ember-paper/pull/753) Nav bar is now available. This feature essentially replaces tabs. +- [#753](https://github.com/miguelcobain/ember-paper/pull/753) and [#755](https://github.com/miguelcobain/ember-paper/pull/755) Tabs are now available. - [#739](https://github.com/miguelcobain/ember-paper/pull/739) Grid list was updated: - now uses camelCased attributes, just like the rest of the project - uses contextual components api, i.e `{{#paper-grid-list as |grid|}}{{#grid.tile}}`. diff --git a/addon/components/paper-nav-ink-bar.js b/addon/components/paper-ink-bar.js similarity index 53% rename from addon/components/paper-nav-ink-bar.js rename to addon/components/paper-ink-bar.js index e3a0f27d2..ccc264bd3 100644 --- a/addon/components/paper-nav-ink-bar.js +++ b/addon/components/paper-ink-bar.js @@ -6,11 +6,12 @@ const { computed, Component, String: { htmlSafe } } = Ember; export default Component.extend({ layout, - tagName: 'md-nav-ink-bar', + tagName: 'md-ink-bar', attributeBindings: ['style'], + classNameBindings: ['movingRight:md-right:md-left'], - style: computed('left', 'width', function() { - return htmlSafe(`left: ${this.get('left')}px; width: ${this.get('width')}px;`); + style: computed('left', 'right', function() { + return htmlSafe(`left: ${this.get('left')}px; right: ${this.get('right')}px;`); }) }); diff --git a/addon/components/paper-nav-bar-item.js b/addon/components/paper-nav-bar-item.js deleted file mode 100644 index a8d8628ef..000000000 --- a/addon/components/paper-nav-bar-item.js +++ /dev/null @@ -1,37 +0,0 @@ -import Ember from 'ember'; -import layout from '../templates/components/paper-nav-bar-item'; -import { ChildMixin } from 'ember-composability-tools'; -const { computed, Component } = Ember; - -export default Component.extend(ChildMixin, { - layout, - tagName: 'li', - classNames: ['md-nav-item'], - attributeBindings: ['ariaSelected:aria-selected'], - ariaSelected: computed.reads('selected'), - accent: true, - - selected: computed('selectedNavItem', 'name', function() { - if (this.get('selectedNavItem') !== undefined) { - return this.get('selectedNavItem') === this.get('name'); - } - }), - - didRender() { - this._super(...arguments); - let button = this.element.querySelector('.md-button'); - let { width } = button.getBoundingClientRect(); - let left = button.offsetLeft; - this.setProperties({ - width, - left - }); - }, - - actions: { - onButtonClick() { - this.sendAction('onClick', ...arguments); - this.sendAction('onSelect', this); - } - } -}); diff --git a/addon/components/paper-nav-bar.js b/addon/components/paper-nav-bar.js deleted file mode 100644 index f7011d26d..000000000 --- a/addon/components/paper-nav-bar.js +++ /dev/null @@ -1,56 +0,0 @@ -import Ember from 'ember'; -import layout from '../templates/components/paper-nav-bar'; -import { ParentMixin } from 'ember-composability-tools'; - -const { computed, Component } = Ember; - -export default Component.extend(ParentMixin, { - layout, - tagName: 'md-nav-bar', - - selectedNavItem: null, // key of item - - _selectedNavItem: computed('childComponents.@each.name', 'selectedNavItem', function() { - return this.get('childComponents').findBy('name', this.get('selectedNavItem')); - }), - - _previousSelectedNavItem: computed('childComponents.@each.name', 'previousSelectedNavItem', function() { - return this.get('childComponents').findBy('name', this.get('previousSelectedNavItem')); - }), - - noInkBar: false, - ariaLabel: null, - previousInkBarPosition: 0, - - inkBarLeft: computed('_selectedNavItem.left', function() { - return this.get('_selectedNavItem.left') || 0; - }), - - inkBarWidth: computed('_selectedNavItem.width', function() { - return this.get('_selectedNavItem.width') || 0; - }), - - setMovingRight() { - let movingRight = this.get('_previousSelectedNavItem.left') < this.get('_selectedNavItem.left'); - this.set('movingRight', movingRight); - }, - - didReceiveAttrs() { - this._super(...arguments); - if (this.get('selectedNavItem') !== this.get('previousSelectedNavItem')) { - this.setMovingRight(); - this.set('previousSelectedNavItem', this.get('selectedNavItem')); - } - }, - - actions: { - onChange(selected) { - // support non DDAU scenario - if (this.get('onChange')) { - this.sendAction('onChange', selected.get('name')); - } else { - this.set('selectedNavItem', selected.get('name')); - } - } - } -}); diff --git a/addon/components/paper-tab.js b/addon/components/paper-tab.js new file mode 100644 index 000000000..73e583ab4 --- /dev/null +++ b/addon/components/paper-tab.js @@ -0,0 +1,50 @@ +import Ember from 'ember'; +import layout from '../templates/components/paper-tab'; +import { ChildMixin } from 'ember-composability-tools'; +import RippleMixin from 'ember-paper/mixins/ripple-mixin'; +import FocusableMixin from 'ember-paper/mixins/focusable-mixin'; +const { computed, Component, String: { htmlSafe } } = Ember; + +export default Component.extend(ChildMixin, RippleMixin, FocusableMixin, { + layout, + tagName: 'md-tab-item', + classNames: ['md-tab'], + classNameBindings: ['isSelected:md-active'], + attributeBindings: ['isSelected:aria-selected', 'href', 'style'], + + rippleContainerSelector: null, + + // tags have brower styles or are usually styled by the user + // this makes sure that tab item still looks good with an anchor tag + style: computed('href', function() { + if (this.get('href')) { + return htmlSafe('text-decoration: none; border: none;'); + } + }), + + isSelected: computed('selected', 'name', function() { + if (this.get('selected') !== undefined) { + return this.get('selected') === this.get('name'); + } + }), + + init() { + this._super(...arguments); + if (this.get('href')) { + this.set('tagName', 'a'); + } + }, + + didRender() { + this._super(...arguments); + let button = this.element; + let { width } = button.getBoundingClientRect(); + let left = button.offsetLeft; + this.setProperties({ width, left }); + }, + + click() { + this.sendAction('onClick', ...arguments); + this.sendAction('onSelect', this); + } +}); diff --git a/addon/components/paper-tabs.js b/addon/components/paper-tabs.js new file mode 100644 index 000000000..56145ab3b --- /dev/null +++ b/addon/components/paper-tabs.js @@ -0,0 +1,122 @@ +import Ember from 'ember'; +import layout from '../templates/components/paper-tabs'; +import { ParentMixin } from 'ember-composability-tools'; +import ColorMixin from 'ember-paper/mixins/color-mixin'; + +const { computed, Component, String: { htmlSafe } } = Ember; + +export default Component.extend(ParentMixin, ColorMixin, { + layout, + tagName: 'md-tabs', + + classNames: ['md-no-tab-content'], + attributeBindings: ['borderBottom:md-border-bottom'], + + selected: null, // key of item + + _selectedTab: computed('childComponents.@each.name', 'selected', function() { + return this.get('childComponents').findBy('name', this.get('selected')); + }), + + _previousSelectedTab: computed('childComponents.@each.name', 'previousSelectedNavItem', function() { + return this.get('childComponents').findBy('name', this.get('previousSelected')); + }), + + noInkBar: false, + noInk: false, + ariaLabel: null, + previousInkBarPosition: 0, + + inkBarLeft: computed('_selectedTab.left', function() { + return this.get('_selectedTab.left') || 0; + }), + + inkBarRight: computed('wrapperWidth', '_selectedTab.width', 'inkBarLeft', function() { + return this.get('wrapperWidth') - this.get('inkBarLeft') - (this.get('_selectedTab.width') || 0); + }), + + tabsWidth: computed('childComponents.@each.width', function() { + return this.get('childComponents').reduce((prev, t) => prev + t.get('width'), 0); + }), + + shouldPaginate: computed('canvasWidth', function() { + return this.get('tabsWidth') > this.get('canvasWidth'); + }), + + didReceiveAttrs() { + this._super(...arguments); + if (this.get('selected') !== this.get('previousSelected')) { + this.setMovingRight(); + this.set('previousSelected', this.get('selectedNavItem')); + } + }, + + didInsertElement() { + this._super(...arguments); + + let updateCanvasWidth = () => { + let { width: canvasWidth } = this.element.querySelector('md-tabs-canvas').getBoundingClientRect(); + let { width: wrapperWidth } = this.element.querySelector('md-pagination-wrapper').getBoundingClientRect(); + this.set('canvasWidth', canvasWidth); + this.set('wrapperWidth', wrapperWidth); + }; + + window.addEventListener('resize', updateCanvasWidth); + window.addEventListener('orientationchange', updateCanvasWidth); + this.updateCanvasWidth = updateCanvasWidth; + }, + + didRender() { + this._super(...arguments); + this.updateCanvasWidth(); + }, + + willDestroyElement() { + this._super(...arguments); + window.removeEventListener('resize', this.updateCanvasWidth); + window.removeEventListener('orientationchange', this.updateCanvasWidth); + }, + + setMovingRight() { + let movingRight = this.get('_previousSelectedTab.left') < this.get('_selectedTab.left'); + this.set('movingRight', movingRight); + }, + + currentOffset: 0, + canPageBack: computed.gt('currentOffset', 0), + canPageForward: computed('wrapperWidth', 'currentOffset', 'canvasWidth', function() { + return this.get('wrapperWidth') - this.get('currentOffset') > this.get('canvasWidth'); + }), + + actions: { + previousPage() { + let tab = this.get('childComponents').find((t) => { + return t.get('left') >= this.get('currentOffset'); + }); + if (tab) { + let left = Math.max(0, tab.get('left') - this.get('canvasWidth')); + this.set('currentOffset', left); + this.set('paginationStyle', htmlSafe(`transform: translate3d(-${left}px, 0px, 0px);`)); + } + }, + + nextPage() { + let tab = this.get('childComponents').find((t) => { + return t.get('left') + t.get('width') > this.get('canvasWidth'); + }); + if (tab) { + this.set('currentOffset', tab.get('left')); + this.set('paginationStyle', htmlSafe(`transform: translate3d(-${tab.get('left')}px, 0px, 0px);`)); + } + }, + + onChange(selected) { + // support non DDAU scenario + if (this.get('onChange')) { + this.sendAction('onChange', selected.get('name')); + } else { + this.set('selected', selected.get('name')); + } + } + } +}); diff --git a/addon/templates/components/paper-nav-bar-item.hbs b/addon/templates/components/paper-nav-bar-item.hbs deleted file mode 100644 index 243880c5e..000000000 --- a/addon/templates/components/paper-nav-bar-item.hbs +++ /dev/null @@ -1,15 +0,0 @@ -{{#paper-button - accent=accent - disabled=disabled - onClick=(action "onButtonClick") - href=href - class=(concat - "_md-nav-button" - (unless selected " md-unselected") - )}} - {{#if hasBlock}} - {{yield}} - {{else}} - {{name}} - {{/if}} -{{/paper-button}} diff --git a/addon/templates/components/paper-nav-bar.hbs b/addon/templates/components/paper-nav-bar.hbs deleted file mode 100644 index dc71dd88d..000000000 --- a/addon/templates/components/paper-nav-bar.hbs +++ /dev/null @@ -1,15 +0,0 @@ -
- - {{#unless noInkBar}} - {{paper-nav-ink-bar class=(if movingRight "_md-right" "_md-left") left=inkBarLeft width=inkBarWidth}} - {{/unless}} -
diff --git a/addon/templates/components/paper-tab.hbs b/addon/templates/components/paper-tab.hbs new file mode 100644 index 000000000..df4901a68 --- /dev/null +++ b/addon/templates/components/paper-tab.hbs @@ -0,0 +1,5 @@ +{{#if hasBlock}} + {{yield}} +{{else}} + {{name}} +{{/if}} \ No newline at end of file diff --git a/addon/templates/components/paper-tabs.hbs b/addon/templates/components/paper-tabs.hbs new file mode 100644 index 000000000..afcc4bb0b --- /dev/null +++ b/addon/templates/components/paper-tabs.hbs @@ -0,0 +1,25 @@ + + {{#if shouldPaginate}} + + {{paper-icon "keyboard-arrow-left"}} + + + {{paper-icon "keyboard-arrow-left"}} + + {{/if}} + + + + {{yield (hash + tab=(component "paper-tab" + noInk=noInk + selected=selected + onSelect=(action "onChange") + ) + )}} + {{#unless noInkBar}} + {{paper-ink-bar movingRight=movingRight left=inkBarLeft right=inkBarRight}} + {{/unless}} + + + \ No newline at end of file diff --git a/app/components/paper-ink-bar.js b/app/components/paper-ink-bar.js new file mode 100644 index 000000000..ab854897d --- /dev/null +++ b/app/components/paper-ink-bar.js @@ -0,0 +1 @@ +export { default } from 'ember-paper/components/paper-ink-bar'; \ No newline at end of file diff --git a/app/components/paper-nav-bar-item.js b/app/components/paper-nav-bar-item.js deleted file mode 100644 index 3196befdd..000000000 --- a/app/components/paper-nav-bar-item.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'ember-paper/components/paper-nav-bar-item'; \ No newline at end of file diff --git a/app/components/paper-nav-bar.js b/app/components/paper-nav-bar.js deleted file mode 100644 index a77d23a45..000000000 --- a/app/components/paper-nav-bar.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'ember-paper/components/paper-nav-bar'; \ No newline at end of file diff --git a/app/components/paper-nav-ink-bar.js b/app/components/paper-nav-ink-bar.js deleted file mode 100644 index 4907c147f..000000000 --- a/app/components/paper-nav-ink-bar.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'ember-paper/components/paper-nav-ink-bar'; \ No newline at end of file diff --git a/app/components/paper-tab.js b/app/components/paper-tab.js new file mode 100644 index 000000000..99e32ffbf --- /dev/null +++ b/app/components/paper-tab.js @@ -0,0 +1 @@ +export { default } from 'ember-paper/components/paper-tab'; \ No newline at end of file diff --git a/app/components/paper-tabs.js b/app/components/paper-tabs.js new file mode 100644 index 000000000..00217b7d9 --- /dev/null +++ b/app/components/paper-tabs.js @@ -0,0 +1 @@ +export { default } from 'ember-paper/components/paper-tabs'; \ No newline at end of file diff --git a/app/styles/ember-paper.scss b/app/styles/ember-paper.scss index 4980ce8bf..ff67424a7 100644 --- a/app/styles/ember-paper.scss +++ b/app/styles/ember-paper.scss @@ -151,8 +151,8 @@ @import './angular-material/components/toast/toast'; @import './angular-material/components/toast/toast-theme'; -@import './angular-material/components/navBar/navBar'; -@import './angular-material/components/navBar/navBar-theme'; +@import './angular-material/components/tabs/tabs'; +@import './angular-material/components/tabs/tabs-theme'; // some overrides that are needed for ember-paper (avoid if possible) @import './overrides/paper-autocomplete'; diff --git a/index.js b/index.js index 3ce23840c..db25ba66f 100644 --- a/index.js +++ b/index.js @@ -180,8 +180,8 @@ module.exports = { 'components/toast/toast.scss', 'components/toast/toast-theme.scss', - 'components/navBar/navBar.scss', - 'components/navBar/navBar-theme.scss' + 'components/tabs/tabs.scss', + 'components/tabs/tabs-theme.scss' ]; var angularScssFiles = new Funnel(this.pathBase('angular-material-source'), { diff --git a/tests/dummy/app/controllers/demo/nav-bar.js b/tests/dummy/app/controllers/demo/tabs.js similarity index 100% rename from tests/dummy/app/controllers/demo/nav-bar.js rename to tests/dummy/app/controllers/demo/tabs.js diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index 936147397..fb7cdf763 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -29,7 +29,7 @@ Router.map(function() { this.route('input'); this.route('list'); this.route('menu'); - this.route('nav-bar', function() { + this.route('tabs', function() { this.route('nested-route'); }); this.route('progress-circular'); diff --git a/tests/dummy/app/styles/demo.scss b/tests/dummy/app/styles/demo.scss index ef9cc08e2..abcc14607 100644 --- a/tests/dummy/app/styles/demo.scss +++ b/tests/dummy/app/styles/demo.scss @@ -1498,9 +1498,7 @@ md-input-container .hint { } } -/* Nav Bar demo */ -md-content .ext-content { - padding: 50px; - margin: 20px; - background-color: #FFF2E0; -} +/* tabs demo */ +.tabs-demo .md-padding h1:first-child { + margin-top: 0; +} \ No newline at end of file diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs index ac3573d51..1273be0fb 100644 --- a/tests/dummy/app/templates/application.hbs +++ b/tests/dummy/app/templates/application.hbs @@ -3,7 +3,7 @@ open=isSidenavOpen onToggle=(action (mut isSidenavOpen))}} {{#paper-toolbar class="site-content-toolbar" tall=true}} {{/paper-toolbar}} @@ -29,7 +29,6 @@ {{#submenu-item active=(is-active "demo.input" currentRouteName) href=(href-to "demo.input")}}Input{{/submenu-item}} {{#submenu-item active=(is-active "demo.list" currentRouteName) href=(href-to "demo.list")}}List{{/submenu-item}} {{#submenu-item active=(is-active "demo.menu" currentRouteName) href=(href-to "demo.menu")}}Menu{{/submenu-item}} - {{#submenu-item active=(is-active "demo.nav-bar.index" currentRouteName) href=(href-to "demo.nav-bar")}}Nav Bar{{/submenu-item}} {{#submenu-item active=(is-active "demo.progress-circular" currentRouteName) href=(href-to "demo.progress-circular")}}Progress Circular{{/submenu-item}} {{#submenu-item active=(is-active "demo.progress-linear" currentRouteName) href=(href-to "demo.progress-linear")}}Progress Linear{{/submenu-item}} {{#submenu-item active=(is-active "demo.radio" currentRouteName) href=(href-to "demo.radio")}}Radio{{/submenu-item}} @@ -37,6 +36,7 @@ {{#submenu-item active=(is-active "demo.sidenav" currentRouteName) href=(href-to "demo.sidenav")}}Sidenav{{/submenu-item}} {{#submenu-item active=(is-active "demo.slider" currentRouteName) href=(href-to "demo.slider")}}Slider{{/submenu-item}} {{#submenu-item active=(is-active "demo.switch" currentRouteName) href=(href-to "demo.switch")}}Switch{{/submenu-item}} + {{#submenu-item active=(is-active "demo.tabs.index" currentRouteName) href=(href-to "demo.tabs")}}Tabs{{/submenu-item}} {{#submenu-item active=(is-active "demo.toast" currentRouteName) href=(href-to "demo.toast")}}Toast{{/submenu-item}} {{#submenu-item active=(is-active "demo.toolbar" currentRouteName) href=(href-to "demo.toolbar")}}Toolbar{{/submenu-item}} {{#submenu-item active=(is-active "demo.tooltip" currentRouteName) href=(href-to "demo.tooltip")}}Tooltip{{/submenu-item}} diff --git a/tests/dummy/app/templates/demo/nav-bar/index.hbs b/tests/dummy/app/templates/demo/nav-bar/index.hbs deleted file mode 100644 index 28433de9d..000000000 --- a/tests/dummy/app/templates/demo/nav-bar/index.hbs +++ /dev/null @@ -1 +0,0 @@ -This content lives in a nested "index" route. diff --git a/tests/dummy/app/templates/demo/nav-bar/nested-route.hbs b/tests/dummy/app/templates/demo/nav-bar/nested-route.hbs deleted file mode 100644 index 6a8ad0b16..000000000 --- a/tests/dummy/app/templates/demo/nav-bar/nested-route.hbs +++ /dev/null @@ -1 +0,0 @@ -This content lives in a nested "nested-route" route. diff --git a/tests/dummy/app/templates/demo/nav-bar.hbs b/tests/dummy/app/templates/demo/tabs.hbs similarity index 53% rename from tests/dummy/app/templates/demo/nav-bar.hbs rename to tests/dummy/app/templates/demo/tabs.hbs index 3f836bf18..64ab61d1c 100644 --- a/tests/dummy/app/templates/demo/nav-bar.hbs +++ b/tests/dummy/app/templates/demo/tabs.hbs @@ -1,6 +1,6 @@ -{{page-toolbar pageTitle="Nav Bar" isDemo=true}} +{{page-toolbar pageTitle="Tabs" isDemo=true}} -{{#doc-content}} +{{#doc-content class="tabs-demo"}}
{{#paper-card class="navBardemoBasicUsage"}} @@ -19,28 +19,43 @@
- {{#paper-content class="md-padding"}} + {{#paper-content}} {{! BEGIN-SNIPPET basic-usage}} - {{#paper-nav-bar - selectedNavItem=selectedNavItem - onChange=(action (mut selectedNavItem)) as |nav|}} - {{#nav.item name=1}} + {{#paper-tabs + borderBottom=true + selected=selectedNavItem + onChange=(action (mut selectedNavItem)) as |tabs|}} + {{#tabs.tab name=1}} Page One - {{/nav.item}} - {{#nav.item name=2}} + {{/tabs.tab}} + {{#tabs.tab name=2}} Page Two - {{/nav.item}} - {{#nav.item name=3}} + {{/tabs.tab}} + {{#tabs.tab name=3}} Page Three - {{/nav.item}} - {{/paper-nav-bar}} + {{/tabs.tab}} + {{#tabs.tab name=4}} + Page Three + {{/tabs.tab}} + {{#tabs.tab name=5}} + Page Three + {{/tabs.tab}} + {{/paper-tabs}} - {{#liquid-bind selectedNavItem class="ext-content"}} - External content for {{selectedNavItem}}. + {{#liquid-bind selectedNavItem class="md-padding" as |current|}} +

Tab {{current}}

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Nulla venenatis ante augue. Phasellus volutpat neque ac dui mattis + vulputate. Etiam consequat aliquam cursus. In sodales pretium ultrices. + Maecenas lectus est, sollicitudin consectetur felis nec, feugiat ultricies mi. +

{{/liquid-bind}} {{! END-SNIPPET }} -

Note: transitions were implemented using liquid-fire.

+
+ Note: transitions were implemented using liquid-fire. +
{{/paper-content}}
{{/paper-card}} @@ -63,23 +78,23 @@
- {{#paper-content class="md-padding"}} + {{#paper-content}} {{! BEGIN-SNIPPET routable-usage}} - {{#paper-nav-bar - selectedNavItem=selectedNavRoute - onChange=(action (mut selectedNavRoute)) as |nav|}} - {{#nav.item name="page-one" href="#/components/nav-bar/"}} + {{#paper-tabs borderBottom=true as |tabs|}} + {{#tabs.tab name="page-one" href=(href-to "demo.tabs.index")}} Index - {{/nav.item}} - {{#nav.item name="page-two" href="#/components/nav-bar/nested-route"}} + {{/tabs.tab}} + {{#tabs.tab name="page-two" href=(href-to "demo.tabs.nested-route")}} Nested Route - {{/nav.item}} - {{/paper-nav-bar}} + {{/tabs.tab}} + {{/paper-tabs}} - {{liquid-outlet class="ext-content"}} + {{liquid-outlet class="md-padding"}} {{! END-SNIPPET }} -

Note: transitions were implemented using liquid-fire.

+
+ Note: transitions were implemented using liquid-fire. +
{{/paper-content}}
{{/paper-card}} @@ -88,14 +103,15 @@
{{paper-api (p-section - (p-row "selectedNavItem" "string" "Name of the active tab.") + (p-row "selected" "string" "Name of the active tab.") (p-row "onChange" "action" "An action triggered when the active tab changes.") + (p-row "accent" "boolean" "Pass `false` to enable accent color on tab.") + (p-row "primary" "boolean" "Pass `false` to enable primary color on tab.") ) (p-section - "`nav.item` API" + "`tabs.tab` API" (p-row "name" "string" "Name of the tab. To activate the tab, `selectedNavItem` needs to have this value.") (p-row "disabled" "boolean" "Pass `true` to disable the tab button.") - (p-row "accent" "boolean" "Pass `false` to disable accent color on tab. Default is `true`.") (p-row "href" "string" "You can pass an href to the tab button to render a link. Hint: use `ember-href-to` to generate route urls.") (p-row "onClick" "action" "An action triggered when the tab button is clicked.") ) title="API Usage" diff --git a/tests/dummy/app/templates/demo/tabs/index.hbs b/tests/dummy/app/templates/demo/tabs/index.hbs new file mode 100644 index 000000000..7d58f48e8 --- /dev/null +++ b/tests/dummy/app/templates/demo/tabs/index.hbs @@ -0,0 +1,2 @@ +

Index Route

+

This content lives in a nested "index" route.

diff --git a/tests/dummy/app/templates/demo/tabs/nested-route.hbs b/tests/dummy/app/templates/demo/tabs/nested-route.hbs new file mode 100644 index 000000000..7c68340ef --- /dev/null +++ b/tests/dummy/app/templates/demo/tabs/nested-route.hbs @@ -0,0 +1,2 @@ +

Nested Route

+

This content lives in a nested "nested-route" route.

diff --git a/tests/dummy/app/transitions.js b/tests/dummy/app/transitions.js index 52b9ed25b..fd7e6e7d8 100644 --- a/tests/dummy/app/transitions.js +++ b/tests/dummy/app/transitions.js @@ -16,8 +16,8 @@ export default function() { // nav bar demo - routable usage this.transition( - this.fromRoute('demo.nav-bar.index'), - this.toRoute('demo.nav-bar.nested-route'), + this.fromRoute('demo.tabs.index'), + this.toRoute('demo.tabs.nested-route'), this.use('toLeft'), this.reverse('toRight') ); diff --git a/tests/integration/components/paper-nav-bar-test.js b/tests/integration/components/paper-nav-bar-test.js deleted file mode 100644 index d585b1c3c..000000000 --- a/tests/integration/components/paper-nav-bar-test.js +++ /dev/null @@ -1,163 +0,0 @@ -import { moduleForComponent, test } from 'ember-qunit'; -import hbs from 'htmlbars-inline-precompile'; -import { find, click } from 'ember-native-dom-helpers'; - -moduleForComponent('paper-nav-bar', 'Integration | Component | paper nav bar', { - integration: true -}); - -test('can set default selected tab', function(assert) { - this.render(hbs` - {{#paper-nav-bar selectedNavItem="two" as |nav|}} - {{nav.item name="one"}} - {{nav.item name="two"}} - {{nav.item name="three"}} - {{/paper-nav-bar}} - `); - - assert.ok(find('.md-nav-item:nth-child(2)').hasAttribute('aria-selected')); -}); - -test('blockless nav bar items render name prop', function(assert) { - this.render(hbs` - {{#paper-nav-bar as |nav|}} - {{nav.item name="one"}} - {{nav.item name="two"}} - {{nav.item name="three"}} - {{/paper-nav-bar}} - `); - - assert.ok(find('.md-nav-item:nth-child(1)').textContent, 'one'); - assert.ok(find('.md-nav-item:nth-child(2)').textContent, 'two'); - assert.ok(find('.md-nav-item:nth-child(3)').textContent, 'three'); -}); - -test('block nav bar items renders block', function(assert) { - this.render(hbs` - {{#paper-nav-bar as |nav|}} - {{#nav.item}} - one - {{/nav.item}} - {{#nav.item}} - two - {{/nav.item}} - {{#nav.item}} - three - {{/nav.item}} - {{/paper-nav-bar}} - `); - - assert.ok(find('.md-nav-item:nth-child(1)').textContent, 'one'); - assert.ok(find('.md-nav-item:nth-child(2)').textContent, 'two'); - assert.ok(find('.md-nav-item:nth-child(3)').textContent, 'three'); -}); - -test('can change selected tab using property', function(assert) { - this.selected = 'two'; - - this.render(hbs` - {{#paper-nav-bar selectedNavItem=selected as |nav|}} - {{nav.item name="one"}} - {{nav.item name="two"}} - {{nav.item name="three"}} - {{/paper-nav-bar}} - `); - - assert.ok(find('.md-nav-item:nth-child(2)').hasAttribute('aria-selected')); - - this.set('selected', 'three'); - - assert.ok(find('.md-nav-item:nth-child(3)').hasAttribute('aria-selected')); - -}); - -test('clicking on a tab sets it to active', async function(assert) { - this.render(hbs` - {{#paper-nav-bar as |nav|}} - {{nav.item name="one"}} - {{nav.item name="two"}} - {{nav.item name="three"}} - {{/paper-nav-bar}} - `); - - await click('.md-nav-item:nth-child(3) button'); - - assert.ok(find('.md-nav-item:nth-child(3)').hasAttribute('aria-selected')); -}); - -test('clicking on multiple tabs works', async function(assert) { - this.render(hbs` - {{#paper-nav-bar as |nav|}} - {{nav.item name="one"}} - {{nav.item name="two"}} - {{nav.item name="three"}} - {{/paper-nav-bar}} - `); - - await click('.md-nav-item:nth-child(2) button'); - await click('.md-nav-item:nth-child(3) button'); - await click('.md-nav-item:nth-child(1) button'); - - assert.ok(find('.md-nav-item:nth-child(1)').hasAttribute('aria-selected')); -}); - -test('onChange is triggered', async function(assert) { - assert.expect(1); - - this.onChange = (name) => { - assert.equal(name, 'two'); - }; - - this.render(hbs` - {{#paper-nav-bar onChange=onChange as |nav|}} - {{nav.item name="one"}} - {{nav.item name="two"}} - {{nav.item name="three"}} - {{/paper-nav-bar}} - `); - - await click('.md-nav-item:nth-child(2) button'); -}); - -test('item onClick is triggered', async function(assert) { - assert.expect(1); - - this.onClick = () => { - assert.ok(true); - }; - - this.render(hbs` - {{#paper-nav-bar onChange=onChange as |nav|}} - {{nav.item name="one"}} - {{nav.item name="two"}} - {{nav.item name="three" onClick=onClick}} - {{/paper-nav-bar}} - `); - - await click('.md-nav-item:nth-child(3) button'); -}); - -test('has ink bar by default', async function(assert) { - this.render(hbs` - {{#paper-nav-bar as |nav|}} - {{nav.item}} - {{nav.item}} - {{nav.item}} - {{/paper-nav-bar}} - `); - - assert.ok(find('md-nav-ink-bar')); -}); - -test('noInkBar disables ink bar', async function(assert) { - - this.render(hbs` - {{#paper-nav-bar noInkBar=true as |nav|}} - {{nav.item}} - {{nav.item}} - {{nav.item}} - {{/paper-nav-bar}} - `); - - assert.notOk(find('md-nav-ink-bar')); -}); diff --git a/tests/integration/components/paper-tabs-test.js b/tests/integration/components/paper-tabs-test.js new file mode 100644 index 000000000..08167c106 --- /dev/null +++ b/tests/integration/components/paper-tabs-test.js @@ -0,0 +1,191 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; +import { find, click, findAll } from 'ember-native-dom-helpers'; + +moduleForComponent('paper-tabs', 'Integration | Component | paper tabs', { + integration: true +}); + +test('can set default selected tab', function(assert) { + this.render(hbs` + {{#paper-tabs selected="two" as |tabs|}} + {{tabs.tab name="one"}} + {{tabs.tab name="two"}} + {{tabs.tab name="three"}} + {{/paper-tabs}} + `); + + assert.ok(find('.md-tab:nth-child(2)').classList.contains('md-active')); +}); + +test('blockless nav bar items render name prop', function(assert) { + this.render(hbs` + {{#paper-tabs as |tabs|}} + {{tabs.tab name="one"}} + {{tabs.tab name="two"}} + {{tabs.tab name="three"}} + {{/paper-tabs}} + `); + + assert.ok(find('.md-tab:nth-child(1)').textContent, 'one'); + assert.ok(find('.md-tab:nth-child(2)').textContent, 'two'); + assert.ok(find('.md-tab:nth-child(3)').textContent, 'three'); +}); + +test('block nav bar items renders block', function(assert) { + this.render(hbs` + {{#paper-tabs as |tabs|}} + {{#tabs.tab}} + one + {{/tabs.tab}} + {{#tabs.tab}} + two + {{/tabs.tab}} + {{#tabs.tab}} + three + {{/tabs.tab}} + {{/paper-tabs}} + `); + + assert.ok(find('.md-tab:nth-child(1)').textContent, 'one'); + assert.ok(find('.md-tab:nth-child(2)').textContent, 'two'); + assert.ok(find('.md-tab:nth-child(3)').textContent, 'three'); +}); + +test('can change selected tab using property', function(assert) { + this.selected = 'two'; + + this.render(hbs` + {{#paper-tabs selected=selected as |tabs|}} + {{tabs.tab name="one"}} + {{tabs.tab name="two"}} + {{tabs.tab name="three"}} + {{/paper-tabs}} + `); + + assert.ok(find('.md-tab:nth-child(2)').classList.contains('md-active')); + + this.set('selected', 'three'); + + assert.ok(find('.md-tab:nth-child(3)').classList.contains('md-active')); + +}); + +test('clicking on a tab sets it to active', async function(assert) { + this.render(hbs` + {{#paper-tabs as |tabs|}} + {{tabs.tab name="one"}} + {{tabs.tab name="two"}} + {{tabs.tab name="three"}} + {{/paper-tabs}} + `); + + await click('.md-tab:nth-child(3)'); + + assert.ok(find('.md-tab:nth-child(3)').classList.contains('md-active')); +}); + +test('clicking on multiple tabs works', async function(assert) { + this.render(hbs` + {{#paper-tabs as |tabs|}} + {{tabs.tab name="one"}} + {{tabs.tab name="two"}} + {{tabs.tab name="three"}} + {{/paper-tabs}} + `); + + await click('.md-tab:nth-child(2)'); + await click('.md-tab:nth-child(3)'); + await click('.md-tab:nth-child(1)'); + + assert.ok(find('.md-tab:nth-child(1)').classList.contains('md-active')); +}); + +test('onChange is triggered', async function(assert) { + assert.expect(1); + + this.onChange = (name) => { + assert.equal(name, 'two'); + }; + + this.render(hbs` + {{#paper-tabs onChange=onChange as |tabs|}} + {{tabs.tab name="one"}} + {{tabs.tab name="two"}} + {{tabs.tab name="three"}} + {{/paper-tabs}} + `); + + await click('.md-tab:nth-child(2)'); +}); + +test('item onClick is triggered', async function(assert) { + assert.expect(1); + + this.onClick = () => { + assert.ok(true); + }; + + this.render(hbs` + {{#paper-tabs onChange=onChange as |tabs|}} + {{tabs.tab name="one"}} + {{tabs.tab name="two"}} + {{tabs.tab name="three" onClick=onClick}} + {{/paper-tabs}} + `); + + await click('.md-tab:nth-child(3)'); +}); + +test('has ink bar by default', function(assert) { + this.render(hbs` + {{#paper-tabs as |tabs|}} + {{tabs.tab}} + {{tabs.tab}} + {{tabs.tab}} + {{/paper-tabs}} + `); + + assert.ok(find('md-ink-bar')); +}); + +test('noInkBar disables ink bar', function(assert) { + + this.render(hbs` + {{#paper-tabs noInkBar=true as |tabs|}} + {{tabs.tab}} + {{tabs.tab}} + {{tabs.tab}} + {{/paper-tabs}} + `); + + assert.notOk(find('md-ink-bar')); +}); + +test('borderBottom true adds border', function(assert) { + this.render(hbs` + {{#paper-tabs borderBottom=true as |tabs|}} + {{tabs.tab}} + {{tabs.tab}} + {{tabs.tab}} + {{/paper-tabs}} + `); + + assert.ok(find('md-tabs').hasAttribute('md-border-bottom')); +}); + +test('using href renders anchor tags', function(assert) { + this.render(hbs` + {{#paper-tabs as |tabs|}} + {{tabs.tab href="a"}} + {{tabs.tab href="b"}} + {{tabs.tab href="c"}} + {{/paper-tabs}} + `); + + let tabs = findAll('a.md-tab'); + assert.equal(tabs.length, 3); + tabs.forEach((t) => { + assert.ok(t.hasAttribute('href')); + }); +});