Skip to content

Commit 2af2167

Browse files
thetaPCIonitron
andauthored
feat(tab-bar): add expand and shape props for ionic theme (#29888)
Co-authored-by: ionitron <[email protected]>
1 parent bde1d09 commit 2af2167

File tree

32 files changed

+496
-22
lines changed

32 files changed

+496
-22
lines changed

core/api.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,8 +2177,10 @@ ion-tab,method,setActive,setActive() => Promise<void>
21772177

21782178
ion-tab-bar,shadow
21792179
ion-tab-bar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
2180+
ion-tab-bar,prop,expand,"compact" | "full",'full',false,false
21802181
ion-tab-bar,prop,mode,"ios" | "md",undefined,false,false
21812182
ion-tab-bar,prop,selectedTab,string | undefined,undefined,false,false
2183+
ion-tab-bar,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
21822184
ion-tab-bar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
21832185
ion-tab-bar,prop,translucent,boolean,false,false,false
21842186
ion-tab-bar,css-prop,--background,ionic

core/src/components.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,6 +3411,10 @@ export namespace Components {
34113411
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
34123412
*/
34133413
"color"?: Color;
3414+
/**
3415+
* Set to `"compact"` to display a width based on the items inside the tab bar. This value will only work for the `ionic` theme. Set to `"full"` to display a full width tab bar. Defaults to `"full"`.
3416+
*/
3417+
"expand": 'compact' | 'full';
34143418
/**
34153419
* The mode determines the platform behaviors of the component.
34163420
*/
@@ -3419,6 +3423,10 @@ export namespace Components {
34193423
* The selected tab component
34203424
*/
34213425
"selectedTab"?: string;
3426+
/**
3427+
* Set to `"soft"` for a tab bar with slightly rounded corners, `"round"` for a tab bar with fully rounded corners, or `"rectangular"` for a tab bar without rounded corners. Defaults to `"round"` for the `"ionic"` theme, undefined for all other themes.
3428+
*/
3429+
"shape"?: 'soft' | 'round' | 'rectangular';
34223430
/**
34233431
* The theme determines the visual appearance of the component.
34243432
*/
@@ -8765,6 +8773,10 @@ declare namespace LocalJSX {
87658773
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
87668774
*/
87678775
"color"?: Color;
8776+
/**
8777+
* Set to `"compact"` to display a width based on the items inside the tab bar. This value will only work for the `ionic` theme. Set to `"full"` to display a full width tab bar. Defaults to `"full"`.
8778+
*/
8779+
"expand"?: 'compact' | 'full';
87688780
/**
87698781
* The mode determines the platform behaviors of the component.
87708782
*/
@@ -8775,6 +8787,10 @@ declare namespace LocalJSX {
87758787
* The selected tab component
87768788
*/
87778789
"selectedTab"?: string;
8790+
/**
8791+
* Set to `"soft"` for a tab bar with slightly rounded corners, `"round"` for a tab bar with fully rounded corners, or `"rectangular"` for a tab bar without rounded corners. Defaults to `"round"` for the `"ionic"` theme, undefined for all other themes.
8792+
*/
8793+
"shape"?: 'soft' | 'round' | 'rectangular';
87788794
/**
87798795
* The theme determines the visual appearance of the component.
87808796
*/

core/src/components/tab-bar/tab-bar.common.scss

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,13 @@
99
align-items: center;
1010
justify-content: center;
1111

12-
width: auto;
13-
14-
/* stylelint-disable */
15-
padding-right: var(--ion-safe-area-right);
16-
padding-bottom: var(--ion-safe-area-bottom, 0);
17-
padding-left: var(--ion-safe-area-left);
18-
/* stylelint-enable */
19-
2012
border-top: var(--border);
2113

2214
background: var(--background);
2315
color: var(--color);
2416

2517
text-align: center;
2618

27-
contain: strict;
2819
user-select: none;
2920

3021
/* stylelint-disable-next-line declaration-no-important */
@@ -41,9 +32,6 @@
4132
}
4233

4334
:host([slot="top"]) {
44-
padding-top: var(--ion-safe-area-top, 0);
45-
padding-bottom: 0;
46-
4735
border-top: 0;
4836
border-bottom: var(--border);
4937
}
@@ -52,3 +40,25 @@
5240
/* stylelint-disable-next-line declaration-no-important */
5341
display: none !important;
5442
}
43+
44+
// Tab Bar Expand
45+
// --------------------------------------------------
46+
47+
/* Full */
48+
:host(.tab-bar-full) {
49+
width: auto;
50+
51+
contain: strict;
52+
53+
/* stylelint-disable */
54+
padding-bottom: var(--ion-safe-area-bottom, 0);
55+
56+
padding-right: var(--ion-safe-area-right);
57+
padding-left: var(--ion-safe-area-left);
58+
/* stylelint-enable */
59+
}
60+
61+
:host([slot="top"].tab-bar-full) {
62+
padding-top: var(--ion-safe-area-top, 0);
63+
padding-bottom: 0;
64+
}

core/src/components/tab-bar/tab-bar.ionic.scss

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,68 @@
1919
*/
2020
min-height: calc(globals.$ionic-scale-1400 - calc(globals.$ionic-space-100 * 2));
2121

22-
padding-top: calc(globals.$ionic-space-100 + var(--ion-safe-area-top, 0));
23-
padding-bottom: calc(globals.$ionic-space-100 + var(--ion-safe-area-bottom, 0));
22+
gap: globals.$ionic-space-300;
23+
24+
// TODO(ROU-10853): replace this value with a layer token
25+
z-index: 10;
26+
}
27+
28+
// Tab Bar Expand
29+
// --------------------------------------------------
2430

31+
/* Full */
32+
:host(.tab-bar-full) {
2533
/* stylelint-disable */
34+
padding-top: globals.$ionic-space-100;
35+
padding-bottom: calc(globals.$ionic-space-100 + var(--ion-safe-area-bottom, 0));
36+
2637
padding-right: calc(globals.$ionic-space-400 + var(--ion-safe-area-right, 0));
2738
padding-left: calc(globals.$ionic-space-400 + var(--ion-safe-area-left, 0));
2839
/* stylelint-enable */
40+
}
2941

30-
gap: globals.$ionic-space-300;
42+
:host([slot="top"].tab-bar-full) {
43+
padding-top: calc(globals.$ionic-space-100 + var(--ion-safe-area-top, 0));
44+
padding-bottom: globals.$ionic-space-100;
45+
}
3146

32-
// TODO(ROU-10853): replace this value with a layer token
33-
z-index: 10;
47+
/* Compact */
48+
:host(.tab-bar-compact) {
49+
@include globals.padding(globals.$ionic-space-100, globals.$ionic-space-400);
50+
51+
position: absolute;
52+
53+
align-self: center;
54+
55+
width: fit-content;
56+
57+
box-shadow: #{globals.$ionic-elevation-200};
58+
59+
contain: content;
60+
}
61+
62+
:host([slot="top"].tab-bar-compact) {
63+
top: calc(globals.$ionic-space-100 + var(--ion-safe-area-top, 0));
64+
}
65+
66+
:host([slot="bottom"].tab-bar-compact) {
67+
bottom: calc(globals.$ionic-space-100 + var(--ion-safe-area-bottom, 0));
68+
}
69+
70+
// Tab Bar Shapes
71+
// --------------------------------------------------
72+
73+
/* Soft */
74+
:host(.tab-bar-soft) {
75+
@include globals.border-radius(globals.$ionic-border-radius-400);
76+
}
77+
78+
/* Round */
79+
:host(.tab-bar-round) {
80+
@include globals.border-radius(globals.$ionic-border-radius-full);
81+
}
82+
83+
/* Rectangular */
84+
:host(.tab-bar-rectangular) {
85+
@include globals.border-radius(globals.$ionic-border-radius-0);
3486
}

core/src/components/tab-bar/tab-bar.tsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ export class TabBar implements ComponentInterface {
5656
*/
5757
@Prop() translucent = false;
5858

59+
/**
60+
* Set to `"compact"` to display a width based on the items
61+
* inside the tab bar. This value will only work for the
62+
* `ionic` theme.
63+
*
64+
* Set to `"full"` to display a full width tab bar.
65+
*
66+
* Defaults to `"full"`.
67+
*/
68+
@Prop() expand: 'compact' | 'full' = 'full';
69+
70+
/**
71+
* Set to `"soft"` for a tab bar with slightly rounded corners,
72+
* `"round"` for a tab bar with fully rounded corners, or
73+
* `"rectangular"` for a tab bar without rounded corners.
74+
*
75+
* Defaults to `"round"` for the `"ionic"` theme, undefined for all other themes.
76+
*/
77+
@Prop() shape?: 'soft' | 'round' | 'rectangular';
78+
5979
/** @internal */
6080
@Event() ionTabBarChanged!: EventEmitter<TabBarChangedEventDetail>;
6181

@@ -96,9 +116,26 @@ export class TabBar implements ComponentInterface {
96116
this.ionTabBarLoaded.emit();
97117
}
98118

119+
private getShape(): string | undefined {
120+
const theme = getIonTheme(this);
121+
const { shape } = this;
122+
123+
// TODO(ROU-11234): Remove theme check when shapes are defined for all themes.
124+
if (theme !== 'ionic') {
125+
return undefined;
126+
}
127+
128+
if (shape === undefined) {
129+
return 'round';
130+
}
131+
132+
return shape;
133+
}
134+
99135
render() {
100-
const { color, translucent, keyboardVisible } = this;
136+
const { color, translucent, keyboardVisible, expand } = this;
101137
const theme = getIonTheme(this);
138+
const shape = this.getShape();
102139
const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
103140

104141
return (
@@ -109,6 +146,8 @@ export class TabBar implements ComponentInterface {
109146
[theme]: true,
110147
'tab-bar-translucent': translucent,
111148
'tab-bar-hidden': shouldHide,
149+
[`tab-bar-${expand}`]: true,
150+
[`tab-bar-${shape}`]: shape !== undefined,
112151
})}
113152
>
114153
<slot></slot>

core/src/components/tab-bar/test/basic/tab-bar.e2e.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ configs({ modes: ['ionic-md', 'md', 'ios'] }).forEach(({ title, screenshot, conf
99
test('should not have visual regressions', async ({ page }) => {
1010
await page.setContent(
1111
`
12+
<style>
13+
:root {
14+
background: #ccc7c7;
15+
}
16+
</style>
17+
1218
<ion-tab-bar selected-tab="2">
1319
<ion-tab-button tab="1">
1420
<ion-icon name="home-outline"></ion-icon>
876 Bytes
Loading
1.54 KB
Loading
919 Bytes
Loading
875 Bytes
Loading

0 commit comments

Comments
 (0)