mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
fix(tab-bar): update to match MD design and remove transforms (#16348)
Updates the tab-bar to match the MD bottom navigation spec: https://material.io/design/components/bottom-navigation.html#specs Changes proposed in this pull request: - moved flex properties to host, inherit in child anchor element - this allows the user to customize the tab-button flex properties & fixes #16231 - increased letter spacing - removed transforms / transitions on active tab - decreased badge size, add badge styling when empty for MD - fix badge positioning on both iOS and MD - updates e2e tests, adds a preview test for tab-bar - updates documentation surrounding tabs fixes #16231 fixes ionic-team/ionic-docs#175 fixes ionic-team/ionic-docs#163
This commit is contained in:
@ -1,25 +1,6 @@
|
||||
# ion-tab-bar
|
||||
|
||||
Tab bar is the UI component that implements the array of button of `ion-tabs`. It's provided by default when `ion-tabs` is used, though, this "implicit" tab bar can not be customized.
|
||||
|
||||
In order to have a custom tab bar, it should be provided in user's markup as direct children of `ion-tabs`:
|
||||
|
||||
```html
|
||||
<style>
|
||||
ion-tab-bar {
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ion-tabs>
|
||||
<!-- User tabs -->
|
||||
<ion-tab></ion-tab>
|
||||
<ion-tab></ion-tab>
|
||||
|
||||
<!-- User provided ion-tab-bar that can be customized -->
|
||||
<ion-tab-bar slot="bottom" color="dark" layout="icon-only">
|
||||
</ion-tabs>
|
||||
```
|
||||
The tab bar is a UI component that contains a set of [tab buttons](../tab-button). A tab bar must be provided inside of [tabs](../tabs) to communicate with each [tab](../tab).
|
||||
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
@ -7,10 +7,7 @@
|
||||
* @prop --color: Color of the tab bar
|
||||
*/
|
||||
|
||||
@include padding-horizontal(
|
||||
var(--ion-safe-area-left),
|
||||
var(--ion-safe-area-right)
|
||||
);
|
||||
@include padding-horizontal(var(--ion-safe-area-left), var(--ion-safe-area-right));
|
||||
|
||||
display: flex;
|
||||
|
||||
@ -33,13 +30,14 @@
|
||||
}
|
||||
|
||||
:host(.ion-color) {
|
||||
--background: #{current-color(base)};
|
||||
background: #{current-color(base)};
|
||||
}
|
||||
|
||||
:host(.ion-color) ::slotted(ion-tab-button) {
|
||||
--color: #{current-color(contrast, .7)};
|
||||
--color-selected: #{current-color(contrast)};
|
||||
--background-focused: #{current-color(shade)};
|
||||
--color-selected: #{current-color(contrast)};;
|
||||
|
||||
color: #{current-color(contrast, .7)};
|
||||
}
|
||||
|
||||
:host([slot="top"]) {
|
||||
|
10
core/src/components/tab-bar/test/preview/e2e.ts
Normal file
10
core/src/components/tab-bar/test/preview/e2e.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('tab-bar: preview', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/tab-bar/test/preview?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
202
core/src/components/tab-bar/test/preview/index.html
Normal file
202
core/src/components/tab-bar/test/preview/index.html
Normal file
@ -0,0 +1,202 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Tab Bar - Preview</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">
|
||||
<script src="../../../../../dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="../../../../../css/ionic.bundle.css">
|
||||
<link rel="stylesheet" href="../../../../../scripts/testing/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Default -->
|
||||
<ion-tab-bar 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>23</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 selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-top">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-label>Favorites</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-tab-button>
|
||||
|
||||
<ion-tab-button tab="4">
|
||||
<ion-icon name="calendar"></ion-icon>
|
||||
<ion-badge color="danger">47</ion-badge>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
<ion-tab-bar 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>Favorites</ion-label>
|
||||
</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-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
<ion-tab-bar 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>
|
||||
|
||||
|
||||
<!-- Icons on top of text -->
|
||||
<ion-tab-bar color="secondary" selected-tab="1">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-label>Location</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2">
|
||||
<ion-badge color="danger">44</ion-badge>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3">
|
||||
<ion-label>Radio</ion-label>
|
||||
<ion-icon name="musical-notes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- Icons below text -->
|
||||
<ion-tab-bar color="dark" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-bottom">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2" layout="icon-top">
|
||||
<ion-badge>16</ion-badge>
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3" layout="icon-bottom">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- Icons right of text -->
|
||||
<ion-tab-bar color="danger" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-end">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2" layout="icon-end">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge color="dark">33</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3" layout="icon-end">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- Icons left of text -->
|
||||
<ion-tab-bar color="light" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-start">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
<ion-badge color="danger">12</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2" layout="icon-start">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3" layout="icon-start">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- No icons -->
|
||||
<ion-tab-bar color="primary" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-hide">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2" layout="icon-hide">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3" layout="icon-hide">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
<ion-badge color="danger">2</ion-badge>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
ion-tab-bar {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -3,228 +3,250 @@
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Tab - Colors</title>
|
||||
<title>Tab Bar - Scenarios</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">
|
||||
<script src="../../../../../dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="../../../../../css/ionic.bundle.css">
|
||||
<link rel="stylesheet" href="../../../../../scripts/testing/styles.css">
|
||||
|
||||
<style>
|
||||
.custom-tabbar {
|
||||
overflow: visible;
|
||||
contain: none;
|
||||
}
|
||||
.main-tab {
|
||||
--padding-top: 18px;
|
||||
|
||||
border-radius: 50%;
|
||||
max-width: 80px;
|
||||
height: 80px;
|
||||
background: #848484;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<!-- Default -->
|
||||
<ion-tab-bar selected-tab="1">
|
||||
|
||||
<!-- Default -->
|
||||
<ion-tab-bar selected-tab="1">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-label>Recents</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
<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='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-button tab='3'>
|
||||
<ion-label>Settings</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- Icons -->
|
||||
<ion-tab-bar color="primary" selected-tab="1">
|
||||
<ion-tab-button tab='1'>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<!-- Icons -->
|
||||
<ion-tab-bar color="primary" selected-tab="1">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2' selected-tab="1">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2" selected-tab="1">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3'>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
<ion-tab-button tab="3">
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
<!-- Icons on top of text -->
|
||||
<ion-tab-bar color="secondary" selected-tab="1">
|
||||
<ion-tab-button tab='1'>
|
||||
<ion-label>Location</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<!-- Icons on top of text -->
|
||||
<ion-tab-bar color="secondary" selected-tab="1">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-label>Location</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2'>
|
||||
<ion-badge>6</ion-badge>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2">
|
||||
<ion-badge>6</ion-badge>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3'>
|
||||
<ion-label>Radio</ion-label>
|
||||
<ion-icon name="musical-notes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="3">
|
||||
<ion-label>Radio</ion-label>
|
||||
<ion-icon name="musical-notes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- Icons below text -->
|
||||
<ion-tab-bar color="dark" selected-tab="1">
|
||||
<!-- Icons below text -->
|
||||
<ion-tab-bar color="dark" selected-tab="1">
|
||||
|
||||
<ion-tab-button tab='1' layout="icon-bottom">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="1" layout="icon-bottom">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2' layout="icon-top">
|
||||
<ion-badge>6</ion-badge>
|
||||
<ion-label>hi</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2" layout="icon-top">
|
||||
<ion-badge>6</ion-badge>
|
||||
<ion-label>hi</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3' layout="icon-bottom">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="3" layout="icon-bottom">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- Icons right of text -->
|
||||
<ion-tab-bar color="danger" selected-tab="1">
|
||||
<ion-tab-button tab='1' layout="icon-end">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<!-- Icons right of text -->
|
||||
<ion-tab-bar color="danger" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-end">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2' layout="icon-end">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge>6</ion-badge>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2" layout="icon-end">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge>6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3' layout="icon-end">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="3" layout="icon-end">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- Icons left of text -->
|
||||
<ion-tab-bar color="light" selected-tab="1">
|
||||
<ion-tab-button tab='1' layout="icon-start">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<!-- Icons left of text -->
|
||||
<ion-tab-bar color="light" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-start">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2' layout="icon-start">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge color="danger">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2" layout="icon-start">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge color="danger">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3' layout="icon-start">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="3" layout="icon-start">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- No icons -->
|
||||
<ion-tab-bar color="primary" selected-tab="1">
|
||||
<ion-tab-button tab='1' layout="icon-hide">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<!-- No icons -->
|
||||
<ion-tab-bar color="primary" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-hide">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2' layout="icon-hide">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge color="danger">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2" layout="icon-hide">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge color="danger">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3' layout="icon-hide">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
<ion-tab-button tab="3" layout="icon-hide">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- No label -->
|
||||
<ion-tab-bar color="secondary" selected-tab="1">
|
||||
<ion-tab-button tab='1' layout="label-hide">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
<ion-badge>6</ion-badge>
|
||||
</ion-tab-button>
|
||||
<!-- No label -->
|
||||
<ion-tab-bar color="secondary" selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="label-hide">
|
||||
<ion-label>Recents</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
<ion-badge>6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2' layout="label-hide">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge color="danger">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2" layout="label-hide">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-badge color="danger">6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3' layout="label-hide">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
<ion-tab-button tab="3" layout="label-hide">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
|
||||
<!-- No overflow text -->
|
||||
<ion-tab-bar color="danger" selected-tab="1">
|
||||
<ion-tab-button tab='1'>
|
||||
<ion-label>Indiana Jones and the Raiders of the Lost Ark</ion-label>
|
||||
</ion-tab-button>
|
||||
<!-- No overflow text -->
|
||||
<ion-tab-bar color="danger" selected-tab="1">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-label>Indiana Jones and the Raiders of the Lost Ark</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2'>
|
||||
<ion-label>Indiana Jones and the Temple of Doom</ion-label>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2">
|
||||
<ion-label>Indiana Jones and the Temple of Doom</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3'>
|
||||
<ion-label>Indiana Jones and the Last Crusade</ion-label>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
<ion-tab-button tab="3">
|
||||
<ion-label>Indiana Jones and the Last Crusade</ion-label>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
<!-- Custom TabBar -->
|
||||
<ion-tab-bar selected-tab="1" class="custom-tabbar">
|
||||
<ion-tab-button tab='1'>
|
||||
<ion-label>Location</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<!-- Custom Tab Bar -->
|
||||
<ion-tab-bar selected-tab="1" class="custom-tabbar">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-label>Location</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='2' class="main-tab">
|
||||
<ion-icon src="/src/components/tab-bar/test/scenarios/camera.svg"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="2" class="main-tab">
|
||||
<ion-icon src="/src/components/tab-bar/test/scenarios/camera.svg"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab='3'>
|
||||
<ion-label>Radio</ion-label>
|
||||
<ion-icon name="musical-notes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="3">
|
||||
<ion-label>Radio</ion-label>
|
||||
<ion-icon name="musical-notes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tab-bar>
|
||||
|
||||
</ion-app>
|
||||
<!-- Custom Tab Bar Colors -->
|
||||
<ion-tab-bar selected-tab="1" class="custom-tabbar-color">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-label>Location</ion-label>
|
||||
<ion-icon name="navigate"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2">
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3">
|
||||
<ion-label>Radio</ion-label>
|
||||
<ion-icon name="musical-notes"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
|
||||
<style>
|
||||
.custom-tabbar {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
overflow: visible;
|
||||
contain: none;
|
||||
}
|
||||
|
||||
.main-tab {
|
||||
border-radius: 50%;
|
||||
max-width: 80px;
|
||||
height: 80px;
|
||||
background: #3880ff;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.custom-tabbar-color {
|
||||
--background: #7044ff;
|
||||
}
|
||||
|
||||
.custom-tabbar-color ion-tab-button {
|
||||
--color: rgba(255, 255, 255, .7);
|
||||
--color-selected: white;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
10
core/src/components/tab-bar/test/spec/e2e.ts
Normal file
10
core/src/components/tab-bar/test/spec/e2e.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('tab-bar: spec', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/tab-bar/test/spec?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
169
core/src/components/tab-bar/test/spec/index.html
Normal file
169
core/src/components/tab-bar/test/spec/index.html
Normal file
@ -0,0 +1,169 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Tab Bar - Spec</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">
|
||||
<script src="../../../../../dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="../../../../../css/ionic.bundle.css">
|
||||
<link rel="stylesheet" href="../../../../../scripts/testing/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Default -->
|
||||
<ion-tab-bar 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 selected-tab="1">
|
||||
<ion-tab-button tab="1" layout="icon-top">
|
||||
<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 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 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 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 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 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>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background: #222;
|
||||
}
|
||||
|
||||
ion-tab-bar {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.custom-height {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.custom-top ion-tab-button {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
21
core/src/components/tab-bar/usage/angular.md
Normal file
21
core/src/components/tab-bar/usage/angular.md
Normal file
@ -0,0 +1,21 @@
|
||||
```html
|
||||
<ion-tabs>
|
||||
<!-- Tab views -->
|
||||
<ion-tab tab="account"></ion-tab>
|
||||
<ion-tab tab="contact"></ion-tab>
|
||||
<ion-tab tab="settings"></ion-tab>
|
||||
|
||||
<!-- Tab bar -->
|
||||
<ion-tab-bar slot="bottom">
|
||||
<ion-tab-button tab="account">
|
||||
<ion-icon name="person"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="contact">
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="settings">
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
```
|
21
core/src/components/tab-bar/usage/javascript.md
Normal file
21
core/src/components/tab-bar/usage/javascript.md
Normal file
@ -0,0 +1,21 @@
|
||||
```html
|
||||
<ion-tabs>
|
||||
<!-- Tab views -->
|
||||
<ion-tab tab="account"></ion-tab>
|
||||
<ion-tab tab="contact"></ion-tab>
|
||||
<ion-tab tab="settings"></ion-tab>
|
||||
|
||||
<!-- Tab bar -->
|
||||
<ion-tab-bar slot="bottom">
|
||||
<ion-tab-button tab="account">
|
||||
<ion-icon name="person"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="contact">
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-tab-button>
|
||||
<ion-tab-button tab="settings">
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
```
|
@ -1,8 +1,8 @@
|
||||
# ion-tab-bar
|
||||
# ion-tab-button
|
||||
|
||||
Tab bar is a UI component that hold the array of [tab buttons](../tab-button). The Tab bar can provide a global setting for different tab/icon layouts as well as different positions for the bar itself.
|
||||
A tab button is a UI component that is placed inside of a [tab bar](../tab-bar). The tab button can specify the layout of the icon and label and connect to a [tab view](../tab).
|
||||
|
||||
See the [Tabs API Docs](../Tabs/) for more details on configuring Tabs.
|
||||
See the [tabs documentation](../tabs) for more details on configuring tabs.
|
||||
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
@ -25,12 +25,25 @@
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
::slotted(ion-label) {
|
||||
@include margin(0, null, 1px, null);
|
||||
|
||||
min-height: $tab-button-ios-font-size + 1;
|
||||
// iOS Tab Button: Badge
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(ion-badge) {
|
||||
@include padding(1px, 6px);
|
||||
@include position(4px, null, null, calc(50% + 6px));
|
||||
|
||||
height: auto;
|
||||
|
||||
font-size: 12px;
|
||||
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
|
||||
// iOS Tab Button: Icon
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(ion-icon) {
|
||||
@include margin(4px, null, null, null);
|
||||
|
||||
@ -42,7 +55,17 @@
|
||||
}
|
||||
|
||||
|
||||
// iOS TabButton Layout
|
||||
// iOS Tab Button: Label
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(ion-label) {
|
||||
@include margin(0, null, 1px, null);
|
||||
|
||||
min-height: $tab-button-ios-font-size + 1;
|
||||
}
|
||||
|
||||
|
||||
// iOS Tab Button Layout
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.tab-layout-icon-end) ::slotted(ion-label),
|
||||
@ -67,6 +90,54 @@
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
// iOS Tab Button: Icon Bottom Layout
|
||||
// --------------------------------------------------
|
||||
|
||||
// Badge
|
||||
:host(.tab-layout-icon-bottom) ::slotted(ion-badge) {
|
||||
@include position(null, null, null, calc(50% + 12px));
|
||||
}
|
||||
|
||||
// Icon
|
||||
:host(.tab-layout-icon-bottom) ::slotted(ion-icon) {
|
||||
@include margin(0, null, 1px, null);
|
||||
}
|
||||
|
||||
// Label
|
||||
:host(.tab-layout-icon-bottom) ::slotted(ion-label) {
|
||||
@include margin(4px, null, null, null);
|
||||
}
|
||||
|
||||
|
||||
// iOS Tab Button: Icon Start / End Layout
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.tab-layout-icon-start) ::slotted(ion-badge),
|
||||
:host(.tab-layout-icon-end) ::slotted(ion-badge) {
|
||||
@include position(10px, null, null, calc(50% + 35px));
|
||||
}
|
||||
|
||||
|
||||
// iOS Tab Button: Icon Hide / Label Only Layout
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// Badge
|
||||
:host(.tab-layout-icon-hide) ::slotted(ion-badge),
|
||||
:host(.tab-has-label-only) ::slotted(ion-badge) {
|
||||
@include position(10px, null, null, calc(50% + 30px));
|
||||
}
|
||||
|
||||
|
||||
// iOS Tab Button: Icon Only / Label Hide Layout
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// Badge
|
||||
:host(.tab-layout-label-hide) ::slotted(ion-badge),
|
||||
:host(.tab-has-icon-only) ::slotted(ion-badge) {
|
||||
@include position(10px, null, null, null);
|
||||
}
|
||||
|
||||
:host(.tab-layout-label-hide) ::slotted(ion-icon) {
|
||||
@include margin(0);
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
@import "./tab-button.md.vars";
|
||||
|
||||
// Material Design Tab Button
|
||||
// --------------------------------------------------
|
||||
// --------------------------------------------------------------
|
||||
|
||||
:host {
|
||||
--padding-top: #{$tab-button-md-padding-top};
|
||||
@ -18,71 +18,137 @@
|
||||
|
||||
font-size: $tab-button-md-font-size;
|
||||
font-weight: $tab-button-md-font-weight;
|
||||
|
||||
letter-spacing: $tab-button-md-letter-spacing;
|
||||
}
|
||||
|
||||
|
||||
// Material Design Tab Button Text
|
||||
// --------------------------------------------------
|
||||
// Material Design Tab Button: Label
|
||||
// --------------------------------------------------------------
|
||||
|
||||
::slotted(ion-label) {
|
||||
@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);
|
||||
|
||||
transition: $tab-button-md-text-transition;
|
||||
|
||||
text-transform: $tab-button-md-text-capitalization;
|
||||
}
|
||||
|
||||
::slotted(.tab-selected) ::slotted(ion-label) {
|
||||
transform: #{$tab-button-md-text-transform-active};
|
||||
|
||||
transition: $tab-button-md-text-transition;
|
||||
}
|
||||
|
||||
// Material Design Tab Button Icon
|
||||
// --------------------------------------------------
|
||||
// Material Design Tab Button: Icon
|
||||
// --------------------------------------------------------------
|
||||
|
||||
::slotted(ion-icon) {
|
||||
@include margin($tab-button-md-icon-margin-top, $tab-button-md-icon-margin-end, $tab-button-md-icon-margin-bottom, $tab-button-md-icon-margin-start);
|
||||
@include transform-origin(center, center);
|
||||
|
||||
width: $tab-button-md-icon-size;
|
||||
height: $tab-button-md-icon-size;
|
||||
|
||||
transition: $tab-button-md-icon-transition;
|
||||
|
||||
font-size: $tab-button-md-icon-size;
|
||||
}
|
||||
|
||||
// Material Design Tab Button: Badge
|
||||
// --------------------------------------------------------------
|
||||
|
||||
::slotted(ion-badge) {
|
||||
@include border-radius($tab-button-md-badge-border-radius);
|
||||
@include padding($tab-button-md-badge-padding-top, $tab-button-md-badge-padding-end, $tab-button-md-badge-padding-bottom, $tab-button-md-badge-padding-start);
|
||||
@include position(8px, null, null, calc(50% + 6px));
|
||||
|
||||
min-width: $tab-button-md-badge-min-width;
|
||||
|
||||
font-size: $tab-button-md-badge-font-size;
|
||||
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
::slotted(ion-badge:empty) {
|
||||
display: block;
|
||||
|
||||
min-width: $tab-button-md-badge-size-empty;
|
||||
|
||||
height: $tab-button-md-badge-size-empty;
|
||||
}
|
||||
|
||||
|
||||
// Material Design TabButton Layout
|
||||
// --------------------------------------------------
|
||||
// Material Design Tab Button: Icon Top Layout
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// Icon
|
||||
:host(.tab-layout-icon-top) ::slotted(ion-icon) {
|
||||
@include margin(6px, null, 2px, null);
|
||||
}
|
||||
|
||||
// Label
|
||||
:host(.tab-layout-icon-top) ::slotted(ion-label) {
|
||||
margin-bottom: -2px;
|
||||
@include margin(0, null, 6px, null);
|
||||
}
|
||||
|
||||
|
||||
// Material Design Tab Button: Icon Bottom Layout
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// Badge
|
||||
:host(.tab-layout-icon-bottom) ::slotted(ion-badge) {
|
||||
@include position(8px, null, null, 70%);
|
||||
}
|
||||
|
||||
// Icon
|
||||
:host(.tab-layout-icon-bottom) ::slotted(ion-icon) {
|
||||
@include margin(0, null, 6px, null);
|
||||
}
|
||||
|
||||
// Label
|
||||
:host(.tab-layout-icon-bottom) ::slotted(ion-label) {
|
||||
margin-top: -2px;
|
||||
// --label-transform: transform-origin(center, top);
|
||||
@include margin(6px, null, 0, null);
|
||||
}
|
||||
|
||||
:host(.tab-selected) ::slotted(ion-label) {
|
||||
transform: #{$tab-button-md-text-transform-active};
|
||||
|
||||
// Material Design Tab Button: Icon Start / Icon End Layout
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// Badge
|
||||
:host(.tab-layout-icon-start) ::slotted(ion-badge),
|
||||
:host(.tab-layout-icon-end) ::slotted(ion-badge) {
|
||||
@include position(16px, null, null, 80%);
|
||||
}
|
||||
|
||||
:host(.tab-selected) ::slotted(ion-icon) {
|
||||
transform: #{$tab-button-md-icon-transform-active};
|
||||
// Icon
|
||||
:host(.tab-layout-icon-start) ::slotted(ion-icon) {
|
||||
@include margin(null, 6px, null, null);
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-end.tab-selected) ::slotted(ion-icon) {
|
||||
transform: #{$tab-button-md-icon-right-transform-active};
|
||||
// Icon
|
||||
:host(.tab-layout-icon-end) ::slotted(ion-icon) {
|
||||
@include margin(null, null, null, 6px);
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-bottom.tab-selected) ::slotted(ion-icon) {
|
||||
transform: #{$tab-button-md-icon-bottom-transform-active};
|
||||
|
||||
// Material Design Tab Button: Icon Hide / Label Only Layout
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// Badge
|
||||
:host(.tab-layout-icon-hide) ::slotted(ion-badge),
|
||||
:host(.tab-has-label-only) ::slotted(ion-badge) {
|
||||
@include position(16px, null, null, 70%);
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-start.tab-selected) ::slotted(ion-icon) {
|
||||
transform: #{$tab-button-md-icon-left-transform-active};
|
||||
// Label
|
||||
:host(.tab-layout-icon-hide) ::slotted(ion-label),
|
||||
:host(.tab-has-label-only) ::slotted(ion-label) {
|
||||
@include margin(0, null, 0, null);
|
||||
}
|
||||
|
||||
|
||||
// Material Design Tab Button: Icon Only / Label Hide Layout
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// Badge
|
||||
:host(.tab-layout-label-hide) ::slotted(ion-badge),
|
||||
:host(.tab-has-icon-only) ::slotted(ion-badge) {
|
||||
@include position(16px, null, null, null);
|
||||
}
|
||||
|
||||
// Icon
|
||||
:host(.tab-layout-label-hide) ::slotted(ion-icon),
|
||||
:host(.tab-has-icon-only) ::slotted(ion-icon) {
|
||||
@include margin(0, null, 0, null);
|
||||
|
||||
font-size: 24px;
|
||||
}
|
@ -4,20 +4,23 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Padding top on the tab button
|
||||
$tab-button-md-padding-top: 8px !default;
|
||||
$tab-button-md-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end on the tab button
|
||||
$tab-button-md-padding-end: 12px !default;
|
||||
|
||||
/// @prop - Padding bottom on the tab button
|
||||
$tab-button-md-padding-bottom: 10px !default;
|
||||
$tab-button-md-padding-bottom: 0 !default;
|
||||
|
||||
/// @prop - Padding start on the tab button
|
||||
$tab-button-md-padding-start: 12px, !default;
|
||||
$tab-button-md-padding-start: 12px !default;
|
||||
|
||||
/// @prop - Font size of the inactive tab button text
|
||||
$tab-button-md-font-size: 12px !default;
|
||||
|
||||
/// @prop - Letter spacing of the tab button
|
||||
$tab-button-md-letter-spacing: .03em !default;
|
||||
|
||||
/// @prop - Font weight of the tab button text
|
||||
$tab-button-md-font-weight: normal !default;
|
||||
|
||||
@ -33,14 +36,26 @@ $tab-button-md-icon-color: $tabbar-md-color !default;
|
||||
/// @prop - Icon color of the active tab button
|
||||
$tab-button-md-icon-color-active: $tabbar-md-color-activated !default;
|
||||
|
||||
/// @prop - Margin top on the tab button icon
|
||||
$tab-button-md-icon-margin-top: 16px !default;
|
||||
|
||||
/// @prop - Margin end on the tab button icon
|
||||
$tab-button-md-icon-margin-end: 0 !default;
|
||||
|
||||
/// @prop - Margin bottom on the tab button icon
|
||||
$tab-button-md-icon-margin-bottom: $tab-button-md-icon-margin-top !default;
|
||||
|
||||
/// @prop - Margin start on the tab button icon
|
||||
$tab-button-md-icon-margin-start: $tab-button-md-icon-margin-end !default;
|
||||
|
||||
/// @prop - Font size of the active tab button text
|
||||
$tab-button-md-font-size-active: 14px !default;
|
||||
|
||||
/// @prop - Margin top on the tab button text
|
||||
$tab-button-md-text-margin-top: 0 !default;
|
||||
$tab-button-md-text-margin-top: 2px !default;
|
||||
|
||||
/// @prop - Margin end on the tab button text
|
||||
$tab-button-md-text-margin-end: $tab-button-md-text-margin-top !default;
|
||||
$tab-button-md-text-margin-end: 0 !default;
|
||||
|
||||
/// @prop - Margin bottom on the tab button text
|
||||
$tab-button-md-text-margin-bottom: $tab-button-md-text-margin-top !default;
|
||||
@ -51,29 +66,32 @@ $tab-button-md-text-margin-start: $tab-button-md-text-margin-end !
|
||||
/// @prop - Capitalization of the tab button text
|
||||
$tab-button-md-text-capitalization: none !default;
|
||||
|
||||
/// @prop - Transform for the active tab button text
|
||||
$tab-button-md-text-transform-active: scale3d($tab-button-md-font-size-active / $tab-button-md-font-size, $tab-button-md-font-size-active / $tab-button-md-font-size, 1) !default;
|
||||
|
||||
/// @prop - Text transition for the tab button text
|
||||
$tab-button-md-text-transition: transform .1s ease-in-out !default;
|
||||
|
||||
/// @prop - Transform for the active tab button icon when the layout is icon-top, icon-only, or label-only
|
||||
$tab-button-md-icon-transform-active: translate3d(0, -2px, 0) !default;
|
||||
|
||||
/// @prop - Transform for the active tab button icon when the layout is icon-right
|
||||
$tab-button-md-icon-right-transform-active: translate3d(6px, 0, 0) !default;
|
||||
|
||||
/// @prop - Transform for the active tab button icon when the layout is icon-bottom
|
||||
$tab-button-md-icon-bottom-transform-active: translate3d(0, 2px, 0) !default;
|
||||
|
||||
/// @prop - Transform for the active tab button icon when the layout is icon-left
|
||||
$tab-button-md-icon-left-transform-active: translate3d(-6px, 0, 0) !default;
|
||||
|
||||
/// @prop - Text transition for the tab button icon
|
||||
$tab-button-md-icon-transition: transform .1s ease-in-out !default;
|
||||
|
||||
/// @prop - Size of the tab button icon
|
||||
$tab-button-md-icon-size: 22px !default;
|
||||
|
||||
/// @prop - Opacity of the inactive tab button
|
||||
$tab-button-md-opacity: .7 !default;
|
||||
|
||||
/// @prop - Border radius on the tab button badge
|
||||
$tab-button-md-badge-border-radius: 8px !default;
|
||||
|
||||
/// @prop - Padding top on the tab button badge
|
||||
$tab-button-md-badge-padding-top: 3px !default;
|
||||
|
||||
/// @prop - Padding end on the tab button badge
|
||||
$tab-button-md-badge-padding-end: 2px !default;
|
||||
|
||||
/// @prop - Padding bottom on the tab button badge
|
||||
$tab-button-md-badge-padding-bottom: 2px !default;
|
||||
|
||||
/// @prop - Padding start on the tab button badge
|
||||
$tab-button-md-badge-padding-start: 2px !default;
|
||||
|
||||
/// @prop - Minimum width of the tab button badge
|
||||
$tab-button-md-badge-min-width: 12px !default;
|
||||
|
||||
/// @prop - Font size of the tab button badge
|
||||
$tab-button-md-badge-font-size: 8px !default;
|
||||
|
||||
/// @prop - Size of the empty tab button badge
|
||||
$tab-button-md-badge-size-empty: 8px !default;
|
||||
|
@ -12,32 +12,33 @@
|
||||
* @prop --padding-start: Start padding of the tab button
|
||||
* @prop --ripple-color: Color of the button ripple effect
|
||||
*/
|
||||
--badge-end: 4%;
|
||||
--ripple-color: var(--color-selected);
|
||||
|
||||
flex: 1;
|
||||
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 100%;
|
||||
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
// Tab Button: Native
|
||||
// --------------------------------------------------
|
||||
|
||||
a {
|
||||
@include text-inherit();
|
||||
@include margin(0);
|
||||
@include padding(
|
||||
var(--padding-top),
|
||||
var(--padding-end),
|
||||
var(--padding-bottom),
|
||||
var(--padding-start),
|
||||
);
|
||||
@include padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
|
||||
@include text-inherit();
|
||||
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
flex-direction: inherit;
|
||||
align-items: inherit;
|
||||
justify-content: inherit;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -66,6 +67,10 @@ a:focus-visible {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Tab Button: States
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.tab-selected) {
|
||||
color: var(--color-selected);
|
||||
}
|
||||
@ -81,15 +86,9 @@ a:focus-visible {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
::slotted(ion-label) {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
::slotted(ion-icon) {
|
||||
order: -1;
|
||||
|
||||
height: 1em;
|
||||
}
|
||||
// Tab Button: Label / Icon
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(ion-label),
|
||||
::slotted(ion-icon) {
|
||||
@ -97,7 +96,6 @@ a:focus-visible {
|
||||
|
||||
align-self: center;
|
||||
|
||||
min-width: 26px;
|
||||
max-width: 100%;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
@ -108,55 +106,49 @@ a:focus-visible {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
::slotted(ion-label) {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
::slotted(ion-icon) {
|
||||
order: -1;
|
||||
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
|
||||
:host(.tab-has-label-only) ::slotted(ion-label) {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Tab Badges
|
||||
// Tab Button: Badge
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(ion-badge) {
|
||||
@include position(null, var(--badge-end), null, null);
|
||||
@include padding(1px, 6px);
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
position: absolute;
|
||||
|
||||
height: auto;
|
||||
|
||||
font-size: 12px;
|
||||
|
||||
line-height: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
||||
// Tab Button Layout
|
||||
// Tab Button: Layout
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.tab-layout-icon-start) a {
|
||||
:host(.tab-layout-icon-start) {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-end) a {
|
||||
:host(.tab-layout-icon-end) {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-bottom) a {
|
||||
:host(.tab-layout-icon-bottom) {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-start) a,
|
||||
:host(.tab-layout-icon-end) a,
|
||||
:host(.tab-layout-icon-hide) a,
|
||||
:host(.tab-layout-label-hide) a,
|
||||
:host(.tab-has-icon-only) a,
|
||||
:host(.tab-has-label-only) a {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-hide) ::slotted(ion-icon) {
|
||||
display: none;
|
||||
}
|
||||
@ -165,21 +157,6 @@ a:focus-visible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-top),
|
||||
:host(.tab-layout-icon-bottom),
|
||||
:host(.tab-layout-icon-only),
|
||||
:host(.tab-layout-label-hide),
|
||||
:host(.tab-has-icon-only) {
|
||||
--badge-end: #{calc(50% - 30px)};
|
||||
}
|
||||
|
||||
:host(.tab-layout-icon-hide),
|
||||
:host(.tab-layout-icon-start),
|
||||
:host(.tab-layout-icon-end),
|
||||
:host(.tab-has-label-only) {
|
||||
--badge-end: #{calc(50% - 50px)};
|
||||
}
|
||||
|
||||
ion-ripple-effect {
|
||||
color: var(--ripple-color);
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
# ion-tab
|
||||
|
||||
The Tab component is a child component of the [Tabs](../Tabs/) component.
|
||||
Each Tab is meant to be a top level navigation stack for an app.
|
||||
Meaning that an app can have many tabs, all wit their own independent navigation.
|
||||
The tab component is a child component of [tabs](../tabs). Each tab can contain a top level navigation stack for an app or a single view. An app can have many tabs, all with their own independent navigation.
|
||||
|
||||
See the [Tabs API Docs](../Tabs/) for more details on configuring Tabs.
|
||||
See the [tabs documentation](../tabs/) for more details on configuring tabs.
|
||||
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
@ -22,7 +22,7 @@ In order to do so, an `ion-tab-bar` should be provided as a direct child of `ion
|
||||
|
||||
<ion-tab-button tab="settings">
|
||||
<ion-label>Settings</ion-label>
|
||||
<ion-icon name="gear"></ion-icon>
|
||||
<ion-icon name="settings"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
|
@ -39,5 +39,6 @@
|
||||
<ion-label>About</ion-label>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
</ion-tabs>
|
||||
```
|
||||
|
@ -1,13 +1,21 @@
|
||||
```html
|
||||
<ion-tabs>
|
||||
|
||||
<ion-tab tab="tab-schedule">
|
||||
<ion-nav></ion-nav>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab tab="tab-speaker">
|
||||
<ion-nav></ion-nav>
|
||||
</ion-tab>
|
||||
<ion-tab tab="tab-map" component="page-map"></ion-tab>
|
||||
<ion-tab tab="tab-about" component="page-about"></ion-tab>
|
||||
|
||||
<ion-tab tab="tab-map" component="page-map">
|
||||
<ion-nav></ion-nav>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab tab="tab-about" component="page-about">
|
||||
<ion-nav></ion-nav>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab-bar slot="bottom">
|
||||
<ion-tab-button tab="tab-schedule">
|
||||
@ -15,18 +23,22 @@
|
||||
<ion-label>Schedule</ion-label>
|
||||
<ion-badge>6</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-speaker">
|
||||
<ion-icon name="contacts"></ion-icon>
|
||||
<ion-label>Speakers</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-map">
|
||||
<ion-icon name="map"></ion-icon>
|
||||
<ion-label>Map</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="tab-about">
|
||||
<ion-icon name="information-circle"></ion-icon>
|
||||
<ion-label>About</ion-label>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
|
||||
</ion-tabs>
|
||||
```
|
||||
|
Reference in New Issue
Block a user