mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
refactor(components): update to use shadow DOM and work with css variables
- updates components to use shadow DOM or scoped if they require css variables - moves global styles to an external stylesheet that needs to be imported - adds support for additional colors and removes the Sass loops to generate colors for each component - several property renames, bug fixes, and test updates Co-authored-by: Manu Mtz.-Almeida <manu.mtza@gmail.com> Co-authored-by: Adam Bradley <adambradley25@gmail.com> Co-authored-by: Cam Wiegert <cam@camwiegert.com>
This commit is contained in:
@ -8,6 +8,16 @@ TabButton is an internal component for tabs. Please see the [Tab docs](../tab) f
|
||||
|
||||
## Properties
|
||||
|
||||
#### color
|
||||
|
||||
string
|
||||
|
||||
|
||||
#### mode
|
||||
|
||||
string
|
||||
|
||||
|
||||
#### selected
|
||||
|
||||
boolean
|
||||
@ -24,6 +34,16 @@ The tab component for the button
|
||||
|
||||
## Attributes
|
||||
|
||||
#### color
|
||||
|
||||
string
|
||||
|
||||
|
||||
#### mode
|
||||
|
||||
string
|
||||
|
||||
|
||||
#### selected
|
||||
|
||||
boolean
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
@import "./tab-button";
|
||||
@import "./tab-button.ios.vars";
|
||||
|
||||
.tab-button-ios {
|
||||
:host {
|
||||
max-width: $tab-button-ios-max-width;
|
||||
|
||||
font-size: $tab-button-ios-font-size;
|
||||
color: $tab-button-ios-text-color;
|
||||
|
||||
fill: $tab-button-ios-icon-color;
|
||||
--color-selected: #{$tabbar-ios-text-color-active};
|
||||
--background-focused: #{$tabbar-ios-background-color-focused};
|
||||
}
|
||||
|
||||
.tab-button-ios.focused {
|
||||
background: $tabbar-ios-background-color-focused;
|
||||
}
|
||||
|
||||
.tab-button-ios .tab-cover {
|
||||
.tab-button-native {
|
||||
@include padding(
|
||||
$tab-button-ios-padding-top,
|
||||
$tab-button-ios-padding-end,
|
||||
@ -22,37 +20,36 @@
|
||||
$tab-button-ios-padding-start);
|
||||
}
|
||||
|
||||
.tab-button-ios:hover,
|
||||
.tab-button-ios.tab-selected {
|
||||
color: $tab-button-ios-text-color-active;
|
||||
|
||||
fill: $tab-button-ios-icon-color-active;
|
||||
}
|
||||
|
||||
.tab-button-ios .tab-button-text {
|
||||
.tab-button-text {
|
||||
@include margin(0, null, 1px, null);
|
||||
|
||||
min-height: $tab-button-ios-font-size + 1;
|
||||
}
|
||||
|
||||
.tab-button-ios.has-title-only .tab-button-text {
|
||||
:host(.has-title-only) .tab-button-text {
|
||||
@include margin(2px, 0);
|
||||
|
||||
font-size: $tab-button-ios-font-size + 2;
|
||||
|
||||
font-size: 14px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.tab-button-ios .tab-button-icon {
|
||||
.tab-button-icon {
|
||||
@include margin(4px, null, null, null);
|
||||
|
||||
font-size: $tab-button-ios-icon-size;
|
||||
}
|
||||
|
||||
.tabbar-ios .tab-button-icon::before {
|
||||
.tab-button-icon::before {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.layout-icon-end .tab-button-ios .tab-button-text,
|
||||
.layout-icon-start .tab-button-ios .tab-button-text,
|
||||
.layout-icon-hide .tab-button-ios .tab-button-text,
|
||||
.tab-button-ios.has-title-only .tab-button-text {
|
||||
.layout-icon-hide .tab-button-ios .tab-button-text {
|
||||
@include margin(2px, 0);
|
||||
|
||||
font-size: 14px;
|
||||
|
||||
@ -4,20 +4,18 @@
|
||||
// Material Design Tab Button
|
||||
// --------------------------------------------------
|
||||
|
||||
.tab-button-md {
|
||||
:host {
|
||||
max-width: 168px;
|
||||
|
||||
font-weight: $tab-button-md-font-weight;
|
||||
|
||||
color: $tab-button-md-text-color;
|
||||
|
||||
fill: $tab-button-md-icon-color;
|
||||
--color-selected: #{$tabbar-md-text-color-active};
|
||||
--background-focused: #{$tabbar-md-background-color-focused};
|
||||
}
|
||||
|
||||
.tab-button-md.focused {
|
||||
background: $tabbar-md-background-color-focused;
|
||||
}
|
||||
|
||||
.tab-button-md .tab-cover {
|
||||
.tab-button-native {
|
||||
@include padding(
|
||||
$tab-button-md-padding-top,
|
||||
$tab-button-md-padding-end,
|
||||
@ -27,27 +25,10 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.scrollable .tab-button-md {
|
||||
overflow: hidden;
|
||||
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
.tab-button-md.tab-selected {
|
||||
color: $tab-button-md-text-color-active;
|
||||
|
||||
fill: $tab-button-md-icon-color-active;
|
||||
}
|
||||
|
||||
// Material Design Tab Button Text
|
||||
// --------------------------------------------------
|
||||
|
||||
.placement-top .tab-button-md.tab-selected .tab-button-icon,
|
||||
.placement-top .tab-button-md.tab-selected .tab-button-text {
|
||||
transform: inherit;
|
||||
}
|
||||
|
||||
.tab-button-md .tab-button-text {
|
||||
.tab-button-text {
|
||||
@include margin($tab-button-md-text-margin-top, $tab-button-md-text-margin-end, $tab-button-md-text-margin-bottom, $tab-button-md-text-margin-start);
|
||||
|
||||
@include transform-origin(center, bottom);
|
||||
@ -58,25 +39,15 @@
|
||||
transition: $tab-button-md-text-transition;
|
||||
}
|
||||
|
||||
.tab-button-md.tab-selected .tab-button-text {
|
||||
:host(.tab-selected) .tab-button-text {
|
||||
transform: $tab-button-md-text-transform-active;
|
||||
transition: $tab-button-md-text-transition;
|
||||
}
|
||||
|
||||
.layout-icon-top .tab-button-md .has-icon .tab-button-text {
|
||||
@include margin(null, null, -2px, null);
|
||||
}
|
||||
|
||||
.layout-icon-bottom .tab-button-md .tab-button-text {
|
||||
@include transform-origin(center, top);
|
||||
|
||||
@include margin(-2px, null, null, null);
|
||||
}
|
||||
|
||||
// Material Design Tab Button Icon
|
||||
// --------------------------------------------------
|
||||
|
||||
.tab-button-md .tab-button-icon {
|
||||
.tab-button-icon {
|
||||
@include transform-origin(center, center);
|
||||
|
||||
width: $tab-button-md-icon-size;
|
||||
@ -88,13 +59,23 @@
|
||||
}
|
||||
|
||||
// Tab layout: icon-top, icon-only, title-only
|
||||
.tab-button-md.tab-selected .tab-button-icon {
|
||||
:host(.tab-selected) .tab-button-icon {
|
||||
@include transform(translate3d(
|
||||
$tab-button-md-icon-transform-x-active,
|
||||
$tab-button-md-icon-transform-y-active,
|
||||
$tab-button-md-icon-transform-z-active));
|
||||
}
|
||||
|
||||
|
||||
// Material Design Tab with Icon or Title only
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.icon-only),
|
||||
:host(.has-title-only) {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
// Tab layout: icon-end
|
||||
.layout-icon-end .tab-button-md.tab-selected .tab-button-icon {
|
||||
@include transform(translate3d(
|
||||
@ -119,12 +100,17 @@
|
||||
$tab-button-md-icon-left-transform-z-active));
|
||||
}
|
||||
|
||||
// Material Design Tab with Icon or Title only
|
||||
// --------------------------------------------------
|
||||
.layout-icon-top .tab-button-md .has-icon .tab-button-text {
|
||||
@include margin(null, null, -2px, null);
|
||||
}
|
||||
|
||||
.layout-icon-bottom .tab-button-md .tab-button-text {
|
||||
@include transform-origin(center, top);
|
||||
|
||||
@include margin(-2px, null, null, null);
|
||||
}
|
||||
|
||||
.layout-icon-hide .tab-button-md,
|
||||
.layout-title-hide .tab-button-md,
|
||||
.tab-button-md.icon-only,
|
||||
.tab-button-md.has-title-only {
|
||||
.layout-title-hide .tab-button-md {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
ion-tab-button {
|
||||
:host {
|
||||
@include margin(0);
|
||||
@include text-align(center);
|
||||
text-align: center;
|
||||
@include border-radius(0);
|
||||
|
||||
box-sizing: border-box;
|
||||
@ -22,13 +22,31 @@ ion-tab-button {
|
||||
background: none;
|
||||
|
||||
user-select: none;
|
||||
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
ion-tab-button a {
|
||||
:host(.ion-color) {
|
||||
color: #{current-color(contrast)};
|
||||
|
||||
--color-selected: #{current-color(contrast)};
|
||||
--background-selected: #{current-color(shade)};
|
||||
}
|
||||
|
||||
:host(.focused) {
|
||||
background: var(--background-focused);
|
||||
}
|
||||
|
||||
:host(:hover),
|
||||
:host(.tab-selected) {
|
||||
color: var(--color-selected);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tab-cover {
|
||||
.tab-button-native {
|
||||
@include margin(0);
|
||||
@include padding(0);
|
||||
|
||||
@ -45,6 +63,7 @@ ion-tab-button a {
|
||||
color: inherit;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:active,
|
||||
&:focus {
|
||||
@ -52,16 +71,18 @@ ion-tab-button a {
|
||||
}
|
||||
}
|
||||
|
||||
.tab-btn-disabled {
|
||||
:host(.tab-button-disabled) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
> .tab-cover {
|
||||
opacity: .4;
|
||||
}
|
||||
:host(.tab-button-disabled) .tab-button-native {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
.tab-button-text,
|
||||
.tab-button-icon {
|
||||
box-sizing: border-box;
|
||||
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
|
||||
@ -74,15 +95,39 @@ ion-tab-button a {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.has-icon .tab-button-icon,
|
||||
.has-title .tab-button-text {
|
||||
:host(.has-icon) .tab-button-icon,
|
||||
:host(.has-title) .tab-button-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.has-title-only .tab-button-text {
|
||||
:host(.has-title-only) .tab-button-text {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:host(.has-icon) .tab-badge {
|
||||
@include position(null, calc(50% - 30px), null, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Tab Badges
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -110,25 +155,6 @@ ion-tab-button a {
|
||||
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,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {Component, Element, Event, EventEmitter, Listen, Prop, State} from '@stencil/core';
|
||||
import { Mode } from '../../interface';
|
||||
import { Component, Element, Event, EventEmitter, Listen, Prop, State } from '@stencil/core';
|
||||
import { Color, Mode } from '../../interface';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -7,13 +8,15 @@ import { Mode } from '../../interface';
|
||||
styleUrls: {
|
||||
ios: 'tab-button.ios.scss',
|
||||
md: 'tab-button.md.scss'
|
||||
}
|
||||
},
|
||||
shadow: true
|
||||
})
|
||||
export class TabButton {
|
||||
|
||||
@Element() el!: HTMLElement;
|
||||
|
||||
mode!: Mode;
|
||||
@Prop() mode!: Mode;
|
||||
@Prop() color?: Color;
|
||||
|
||||
@State() keyFocus = false;
|
||||
|
||||
@ -71,13 +74,14 @@ export class TabButton {
|
||||
'aria-selected': selected,
|
||||
'hidden': !tab.show,
|
||||
class: {
|
||||
...createColorClasses(this.color),
|
||||
'tab-selected': selected,
|
||||
'has-title': hasTitle,
|
||||
'has-icon': hasIcon,
|
||||
'has-title-only': hasTitleOnly,
|
||||
'has-icon-only': hasIconOnly,
|
||||
'has-badge': hasBadge,
|
||||
'tab-btn-disabled': tab.disabled,
|
||||
'tab-button-disabled': tab.disabled,
|
||||
'focused': this.keyFocus
|
||||
}
|
||||
};
|
||||
@ -90,7 +94,7 @@ export class TabButton {
|
||||
return [
|
||||
<a
|
||||
href={href}
|
||||
class="tab-cover"
|
||||
class="tab-button-native"
|
||||
onKeyUp={this.onKeyUp.bind(this)}
|
||||
onBlur={this.onBlur.bind(this)}>
|
||||
{ tab.icon && <ion-icon class="tab-button-icon" icon={tab.icon}></ion-icon> }
|
||||
|
||||
Reference in New Issue
Block a user