Skip to content

chore(git): sync with main#31104

Merged
ShaneK merged 17 commits into
major-9.0from
sync-major-9.0-with-main
Apr 30, 2026
Merged

chore(git): sync with main#31104
ShaneK merged 17 commits into
major-9.0from
sync-major-9.0-with-main

Conversation

@ShaneK

@ShaneK ShaneK commented Apr 30, 2026

Copy link
Copy Markdown
Member

Sync major-9.0 with main.

gnbm and others added 16 commits April 3, 2026 18:24
Issue number: resolves 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?
<!-- Please describe the current behavior that you are modifying. -->
In the dark palette, the `--ion-tab-bar-background-focused` CSS token
was not defined.
When a `ion-tab-button` receives focus, the `::after` overlay on
`.button-native` falls back to `get-color-shade(#fff)` → `#e0e0e0` — a
light grey that blends into the dark background and makes the focus
indicator invisible.

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

- `--ion-tab-bar-background-focused` is now defined in the dark palette:
`#252525` for iOS and `#353535` for MD , providing a dark-appropriate
focus indicator.
The same token is added to `high-contrast-dark.scss` with the same
values.
- A screenshot e2e test is added under `tab-button/test/states/` (where
the existing focused-state tests live) using `configs({ palettes:
['dark'] })` and `page.setContent()` with `class="ion-focused"` applied
directly, matching the established pattern for focus-state testing in
this component.


## 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. -->
The test triggers keyboard mode (required by `focus-visible.ts`) before
focusing the inner `<a>` element inside the tab button's shadow DOM,
since calling `.focus()` on the host element is a no-op without
`delegatesFocus`.

