diff --git a/packages/core/src/components/app/app.ios.vars.scss b/packages/core/src/components/app/app.ios.vars.scss index 0097466ec5..ae14385183 100644 --- a/packages/core/src/components/app/app.ios.vars.scss +++ b/packages/core/src/components/app/app.ios.vars.scss @@ -1,6 +1,6 @@ @import "../../themes/ionic.globals.ios"; -@import "../tabs/tabs.ios.vars"; +@import "../tabbar/tabbar.ios.vars"; // iOS App // -------------------------------------------------- diff --git a/packages/core/src/components/app/app.md.vars.scss b/packages/core/src/components/app/app.md.vars.scss index 8cd780bbd1..9482901799 100644 --- a/packages/core/src/components/app/app.md.vars.scss +++ b/packages/core/src/components/app/app.md.vars.scss @@ -1,6 +1,6 @@ @import "../../themes/ionic.globals.md"; -@import "../tabs/tabs.md.vars"; +@import "../tabbar/tabbar.md.vars"; // Material Design App diff --git a/packages/core/src/components/tab/tab.scss b/packages/core/src/components/tab/tab.scss new file mode 100644 index 0000000000..1b9cc4de49 --- /dev/null +++ b/packages/core/src/components/tab/tab.scss @@ -0,0 +1,19 @@ +@import "../../themes/ionic.globals"; + +ion-tab { + @include position(0, null, null, 0); + + position: absolute; + z-index: -1; + display: none; + + width: 100%; + height: 100%; + + contain: layout size style; +} + +ion-tab.show-tab { + z-index: $z-index-page-container; + display: block; +} diff --git a/packages/core/src/components/tab/tab.tsx b/packages/core/src/components/tab/tab.tsx index 61ca95fc66..c004510fd5 100644 --- a/packages/core/src/components/tab/tab.tsx +++ b/packages/core/src/components/tab/tab.tsx @@ -5,6 +5,7 @@ import { FrameworkDelegate } from '../..'; @Component({ tag: 'ion-tab', + styleUrl: 'tab.scss' }) export class Tab { diff --git a/packages/core/src/components/tabs/tabs.ios.scss b/packages/core/src/components/tabbar/tabbar.ios.scss similarity index 98% rename from packages/core/src/components/tabs/tabs.ios.scss rename to packages/core/src/components/tabbar/tabbar.ios.scss index 338a675a1b..434f05fe00 100644 --- a/packages/core/src/components/tabs/tabs.ios.scss +++ b/packages/core/src/components/tabbar/tabbar.ios.scss @@ -1,5 +1,5 @@ -@import "./tabs"; -@import "./tabs.ios.vars"; +@import "./tabbar"; +@import "./tabbar.ios.vars"; // iOS Tabs // -------------------------------------------------- diff --git a/packages/core/src/components/tabs/tabs.ios.vars.scss b/packages/core/src/components/tabbar/tabbar.ios.vars.scss similarity index 100% rename from packages/core/src/components/tabs/tabs.ios.vars.scss rename to packages/core/src/components/tabbar/tabbar.ios.vars.scss diff --git a/packages/core/src/components/tabs/tabs.md.scss b/packages/core/src/components/tabbar/tabbar.md.scss similarity index 98% rename from packages/core/src/components/tabs/tabs.md.scss rename to packages/core/src/components/tabbar/tabbar.md.scss index 28bf22da1d..1be738bd16 100644 --- a/packages/core/src/components/tabs/tabs.md.scss +++ b/packages/core/src/components/tabbar/tabbar.md.scss @@ -1,5 +1,5 @@ -@import "./tabs"; -@import "./tabs.md.vars"; +@import "./tabbar"; +@import "./tabbar.md.vars"; .tabbar-md { height: $tabs-md-tab-height; diff --git a/packages/core/src/components/tabs/tabs.md.vars.scss b/packages/core/src/components/tabbar/tabbar.md.vars.scss similarity index 100% rename from packages/core/src/components/tabs/tabs.md.vars.scss rename to packages/core/src/components/tabbar/tabbar.md.vars.scss diff --git a/packages/core/src/components/tabbar/tabbar.scss b/packages/core/src/components/tabbar/tabbar.scss new file mode 100644 index 0000000000..3f5c99e60f --- /dev/null +++ b/packages/core/src/components/tabbar/tabbar.scss @@ -0,0 +1,183 @@ +@import "../../themes/ionic.globals"; + +ion-tabbar { + position: relative; + + z-index: $z-index-toolbar; + display: flex; + + align-items: center; + justify-content: center; + + order: 1; + + width: 100%; +} + +ion-tabbar.tabbar-hidden { + display: none; +} + +ion-tabbar.placement-top { + order: -1; +} + +ion-tab-button { + @include margin(0); + @include text-align(center); + @include border-radius(0); + + box-sizing: border-box; + + position: relative; + z-index: 0; + display: flex; + overflow: hidden; + + flex: 1; + flex-direction: column; + align-items: center; + justify-content: space-between; + + border: 0; + + text-decoration: none; + background: none; + cursor: pointer; + + user-select: none; +} + +.tab-disabled { + pointer-events: none; +} + +.tab-disabled > * { + opacity: .4; +} + +.tab-button-text, +.tab-button-icon { + display: none; + overflow: hidden; + + align-self: center; + + min-width: 26px; + max-width: 100%; + + text-overflow: ellipsis; + white-space: nowrap; +} + +.has-icon .tab-button-icon, +.has-title .tab-button-text { + display: block; +} + +.has-title-only .tab-button-text { + white-space: normal; +} + +.layout-icon-start ion-tab-button { + flex-direction: row; +} + +.layout-icon-end ion-tab-button { + flex-direction: row-reverse; +} + +.layout-icon-bottom ion-tab-button { + flex-direction: column-reverse; +} + +.layout-icon-start ion-tab-button, +.layout-icon-end ion-tab-button, +.layout-icon-hide ion-tab-button, +.layout-title-hide ion-tab-button { + justify-content: center; +} + +.tab-hidden, +.layout-icon-hide .tab-button-icon, +.layout-title-hide .tab-button-text { + display: none; +} + +// Tab Badges +// -------------------------------------------------- + +.tab-badge { + @include position(6%, 4%, null, null); // 4% fallback + @include position(null, calc(50% - 50px), null, null); + @include padding(1px, 6px); + + position: absolute; + + height: auto; + + font-size: 12px; + line-height: 16px; +} + +.has-icon .tab-badge { + @include position(null, calc(50% - 30px), null, null); +} + +.layout-icon-bottom .tab-badge, +.layout-icon-start .tab-badge, +.layout-icon-end .tab-badge { + @include position(null, calc(50% - 50px), null, null); +} + +// Tab Highlight +// -------------------------------------------------- + +.tabbar-highlight { + @include position(null, null, 0, 0); + @include transform-origin(0, 0); + + position: absolute; + + display: block; + + width: 1px; + height: 2px; + + transform: translateZ(0); + + &.animated { + transition-duration: 300ms; + transition-property: transform; + transition-timing-function: cubic-bezier(.4, 0, .2, 1); + + will-change: transform; + } +} + +.placement-top .tabbar-highlight { + bottom: 0; +} + +.placement-bottom .tabbar-highlight { + top: 0; +} + + +// Overflow Scrolling +// -------------------------------------------------- + +ion-tabbar.scrollable ion-scroll { + overflow: hidden; +} + +ion-tabbar.scrollable .scroll-inner { + position: relative; + display: flex; + + flex-direction: row; +} + +ion-tabbar.scrollable ion-button.inactive { + visibility: hidden; +} diff --git a/packages/core/src/components/tabbar/tabbar.tsx b/packages/core/src/components/tabbar/tabbar.tsx index 7c02be6b6b..d38c6022e0 100644 --- a/packages/core/src/components/tabbar/tabbar.tsx +++ b/packages/core/src/components/tabbar/tabbar.tsx @@ -4,6 +4,10 @@ import { DomController } from '../../index'; @Component({ tag: 'ion-tabbar', + styleUrls: { + ios: 'tabbar.ios.scss', + md: 'tabbar.md.scss' + }, host: { theme: 'tabbar' } @@ -152,41 +156,34 @@ export class Tabbar { hostData() { const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'tabbar-translucent') : {}; - const layoutClass = `layout-${this.layout}`; - const placementClass = `placement-${this.placement}`; - - const hostClasses = { - ...themedClasses, - 'tabbar-hidden': this.hidden, - 'scrollable': this.scrollable, - [layoutClass]: true, - [placementClass]: true - }; - return { role: 'tablist', - class: hostClasses + class: { + ...themedClasses, + [`layout-${this.layout}`]: true, + [`placement-${this.placement}`]: true, + 'tabbar-hidden': this.hidden, + 'scrollable': this.scrollable + } }; } render() { - const selectedTab = this.selectedTab, - ionTabbarHighlight = this.highlight ?
as HTMLElement : null, - tabButtons = this.tabs.map(tab => ); - + const selectedTab = this.selectedTab; + const ionTabbarHighlight = this.highlight ?
as HTMLElement : null; + const tabButtons = this.tabs.map(tab => ); if (this.scrollable) { return [ this.scrollByTab('left')} fill='clear' class={{inactive: !this.canScrollLeft}}> , - { - this.scrollEl = scrollEl; - }}> + + this.scrollEl = scrollEl}> {tabButtons} {ionTabbarHighlight} , + this.scrollByTab('right')} fill='clear' class={{inactive: !this.canScrollRight}}> diff --git a/packages/core/src/components/tabs/tabs.scss b/packages/core/src/components/tabs/tabs.scss index 8c021584b9..c00449b044 100644 --- a/packages/core/src/components/tabs/tabs.scss +++ b/packages/core/src/components/tabs/tabs.scss @@ -1,12 +1,5 @@ @import "../../themes/ionic.globals"; -// Util -// -------------------------------------------------- -@import "../../themes/util"; - -// Tabs -// -------------------------------------------------- - ion-tabs { @include position(0); @@ -31,205 +24,3 @@ ion-tabs { contain: layout size style; } - -ion-tab { - @include position(0, null, null, 0); - - position: absolute; - z-index: -1; - display: none; - - width: 100%; - height: 100%; - - contain: layout size style; -} - -ion-tab.show-tab { - z-index: $z-index-page-container; - display: block; -} - -// Tabbar -// -------------------------------------------------- - -ion-tabbar { - position: relative; - - z-index: $z-index-toolbar; - display: flex; - - align-items: center; - justify-content: center; - - order: 1; - - width: 100%; -} - -ion-tabbar.tabbar-hidden { - display: none; -} - -ion-tabbar.placement-top { - order: -1; -} - -ion-tab-button { - @include margin(0); - @include text-align(center); - @include border-radius(0); - - box-sizing: border-box; - - position: relative; - z-index: 0; - display: flex; - overflow: hidden; - - flex: 1; - flex-direction: column; - align-items: center; - justify-content: space-between; - - border: 0; - - text-decoration: none; - background: none; - cursor: pointer; - - user-select: none; -} - -.tab-disabled { - pointer-events: none; -} - -.tab-disabled > * { - opacity: .4; -} - -.tab-button-text, -.tab-button-icon { - display: none; - overflow: hidden; - - align-self: center; - - min-width: 26px; - max-width: 100%; - - text-overflow: ellipsis; - white-space: nowrap; -} - -.has-icon .tab-button-icon, -.has-title .tab-button-text { - display: block; -} - -.has-title-only .tab-button-text { - white-space: normal; -} - -.layout-icon-start ion-tab-button { - flex-direction: row; -} - -.layout-icon-end ion-tab-button { - flex-direction: row-reverse; -} - -.layout-icon-bottom ion-tab-button { - flex-direction: column-reverse; -} - -.layout-icon-start ion-tab-button, -.layout-icon-end ion-tab-button, -.layout-icon-hide ion-tab-button, -.layout-title-hide ion-tab-button { - justify-content: center; -} - -.tab-hidden, -.layout-icon-hide .tab-button-icon, -.layout-title-hide .tab-button-text { - display: none; -} - -// Tab Badges -// -------------------------------------------------- - -.tab-badge { - @include position(6%, 4%, null, null); // 4% fallback - @include position(null, calc(50% - 50px), null, null); - @include padding(1px, 6px); - - position: absolute; - - height: auto; - - font-size: 12px; - line-height: 16px; -} - -.has-icon .tab-badge { - @include position(null, calc(50% - 30px), null, null); -} - -.layout-icon-bottom .tab-badge, -.layout-icon-start .tab-badge, -.layout-icon-end .tab-badge { - @include position(null, calc(50% - 50px), null, null); -} - -// Tab Highlight -// -------------------------------------------------- - -.tabbar-highlight { - @include position(null, null, 0, 0); - @include transform-origin(0, 0); - - position: absolute; - - display: block; - - width: 1px; - height: 2px; - - transform: translateZ(0); - - &.animated { - transition-duration: 300ms; - transition-property: transform; - transition-timing-function: cubic-bezier(.4, 0, .2, 1); - - will-change: transform; - } -} - -.placement-top .tabbar-highlight { - bottom: 0; -} - -.placement-bottom .tabbar-highlight { - top: 0; -} - -// Overflow Scrolling -// -------------------------------------------------- - -ion-tabbar.scrollable ion-scroll { - overflow: hidden; -} - -ion-tabbar.scrollable .scroll-inner { - position: relative; - display: flex; - - flex-direction: row; -} - -ion-tabbar.scrollable ion-button.inactive { - visibility: hidden; -} diff --git a/packages/core/src/components/tabs/tabs.tsx b/packages/core/src/components/tabs/tabs.tsx index 6107c6f57c..eeabdcbcd8 100644 --- a/packages/core/src/components/tabs/tabs.tsx +++ b/packages/core/src/components/tabs/tabs.tsx @@ -1,13 +1,10 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core'; -import { Config, NavOutlet, NavEventDetail } from '../../index'; +import { Config, NavEventDetail, NavOutlet } from '../../index'; @Component({ tag: 'ion-tabs', - styleUrls: { - ios: 'tabs.ios.scss', - md: 'tabs.md.scss' - } + styleUrl: 'tabs.scss' }) export class Tabs implements NavOutlet { private ids = -1;