Compare commits

...

1 Commits

Author SHA1 Message Date
Sean Perkins
cefcd02fb9 fix(tab-tab): iOS translucent tab bar 2022-03-24 18:49:25 -04:00
9 changed files with 263 additions and 5 deletions

View File

@@ -6359,6 +6359,7 @@ declare namespace LocalJSX {
* The mode determines which platform styles to use.
*/
"mode"?: "ios" | "md";
"onIonStyle"?: (event: CustomEvent<StyleEventDetail>) => void;
"onIonTabBarChanged"?: (event: CustomEvent<TabBarChangedEventDetail>) => void;
/**
* The selected tab component

View File

@@ -44,7 +44,7 @@
:host(.fab-vertical-bottom) {
bottom: $fab-content-margin;
bottom: var(--tab-translucent-safe-area, $fab-content-margin);
}
:host(.fab-vertical-bottom.fab-edge) {

View File

@@ -15,5 +15,5 @@ ion-footer {
}
ion-footer ion-toolbar:last-of-type {
padding-bottom: var(--ion-safe-area-bottom, 0);
}
padding-bottom: calc(var(--ion-safe-area-bottom, 0) + var(--tab-translucent-safe-area, 0));
}

View File

@@ -1,7 +1,7 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Prop, State, Watch, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { Color, TabBarChangedEventDetail } from '../../interface';
import { Color, StyleEventDetail, TabBarChangedEventDetail } from '../../interface';
import { createColorClasses } from '../../utils/theme';
/**
@@ -30,6 +30,8 @@ export class TabBar implements ComponentInterface {
*/
@Prop({ reflect: true }) color?: Color;
@Event() ionStyle!: EventEmitter<StyleEventDetail>;
/**
* The selected tab component
*/
@@ -50,11 +52,28 @@ export class TabBar implements ComponentInterface {
*/
@Prop() translucent = false;
@Watch('translucent')
translucentChanged() {
// Find all tabs
const tabs = Array.from(this.el.closest('ion-tabs')?.querySelectorAll('ion-tab') ?? []);
for (const tab of tabs) {
if (this.translucent) {
tab.classList.add('tab-bar-translucent');
} else {
tab.classList.remove('tab-bar-translucent');
}
}
this.ionStyle.emit({
'tab-bar-translucent': this.translucent
})
}
/** @internal */
@Event() ionTabBarChanged!: EventEmitter<TabBarChangedEventDetail>;
componentWillLoad() {
this.selectedTabChanged();
this.translucentChanged();
}
connectedCallback() {

View File

@@ -2,3 +2,9 @@
/* stylelint-disable-next-line declaration-no-important */
display: none !important;
}
:host(.tab-bar-translucent) ::slotted(ion-content) {
/* stylelint-disable-next-line declaration-no-important */
--padding-bottom: 50px !important;
}

View File

@@ -0,0 +1,11 @@
@import './tabs';
:host(.tab-bar-translucent) {
--tab-translucent-safe-area: 60px;
}
slot[name='bottom']::slotted([translucent]) {
position: absolute;
bottom: 0;
width: 100%;
}

View File

@@ -0,0 +1 @@
@import './tabs';

View File

@@ -9,7 +9,10 @@ import { NavOutlet, RouteID, RouteWrite, TabButtonClickEventDetail } from '../..
*/
@Component({
tag: 'ion-tabs',
styleUrl: 'tabs.scss',
styleUrls: {
ios: 'tabs.ios.scss',
md: 'tabs.md.scss'
},
shadow: true
})
export class Tabs implements NavOutlet {
@@ -21,6 +24,8 @@ export class Tabs implements NavOutlet {
@State() selectedTab?: HTMLIonTabElement;
@State() private tabCustomClasses: { [key: string]: boolean } = {};
/** @internal */
@Prop({ mutable: true }) useRouter = false;
@@ -182,10 +187,21 @@ export class Tabs implements NavOutlet {
}
}
private onIonStyle = (ev: any) => {
if (ev.target.tagName === 'ION-TAB-BAR') {
for (const key of Object.keys(ev.detail)) {
this.tabCustomClasses[key] = ev.detail[key];
}
this.tabCustomClasses = {...this.tabCustomClasses};
}
}
render() {
return (
<Host
onIonTabButtonClick={this.onTabClicked}
onIonStyle={this.onIonStyle}
class={this.tabCustomClasses}
>
<slot name="top"></slot>
<div class="tabs-inner">

View File

@@ -0,0 +1,204 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Tab - Translucent</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<style>
.scrollable-area {
height: 1400px;
background: red;
color: white;
}
.images {
display: grid;
gap: 4px;
grid-template-columns: 1fr 1fr;
}
.images img {
height: 100%;
}
</style>
</head>
<body>
<ion-app>
<ion-tabs>
<ion-tab tab="tab-one">
<ion-header>
<ion-toolbar>
<ion-title>Tab One</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<h1>Tab One</h1>
<div class="images">
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
</div>
<div style="text-align: center;padding: 8px 0;">This is the end of the content</div>
<ion-fab slot="fixed" horizontal="end" vertical="bottom">
<ion-fab-button class="custom-white">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
</ion-tab>
<ion-tab tab="schedule">
<ion-header>
<ion-toolbar>
<ion-title>Tab Two</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<h1>Tab Two</h1>
<div class="images">
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
<img src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
<img src="https://images.pexels.com/photos/844297/pexels-photo-844297.jpeg" />
<img src="https://images.unsplash.com/photo-1607791330831-d3dcf312e2d1" />
<img src="https://images.template.net/wp-content/uploads/2016/04/25103502/HD-Featured-Image.jpg" />
<img src="https://wallpaper.dog/large/20435883.jpg" />
</div>
</ion-content>
<ion-footer>
<ion-toolbar>
<ion-title>Tab Two Footer</ion-title>
</ion-toolbar>
</ion-footer>
</ion-tab>
<ion-tab tab="tab-three">
<ion-header>
<ion-toolbar>
<ion-title>Tab Three</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<h1>Tab Three</h1>
</ion-content>
</ion-tab>
<ion-tab tab="tab-four">
<ion-header>
<ion-toolbar>
<ion-title>Tab Three</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<h1>Tab Three</h1>
</ion-content>
</ion-tab>
<ion-tab-bar slot="bottom" translucent="true">
<ion-tab-button href="" tab="tab-one">
<ion-label>Tab One</ion-label>
<ion-icon name="star"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="schedule">
<ion-label>Tab Two</ion-label>
<ion-icon name="globe"></ion-icon>
<ion-badge color="danger">6</ion-badge>
</ion-tab-button>
<ion-tab-button tab="tab-three">
<ion-label>Tab Three</ion-label>
<ion-icon name="logo-facebook"></ion-icon>
<ion-badge color="primary">6</ion-badge>
</ion-tab-button>
<ion-tab-button tab="tab-four" class="e2eTabFourButton">
<ion-label>Tab Four</ion-label>
<ion-icon name="chatbox"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
</ion-app>
<style>
.custom-white {
--background: white;
--background-hover: #888;
--background-focused: #444;
--color: #3880ff;
}
.ios .custom-white {
--background-activated: #ddd;
}
</style>
</body>
</html>