From 6b781fb165917b3250a30db4e82198a4a3e05207 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:57:00 -0600
Subject: [PATCH 1/6] chore(deps): update actions/checkout action to v4
(#29047)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[](https://renovatebot.com)
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://togithub.com/actions/checkout) | action |
major | `v3` -> `v4` |
---
### Release Notes
actions/checkout (actions/checkout)
###
[`v4`](https://togithub.com/actions/checkout/blob/HEAD/CHANGELOG.md#v400)
[Compare Source](https://togithub.com/actions/checkout/compare/v3...v4)
- [Support fetching without the --progress
option](https://togithub.com/actions/checkout/pull/1067)
- [Update to node20](https://togithub.com/actions/checkout/pull/1436)
---
### Configuration
📅 **Schedule**: Branch creation - "every weekday before 11am" (UTC),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
â™» **Rebasing**: Never, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] If you want to rebase/retry this PR, check
this box
---
This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/ionic-team/ionic-framework).
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
.../build-core-stencil-prerelease/action.yml | 2 +-
.../workflows/actions/build-core/action.yml | 2 +-
.github/workflows/build.yml | 30 +++++++++----------
.github/workflows/codeql-analysis.yml | 2 +-
.github/workflows/dev-build.yml | 2 +-
.github/workflows/nightly.yml | 2 +-
.github/workflows/release-ionic.yml | 16 +++++-----
.github/workflows/release.yml | 4 +--
.github/workflows/stencil-nightly.yml | 30 +++++++++----------
.github/workflows/update-screenshots.yml | 6 ++--
10 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/.github/workflows/actions/build-core-stencil-prerelease/action.yml b/.github/workflows/actions/build-core-stencil-prerelease/action.yml
index 425ce239e1f..c584a0500a7 100644
--- a/.github/workflows/actions/build-core-stencil-prerelease/action.yml
+++ b/.github/workflows/actions/build-core-stencil-prerelease/action.yml
@@ -8,7 +8,7 @@ inputs:
runs:
using: 'composite'
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
diff --git a/.github/workflows/actions/build-core/action.yml b/.github/workflows/actions/build-core/action.yml
index b2b9fd75ed9..0d3655e60ea 100644
--- a/.github/workflows/actions/build-core/action.yml
+++ b/.github/workflows/actions/build-core/action.yml
@@ -8,7 +8,7 @@ inputs:
runs:
using: 'composite'
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2cd2a4658db..34e45952c7e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -22,7 +22,7 @@ jobs:
build-core:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-core
with:
ionicons-version: ${{ inputs.ionicons_npm_release_tag }}
@@ -31,21 +31,21 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-clean-build
test-core-lint:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-lint
test-core-spec:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-spec
test-core-screenshot:
@@ -62,7 +62,7 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -90,14 +90,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue
build-vue-router:
needs: [build-vue]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue-router
test-vue-e2e:
@@ -108,7 +108,7 @@ jobs:
needs: [build-vue, build-vue-router]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-vue-e2e
with:
app: ${{ matrix.apps }}
@@ -126,14 +126,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular
build-angular-server:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
@@ -144,7 +144,7 @@ jobs:
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-angular-e2e
with:
app: ${{ matrix.apps }}
@@ -162,14 +162,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react
build-react-router:
needs: [build-react]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react-router
test-react-router-e2e:
@@ -180,7 +180,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-router-e2e
with:
app: ${{ matrix.apps }}
@@ -202,7 +202,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-e2e
with:
app: ${{ matrix.apps }}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index adfc4529535..46a2780e789 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -14,7 +14,7 @@ jobs:
permissions:
security-events: write
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: github/codeql-action/init@v2
with:
languages: javascript
diff --git a/.github/workflows/dev-build.yml b/.github/workflows/dev-build.yml
index 2e69d9e5c46..48dc911c622 100644
--- a/.github/workflows/dev-build.yml
+++ b/.github/workflows/dev-build.yml
@@ -9,7 +9,7 @@ jobs:
outputs:
dev-hash: ${{ steps.create-dev-hash.outputs.DEV_HASH }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
# A 1 is required before the timestamp
# as lerna will fail when there is a leading 0
# See https://github.com/lerna/lerna/issues/2840
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index c728f48f16a..6f812a02f6c 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -12,7 +12,7 @@ jobs:
outputs:
nightly-hash: ${{ steps.create-nightly-hash.outputs.NIGHTLY_HASH }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
# A 1 is required before the timestamp
# as lerna will fail when there is a leading 0
# See https://github.com/lerna/lerna/issues/2840
diff --git a/.github/workflows/release-ionic.yml b/.github/workflows/release-ionic.yml
index b6be9a446b7..4532d499555 100644
--- a/.github/workflows/release-ionic.yml
+++ b/.github/workflows/release-ionic.yml
@@ -22,7 +22,7 @@ jobs:
release-core:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/publish-npm
with:
scope: '@ionic/core'
@@ -48,7 +48,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Restore @ionic/docs built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -68,7 +68,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -95,7 +95,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -121,7 +121,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -147,7 +147,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -168,7 +168,7 @@ jobs:
needs: [release-react]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -194,7 +194,7 @@ jobs:
needs: [release-vue]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e8e9711f777..c761f5b3f2f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -50,7 +50,7 @@ jobs:
needs: [release-ionic]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
token: ${{ secrets.IONITRON_TOKEN }}
fetch-depth: 0
@@ -78,7 +78,7 @@ jobs:
needs: [finalize-release]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
# Pull the latest version of the reference
# branch instead of the revision that triggered
# the workflow otherwise we won't get the commit
diff --git a/.github/workflows/stencil-nightly.yml b/.github/workflows/stencil-nightly.yml
index 01ab63bb5e5..56d3a56a714 100644
--- a/.github/workflows/stencil-nightly.yml
+++ b/.github/workflows/stencil-nightly.yml
@@ -26,7 +26,7 @@ jobs:
build-core-with-stencil-nightly:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-core-stencil-prerelease
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
@@ -35,21 +35,21 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-clean-build
test-core-lint:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-lint
test-core-spec:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-spec
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
@@ -72,7 +72,7 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -100,14 +100,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue
build-vue-router:
needs: [build-vue]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue-router
test-vue-e2e:
@@ -118,7 +118,7 @@ jobs:
needs: [build-vue, build-vue-router]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-vue-e2e
with:
app: ${{ matrix.apps }}
@@ -136,14 +136,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular
build-angular-server:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
@@ -154,7 +154,7 @@ jobs:
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-angular-e2e
with:
app: ${{ matrix.apps }}
@@ -172,14 +172,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react
build-react-router:
needs: [build-react]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react-router
test-react-router-e2e:
@@ -190,7 +190,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-router-e2e
with:
app: ${{ matrix.apps }}
@@ -212,7 +212,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-e2e
with:
app: ${{ matrix.apps }}
diff --git a/.github/workflows/update-screenshots.yml b/.github/workflows/update-screenshots.yml
index b78a13c42a6..bce7f324f2b 100644
--- a/.github/workflows/update-screenshots.yml
+++ b/.github/workflows/update-screenshots.yml
@@ -12,7 +12,7 @@ jobs:
build-core:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-core
test-core-screenshot:
@@ -33,7 +33,7 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -45,7 +45,7 @@ jobs:
runs-on: ubuntu-latest
needs: [test-core-screenshot]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
# Normally, we could just push with the
# default GITHUB_TOKEN, but that will
# not cause the build workflow
From 1fc4b76f5940b38fd89e19561d6b4738dfb8ae5d Mon Sep 17 00:00:00 2001
From: Liam DeBeasi
Date: Wed, 14 Feb 2024 12:19:23 -0500
Subject: [PATCH 2/6] fix(label): do not grow when in end slot (#29036)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Issue number: resolves #29033
---------
## What is the current behavior?
In https://github.com/ionic-team/ionic-framework/pull/28773 I resolved
several incorrect behaviors with Items related to text wrapping.
However, it looks like I missed the removal of
https://github.com/ionic-team/ionic-framework/pull/28146/files#diff-4a1156704dbf45b0dad273b6909b190ca45e4380aa7378ba88d0dd7d48d7d473R37
which caused the issue to persist when adding a label to the end slot.
## What is the new behavior?
- Removed logic that caused `ion-label` to grow larger than it needed to
be
| `main` | branch |
| - | - |
| 
| 
|
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
Dev build: `7.7.2-dev.11707840956.16e27b4c`
---------
Co-authored-by: ionitron
---
core/src/components/label/label.scss | 8 ------
.../components/label/test/item/item.e2e.ts | 27 ++++++++++++++++++
...label-item-ios-ltr-Mobile-Chrome-linux.png | Bin 0 -> 2629 bytes
...abel-item-ios-ltr-Mobile-Firefox-linux.png | Bin 0 -> 2817 bytes
...label-item-ios-ltr-Mobile-Safari-linux.png | Bin 0 -> 2366 bytes
.../label-item-md-ltr-Mobile-Chrome-linux.png | Bin 0 -> 2545 bytes
...label-item-md-ltr-Mobile-Firefox-linux.png | Bin 0 -> 2659 bytes
.../label-item-md-ltr-Mobile-Safari-linux.png | Bin 0 -> 2171 bytes
8 files changed, 27 insertions(+), 8 deletions(-)
create mode 100644 core/src/components/label/test/item/item.e2e.ts
create mode 100644 core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-ios-ltr-Mobile-Chrome-linux.png
create mode 100644 core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-ios-ltr-Mobile-Firefox-linux.png
create mode 100644 core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-ios-ltr-Mobile-Safari-linux.png
create mode 100644 core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-md-ltr-Mobile-Chrome-linux.png
create mode 100644 core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-md-ltr-Mobile-Firefox-linux.png
create mode 100644 core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-md-ltr-Mobile-Safari-linux.png
diff --git a/core/src/components/label/label.scss b/core/src/components/label/label.scss
index ff3e372bf50..fc197ef171d 100644
--- a/core/src/components/label/label.scss
+++ b/core/src/components/label/label.scss
@@ -29,14 +29,6 @@
overflow: hidden;
}
-// TODO(FW-5289): move to :host-context(.item)
-// Shouldn't need :not(.item-input) as this was
-// only needed because of the specificity with
-// :not(.item-legacy)
-:host-context(.item:not(.item-input):not(.item-legacy)) {
- flex-grow: 1;
-}
-
:host(.ion-color) {
color: current-color(base);
}
diff --git a/core/src/components/label/test/item/item.e2e.ts b/core/src/components/label/test/item/item.e2e.ts
new file mode 100644
index 00000000000..aa14200707a
--- /dev/null
+++ b/core/src/components/label/test/item/item.e2e.ts
@@ -0,0 +1,27 @@
+import { expect } from '@playwright/test';
+import { configs, test } from '@utils/test/playwright';
+
+configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
+ test.describe(title('label: in item'), () => {
+ test('should render correctly in an item', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/29033',
+ });
+ await page.setContent(
+ `
+
+ Start
+ Default
+ End
+
+ `,
+ config
+ );
+
+ const item = page.locator('ion-item');
+
+ await expect(item).toHaveScreenshot(screenshot(`label-item`));
+ });
+ });
+});
diff --git a/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-ios-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 0000000000000000000000000000000000000000..22bb5edec93eb30b1b269ab2f6824dcfc239f100
GIT binary patch
literal 2629
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
literal 0
HcmV?d00001
diff --git a/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-ios-ltr-Mobile-Safari-linux.png b/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-ios-ltr-Mobile-Safari-linux.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee38a59023374b519404691d4c268193ff7ce44c
GIT binary patch
literal 2366
zcmbuBhgVa}7KZ~DA%-ZC5;0N~X(A|13`o%!dNma3NI*a#Vo*>nU?V{g4T1(V5qVrG
zf=Hw#bkNXC=tLl>B!(JnfIw*Xyno@nnYGT@`^-9fW`6tIvnIvG$$Ae20Re$Pdu(mc
z7!XJ#39z-nqQLXJbTSEeiDT`p(V(6G_Wv{#J_UimOSb54MY%>Q9_+}Vx+U0ht4pGU~cA0q96LIsP92cT``R&U0lBqX@H
zK1JoeXD}>c1kYc+dPT>IhW8{&Na^eA58Dd_0x{8hb#)t<+CCObxV~QIS<=#imXVQp
z%!EORLqkI?WoVU}D1KMIeO6Cz?@6U=E8fT>;M|gulH}xM{@#^eJZqrov=X0$D080K
zZg=
zN=lZNmiBYU;Hf|)V9Lb%_h)a^dT`S_gQb+spLGU%AHbbd2_@v6H5bYl+S;Cq{9IC6
zTKeuC4u@NuorR^g-Y_xK)J%TkHxubY#Rfe{geib9i`|5&5NKhp3
zn8u2RU)rj^y(R4Eu(7n_Zv|a<>W>_f4)7#Qna>iPf8LexBx=oa5|_rbUMAh
z-nYn2h0xX26%i2ufk3={d}O4hfy7!_S#<;kG{)QdTWZPzj+2v9aX>AAQi227ZiUAA
zRh&*HtHHpgW@h$wc3Q`dHPqLy#hag3gQxoW`SG}13WdVu@y?-8)6>(HanX){G8`No
zk7;S4RR&nur&FYjsJ$T-0~Q)or$Pw{iG{g2GMSu>#D8S5NS(nDF;VlJFC0$&rEWOE
z#ls^rH#aaS=rxf@%*xtN;z`zpFZzp+KaGzM&fUm$v3coVe+z&0s*|QH;FIm-U@#aQ
zKFZ-JAP|3lZN4{IcQZ6J^fVF)d%Uo);EKWAGF3v&PB0?jaCn-s1+X=LZhqfOW8VC{
zNo3E8)$y#EnVGj)Vq#(uoa%JsaUC7p<;!JNRhD2iRaH(k{)n2I<%J7b-TY#=;y-_4
zfJ`W~_vKi8VY3VQ9Y6Wu;o$~)dbtB(=H}+c#>R<>iAz`Zp#a>1JBgC}0g>>gMn(lR
z+MUJmliX*_DR~5fURkL7@*^Y}FdMp@ZzDJg(+rtV*VC4T&fDu1}vJv=dy
zdLq!ax~}d4fdFdmf5+v#Z8Uh#Ga{Z
z@$vB;Z2&Xpz$vX*D06vb1#s*=I{8t4ev`|~H+0$xI_p#=Bpv`na5$WdjEw$%7Xs`7
zb01jD$jHb7N87G?TUMq=?fpJCci5h!V9fpYE$^)SMR%rdNmJ9Ec9J6aa0*)g5*SbCz}o9!OcBAkJ@>^Zq*MA49xW96c!Xj
zAz!jsPJlYZ$NK}$0E8mi_IgyT{`k_@(*w()CR^rYX2$&ddUnOgB0d~Vqoxz9$2eQrLJQ_rj0>71w-ZU9Cz*5xJ)rTcV7)e#w{4_fNUMn=()6;WpeLX?A
zoWfaB--;2r7abN6p>1R|IySccbBYN*Y?93i*5BCJSQU(&Gki{=%r7pEu-O5hR+nb_
zCMPGy#>UVAWILcFytLuxyD#eIVUCVfS5-x)>vsJ3(TvfRhe}GO0=36$Pm@t|baV^~
z3L0_+?LrtB8+-ZrJ%$Olx8lOX
z7l89v7aF%RPbRT;8khJ{HGoLk@a~BTA8mMhYwKeYiOyi0P>h>UK2BcJX?Yn9o|~P0KPF()0$%6fB6&y_KkBj}0u_eEa-DZ1T^DD(E_TA2XGZUDxnrlu?m*Tj8?
zW=?2mXjrPGV~Q&2bfB*M*QUcmLXtR=E=6vbqG1l_W&G>L>exvU&;nul=xz|Ga_{XE
zyFq6TKgj@rWJQ55|Fd~)E7u1EU&TSUvs~UocXqKMIp4a9L^Xj65y;lk30;c1c>iBQ
Cu6MBj
literal 0
HcmV?d00001
diff --git a/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-md-ltr-Mobile-Chrome-linux.png b/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-md-ltr-Mobile-Chrome-linux.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf3c72e7a56c314454c877a01fcf4e25707b0fcd
GIT binary patch
literal 2545
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
literal 0
HcmV?d00001
diff --git a/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-md-ltr-Mobile-Safari-linux.png b/core/src/components/label/test/item/item.e2e.ts-snapshots/label-item-md-ltr-Mobile-Safari-linux.png
new file mode 100644
index 0000000000000000000000000000000000000000..571d817f73063b9ff6a85340a185203b5cab8d18
GIT binary patch
literal 2171
zcmb_eXH=6*8vank5DDbcRRk156Sx$ON)ZSxNYlVdkRsj#iV#o%X%XYHL_pfb9EgF7
zsN8@M0+LV+3W|V$k!~o`6-ba05fc;Ye(b;fv%mJ4b7tn8nKSd2d7gLD&wDt-pogFU
z0Ki<(4j2HCxDU=vAbY^RKg)jQ?6xOOWh4NAn7BCDdB^{?Jb_1h@iq2;
z?~O^Id^Wu1S5+#NXZDFmb_!u;#Ji+Da^L^pk};}HhYcUDJ(!Z2`>1pl;b?>jMxfR^
zK5WCO4wz>t4?i)`u#~@`Y&BmnnO+8Y1iUfN=N%eFaL3^cvz$u$Lt`u^*zDuh)>~T}
zzib9_HPb|*cp&upbr%nh`ouk`rzS|`(6^NxgSAGifu0_g<2W0|B9qBVC4+R{UclYm
z{SsZ+o}m(B5uhzU$K`H_#lCU+wU1ZhUoQ?<7rK?s%*-4<70HWfOqJ7E7l|sz!-Io^
zgMyxvm+MM6Fd
zv9$CH3^Z1RzG`gT+}fJa%~$@_W-+-72UCOaA?GeWJXi-E=YFEF<-Gfa>b`
z*lJ;6!Bho_M6Qd)XHK6MZEQ5u*YB~7jjgxU1n$|V%JzrWg4P3%D3q?w&gm#tc6PRe
zghU*F^5o?f4oC2%J!5{b^FMI3XJQR0Zc;!YGU6N>Eh;LGiuii-v_YPMmR4(bclX4E
zwUN>CSi_Cryslu3LEg&BN>5J@raUGpYM}9GWxDpiT3&>(mDkEkN=h!#Wu>M6IhP+x
zYl=V4P
zXGfdVbt3#qWMq#&l@n%jcN2Tz!mV$g${7qsMTG%l^BafeQ{|tYlT%Hn-;R!^(P+#l
z+#dokBg@On;bCFQApRlv^{bF91ih5BQ?rc4Z3veI0s*)l#rn&m?3YmZFl!Wt%yJ^J
z=U^}x=uw8nGs0u6;ryC71A0)#DK-{q2iGB`v**rf%QMD9Ppo{dJB~mQHPgyGi}%>#
z@vm6qz-of{2UYxu!>N1n#ODJcOaXU>RSZN3y}
zD`%)sQ_$MSXd^gbu9mZ#jzWR~9MZY3ptv|LF3!`i1(b3V`x)->Ul+@*nqEIMS>NmJOMF3n``J$KC;LwmV
z9Bx}rK1U@IiLq|;YkS0yYpPHJOXu?(Z_4N%5
z3|Pjk$iQF+W$rI5T&LYog9Gt+{P56FfhWbSRE*Vx|9LogVY7u
zrML~IC$*RR``E23S6c3zGBq&?5*M9LZ8g2&1Bk#^&nOui8F@>%yw)GK8gGRxqz^B4
zBfyjo1%z>?5D_CUo<4t`#-6(x5<)r9@&3K4j8p=SRePMD=Xlez(!SV+FtjLeDp>_t
z(B9te<>h5jlwHXH&8Bgn#CO4Fj*gC5IXN_MgBtAXpINFI?NBK61DmY{c^707dZIuq
z7LShlGLTkQuNe$86O+Ey)~`c!zoeuj_T=U7@m7GIzP_}aoC=iqX3f4@g2`k?L`38x
zCMPFf#qqZT@qT_|2ULuApX5l5y|(;yX1BBUC}$!+7Vg_uz=VJ5Wfz-KB9v
zPft(v;K7#VQ&v`LN=hNV&(7r7Lyvd8W=5%~
zr~q$Mm3cqkU1)D_Uszb!UFTGC;aIMTYNq+M9=PP{x?r)h6RoSO>*?7G#w^_d)!c!A
zBzIpuuK0j|+W|ti7tP9n
Date: Wed, 14 Feb 2024 12:33:11 -0500
Subject: [PATCH 3/6] fix(overlays): focus is returned to last focus element
when focusing toast (#28950)
Issue number: resolves #28261
---------
## What is the current behavior?
When moving focus from a focus-trapped overlay to a toast, focus is
moved back to the overlay. This is the correct behavior as focus should
never leave a focus-trapped overlay (unless the overlay is dismissed or
focus is moved to a _new_ top-most overlay). However, the way we return
focus is a bit unexpected because it always returns focus to the last
focusable element in the overlay.
This means that if you were focused on the first focusable element,
presented the toast, and then focused the toast, focus might not be
moved back to that first focusable element. In the case of the linked
issue, this was causing an unexpected scroll so that the last focused
element could be in view.
## What is the new behavior?
- This fix adds an exception for `ion-toast` (as it is the only overlay
that is **not** focus trapped) that ensures that focus is moved back to
the last focus element.
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
Dev build: `7.7.1-dev.11707253408.186eea70`
Note: We don't recommend this pattern in general because it would be
impossible for a screen reader user to focus the toast. However, we can
at least improve the experience for developers who continue to implement
this pattern by returning focus in a more predictable manner.
Docs: https://github.com/ionic-team/ionic-docs/pull/3432
Testing:
Reviewers should manually test the following behaviors:
1. Create a modal with 2 buttons. Have one of the buttons present a
toast. Open the toast and verify that you can still Tab to cycle through
the buttons in the modal.
2. Create a modal with 2 buttons. Have one of the buttons present a
toast. Open the toast. Move focus to the toast and verify that you can
still Tab to cycle through the buttons in the modal (once focus is
returned to the modal).
---
core/src/components/select/select.tsx | 6 +-
core/src/utils/helpers.ts | 2 +-
core/src/utils/overlays.ts | 93 ++++++++++----
core/src/utils/test/overlays/overlays.e2e.ts | 120 +++++++++++++++++++
4 files changed, 196 insertions(+), 25 deletions(-)
diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx
index 9fe26349bb1..e15ae27e653 100644
--- a/core/src/components/select/select.tsx
+++ b/core/src/components/select/select.tsx
@@ -2,7 +2,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Element, Event, Host, Method, Prop, State, Watch, h, forceUpdate } from '@stencil/core';
import type { LegacyFormController, NotchController } from '@utils/forms';
import { compareOptions, createLegacyFormController, createNotchController, isOptionSelected } from '@utils/forms';
-import { findItemLabel, focusElement, getAriaLabel, renderHiddenInput, inheritAttributes } from '@utils/helpers';
+import { findItemLabel, focusVisibleElement, getAriaLabel, renderHiddenInput, inheritAttributes } from '@utils/helpers';
import type { Attributes } from '@utils/helpers';
import { printIonWarning } from '@utils/logging';
import { actionSheetController, alertController, popoverController } from '@utils/overlays';
@@ -329,7 +329,7 @@ export class Select implements ComponentInterface {
);
if (selectedItem) {
- focusElement(selectedItem);
+ focusVisibleElement(selectedItem);
/**
* Browsers such as Firefox do not
@@ -355,7 +355,7 @@ export class Select implements ComponentInterface {
'ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)'
);
if (firstEnabledOption) {
- focusElement(firstEnabledOption.closest('ion-item')!);
+ focusVisibleElement(firstEnabledOption.closest('ion-item')!);
/**
* Focus the option for the same reason as we do above.
diff --git a/core/src/utils/helpers.ts b/core/src/utils/helpers.ts
index 3dff5a5e657..81ffb4efa92 100644
--- a/core/src/utils/helpers.ts
+++ b/core/src/utils/helpers.ts
@@ -262,7 +262,7 @@ export const findItemLabel = (componentEl: HTMLElement): HTMLIonLabelElement | n
return null;
};
-export const focusElement = (el: HTMLElement) => {
+export const focusVisibleElement = (el: HTMLElement) => {
el.focus();
/**
diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts
index 8ccb015d8d8..11ec2f56698 100644
--- a/core/src/utils/overlays.ts
+++ b/core/src/utils/overlays.ts
@@ -22,7 +22,13 @@ import type {
import { CoreDelegate } from './framework-delegate';
import { OVERLAY_BACK_BUTTON_PRIORITY } from './hardware-back-button';
-import { addEventListener, componentOnReady, focusElement, getElementRoot, removeEventListener } from './helpers';
+import {
+ addEventListener,
+ componentOnReady,
+ focusVisibleElement,
+ getElementRoot,
+ removeEventListener,
+} from './helpers';
import { printIonWarning } from './logging';
let lastOverlayIndex = 0;
@@ -131,38 +137,55 @@ export const createOverlay = (
*/
const focusableQueryString =
'[tabindex]:not([tabindex^="-"]):not([hidden]):not([disabled]), input:not([type=hidden]):not([tabindex^="-"]):not([hidden]):not([disabled]), textarea:not([tabindex^="-"]):not([hidden]):not([disabled]), button:not([tabindex^="-"]):not([hidden]):not([disabled]), select:not([tabindex^="-"]):not([hidden]):not([disabled]), .ion-focusable:not([tabindex^="-"]):not([hidden]):not([disabled]), .ion-focusable[disabled="false"]:not([tabindex^="-"]):not([hidden])';
+const isOverlayHidden = (overlay: Element) => overlay.classList.contains('overlay-hidden');
+/**
+ * Focuses the first descendant in an overlay
+ * that can receive focus. If none exists,
+ * the entire overlay will be focused.
+ */
export const focusFirstDescendant = (ref: Element, overlay: HTMLIonOverlayElement) => {
- let firstInput = ref.querySelector(focusableQueryString) as HTMLElement | null;
-
- const shadowRoot = firstInput?.shadowRoot;
- if (shadowRoot) {
- // If there are no inner focusable elements, just focus the host element.
- firstInput = shadowRoot.querySelector(focusableQueryString) || firstInput;
- }
+ const firstInput = ref.querySelector(focusableQueryString) as HTMLElement | null;
- if (firstInput) {
- focusElement(firstInput);
- } else {
- // Focus overlay instead of letting focus escape
- overlay.focus();
- }
+ focusElementInOverlay(firstInput, overlay);
};
-const isOverlayHidden = (overlay: Element) => overlay.classList.contains('overlay-hidden');
-
+/**
+ * Focuses the last descendant in an overlay
+ * that can receive focus. If none exists,
+ * the entire overlay will be focused.
+ */
const focusLastDescendant = (ref: Element, overlay: HTMLIonOverlayElement) => {
const inputs = Array.from(ref.querySelectorAll(focusableQueryString)) as HTMLElement[];
- let lastInput = inputs.length > 0 ? inputs[inputs.length - 1] : null;
+ const lastInput = inputs.length > 0 ? inputs[inputs.length - 1] : null;
+
+ focusElementInOverlay(lastInput, overlay);
+};
+
+/**
+ * Focuses a particular element in an overlay. If the element
+ * doesn't have anything focusable associated with it then
+ * the overlay itself will be focused.
+ * This should be used instead of the focus() method
+ * on most elements because the focusable element
+ * may not be the host element.
+ *
+ * For example, if an ion-button should be focused
+ * then we should actually focus the native