<PaperTabs @center={{this.center}} @stretch={{this.stretch}} @borderBottom={{this.borderBottom}} @selected={{this.selectedBasicTab}} @onChange={{action (mut this.selectedBasicTab)}} as |tabs|>
<tabs.tab>
Page One
</tabs.tab>
<tabs.tab @disabled={{true}}>
Page Two (disabled)
</tabs.tab>
<tabs.tab>
Page Three
</tabs.tab>
<tabs.tab>
Page Four
</tabs.tab>
<tabs.tab>
Page Five
</tabs.tab>
</PaperTabs>
{{#liquid-bind (hash tab=this.selectedBasicTab) class="md-padding" as |current|}}
<h1 class="md-display-2">Tab {{current.tab}}</h1>
<p>
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.
</p>
{{/liquid-bind}}
Tab 0
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.
Note: transitions were implemented using liquid-fire.
The way that we teach paper-tabs is that they are essentially a radio-group
with some additional features (like tab pagination). So, this component essentially is
just a tab header you can use to control a value of a property.
To reinforce this idea, each of the tabs optionally accepts a value
property which needs to match the paper-tabs
selected
property (see API table below for more info). You don't need to use the value property,
though. Each tab is automatically given a value equal to its index. So, your onChange
action will start getting integer values if you don't specify any value on the tabs.
It is up to the user to manage the body of the tabs. They're free to use liquid-fire
,
css transitions or even just plain handlebars {{#if}}
s.
This makes the component much more flexible and DDAU-compliant, in our experience,
but it also means you will need to do a little bit more work to manage what you want to do with
the value. Thankfully Ember makes this dead easy for us.
To test tab pagination resize the browser.
<PaperTabs @primary={{true}} @borderBottom={{true}} @selected={{this.selectedChapter}} @onChange={{action (mut this.selectedChapter)}} as |tabs|>
{{#each this.chapters as |chapter|}}
<tabs.tab @value={{chapter}}>
{{chapter.title}}
</tabs.tab>
{{/each}}
</PaperTabs>
{{#liquid-bind (hash tab=this.selectedChapter.index m=this.selectedChapter) class="md-padding dynamic-animation" as |current|}}
<h1 class="md-display-2">{{current.m.title}}</h1>
<p>{{current.m.body}}</p>
<PaperButton @primary={{true}} @raised={{true}} @disabled={{eq this.chapters.length 1}} @onClick={{action "removeChapter" current.m}}>
Remove chapter
</PaperButton>
{{/liquid-bind}}
Chapter 1
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.
Note: transitions were implemented using liquid-fire.
In this example we render tabs dynamically, one per model. Note that we need some simple book-keeping to implement some specific features.
What happens when we delete an active chapter? We decide that by setting
selected
. When adding a new chapter we want it to be the
new selected tab. No problem, just set the selected
property
to the newly selected chapter.
<PaperTabs @selected={{this.router.currentRouteName}} @borderBottom={{true}} @onChange={{action "noop"}} as |tabs|>
<tabs.tab @value="demo.tabs.index" @href={{href-to "demo.tabs.index"}}>
Index
</tabs.tab>
<tabs.tab @value="demo.tabs.nested-route" @href={{href-to "demo.tabs.nested-route"}}>
Nested Route
</tabs.tab>
</PaperTabs>
{{liquid-outlet class="md-padding"}}
Nested Route
This content lives in a nested "nested-route" route.
Note: transitions were implemented using liquid-fire.
Sometimes we need to use tabs with routes. If you pass an href
property to a tab, it will render itself as an <a>
tag.
Hint: use ember-href-to
addon to easily generate
urls for your routes. It plays really well with paper-tabs
,
paper-buttons
and even paper-item
s.
Hint: for Ember versions less than 2.15, use the ember-router-service-polyfill
addon to easily retrieve
the current route name and use it as the selected value to paper-tabs
.
API Usage
Option | Type | Description |
---|---|---|
accent |
boolean | Pass true to enable accent color scheme. |
borderBottom |
boolean | Use true to enable border beneath tabs. Default is false. |
onChange |
action | An action triggered when the active tab changes. |
primary |
boolean | Pass true to enable primary color scheme. |
selected |
string or number | Value of the active tab. Each tab automatically gets an index as its value. Default is 0 (the first tab active). |
stretch |
boolean or matchMedia query | Use true/false to permanently enable/disable tab stretching. You can also use a matchMedia query to enable tab stretching only at certain viewport sizes. Default value is sm ((min-width: 600px) and (max-width: 959px) ). |
tabs.tab API |
||
disabled |
boolean | Pass true to disable the tab button. |
href |
string | You can pass an href to the tab button to render a link. Hint: use ember-href-to to generate route urls. |
isSelected |
boolean | Optionally you can set a specific tab as selected directly without relying on the global tabs value. |
onClick |
action | An action triggered when the tab button is clicked. |
value |
string | Value associated with the tab. To activate the tab, selected needs to have this value. Each tab gets a value automatically set to its index, so you don't need to use this property unless you need specific values for some special case. |