fix(tab-button): apply background-focused when tabbing into tab button (#17502)

fixes #17042
This commit is contained in:
Liam DeBeasi
2019-05-14 12:04:41 -04:00
committed by GitHub
parent 3cad7787c2
commit d788a8eac6
9 changed files with 241 additions and 193 deletions

View File

@ -28,7 +28,6 @@
background: #{current-color(base, $tab-bar-ios-translucent-background-color-alpha)};
}
// iOS Translucent Tab bar button
:host(.tab-bar-translucent) ::slotted(ion-tab-button) {
background: transparent;
:host(.tab-bar-translucent) ::slotted(ion-tab-button.ion-focused) {
background: rgba($background-color-rgb, .6);
}

View File

@ -11,8 +11,4 @@
--color-selected: #{$tabbar-md-color-activated};
height: 56px;
}
:host(.tab-bar-translucent) ::slotted(ion-tab-button) {
background: transparent;
}

View File

@ -33,12 +33,6 @@
box-sizing: content-box !important;
}
:host(.ion-color),
:host(.ion-color) ::slotted(ion-tab-button) {
background: #{current-color(base)};
color: #{current-color(contrast, .7)};
}
:host(.ion-color) ::slotted(ion-tab-button) {
--background-focused: #{current-color(shade)};
--color-selected: #{current-color(contrast)};
@ -48,6 +42,25 @@
color: #{current-color(contrast)};;
}
:host(.ion-color),
:host(.ion-color) ::slotted(ion-tab-button) {
color: #{current-color(contrast, .7)};
}
:host(.ion-color),
:host(.ion-color) ::slotted(ion-tab-button) {
background: #{current-color(base)};
}
:host(.ion-color) ::slotted(ion-tab-button.ion-focused),
:host(.tab-bar-translucent) ::slotted(ion-tab-button.ion-focused) {
background: var(--background-focused)
}
:host(.tab-bar-translucent) ::slotted(ion-tab-button) {
background: transparent;
}
:host([slot="top"]) {
padding-bottom: 0;
@ -58,4 +71,4 @@
:host(.tab-bar-hidden) {
/* stylelint-disable-next-line declaration-no-important */
display: none !important;
}
}

View File

@ -5,6 +5,18 @@ test('tab-bar: custom', async () => {
url: '/src/components/tab-bar/test/custom?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
const screenshotCompares = [];
const tabBar = await page.find('ion-tab-bar');
await tabBar.waitForVisible();
screenshotCompares.push(await page.compareScreenshot('tab-bar: custom default'));
await page.keyboard.press('Tab');
screenshotCompares.push(await page.compareScreenshot('tab-bar: custom tabbed'));
await page.waitFor(10000);
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
});

View File

@ -16,6 +16,12 @@
<ion-content>
<!-- Default -->
<ion-tab-bar selected-tab="1">
<ion-tab-button tab="1" disabled>
<ion-icon name="clock"></ion-icon>
<ion-label>Recents</ion-label>
</ion-tab-button>
<ion-tab-button tab="1">
<ion-icon name="clock"></ion-icon>
<ion-label>Recents</ion-label>

View File

