mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(tabs): move css to tabbar
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
@import "../../themes/ionic.globals.ios";
|
||||
|
||||
@import "../tabs/tabs.ios.vars";
|
||||
@import "../tabbar/tabbar.ios.vars";
|
||||
|
||||
// iOS App
|
||||
// --------------------------------------------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "../../themes/ionic.globals.md";
|
||||
|
||||
@import "../tabs/tabs.md.vars";
|
||||
@import "../tabbar/tabbar.md.vars";
|
||||
|
||||
|
||||
// Material Design App
|
||||
|
||||
19
packages/core/src/components/tab/tab.scss
Normal file
19
packages/core/src/components/tab/tab.scss
Normal file
@@ -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;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { FrameworkDelegate } from '../..';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-tab',
|
||||
styleUrl: 'tab.scss'
|
||||
})
|
||||
export class Tab {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@import "./tabs";
|
||||
@import "./tabs.ios.vars";
|
||||
@import "./tabbar";
|
||||
@import "./tabbar.ios.vars";
|
||||
|
||||
// iOS Tabs
|
||||
// --------------------------------------------------
|
||||
@@ -1,5 +1,5 @@
|
||||
@import "./tabs";
|
||||
@import "./tabs.md.vars";
|
||||
@import "./tabbar";
|
||||
@import "./tabbar.md.vars";
|
||||
|
||||
.tabbar-md {
|
||||
height: $tabs-md-tab-height;
|
||||
183
packages/core/src/components/tabbar/tabbar.scss
Normal file
183
packages/core/src/components/tabbar/tabbar.scss
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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 ? <div class='animated tabbar-highlight'/> as HTMLElement : null,
|
||||
tabButtons = this.tabs.map(tab => <ion-tab-button tab={tab} selected={selectedTab === tab}/>);
|
||||
|
||||
const selectedTab = this.selectedTab;
|
||||
const ionTabbarHighlight = this.highlight ? <div class='animated tabbar-highlight'/> as HTMLElement : null;
|
||||
const tabButtons = this.tabs.map(tab => <ion-tab-button tab={tab} selected={selectedTab === tab}/>);
|
||||
|
||||
if (this.scrollable) {
|
||||
return [
|
||||
<ion-button onClick={() => this.scrollByTab('left')} fill='clear' class={{inactive: !this.canScrollLeft}}>
|
||||
<ion-icon name='arrow-dropleft'/>
|
||||
</ion-button>,
|
||||
<ion-scroll
|
||||
ref={(scrollEl: HTMLIonScrollElement) => {
|
||||
this.scrollEl = scrollEl;
|
||||
}}>
|
||||
|
||||
<ion-scroll ref={(scrollEl: HTMLIonScrollElement) => this.scrollEl = scrollEl}>
|
||||
{tabButtons}
|
||||
{ionTabbarHighlight}
|
||||
</ion-scroll>,
|
||||
|
||||
<ion-button onClick={() => this.scrollByTab('right')} fill='clear' class={{inactive: !this.canScrollRight}}>
|
||||
<ion-icon name='arrow-dropright'/>
|
||||
</ion-button>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user