Skip to content

chore(git): sync next#31179

Merged
thetaPC merged 31 commits into
ionic-modularfrom
chore-sync-modular-with-next
May 29, 2026
Merged

chore(git): sync next#31179
thetaPC merged 31 commits into
ionic-modularfrom
chore-sync-modular-with-next

Conversation

@thetaPC

@thetaPC thetaPC commented May 28, 2026

Copy link
Copy Markdown
Contributor

Syncing with next

thetaPC and others added 29 commits May 6, 2026 22:14
…sion (#31110)

Issue number: N/A

---------

## What is the current behavior?

When passing a Playwright flag with a space in its value (e.g.
`--project='Mobile Safari'`), the shell strips the quotes before Node
receives the argument. Since `docker.mjs` passed args to `execa` with
`shell: true`, the unquoted space caused the argument to be split and
Playwright never received the correct value.

Additionally, arguments like `-e DISPLAY=${display}`, `-v
${displayVolume}`, and `--mount` were constructed as combined strings
and passed through shell interpretation, meaning special characters in
those values (e.g. spaces in an absolute path) could cause the command
to fail unexpectedly. This caused CodeQL to trigger with security
issues.

## What is the new behavior?

Each Docker argument is now passed as a separate array element to
`execa` without `shell: true`, so values are forwarded directly to
Docker without shell re-interpretation. This preserves spaces within
argument values (e.g. `--project='Mobile Safari'`) and prevents
uncontrolled expansion of paths and environment variable values.

The security issues stated by CodeQL has been addressed.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

Verify that the following command works: `npm run test.e2e.docker
datetime/test/basic -- -g 'IO fallback' --project='Mobile Safari'
--repeat-each=20`
…le (#31114)

Issue number: N/A

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

We've decided to use `internal` as the prefix for internal CSS variables
and `ion` for public variables. We recently introduced a new internal
variable for the safe area that doesn't have the correct prefix.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Updated `--ion-content-safe-area-padding-bottom` to
`--internal-content-safe-area-padding-bottom`

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

N/A
)

Issue number: resolves #30412

---------
## What is the current behavior?

When a user listener bound to `ion-input` or `ion-item` receives a tap
that requires scroll assist to scroll the input into view, the click
handler fires twice. Programmatic `setFocus()` and keyboard focus into
an offscreen input also dispatch a phantom click event the developer
didn't request.

The cause is `scroll-assist.ts`: after `relocateInput` moves the native
input, a RAF-scheduled `componentEl.click()` re-emits a click on the
host. That recovery was added in #22845 (Feb 2021) to fix #21871, when
scroll assist drove focus from its own touchstart/touchend listeners and
`relocateInput` ran during the in-flight click event's lifecycle.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

The RAF recovery click is removed. #25848 (Sep 2022) restructured scroll
assist to react to `focusin` rather than drive focus from touch events,
so `relocateInput` now runs strictly after the click event has finished
propagating. Combined with `ion-input`'s click capture handler and
`ion-item`'s click-on-padding handler from #30373 (April 2025), the
click is always dispatched on the component host before scroll assist
runs. Re-firing it produced duplicate clicks for user interactions and
phantom clicks for programmatic and keyboard focus.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information


Regression coverage in
`core/src/components/input/test/item/scroll-assist-double-click.e2e.ts`
covers four cases on iOS Mobile Safari and Mobile Chrome: padding click,
direct input click, programmatic `setFocus()`, and keyboard focus. The
first two assert one click event; the last two assert zero. All four
fail without this change and pass with it.

Preview:
-
https://ionic-framework-git-fw-6540-ionic1.vercel.app/src/utils/input-shims/hacks/test?ionic:mode=ios
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@capacitor/core](https://capacitorjs.com)
([source](https://redirect.github.com/ionic-team/capacitor)) | [`8.3.1`
→
`8.3.2`](https://renovatebot.com/diffs/npm/@capacitor%2fcore/8.3.1/8.3.2)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@capacitor%2fcore/8.3.2?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@capacitor%2fcore/8.3.1/8.3.2?slim=true)
|

---

### Release Notes

<details>
<summary>ionic-team/capacitor (@&#8203;capacitor/core)</summary>

###
[`v8.3.2`](https://redirect.github.com/ionic-team/capacitor/blob/HEAD/CHANGELOG.md#832-2026-05-07)

[Compare
Source](https://redirect.github.com/ionic-team/capacitor/compare/8.3.1...8.3.2)

##### Bug Fixes

- **cli:** add cSettings support for compiler flags in generated
Package.swift
([#&#8203;8448](https://redirect.github.com/ionic-team/capacitor/issues/8448))
([0bd0676](https://redirect.github.com/ionic-team/capacitor/commit/0bd0676315c5fd77e50312dd7b5bf4990dcbd7d0))
- **cli:** add system framework and weak framework support in SPM
Package.swift
([#&#8203;8447](https://redirect.github.com/ionic-team/capacitor/issues/8447))
([3232f0f](https://redirect.github.com/ionic-team/capacitor/commit/3232f0fe1d9811b0b5c500e3dc05cb8a250177f8))
- **cli:** correct Capacitor plugin SPM compat check
([#&#8203;8440](https://redirect.github.com/ionic-team/capacitor/issues/8440))
([e5ccc45](https://redirect.github.com/ionic-team/capacitor/commit/e5ccc451dda27d56bca824ed644bd20fe4d988cb))
- **cli:** generate binaryTarget entries for custom xcframeworks in
Package.swift
([#&#8203;8445](https://redirect.github.com/ionic-team/capacitor/issues/8445))
([1f7e33f](https://redirect.github.com/ionic-team/capacitor/commit/1f7e33fca43d183332ec19d22b0d75ef81d8cc6d))
- **cli:** generate resource entries in Package.swift
([#&#8203;8455](https://redirect.github.com/ionic-team/capacitor/issues/8455))
([790bd27](https://redirect.github.com/ionic-team/capacitor/commit/790bd27123497111984227010c3162cec94a108e))
- **cli:** handle Cordova plugins without iOS source files
([#&#8203;8443](https://redirect.github.com/ionic-team/capacitor/issues/8443))
([0da130e](https://redirect.github.com/ionic-team/capacitor/commit/0da130eb7a861bee4e2c35bc0aac53ba9c983fc3))
- **cli:** link plugin dependencies in Package.swift
([#&#8203;8457](https://redirect.github.com/ionic-team/capacitor/issues/8457))
([b3c769e](https://redirect.github.com/ionic-team/capacitor/commit/b3c769e856c826b1174518877cf86ac7ce73bf09))
- **ios:** support Cordova plugins with Package.swift
([#&#8203;8438](https://redirect.github.com/ionic-team/capacitor/issues/8438))
([139943b](https://redirect.github.com/ionic-team/capacitor/commit/139943b0c05fddb2d1ce2d6f468800fddf17b4cf))
- **SystemBars:** avoid extra view padding on API <= 34
([#&#8203;8439](https://redirect.github.com/ionic-team/capacitor/issues/8439))
([5b135a7](https://redirect.github.com/ionic-team/capacitor/commit/5b135a70217be560e7176c8d5b514cc92ed3e4e4))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - "every weekday before 11am"
- 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.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/ionic-team/ionic-framework).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Issue number: internal

---------

## What is the current behavior?

When an `ion-alert` has two buttons whose combined text is too long to
fit on one row, flex-wrap pushes the second button onto a new row. The
horizontal layout's right border (drawn between buttons via
`alert.ios.scss`) stays on the first button, leaving a stray vertical
separator at the wrap edge. The `alert-button-group-vertical` class only
triggers on `buttons.length > 2`, so two-button alerts can't opt into
the clean vertical layout even when they visually need it.

## What is the new behavior?

The alert now watches its button group with a `ResizeObserver` and
toggles `alert-button-group-vertical` whenever the buttons render at
different `offsetTop` values, so wrapping two-button alerts get the same
vertical treatment as three-or-more-button alerts. The wrap state resets
when the `buttons` prop changes so a new button set is re-evaluated from
scratch, and the observer is re-attached in `connectedCallback` so
reconnected alerts keep working. The layout read is deferred via `raf`
to avoid forcing synchronous layout and to sidestep `ResizeObserver`
loop warnings.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

The right-border styling between buttons only exists in iOS mode, so the
new e2e test is iOS only

Preview:
- iOS:
https://ionic-framework-git-fw-7244-ionic1.vercel.app/src/components/alert/test/basic?ionic:mode=ios

A lot of the updated screenshots are because of the new alert button. We
should probably make note of these to go back and update the tests so
they focus on the modal and don't include the background to prevent this
sort of update spam in the future.

---------

Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@capacitor/core](https://capacitorjs.com)
([source](https://redirect.github.com/ionic-team/capacitor)) | [`8.3.2`
→
`8.3.3`](https://renovatebot.com/diffs/npm/@capacitor%2fcore/8.3.2/8.3.3)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@capacitor%2fcore/8.3.3?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@capacitor%2fcore/8.3.2/8.3.3?slim=true)
|

---

### Release Notes

<details>
<summary>ionic-team/capacitor (@&#8203;capacitor/core)</summary>

###
[`v8.3.3`](https://redirect.github.com/ionic-team/capacitor/blob/HEAD/CHANGELOG.md#833-2026-05-08)

[Compare
Source](https://redirect.github.com/ionic-team/capacitor/compare/8.3.2...8.3.3)

##### Bug Fixes

- **cli:** copy plugin files in CocoaPods projects
([#&#8203;8467](https://redirect.github.com/ionic-team/capacitor/issues/8467))
([b2d7719](https://redirect.github.com/ionic-team/capacitor/commit/b2d771926a180e60deea31992d7d4abcd5ca3bc7))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - "every weekday before 11am"
- 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.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/ionic-team/ionic-framework).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) | Type |
Update |
|---|---|---|---|---|---|
|
[@axe-core/playwright](https://redirect.github.com/dequelabs/axe-core-npm)
| [`^4.11.1` →
`^4.11.3`](https://renovatebot.com/diffs/npm/@axe-core%2fplaywright/4.11.1/4.11.3)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@axe-core%2fplaywright/4.11.3?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@axe-core%2fplaywright/4.11.1/4.11.3?slim=true)
| devDependencies | patch |
| [@playwright/test](https://playwright.dev)
([source](https://redirect.github.com/microsoft/playwright)) |
[`^1.58.2` →
`^1.59.1`](https://renovatebot.com/diffs/npm/@playwright%2ftest/1.58.2/1.59.1)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@playwright%2ftest/1.59.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@playwright%2ftest/1.58.2/1.59.1?slim=true)
| devDependencies | minor |
| mcr.microsoft.com/playwright | `v1.58.2` → `v1.59.1` |
![age](https://developer.mend.io/api/mc/badges/age/docker/mcr.microsoft.com%2fplaywright/v1.59.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/docker/mcr.microsoft.com%2fplaywright/v1.58.2/v1.59.1?slim=true)
| final | minor |

---

### Release Notes

<details>
<summary>dequelabs/axe-core-npm (@&#8203;axe-core/playwright)</summary>

###
[`v4.11.3`](https://redirect.github.com/dequelabs/axe-core-npm/compare/v4.11.2...25fbfd2a7b4d38fcdca487d393192e811592f1ec)

[Compare
Source](https://redirect.github.com/dequelabs/axe-core-npm/compare/v4.11.2...v4.11.3)

###
[`v4.11.2`](https://redirect.github.com/dequelabs/axe-core-npm/releases/tag/v4.11.2):
Release 4.11.2

[Compare
Source](https://redirect.github.com/dequelabs/axe-core-npm/compare/v4.11.1...v4.11.2)

##### Bug Fixes

- Update axe-core to v4.11.3
([#&#8203;1306](https://redirect.github.com/dequelabs/axe-core-npm/issues/1306))
([71c4179](https://redirect.github.com/dequelabs/axe-core-npm/commit/71c41796f4cdf2aebcb5e49d1bf6896f4ad72a2a))
- **wdio:** support v9 wdio switchFrame and switchWindow
([#&#8203;1302](https://redirect.github.com/dequelabs/axe-core-npm/issues/1302))
([4689273](https://redirect.github.com/dequelabs/axe-core-npm/commit/4689273aead05133e161fe1d419a60224763ed7c)),
closes
[#&#8203;1164](https://redirect.github.com/dequelabs/axe-core-npm/issues/1164)

</details>

<details>
<summary>microsoft/playwright (@&#8203;playwright/test)</summary>

###
[`v1.59.1`](https://redirect.github.com/microsoft/playwright/compare/v1.59.0...d466ac5358cae058cdc75d2ae3ab3ad220042730)

[Compare
Source](https://redirect.github.com/microsoft/playwright/compare/v1.59.0...v1.59.1)

###
[`v1.59.0`](https://redirect.github.com/microsoft/playwright/compare/v1.58.2...01b2b1533e0bfa1c582117e3ec109fcb57657747)

[Compare
Source](https://redirect.github.com/microsoft/playwright/compare/v1.58.2...v1.59.0)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - "every weekday before 11am"
- 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.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/ionic-team/ionic-framework).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
Issue number: resolves internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
The `item-sliding`has the same animations for md, iOS and Ionic

## What is the new behavior?
New animations were added for the Ionic theme, including:

- Animation for opening the `item-sliding`
- Animation for closing the `item-sliding`
- Animation for expandable options

New conditions were also included to ensure a smoother experience:

- Closing  `item-sliding` by exceeding velocity
- Selecting an extendable option by exceeding the velocity when options
are visible
- Rubber effect  when selecting the option


## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

---------

Co-authored-by: Susmita Bhowmik <susmita.bhowmik@outsystems.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@capacitor/core](https://capacitorjs.com)
([source](https://redirect.github.com/ionic-team/capacitor)) | [`8.3.3`
→
`8.3.4`](https://renovatebot.com/diffs/npm/@capacitor%2fcore/8.3.3/8.3.4)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@capacitor%2fcore/8.3.4?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@capacitor%2fcore/8.3.3/8.3.4?slim=true)
|

---

### Release Notes

<details>
<summary>ionic-team/capacitor (@&#8203;capacitor/core)</summary>

###
[`v8.3.4`](https://redirect.github.com/ionic-team/capacitor/blob/HEAD/CHANGELOG.md#834-2026-05-12)

[Compare
Source](https://redirect.github.com/ionic-team/capacitor/compare/8.3.3...8.3.4)

**Note:** Version bump only for package capacitor

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - "every weekday before 11am"
- 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.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/ionic-team/ionic-framework).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzMuNiIsInVwZGF0ZWRJblZlciI6IjQzLjE3My42IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
### Features

- `layout` property:
  - `uniform` - evenly sized grid rows
  - `masonry` - stacked masonry layout
- `order` property (`masonry` only):
  - `sequential` - preserves DOM order
  - `best-fit` - places items in the shortest column
- `columns` property:
  - Accepts number or string values
  - Supports responsive values by breakpoint (`xs`, `sm`, `md`, `lg`, `xl`, `xxl`)
  - Validates invalid inputs and falls back to defaults with `printIonWarning`
  - Breakpoint objects with no `xs`–`xxl` values (e.g. `{}` or only mistyped keys) are treated as invalid and warned
- `gap` property:
  - Same validation and warning behavior as `columns` for scalar values and breakpoint maps (including empty / non-matching maps)

### Test Coverage

- E2E (basic): uniform layout with images, including breakpoint screenshots
- E2E (layout): uniform and masonry layouts across various div and image scenarios
- Spec tests
  - `columns` / `gap` fallback, normalization, and invalid breakpoint maps (including empty objects and maps with only unrecognized keys)
  - `layout` / masonry scheduling and load-event behavior
  - `order` placement logic (`sequential` and `best-fit`)

---------

Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Release 8.8.7

---------

Co-authored-by: ionitron <hi@ionicframework.com>
…#31148)

Issue number: resolves #29413

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?

In `viewStacks.ts`, `unmountLeavingViews` and `mountIntermediaryViews`
walk the outlet's view stack using `startIndex - delta` (or `startIndex
+ delta`) as the loop end, with no bound on `viewStack.length`. `delta`
comes from the popstate event's history delta. Apps that mount
`<ion-tabs>` at the root with no outer `<ion-router-outlet>` only have
one outlet registered, so `usingLinearNavigation` is true and these
helpers actually run. Each tab switch adds a browser history entry but
reuses existing view items, so `|delta|` can easily exceed the stack
depth above the entering view. The loop then reads `viewStack[i]` as
`undefined` and throws `TypeError: viewItem is undefined` from
`viewItem.mount = false`. The navigation aborts mid-transition, which is
what surfaces the secondary `enteringEl is undefined` warning and leaves
that route stuck

## What is the new behavior?

Both helpers bail when the entering view item isn't in the stack
(`startIndex === -1`) and clamp the loop end to
`Math.min(viewStack.length, ...)`, so a delta that overruns the stack
stops at the last real view item instead of indexing past the end. A new
Vitest spec at
`packages/vue/test/base/tests/unit/tabs-single-outlet.spec.ts` mounts
`<ion-tabs>` as the app root with flat routes, builds up history across
tabs and sub-pages, then calls `router.go(-6)`. Without the fix the spec
catches the unhandled `TypeError` from `viewStacks.ts`

## Does this introduce a breaking change?

- [ ] Yes
- [X] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->

## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Main-branch counterpart of #31145. Source change is byte-identical to
the source portion of that PR so the merge back into `major-9.0`
collapses to a no-op. There are no tests here, but there are in the v9
version because the v9 testing setup is better.
…31154)

Issue number: resolves #25470

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
When an `<ion-tab-button>` declares an `href` with a query string or
fragment, activating the tab drops both. In Angular, `IonTabs.select`
navigates to `tabsPrefix/tab` and never reads the button's `href`. In
Vue, the router splits the path on `?` and discards everything after it,
and `IonTabBar` compares the raw href against the pathname so a tab with
query params never shows as selected. In React, this issue has been
fixed as part of the RR6 migration.

## What is the new behavior?
Tab activation forwards the `href`'s query and fragment as navigation
extras. A saved view's previously-captured extras still win when
re-selecting a tab with prior history, so mid-stack state isn't
clobbered. `IonTabBar`'s selection check now compares pathnames only, so
a tab with a query string still highlights when its pathname is active.

Added Playwright coverage in `@ionic/angular` and Cypress coverage in
`@ionic/vue` for first visit, switching tabs, switching back, and
re-clicking the active tab. The Vue tests will cause a conflict on
merging into major-9.0, but I volunteer to fix that issue when it comes
up.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->


## Other information

Preview pages:
- Angular:
https://ionic-framework-git-fw-7146-ionic1.vercel.app/angular/standalone/tabs-search-params/tab1?foo=bar
- Vue:
https://ionic-framework-git-fw-7146-ionic1.vercel.app/vue/tabs-search-params/tab1?foo=bar
- React: This was fixed in the RR6 migration in V9. Unfortunately this
won't be coming to 8.8 at this time.
…31159)

Issue number: resolves #27843

---------

## What is the current behavior?

`createInlineOverlayComponent` renders inline overlays (modal, popover,
etc.) inside a `<template>` at their declared JSX position. When the
overlay presents, `CoreDelegate` teleports the DOM node into `ion-app`,
but React's synthetic event delegation root stays at the original JSX
parent. Once the overlay lives outside that subtree, React no longer
dispatches events to children inside it, so `onClick`, `onChange`, and
other handlers inside an `IonModal` rendered within an `IonNav` silently
stop firing

## What is the new behavior?

Top-level inline overlays now render through `createPortal` into the
same `ion-app` container that `CoreDelegate` teleports into, so React's
event root follows the DOM

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

This issue also reports the same problem in Vue, but that was fixed in
#30227

Preview:
[navigation-modal](https://ionic-framework-git-fw-6314-ionic1.vercel.app/react/navigation-modal)

Dev build:
```
8.8.8-dev.11779302602.17decfbf
```
# Conflicts:
#	core/package-lock.json
#	core/package.json
#	core/src/components/app/test/safe-area/app.e2e.ts-snapshots/app-action-sheet-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/app/test/safe-area/app.e2e.ts-snapshots/app-menu-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/app/test/safe-area/app.e2e.ts-snapshots/app-picker-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/app/test/safe-area/app.e2e.ts-snapshots/app-toast-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/avatar/test/basic/avatar.e2e.ts-snapshots/avatar-chip-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/avatar/test/basic/avatar.e2e.ts-snapshots/avatar-chip-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/badge/test/basic/badge.e2e.ts-snapshots/badge-basic-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/badge/test/basic/badge.e2e.ts-snapshots/badge-basic-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/badge/test/basic/badge.e2e.ts-snapshots/badge-basic-md-ltr-Mobile-Safari-linux.png
#	core/src/components/badge/test/basic/badge.e2e.ts-snapshots/badge-basic-md-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/a11y/button.e2e.ts-snapshots/button-default-scale-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/a11y/button.e2e.ts-snapshots/button-large-scale-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/a11y/button.e2e.ts-snapshots/button-small-scale-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/a11y/button.e2e.ts-snapshots/button-small-scale-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/basic/button.e2e.ts-snapshots/button-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/basic/button.e2e.ts-snapshots/button-diff-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/basic/button.e2e.ts-snapshots/button-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/basic/button.e2e.ts-snapshots/button-diff-md-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/basic/button.e2e.ts-snapshots/button-ripple-effect-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/basic/button.e2e.ts-snapshots/button-ripple-effect-md-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/clear/button.e2e.ts-snapshots/button-clear-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/clear/button.e2e.ts-snapshots/button-clear-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/clear/button.e2e.ts-snapshots/button-clear-md-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/expand/button.e2e.ts-snapshots/button-expand-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/icon/button.e2e.ts-snapshots/button-icon-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/icon/button.e2e.ts-snapshots/button-icon-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/icon/button.e2e.ts-snapshots/button-icon-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/icon/button.e2e.ts-snapshots/button-icon-md-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/outline/button.e2e.ts-snapshots/button-outline-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/outline/button.e2e.ts-snapshots/button-outline-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/outline/button.e2e.ts-snapshots/button-outline-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/outline/button.e2e.ts-snapshots/button-outline-md-rtl-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-clear-round-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-clear-round-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-color-round-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-color-round-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-expand-round-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-expand-round-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-outline-round-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-outline-round-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-round-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/round/button.e2e.ts-snapshots/button-round-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/size/button.e2e.ts-snapshots/button-size-large-in-buttons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/size/button.e2e.ts-snapshots/button-size-large-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/size/button.e2e.ts-snapshots/button-size-large-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/size/button.e2e.ts-snapshots/button-size-small-in-buttons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/size/button.e2e.ts-snapshots/button-size-small-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/size/button.e2e.ts-snapshots/button-size-small-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/strong/button.e2e.ts-snapshots/button-strong-in-buttons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/strong/button.e2e.ts-snapshots/button-strong-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/strong/button.e2e.ts-snapshots/button-strong-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-block-icons-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-block-icons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-block-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-block-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-full-icons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-full-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-icons-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-icons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-item-button-icons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-item-button-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-large-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-large-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-md-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-small-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/button/test/wrap/button.e2e.ts-snapshots/button-wrap-small-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card-header/test/basic/card-header.e2e.ts-snapshots/card-header-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/card-header/test/basic/card-header.e2e.ts-snapshots/card-header-diff-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/card-header/test/basic/card-header.e2e.ts-snapshots/card-header-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card-header/test/basic/card-header.e2e.ts-snapshots/card-header-diff-md-rtl-Mobile-Safari-linux.png
#	core/src/components/card/test/a11y/card.e2e.ts-snapshots/card-scale-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-button-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-color-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-color-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-diff-md-rtl-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-headings-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-headings-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-no-content-or-header-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-no-content-or-header-md-ltr-Mobile-Safari-linux.png
#	core/src/components/card/test/basic/card.e2e.ts-snapshots/card-translucent-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/chip/test/a11y/chip.e2e.ts-snapshots/chip-scale-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/chip/test/a11y/chip.e2e.ts-snapshots/chip-scale-md-ltr-Mobile-Safari-linux.png
#	core/src/components/chip/test/basic/chip.e2e.ts-snapshots/chip-basic-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/chip/test/basic/chip.e2e.ts-snapshots/chip-basic-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/chip/test/basic/chip.e2e.ts-snapshots/chip-descender-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/chip/test/basic/chip.e2e.ts-snapshots/chip-outline-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/content/content.scss
#	core/src/components/datetime/test/basic/datetime.e2e.ts-snapshots/datetime-footer-custom-buttons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/datetime/test/basic/datetime.e2e.ts-snapshots/datetime-footer-custom-buttons-md-rtl-Mobile-Safari-linux.png
#	core/src/components/grid/test/basic/grid.e2e.ts-snapshots/grid-basic-md-ltr-Mobile-Safari-linux.png
#	core/src/components/grid/test/basic/grid.e2e.ts-snapshots/grid-basic-md-rtl-Mobile-Safari-linux.png
#	core/src/components/grid/test/offsets/grid.e2e.ts-snapshots/grid-offsets-md-ltr-Mobile-Safari-linux.png
#	core/src/components/grid/test/offsets/grid.e2e.ts-snapshots/grid-offsets-md-rtl-Mobile-Safari-linux.png
#	core/src/components/grid/test/padding/grid.e2e.ts-snapshots/grid-padding-md-ltr-Mobile-Safari-linux.png
#	core/src/components/grid/test/padding/grid.e2e.ts-snapshots/grid-padding-md-rtl-Mobile-Safari-linux.png
#	core/src/components/grid/test/sizes/grid.e2e.ts-snapshots/grid-sizes-md-ltr-Mobile-Safari-linux.png
#	core/src/components/grid/test/sizes/grid.e2e.ts-snapshots/grid-sizes-md-rtl-Mobile-Safari-linux.png
#	core/src/components/header/test/basic/header.e2e.ts-snapshots/header-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/input/test/card/input.e2e.ts-snapshots/input-card-md-ltr-Mobile-Safari-linux.png
#	core/src/components/input/test/fill/input.e2e.ts-snapshots/input-fill-shaped-outline-custom-md-ltr-Mobile-Safari-linux.png
#	core/src/components/input/test/fill/input.e2e.ts-snapshots/input-fill-shaped-outline-custom-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-divider/test/basic/item-divider.e2e.ts-snapshots/item-divider-button-end-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-divider/test/basic/item-divider.e2e.ts-snapshots/item-divider-button-end-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-divider/test/basic/item-divider.e2e.ts-snapshots/item-divider-safe-area-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-divider/test/basic/item-divider.e2e.ts-snapshots/item-divider-safe-area-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-end-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-end-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-start-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-start-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-start-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-start-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-bottom-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-bottom-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-bottom-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-bottom-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-end-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-end-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-end-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-end-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-only-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-only-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-only-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-only-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-start-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-start-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-start-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-start-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-top-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-top-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-top-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item-sliding/test/icons/item-sliding.e2e.ts-snapshots/item-sliding-icons-top-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item/test/a11y/item.e2e.ts-snapshots/item-buttons-scale-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/a11y/item.e2e.ts-snapshots/item-buttons-scale-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/buttons/item.e2e.ts-snapshots/item-buttons-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/buttons/item.e2e.ts-snapshots/item-buttons-diff-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item/test/buttons/item.e2e.ts-snapshots/item-buttons-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/buttons/item.e2e.ts-snapshots/item-buttons-diff-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item/test/colors/item.e2e.ts-snapshots/item-colors-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/colors/item.e2e.ts-snapshots/item-colors-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/dividers/item.e2e.ts-snapshots/item-dividers-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/dividers/item.e2e.ts-snapshots/item-dividers-diff-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item/test/lines/item.e2e.ts-snapshots/item-lines-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/lines/item.e2e.ts-snapshots/item-lines-diff-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item/test/lines/item.e2e.ts-snapshots/item-lines-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/lines/item.e2e.ts-snapshots/item-lines-diff-md-rtl-Mobile-Safari-linux.png
#	core/src/components/item/test/media/item.e2e.ts-snapshots/item-media-diff-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/media/item.e2e.ts-snapshots/item-media-diff-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/item/test/media/item.e2e.ts-snapshots/item-media-diff-md-ltr-Mobile-Safari-linux.png
#	core/src/components/item/test/media/item.e2e.ts-snapshots/item-media-diff-md-rtl-Mobile-Safari-linux.png
#	core/src/components/list-header/test/basic/list-header.e2e.ts-snapshots/list-header-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/list-header/test/basic/list-header.e2e.ts-snapshots/list-header-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/list-header/test/basic/list-header.e2e.ts-snapshots/list-header-md-ltr-Mobile-Safari-linux.png
#	core/src/components/list-header/test/basic/list-header.e2e.ts-snapshots/list-header-md-rtl-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-full-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-full-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-full-md-ltr-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-full-md-rtl-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-inset-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-inset-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-inset-md-ltr-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-inset-md-rtl-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-none-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-none-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-none-md-ltr-Mobile-Safari-linux.png
#	core/src/components/list/test/lines/list.e2e.ts-snapshots/list-lines-none-md-rtl-Mobile-Safari-linux.png
#	core/src/components/menu/test/basic/menu.e2e.ts-snapshots/menu-basic-doc-dir-toggled-md-ltr-Mobile-Safari-linux.png
#	core/src/components/menu/test/basic/menu.e2e.ts-snapshots/menu-basic-side-toggled-md-ltr-Mobile-Safari-linux.png
#	core/src/components/menu/test/basic/menu.e2e.ts-snapshots/menu-basic-start-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/menu/test/basic/menu.e2e.ts-snapshots/menu-basic-start-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/menu/test/basic/menu.e2e.ts-snapshots/menu-basic-start-md-ltr-Mobile-Safari-linux.png
#	core/src/components/menu/test/basic/menu.e2e.ts-snapshots/menu-basic-start-md-rtl-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-md-ltr-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-md-rtl-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-tablet-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-tablet-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-tablet-md-ltr-Mobile-Safari-linux.png
#	core/src/components/modal/test/basic/modal.e2e.ts-snapshots/modal-basic-present-tablet-md-rtl-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-basic-popover-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-basic-popover-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-basic-popover-md-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-basic-popover-md-rtl-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-custom-class-popover-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-custom-class-popover-md-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-header-popover-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-header-popover-md-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-long-list-popover-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-long-list-popover-md-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-translucent-header-popover-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/popover/test/basic/popover.e2e.ts-snapshots/popover-basic-translucent-popover-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/radio-group/test/supporting-text/radio-group.e2e.ts-snapshots/radio-group-error-text-custom-css-md-ltr-Mobile-Safari-linux.png
#	core/src/components/radio-group/test/supporting-text/radio-group.e2e.ts-snapshots/radio-group-error-text-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/radio-group/test/supporting-text/radio-group.e2e.ts-snapshots/radio-group-error-text-md-ltr-Mobile-Safari-linux.png
#	core/src/components/radio-group/test/supporting-text/radio-group.e2e.ts-snapshots/radio-group-helper-text-custom-css-md-ltr-Mobile-Safari-linux.png
#	core/src/components/radio-group/test/supporting-text/radio-group.e2e.ts-snapshots/radio-group-helper-text-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/radio-group/test/supporting-text/radio-group.e2e.ts-snapshots/radio-group-helper-text-md-ltr-Mobile-Safari-linux.png
#	core/src/components/radio/test/a11y/radio.e2e.ts-snapshots/radio-scale-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/radio/test/a11y/radio.e2e.ts-snapshots/radio-scale-md-ltr-Mobile-Safari-linux.png
#	core/src/components/select/test/card/select.e2e.ts-snapshots/select-card-md-ltr-Mobile-Safari-linux.png
#	core/src/components/select/test/fill/select.e2e.ts-snapshots/select-fill-shaped-outline-md-ltr-Mobile-Safari-linux.png
#	core/src/components/select/test/fill/select.e2e.ts-snapshots/select-fill-shaped-outline-md-rtl-Mobile-Safari-linux.png
#	core/src/components/select/test/fill/select.e2e.ts-snapshots/select-fill-shaped-solid-md-ltr-Mobile-Safari-linux.png
#	core/src/components/select/test/fill/select.e2e.ts-snapshots/select-fill-shaped-solid-md-rtl-Mobile-Safari-linux.png
#	core/src/components/tab-button/test/basic/tab-button.e2e.ts-snapshots/tab-button-badge-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/tab-button/test/basic/tab-button.e2e.ts-snapshots/tab-button-badge-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/tab-button/test/basic/tab-button.e2e.ts-snapshots/tab-button-badge-md-ltr-Mobile-Safari-linux.png
#	core/src/components/tab-button/test/basic/tab-button.e2e.ts-snapshots/tab-button-badge-md-rtl-Mobile-Safari-linux.png
#	core/src/components/tab-button/test/layout/tab-button.e2e.ts-snapshots/tab-button-icon-below-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/tab-button/test/layout/tab-button.e2e.ts-snapshots/tab-button-icon-below-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/textarea/test/card/textarea.e2e.ts-snapshots/textarea-card-md-ltr-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-outline-md-ltr-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-outline-md-rtl-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-outline-custom-md-ltr-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-outline-custom-md-rtl-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-outline-md-ltr-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-outline-md-rtl-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-solid-custom-md-ltr-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-solid-custom-md-rtl-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-solid-md-ltr-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-shaped-solid-md-rtl-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-solid-md-ltr-Mobile-Safari-linux.png
#	core/src/components/textarea/test/fill/textarea.e2e.ts-snapshots/textarea-fill-solid-md-rtl-Mobile-Safari-linux.png
#	core/src/components/toast/test/basic/toast.e2e.ts-snapshots/toast-bottom-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/toast/test/basic/toast.e2e.ts-snapshots/toast-bottom-md-ltr-Mobile-Safari-linux.png
#	core/src/components/toast/test/basic/toast.e2e.ts-snapshots/toast-middle-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/toast/test/basic/toast.e2e.ts-snapshots/toast-middle-md-ltr-Mobile-Safari-linux.png
#	core/src/components/toast/test/basic/toast.e2e.ts-snapshots/toast-top-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/toast/test/basic/toast.e2e.ts-snapshots/toast-top-md-ltr-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-ios-ltr-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-ios-ltr-dark-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-ios-rtl-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-ios-rtl-dark-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-md-ltr-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-md-ltr-dark-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-md-rtl-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/basic/toolbar.e2e.ts-snapshots/toolbar-basic-text-icon-buttons-md-rtl-dark-Mobile-Safari-linux.png
#	core/src/components/toolbar/test/colors/toolbar.e2e.ts-snapshots/toolbar-colors-md-ltr-Mobile-Safari-linux.png
The merge regenerated package-lock.json and resolved playwright-core
to 1.60.0, but the CI Docker image is v1.59.1-noble. Firefox binaries
are not present for 1.60.0, causing the snapshot update job to fail
with "Executable doesn't exist at /ms-playwright/firefox-1522/firefox".
The ionic-md theme renders the `toggle-activated` press state with
non-deterministic anti-aliasing under the bumped Playwright/WebKit,
producing ~1% pixel drift between consecutive captures. Each update
run shifts which of ltr/rtl matches and the test never converges.

Set maxDiffPixelRatio to 0.02 (well above the observed ~0.01 drift)
to unblock the sync. The underlying ionic-md transition timing should
be addressed in a follow-up.
Issue number: resolves internal

---------

## What is the current behavior?
Playwright tests are hanging because of a [bug that breaks it for node
24.16+](microsoft/playwright#40724)

## What is the new behavior?
Upgrading Playwright to 1.16.0 to fix the issue

## Does this introduce a breaking change?

- [ ] Yes
- [X] No

## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
@vercel

vercel Bot commented May 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ionic-framework Ready Ready Preview, Comment May 29, 2026 12:30am

Request Review

@thetaPC thetaPC marked this pull request as ready for review May 29, 2026 01:22
@thetaPC thetaPC requested a review from a team as a code owner May 29, 2026 01:22
@thetaPC thetaPC requested a review from BenOsodrac May 29, 2026 01:22
@thetaPC thetaPC merged commit 25d3930 into ionic-modular May 29, 2026
112 of 139 checks passed
@thetaPC thetaPC deleted the chore-sync-modular-with-next branch May 29, 2026 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: core @ionic/core package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants