Skip to content

refactor(toolbar): improve slot layout and visibility handling #30371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
837e089
refactor(toolbar): improve slot layout and visibility handling
ShaneK Apr 23, 2025
74230a6
Merge branch 'next' of github.com:ionic-team/ionic-framework into nex…
ShaneK Apr 24, 2025
faf2640
chore(toolbar): code clean up
ShaneK Apr 24, 2025
1683731
chore(toolbar): lint fix
ShaneK Apr 24, 2025
5280f4f
refactor(ion-title): removing unnecessary padding from ion-title
ShaneK Apr 24, 2025
73d4870
chore(lint): running lint
ShaneK Apr 24, 2025
d3ac45d
fix(title): padding
ShaneK Apr 25, 2025
b285cd5
chore(comment): force tests by adding a comment
ShaneK Apr 25, 2025
c664444
chore(): add updated snapshots
Ionitron Apr 25, 2025
4345192
test(segment): toolbar title fix
ShaneK Apr 25, 2025
e5c643b
Update core/src/components/toolbar/toolbar.tsx
ShaneK Apr 28, 2025
f7dc47f
Update core/src/components/toolbar/toolbar.tsx
ShaneK Apr 28, 2025
8dd486e
fix(toolbar): incorrect padding variable for title
ShaneK Apr 28, 2025
34f711f
chore(): add updated snapshots
Ionitron Apr 28, 2025
2720faa
Update core/src/components/toolbar/toolbar.tsx
ShaneK Apr 28, 2025
7ecfa51
fix(toolbar): fixing dynamic slot sizing to ensure better centered co…
ShaneK Apr 29, 2025
fe69481
chore(): add updated snapshots
Ionitron Apr 29, 2025
b26af1e
fix(toolbar): removing flex-grow from toolbar slots so they don't tak…
ShaneK Apr 29, 2025
f613c11
chore(): add updated snapshots
Ionitron Apr 29, 2025
95d3b05
fix(toolbar): fixing button gap
ShaneK Apr 29, 2025
ba08922
Merge branch 'next-branch/FW-6439' of github.com:ionic-team/ionic-fra…
ShaneK Apr 29, 2025
988f238
chore(): add updated snapshots
Ionitron Apr 29, 2025
f1c7a12
fix(toolbar): lint
ShaneK Apr 29, 2025
d2578fe
Merge branch 'next-branch/FW-6439' of github.com:ionic-team/ionic-fra…
ShaneK Apr 29, 2025
8260caf
fix(toolbar): updating slot classes and widths on change so that cont…
ShaneK Apr 29, 2025
1974bfa
Merge branch 'next' into next-branch/FW-6439
ShaneK Apr 30, 2025
8ecb3cf
merge(conflicts): dealing with merge conflicts
ShaneK Apr 30, 2025
427ad01
chore(): add updated snapshots
Ionitron Apr 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 160 additions & 0 deletions core/src/components/segment/test/toolbar/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Segment - Toolbar</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<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>
</head>

<body onload="listenForEvent()">
<ion-app>
<ion-toolbar>
<ion-segment value="a">
<ion-segment-button value="a">
<ion-label>First</ion-label>
</ion-segment-button>
<ion-segment-button value="b">
<ion-label>Second</ion-label>
</ion-segment-button>
<ion-segment-button value="c">
<ion-label>Third</ion-label>
</ion-segment-button>
</ion-segment>
<ion-buttons slot="start">
<ion-button id="button" color="primary" fill="solid"> Start </ion-button>
</ion-buttons>
</ion-toolbar>

<ion-toolbar>
<ion-segment value="a">
<ion-segment-button value="a">
<ion-label>First</ion-label>
</ion-segment-button>
<ion-segment-button value="b">
<ion-label>Second</ion-label>
</ion-segment-button>
<ion-segment-button value="c">
<ion-label>Third</ion-label>
</ion-segment-button>
</ion-segment>
<ion-buttons slot="end">
<ion-button id="button" color="primary" fill="solid"> End </ion-button>
</ion-buttons>
</ion-toolbar>

<ion-toolbar>
<ion-segment value="a">
<ion-segment-button value="a">
<ion-label>First</ion-label>
</ion-segment-button>
<ion-segment-button value="b">
<ion-label>Second</ion-label>
</ion-segment-button>
<ion-segment-button value="c">
<ion-label>Third</ion-label>
</ion-segment-button>
</ion-segment>
<ion-buttons slot="start">
<ion-button id="button" color="primary" fill="solid"> Start </ion-button>
</ion-buttons>
<ion-buttons slot="end">
<ion-button id="button" color="primary" fill="solid"> End </ion-button>
</ion-buttons>
</ion-toolbar>

<ion-toolbar color="primary">
<ion-segment value="a">
<ion-segment-button value="a">
<ion-label>First</ion-label>
</ion-segment-button>
<ion-segment-button value="b">
<ion-label>Second</ion-label>
</ion-segment-button>
<ion-segment-button value="c" disabled="true">
<ion-label>Third</ion-label>
</ion-segment-button>
</ion-segment>
<ion-buttons slot="secondary">
<ion-button id="button" color="primary" fill="solid"> Secondary </ion-button>
</ion-buttons>
<ion-buttons slot="primary">
<ion-button id="button" color="primary" fill="solid"> Primary </ion-button>
</ion-buttons>
</ion-toolbar>

<ion-toolbar color="light">
<ion-segment value="a">
<ion-segment-button value="a">
<ion-label>First</ion-label>
</ion-segment-button>
<ion-segment-button value="b">
<ion-label>Second</ion-label>
</ion-segment-button>
<ion-segment-button value="c" disabled="true">
<ion-label>Third</ion-label>
</ion-segment-button>
</ion-segment>
<ion-buttons slot="start">
<ion-button id="button" color="primary" fill="solid"> Start </ion-button>
</ion-buttons>
<ion-buttons slot="secondary">
<ion-button id="button" color="primary" fill="solid"> Secondary </ion-button>
</ion-buttons>
</ion-toolbar>

<ion-toolbar color="medium">
<ion-segment value="a">
<ion-segment-button value="a">
<ion-label>First</ion-label>
</ion-segment-button>
<ion-segment-button value="b">
<ion-label>Second</ion-label>
</ion-segment-button>
<ion-segment-button value="c" disabled="true">
<ion-label>Third</ion-label>
</ion-segment-button>
</ion-segment>
<ion-buttons slot="primary">
<ion-button id="button" color="primary" fill="solid"> Primary </ion-button>
</ion-buttons>
<ion-buttons slot="end">
<ion-button id="button" color="primary" fill="solid"> End </ion-button>
</ion-buttons>
</ion-toolbar>

<ion-toolbar color="dark">
<ion-segment value="a">
<ion-segment-button value="a">
<ion-label>First</ion-label>
</ion-segment-button>
<ion-segment-button value="b">
<ion-label>Second</ion-label>
</ion-segment-button>
<ion-segment-button value="c" disabled="true">
<ion-label>Third</ion-label>
</ion-segment-button>
</ion-segment>
<ion-buttons slot="start">
<ion-button id="button" color="primary" fill="solid"> Start </ion-button>
</ion-buttons>
<ion-buttons slot="secondary">
<ion-button id="button" color="primary" fill="solid"> Secondary </ion-button>
</ion-buttons>
<ion-buttons slot="primary">
<ion-button id="button" color="primary" fill="solid"> Primary </ion-button>
</ion-buttons>
<ion-buttons slot="end">
<ion-button id="button" color="primary" fill="solid"> End </ion-button>
</ion-buttons>
</ion-toolbar>
</ion-app>
</body>
</html>
2 changes: 1 addition & 1 deletion core/src/components/select/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@

var customModalSelect = document.getElementById('customModalSelect');
var customModalSheetOptions = {
header: 'Pizza Toppings',
header: 'Pizza Toppings are really long',
breakpoints: [0.5],
initialBreakpoint: 0.5,
};
Expand Down
13 changes: 0 additions & 13 deletions core/src/components/title/title.ionic.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,11 @@

:host {
@include globals.typography(globals.$ion-heading-h6-medium);
@include globals.padding(var(--padding-top), 0, var(--padding-bottom));

box-sizing: border-box;
pointer-events: none;
}

:host-context(ion-toolbar) {
@include globals.position(0, null, null, 0);
position: absolute;

width: 100%;
height: 100%;

transform: translateZ(0);

z-index: -1; // TODO(ROU-10853): replace this value with a layer token. This is here to prevent the title from blokcing interaction with buttons.
}

// Title: Large
// --------------------------------------------------

Expand Down
70 changes: 70 additions & 0 deletions core/src/components/toolbar/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,59 @@
<ion-title> Toolbar </ion-title>
</ion-toolbar>

<ion-toolbar>
<ion-buttons slot="start">
<ion-button>
<ion-icon slot="icon-only" name="person-circle"></ion-icon>
</ion-button>
<ion-button>
<ion-icon slot="icon-only" name="search"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title> Toolbar with just start button </ion-title>
</ion-toolbar>

<ion-toolbar>
<ion-buttons slot="end">
<ion-button color="secondary">
<ion-icon slot="icon-only" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title> Toolbar with just end button </ion-title>
</ion-toolbar>

<ion-toolbar>
<ion-buttons slot="start">
<ion-button>
<ion-icon slot="icon-only" name="person-circle"></ion-icon>
</ion-button>
<ion-button>
<ion-icon slot="icon-only" name="search"></ion-icon>
</ion-button>
<ion-button>
<ion-icon slot="icon-only" name="search"></ion-icon>
</ion-button>
</ion-buttons>
<ion-text slot="end"> Small </ion-text>
<ion-title> Toolbar with start content that's long and end content that's short </ion-title>
</ion-toolbar>

<ion-toolbar>
<ion-text slot="start"> Small </ion-text>
<ion-buttons slot="end">
<ion-button>
<ion-icon slot="icon-only" name="person-circle"></ion-icon>
</ion-button>
<ion-button>
<ion-icon slot="icon-only" name="search"></ion-icon>
</ion-button>
<ion-button>
<ion-icon slot="icon-only" name="search"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title> Toolbar with start content that's long and end content that's short </ion-title>
</ion-toolbar>

<ion-toolbar>
<ion-buttons slot="secondary">
<ion-button>
Expand All @@ -59,6 +112,23 @@
<ion-title> This is a long title with buttons. It just goes on and on my friend. </ion-title>
</ion-toolbar>

<ion-toolbar>
<ion-buttons slot="start">
<ion-button>
<ion-icon slot="icon-only" name="person-circle"></ion-icon>
</ion-button>
<ion-button>
<ion-icon slot="icon-only" name="search"></ion-icon>
</ion-button>
</ion-buttons>
<ion-buttons slot="end">
<ion-button color="secondary">
<ion-icon slot="icon-only" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title> This is a long title with start and end buttons. It just goes on and on my friend. </ion-title>
</ion-toolbar>

<ion-toolbar>
<ion-buttons slot="secondary">
<ion-button>
Expand Down
68 changes: 42 additions & 26 deletions core/src/components/toolbar/toolbar.ionic.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
@use "./toolbar.common";
@use "../../themes/ionic/ionic.globals.scss" as globals;

$toolbar-order-ionic: (
slot-start: 1,
slot-secondary: 2,
content: 3,
slot-primary: 4,
slot-end: 5,
);

// Ionic Toolbar
// --------------------------------------------------

Expand All @@ -31,8 +23,7 @@ $toolbar-order-ionic: (
// --------------------------------------------------

.toolbar-content {
flex: 2;
order: map-get($toolbar-order-ionic, content);
flex: 1 1 auto;

min-width: 0;
}
Expand All @@ -44,11 +35,18 @@ $toolbar-order-ionic: (
@include globals.padding(0);
}

// Toolbar: Buttons
// --------------------------------------------------

::slotted(ion-buttons) {
gap: globals.$ion-space-200;
}

// Toolbar: Title
// --------------------------------------------------

::slotted(ion-title) {
@include globals.padding-horizontal(var(--padding-top), var(--padding-end));
@include globals.padding-horizontal(globals.$ion-space-200);
}

:host(.toolbar-title-default) ::slotted(ion-title) {
Expand All @@ -61,32 +59,50 @@ $toolbar-order-ionic: (

// Ionic Toolbar Slot Placement
// --------------------------------------------------
// We're using the slots to force the main toolbar content to be
// cenetered in the toolbar. This is a bit of a hack but it works.
// The main content is placed in the center and then JavaScript evaluates
// the sizes of the different slots and sets what size the pairs should be
// based on the larger one. We then use `flex-basis` to set the expected
// size of the slots and disable `flex-shrink` so that the smaller slot cannot
// shrink and throw off the center, we also diable flex-grow so that slots do
// not grow more than they need. The slots are paired up so the mirroring slots
// always have the same size. That is, start and end are paired and primary
// and secondary are paired. All of this works together to force the main
// content to maintain the center as best as CSS allows while also allowing
// the slots and main content to have fairly dynamic widths.
// --------------------------------------------------

::slotted([slot="secondary"]) {
order: map-get($toolbar-order-ionic, slot-secondary);
}
:host(.has-end-content) slot[name="end"],
:host(.show-end) slot[name="end"] {
display: flex;

::slotted([slot="primary"]) {
order: map-get($toolbar-order-ionic, slot-primary);
flex: 0 0 var(--start-end-size, 0);
justify-content: flex-end;

text-align: end;
}

::slotted([slot="start"]) {
order: map-get($toolbar-order-ionic, slot-start);
:host(.has-start-content) slot[name="start"],
:host(.show-start) slot[name="start"] {
display: flex;

flex: 0 0 var(--start-end-size, 0);
}

::slotted([slot="start"]),
::slotted([slot="end"]) {
:host(.has-primary-content) slot[name="primary"],
:host(.show-primary) slot[name="primary"] {
display: flex;

flex: 1;
gap: globals.$ion-space-200;
flex: 0 0 var(--primary-secondary-size, 0);
justify-content: flex-end;

text-align: end;
}

::slotted([slot="end"]) {
justify-content: end;
order: map-get($toolbar-order-ionic, slot-end);
:host(.has-secondary-content) slot[name="secondary"],
:host(.show-secondary) slot[name="secondary"] {
display: flex;

font-size: globals.$ion-font-size-600;
flex: 0 0 var(--primary-secondary-size, 0);
}
Loading
Loading