@ -12,182 +12,187 @@
</head>
<body>
<ion-app>
<ion-content>
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-label>Recents</ion-label>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-label>Favorites</ion-label>
<ion-badge>6</ion-badge>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-label>Settings</ion-label>
</ion-tab-button>
</ion-tab-bar>
<!-- Badges -->
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
<ion-label>Item One Max</ion-label>
<ion-badge color="danger"></ion-badge>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
<ion-badge color="danger">88</ion-badge>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
<ion-badge color="danger">888+</ion-badge>
</ion-tab-button>
</ion-tab-bar>
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2" layout="icon-bottom">
<ion-icon name="heart"></ion-icon>
<ion-label>Item One Max</ion-label>
<ion-badge color="danger"></ion-badge>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
<ion-badge color="danger">88</ion-badge>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
<ion-badge color="danger">888+</ion-badge>
</ion-tab-button>
</ion-tab-bar>
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2" layout="icon-bottom">
<ion-icon name="heart"></ion-icon>
<ion-label>Item One Max</ion-label>
<ion-badge color="danger">88</ion-badge>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Custom Height -->
<ion-tab-bar translucent color="danger" selected-tab="3" class="custom-height">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Custom Height / Alignment -->
<ion-tab-bar translucent color="tertiary" selected-tab="3" class="custom-height custom-top">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Translucent -->
<ion-tab-bar translucent>
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Translucent / Custom Color -->
<ion-tab-bar translucent class="custom-background">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
</ion-content>
</ion-app>
<!-- Default -->
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-label>Recents</ion-label>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-label>Favorites</ion-label>
<ion-badge>6</ion-badge>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-label>Settings</ion-label>
</ion-tab-button>
</ion-tab-bar>
<!-- Badges -->
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
<ion-label>Item One Max</ion-label>
<ion-badge color="danger"></ion-badge>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
<ion-badge color="danger">88</ion-badge>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
<ion-badge color="danger">888+</ion-badge>
</ion-tab-button>
</ion-tab-bar>
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2" layout="icon-bottom">
<ion-icon name="heart"></ion-icon>
<ion-label>Item One Max</ion-label>
<ion-badge color="danger"></ion-badge>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
<ion-badge color="danger">88</ion-badge>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
<ion-badge color="danger">888+</ion-badge>
</ion-tab-button>
</ion-tab-bar>
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<ion-tab-bar translucent selected-tab="1">
<ion-tab-button tab="1">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2" layout="icon-bottom">
<ion-icon name="heart"></ion-icon>
<ion-label>Item One Max</ion-label>
<ion-badge color="danger">88</ion-badge>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Custom Height -->
<ion-tab-bar translucent color="danger" selected-tab="3" class="custom-height">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Custom Height / Alignment -->
<ion-tab-bar translucent color="tertiary" selected-tab="3" class="custom-height custom-top">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Translucent -->
<ion-tab-bar translucent>
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<!-- Translucent / Custom Color -->
<ion-tab-bar translucent class="custom-background">
<ion-tab-button tab="1">
<ion-icon name="heart"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="2">
<ion-icon name="musical-note"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="3">
<ion-icon name="today"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="4">
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
<style>
body {
background: linear-gradient(
ion-content {
--background: linear-gradient(
to right, orange , yellow, green, cyan, blue, violet
);
}

View File

@ -34,4 +34,4 @@ $tab-button-ios-icon-color-active: $tabbar-ios-color-activated !default;
$tab-button-ios-font-size: 10px !default;
/// @prop - Size of the tab button icon
$tab-button-ios-icon-size: 30px !default;
$tab-button-ios-icon-size: 30px !default;

View File

@ -24,6 +24,8 @@
justify-content: center;
height: 100%;
outline: none;
background: var(--background);
color: var(--color);
@ -61,7 +63,7 @@ a {
-webkit-user-drag: none;
}
a:focus-visible {
:host(.ion-focused) {
background: var(--background-focused);
}

View File

@ -89,9 +89,22 @@ export class TabButton implements ComponentInterface {
return !!this.el.querySelector('ion-icon');
}
private get tabIndex() {
if (this.disabled) { return -1; }
const hasTabIndex = this.el.hasAttribute('tabindex');
if (hasTabIndex) {
return this.el.getAttribute('tabindex');
}
return 0;
}
hostData() {
const { disabled, hasIcon, hasLabel, layout, selected, tab } = this;
const { disabled, hasIcon, hasLabel, tabIndex, layout, selected, tab } = this;
return {
'tabindex': tabIndex,
'role': 'tab',
'aria-selected': selected ? 'true' : null,
'id': tab !== undefined ? `tab-button-${tab}` : null,
@ -105,6 +118,8 @@ export class TabButton implements ComponentInterface {
'tab-has-icon-only': hasIcon && !hasLabel,
[`tab-layout-${layout}`]: true,
'ion-activatable': true,
'ion-selectable': true,
'ion-focusable': true
}
};
}
@ -112,7 +127,7 @@ export class TabButton implements ComponentInterface {
render() {
const { mode, href } = this;
return (
<a href={href}>
<a href={href} tabIndex={-1}>
<slot></slot>
{mode === 'md' && <ion-ripple-effect type="unbounded"></ion-ripple-effect>}
</a>