- [Preview
1](https://ionic-framework-git-fw-6293-ionic1.vercel.app/src/components/tabs/test/basic?ionic:mode=ios&palette=dark)
- [Preview
2](https://ionic-framework-git-fw-6293-ionic1.vercel.app/src/components/tabs/test/basic?ionic:mode=md&palette=dark)

---------

Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
Co-authored-by: Brandy Smith <6577830+brandyscarney@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?
Currently, the Datepicker keeps all the months visited as selected
instead of only the one that is really selected
On iOS devices, the month picker sometimes doesn't appear since the
`datepicker-ready` class is not added

## What is the new behavior?
Only the selected month appears selected in the month picker
On iOS devices, an additional validation is done to add the
`datepicker-ready` class

## 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

The
[Basic](https://ionic-framework-7el9b9l3f-ionic1.vercel.app/src/components/datetime/test/basic/?ionic:theme=ionic)
test should be used to test the multiple-month selection case
<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
Issue number: resolves #31052

---------

<!-- 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?
After a page navigation, ion-checkbox's `onslotchange` event fires
before the element's `textContent` has been updated. It is called again
after `textContent` becomes readable on Safari, but is not called again
after the `textContent` becomes readable on Chrome and Firefox.

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

- Uses `MutationObserver` instead of `onslotchange` and fires
specifically on character data changes. This ensures `hasLabelContent`
is up to date.
- `MutationObserver` does not fire on load, so `hasLabelContent` is
initialized in `connectedCallback`

## 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.
-->
Release 8.8.4

---------

Co-authored-by: ionitron <hi@ionicframework.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?
Vercel preview deployments only build and serve core Stencil component
test pages. Framework-specific test apps (Angular, React, Vue, React
Router) are not included, requiring developers to pull and build locally
to validate them.

## What is the new behavior?
Vercel preview deployments build and serve framework test apps alongside
core component tests under a single preview URL.

## 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. -->
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.0`
→
`8.3.1`](https://renovatebot.com/diffs/npm/@capacitor%2fcore/8.3.0/8.3.1)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@capacitor%2fcore/8.3.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@capacitor%2fcore/8.3.0/8.3.1?slim=true)
|
|
[@capacitor/keyboard](https://redirect.github.com/ionic-team/capacitor-keyboard)
| [`8.0.2` →
`8.0.3`](https://renovatebot.com/diffs/npm/@capacitor%2fkeyboard/8.0.2/8.0.3)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@capacitor%2fkeyboard/8.0.3?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@capacitor%2fkeyboard/8.0.2/8.0.3?slim=true)
|

---

### Release Notes

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

###
[`v8.3.1`](https://redirect.github.com/ionic-team/capacitor/blob/HEAD/CHANGELOG.md#831-2026-04-16)

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

##### Bug Fixes

- **android:** handle null versionName in isNewBinary()
([#&#8203;8397](https://redirect.github.com/ionic-team/capacitor/issues/8397))
([aa1a660](https://redirect.github.com/ionic-team/capacitor/commit/aa1a660f364f9b5f5a1e350e279c8864b04dd13b))
- boundary value extraction for form-data requests
([#&#8203;7518](https://redirect.github.com/ionic-team/capacitor/issues/7518))
([64ab854](https://redirect.github.com/ionic-team/capacitor/commit/64ab854c12330804c24275d88d3a9f7c8e52a73d))
- **cli:** check CAPACITOR\_COCOAPODS\_PATH in determinePackageManager
([#&#8203;8407](https://redirect.github.com/ionic-team/capacitor/issues/8407))
([acb64ab](https://redirect.github.com/ionic-team/capacitor/commit/acb64ab92a37ff53701cde453558e272e2e11eb6))
- **system-bars:** use separate current styles
([#&#8203;8409](https://redirect.github.com/ionic-team/capacitor/issues/8409))
([3d1f8d1](https://redirect.github.com/ionic-team/capacitor/commit/3d1f8d1b61480187375f5cd4de7ba999db007542))

</details>

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

###
[`v8.0.3`](https://redirect.github.com/ionic-team/capacitor-keyboard/blob/HEAD/CHANGELOG.md#803-2026-04-10)

[Compare
Source](https://redirect.github.com/ionic-team/capacitor-keyboard/compare/v8.0.2...v8.0.3)

##### Bug Fixes

- **android:** fixing Keyboard interaction with SystemBars
([#&#8203;62](https://redirect.github.com/ionic-team/capacitor-keyboard/issues/62))
([4afd89b](https://redirect.github.com/ionic-team/capacitor-keyboard/commit/4afd89b4af63609f40e970e7775fd03c5f6b407c))

</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 these
updates 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:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjEyMy44IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

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

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-node](https://redirect.github.com/actions/setup-node) |
action | minor | `v6.3.0` → `v6.4.0` |

---

### Release Notes

<details>
<summary>actions/setup-node (actions/setup-node)</summary>

###
[`v6.4.0`](https://redirect.github.com/actions/setup-node/compare/v6.3.0...v6.4.0)

[Compare
Source](https://redirect.github.com/actions/setup-node/compare/v6.3.0...v6.4.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.

🔕 **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:eyJjcmVhdGVkSW5WZXIiOiI0My4xMjMuOCIsInVwZGF0ZWRJblZlciI6IjQzLjEyMy44IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

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

---------

## What is the current behavior?

Fullscreen modals without an `ion-footer` set `height` and
`padding-bottom` on `.modal-wrapper` to reserve space for the bottom
safe-area. Because `ion-content`'s background does not extend into that
wrapper padding, a visible gap appears between the content and the
bottom edge of the modal.

Separately, modals that declare custom `--width` and `--height` on phone
viewports flash inherited safe-area values while animating in, then snap
to `0px` once the post-animation position correction runs.

## What is the new behavior?
Bottom safe-area compensation now happens inside `ion-content` instead
of on the wrapper, so the modal background stays edge-to-edge.

- New internal `--ion-content-safe-area-padding-bottom` CSS property is
added to `.inner-scroll`'s `padding-bottom` calc.
- `modal.tsx` sets that property on `ion-content` for fullscreen modals
without a footer, and clears it on resize and dismiss.
- Wrapper no longer has `height` or `padding-bottom` inline styles
written to it.
- New `hasCustomModalDimensions()` helper detects modals that override
both `--width` and `--height` to non-fullscreen values. These are zeroed
from the initial safe-area prediction so there is no flash before the
post-animation correction.
- Extracted `findContentAndFooter()` and `applyFullscreenSafeAreaTo()`
helpers so the resize handler and initial apply share the same lookup.
- E2E tests cover scroll-padding placement, wrapper content area
remaining full viewport height, `.inner-scroll` padding including
safe-area, and custom-dimension modals starting at zero.

## 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

`--ion-content-safe-area-padding-bottom` is an internal property. It is
additive with the existing `--padding-bottom` consumers can set, and it
only takes effect when `modal.tsx` writes it on fullscreen modals
without a footer.

Example pages:
- iOS:
https://ionic-framework-git-fw-7136-ionic1.vercel.app/src/components/modal/test/basic?ionic:mode=ios
- MD:
https://ionic-framework-git-fw-7136-ionic1.vercel.app/src/components/modal/test/basic?ionic:mode=md

Example iOS card modal safe-area:
- iOS:
https://ionic-framework-git-fw-7136-ionic1.vercel.app/src/components/modal/test/safe-area?ionic:mode=ios

## Dev Build:
```
8.8.5-dev.11776879142.101200b9
```
…rfaces (#31093)

Issue number: resolves #30561

---------

<!-- 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. -->

When an `ion-select` with `interface="popover"` or `interface="modal"`
is opened with the keyboard, pressing Enter on a focused option doesn't
commit the value or dismiss the overlay. Only Space works. The `onKeyUp`
handlers in `select-popover.tsx` and `select-modal.tsx` only checked for
`' '`, despite the comment claiming Enter was supported, and
`ion-radio-group`'s arrow-key handler never committed the focused value
on Enter the way native `<select>` does.

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

Pressing Enter on a focused option in the popover or modal interface now
commits that option as the select's value and dismisses the overlay,
matching Space and native `<select>` behavior. `radio-group.tsx` gains
an Enter branch inside its select-interface arrow-key handler that sets
`value` to the focused radio and emits `ionChange` when it differs from
the previous value. `select-popover.tsx` and `select-modal.tsx` track
the `onKeyDown` target so `onKeyUp` only dismisses when the Enter press
started on the same option. That guard stops a held Enter on the
triggering `ion-select` from re-firing inside the just-opened overlay
and auto-dismissing it. The `!ev.repeat` check on keydown covers the
same case for the radio-group commit.

## 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. -->

The keydown/keyup target-matching pattern is the same trick the browser
uses to avoid firing a click when keydown and keyup happen on different
elements. It's needed here because Enter on the `ion-select` trigger
opens the overlay on keydown, and without the guard the corresponding
keyup (now inside the overlay) would immediately commit and dismiss.

Preview page:
- [select /
basic](https://ionic-framework-git-fw-6754-ionic1.vercel.app/src/components/select/test/basic?ionic)
# Conflicts:
#	packages/react-router/package-lock.json
#	packages/react/package-lock.json
#	packages/react/package.json
@ShaneK ShaneK requested a review from a team as a code owner April 30, 2026 13:49
@ShaneK ShaneK requested a review from gnbm April 30, 2026 13:49
@vercel

vercel Bot commented Apr 30, 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 Apr 30, 2026 1:59pm

Request Review

@github-actions github-actions Bot added package: core @ionic/core package package: angular @ionic/angular package package: vue @ionic/vue package package: react @ionic/react package labels Apr 30, 2026
@ShaneK ShaneK merged commit 9fb6430 into major-9.0 Apr 30, 2026
50 checks passed
@ShaneK ShaneK deleted the sync-major-9.0-with-main branch April 30, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: angular @ionic/angular package package: core @ionic/core package package: react @ionic/react package package: vue @ionic/vue package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants