Issue number: resolves#30679
---------
<!-- 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 a page contains a card modal with a `presentingElement`, resizing
the viewport (e.g., rotating from portrait to landscape) triggers the
card modal's "lean back" animation on the presenting element, even when
the modal has never been opened.
## What is the new behavior?
Viewport resize events no longer trigger the presenting element
animation when the modal is not presented. The animation only runs when
the modal is actually open.
## 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. -->
Current dev build:
```
8.7.16-dev.11767028735.16932cea
```
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 `ion-input-password-toggle` button uses `role="switch"` with
`aria-checked`, causing screen readers like VoiceOver to announce both a
state ("On/Off") and an action ("Show/Hide password"). This results in
confusing, redundant output such as "On, Hide Password" or "Off, Show
Password".
## What is the new behavior?
The password toggle button now uses `aria-pressed` instead of
`role="switch"` with `aria-checked`. Screen readers announce the
action-based label ("Show password" or "Hide password") along with the
pressed state, and properly announce state changes when the button is
activated.
## 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. -->
[Old
Preview](https://ionic-framework-git-main-ionic1.vercel.app/src/components/input-password-toggle/test/basic)
[New
Preview](https://ionic-framework-git-fw-6920-ionic1.vercel.app/src/components/input-password-toggle/test/basic)
Current dev build:
```
8.7.15-dev.11766421552.180757ca
```
Issue number: resolves#29929
---------
## What is the current behavior?
When forcing `mode=ios` in a collapsible header,
`.header-collapse-condense` would still be applied from the
`header.md.scss` file, leaving the collapsible header always hidden.
## What is the new behavior?
When forcing `mode=ios` in a collapsible header, the
`.header-collapse-condense` styles from the `header.md.scss` file won't
be applied, and the collapsible header will be visible.
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
Something worth mentioning is that this behavior only appears after
initial load: if the route is loaded refreshing the page, the header
will appear and work correctly, but navigating forth and back will apply
both the .ios and .md style files.
I showcase this with a modal because It'll always display the broken
hehavior.
| Before | After |
|--------|-------|
| <video
src="https://github.com/user-attachments/assets/1307ee9f-452a-4b00-877d-0b8e360d3bf7">
| <video
src="https://github.com/user-attachments/assets/f9ee3851-ce94-4a27-9947-37aa1f5433b9">
|
---------
Co-authored-by: ShaneK <shane@shanessite.net>
Issue number: resolves#30030
---------
## What is the current behavior?
When modals are presented one after another with matching IDs and then
dismissed by ID it will dismiss the first presented modal.
## What is the new behavior?
- When modals are presented one after another with matching IDs and then
dismissed by ID it will dismiss the last (top-most) presented modal.
- Added e2e tests to verify this behavior works the same as the default
dismiss (not passing an ID).
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
[Modal: Dismiss
Behavior](https://ionic-framework-git-fw-7016-ionic1.vercel.app/src/components/modal/test/dismiss-behavior)
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: 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. -->
The safe area variables are only reliant on `env` variables that are
provided by devices.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
Capacitor 8 has released [safe area variable
fallbacks](https://capacitorjs.com/docs/apis/system-bars#android-note)
to provide consistent behaviors with older Android devices:
> Due to a [bug](https://issues.chromium.org/issues/40699457) in some
older versions of Android WebView (< 140), correct safe area values are
not available via the safe-area-inset-x CSS env variables. This plugin
will inject the correct inset values into a new CSS variable(s) named
--safe-area-inset-x that you can use as a fallback in your frontend
styles.
- Updated safe area variables to use the fallbacks provided by
Capacitor.
## 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. -->
Dev build: `8.7.13-dev.11765920447.1a01ab8b`
---------
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
Issue number: resolves internal
---------
## What is the current behavior?
When using ModalController to present a modal in Angular applications,
the browser becomes non-responsive and hangs in some circumstances. This
regression was introduced in #30544 with the addition of a
MutationObserver that watches document.body with subtree: true to detect
when a modal's parent element is removed from the DOM. For
controller-based modals, this observer fires on every DOM mutation in
the document, causing severe performance issues during Angular's change
detection cycles.
## What is the new behavior?
The MutationObserver for parent removal detection is now skipped for
controller-based modals and when the cached parent is the app root
(document.body or ion-app). These parents are never removed from the
DOM, so observing them is unnecessary. This prevents the performance
issues while still maintaining the parent removal detection behavior for
inline modals with meaningful parent elements.
## 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. -->
Current dev build:
```
8.7.12-dev.11765231260.1def96ab
```
---------
Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
Issue number: resolves#30700
---------
## What is the current behavior?
When a sheet modal with showBackdrop=false is rendered in a child route
(nested ion-router-outlet), the parent content becomes non-interactive.
Clicks on buttons or other interactive elements in the parent component
are blocked, even though showBackdrop=false should allow background
interaction.
Two separate issues contributed to this bug:
1. **Root locking with `backdropBreakpoint`**: The `shouldLockRoot`
logic in `overlays.ts` didn't account for `backdropBreakpoint`. Modals
with `backdropBreakpoint > 0` were still locking the root with
`aria-hidden`, even though developers expect background interaction when
the modal is below the backdrop breakpoint.
2. **Child route wrapper blocking**: When a modal is in a child route,
the child route's page wrapper (`ion-page`) and its parent
`ion-router-outlet` remain in the DOM with `position: absolute` covering
the viewport. Even after the modal is moved to `ion-app` and has
`pointer-events: none`, these wrapper elements block clicks to the
parent page's content.
This issue stems from
[#30563](https://github.com/ionic-team/ionic-framework/pull/30563),
which added root-locking behavior that didn't account for modals that
allow background interaction. A partial fix in
[#30689](https://github.com/ionic-team/ionic-framework/pull/30689)
partially addressed `showBackdrop=false` and `focusTrap=false`, but
missed `backdropBreakpoint`.
## What is the new behavior?
Sheet modals with showBackdrop=false or focusTrap=false now correctly
allow interaction with parent content when the modal is in a child
route.
Improvements:
- Recalculates isSheetModal in present() to handle Angular binding
timing
- Sets pointer-events: none on the modal element and its original parent
elements when background interaction should be allowed
- Cleans up pointer-events on dismiss
- Adds regression tests
## 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. -->
Dev build:
```
8.7.12-dev.11765060985.14ad27fb
```
Issue number: internal
---------
## What is the current behavior?
A translucent header in a popover does not consistently render as
translucent upon presenting due to the `offset-top` of the content being
set to `0`.
## What is the new behavior?
Watch the header for height changes using `ResizeObserver` and
recalculate the content dimensions when the header height is greater
than `0`.
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: 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. -->
The screen reader does not announce when an option is selected within
the action sheet interface. This is because the action sheet uses
standard buttons, which do not support a detectable selected state via
native properties or ARIA attributes like `aria-checked` or
`aria-selected`, creating an inconsistent user experience across
different interface types.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Updated the action sheet buttons to accept `role="radio"`
- Added keyboard navigation to follow the pattern for radio group
- Added test
## 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. -->
[Basic](https://ionic-framework-git-fw-6818-ionic1.vercel.app/src/components/select/test/basic/)
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Co-authored-by: Shane <shane@shanessite.net>
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
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. -->
Playwright's `setContent` cannot handle query params which causes the
`scripts.js` to not run effectively.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Update `scripts.js` to accept hash params as well
- Update `scripts.js` to accept the dark class to set dark mode if dark
query or hash was not passed
## 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. -->
How to test:
1. Verify that tests are passing
---------
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
Issue number: resolves#30706
---------
<!-- 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?
Due to some recent unknown changes, the intersection observer for date
time no longer reliably fires, especially in mobile views.
## What is the new behavior?
In this PR, we're adding a visibility check after everything has had a
chance to render to make sure we're setting up properly even if the
intersection observer has failed to trigger for some reason.
## Does this introduce a breaking change?
- [ ] Yes
- [X] No
## Other information
Since the intersection observer is being set up after a `raf`, it's
possible something got introduced to make the initial setup slower for
some reason, causing timing issues. I think we should do a more thorough
investigation into the cause of this problem when we have more time.
This PR also adds tests to verify the new fallback works properly.
Current dev build:
```
8.7.10-dev.11763478209.1d9c4cd8
```
---------
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
Issue number: 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. -->
Currently, when an error text is shown, it may not announce itself to
voice assistants. This is because the way error text currently works is
by always existing in the DOM, but being hidden when there is no error.
When the error state changes, the error text is shown, but as far as the
voice assistant can tell it's always been there and nothing has changed.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Updated aria attributes
- Added observer with an observer
## 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. -->
[Checkbox
preview](https://ionic-framework-git-fw-6757-ionic1.vercel.app/src/components/checkbox/test/validation/)
[Toggle
preview](https://ionic-framework-git-fw-6757-ionic1.vercel.app/src/components/toggle/test/validation/)
[Radio Group
preview](https://ionic-framework-git-fw-6757-ionic1.vercel.app/src/components/radio-group/test/validation/)
⚠️ Flakiness ⚠️
The flakiness on checkbox and toggle is because when a native input is
present on the page, the browser will have the screen reader to be
really fast when it comes to checking information. This speed ends up
being too fast for `ion-checkbox` to be able to add the error text. This
leads to the error text not being announce consistently. There's no
issue when it comes to ion-input or ion-textarea because Ionic uses the
native inputs so their arias are read. There's also no issue
with ion-select because we don't have a native input. It's only an issue
with checkbox and the others is because it has a [native input that is
being
hidden](8e884bd2cb/core/src/components/checkbox/checkbox.tsx (L368-L369)).
So the browser sees that and speeds up the screen reader.
The flakiness on radio group is because when you tab out of the last
radio button, the ionBlur event is emitted by the child <ion-radio>.
This event bubbles up, but the timing is still too early for the group.
Issue number: resolves#30613
---------
<!-- 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. -->
Currently, when you load an accordion group, the initially selected
accordion animates open. This is an unexpected change caused by
upgrading Stencil to >= 4.21.0, which changed the way component
lifecycles got triggered.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
With this change, we're waiting for the accordion in the accordion group
to render and telling it if the update it's going through is the initial
update or not. This allows it to decide to animate properly.
## 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. -->
Current dev build:
```
8.7.8-dev.11761840817.1bede576
```
Issue number: 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. -->
`ionFocus` and `ionBlur` are not being emitted for checkbox and toggle.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Moved the `onFocus` and `onBlur` to `Host`
- Added tests for `onFocus`, `onBlur`, and `onChange`.
- Added a workaround on Playwright in order to trigger `ionBlur` since
Playwright browsers aren't acting like native browsers when it comes to
tabbing.
## 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. -->
Dev build: `8.7.7-dev.11761071592.1d1b804d`
---------
Co-authored-by: ionitron <hi@ionicframework.com>
Co-authored-by: Shane <shane@shanessite.net>
Issue number: 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. -->
As per accessibility guidelines, there should only be one banner
landmark per page. A condensed header creates two banner landmarks since
2 `ion-header` components are required on the page. `ion-header` renders
with a `role="banner"` by default (when not in `ion-menu`).
The visual effect of the condensed header is achieved by rendering two
distinct header components. Because both components exist in the code at
the same time and both have `role="banner"`, they create a duplicate
landmark announcement for screen readers. This leads to a violation with
the accessibility guidelines.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- The role is updated to either `none` or `banner` based off the
header's active state.
- Added test.
## 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. -->
[Preview](https://ionic-framework-git-fw-6767-ionic1.vercel.app/src/components/header/test/condense/?ionic%3Amode=ios)
Issue number: 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. -->
Currently, when an error text is shown, it may not announce itself to
voice assistants. This is because the way error text currently works is
by always existing in the DOM, but being hidden when there is no error.
When the error state changes, the error text is shown, but as far as the
voice assistant can tell it's always been there and nothing has changed.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Updated aria attributes
- Added observer with an observer
We had to do this with a mutation observer and state because it's
important in some frameworks, like Angular, that state changes to cause
a re-render. This, combined with some minor aria changes, makes it so
that when a field is declared invalid, it immediately announces the
invalid state instead of waiting for the user to go back to the invalid
field.
## 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. -->
[Preview](https://ionic-framework-git-fw-6797-ionic1.vercel.app/src/components/select/test/validation/)
Issue number: resolves#25326
---------
<!-- 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. -->
The header flickers upon page transition when on iOS mode and using a
condensed header:
**Entering Page Two (P1 → P2):**
When navigating to Page Two, which has a collapsing header (intended to
be hidden until scroll), the header briefly flashes into view. This
happens because the header is initially rendered with full `opacity: 1`
before the component's logic can apply `opacity: 0` to hide it, causing
a visible flicker.
**Navigating Back (P2 → P1):**
When navigating back, Page One's header briefly bleeds through the top
of Page Two. Although Page Two is on top (`z−index: 100`), its
collapsing header is set to `opacity: 0`. This transparency allows Page
One header (`z−index: 99`) to become visible underneath, as the
transparent area cannot block the content below it.
The header flickers upon page transition when on iOS mode and using a
fade header:
**Entering Page Two (P1 → P2):**
When navigating to Page Two, which has a fade header (should not have a
background on load), the header background briefly flashes into view.
This happens because the header is initially rendered with full
`opacity: 1` before the component's logic can apply `opacity: 0` to hide
it, causing a visible flicker.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Added a transition-specific class that is applied to the condensed
ion-header element to override its default transparency.
This guarantees the header to act as an opaque block during the page
transition, eliminating visual flickering caused by early `opacity: 0`
or the header underneath bleeding through.
- Added a transition-specific class that is applied to the fade
ion-header element to override its default opaque background.
This guarantees the header to act as a transparent block during the page
transition, eliminating visual flickering caused by default `opacity:
1`.
## 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. -->
Dev build: `8.7.6-dev.11759524961.1cff6814`
Issue number: resolves#30611
---------
<!-- 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. -->
Currently, the way tabs are set in the tab bar abuses a bug that existed
in older versions of Stencil where children would be rendered out of the
correct order. This worked in the tab and tab bar's favor previously,
but after the fix it broke our implementation so tabs would no longer
correctly indicate the selected tab on direct navigation.
## What is the new behavior?
We had a temporary fix before we knew what actually caused this issue
before, which was basically just a timeout. That blindly worked because
it triggered after the child was fully rendered. This change embraces
the new, and correct, way these components render and triggers tab
updates correctly.
## 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. -->
Current dev build:
```
8.7.6-dev.11759345401.165fca78
```
---------
Co-authored-by: ionitron <hi@ionicframework.com>
Issue number: resolves#30684
---------
<!-- 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. -->
Recently, we [fixed some issues with aria-hidden in
modals](https://github.com/ionic-team/ionic-framework/pull/30563),
unfortunately at this time we neglected modals that opt out of focus
trapping. As a result, a lot of modals that disable focus trapping still
have it happening and it doesn't get cleaned up properly on dismiss.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
We're now properly checking for and skipping focus traps on modals that
do not want them.
## 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
I created regression tests for Angular in this to prevent this from
happening again. I initially tried to do this with core, but the issue
doesn't seem to reproduce with core.
<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
Current dev build:
```
8.7.5-dev.11758652700.103435a3
```
Issue number: resolves
[#30079](https://github.com/ionic-team/ionic-framework/issues/30079)
---------
<!-- 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. -->
Segments (IonSegment and IonSegmentView) do not work if placed on a
dir="rtl" context. If click on button, it won't slide content of the
next segment.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- calculate scroll value having into consideration the dir value;
## 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. -->
[Preview](https://ionic-framework-git-fw-6768-ionic1.vercel.app/src/components/segment-view/test/rtl)
---------
Co-authored-by: Shane <shane@shanessite.net>
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?
<!-- Please describe the current behavior that you are modifying. -->
Currently, when an error text is shown, it may not announce itself to
voice assistants. This is because the way error text currently works is
by always existing in the DOM, but being hidden when there is no error.
When the error state changes, the error text is shown, but as far as the
voice assistant can tell it's always been there and nothing has changed.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
With these changes, both input and textarea have been updated so they'll
properly announce error text when it shows up. We had to do this with a
mutation observer and state because it's important in some frameworks,
like Angular, that state changes to cause a re-render. This, combined
with some minor aria changes, makes it so that when a field is declared
invalid, it immediately announces the invalid state instead of waiting
for the user to go back to the invalid field.
## 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. -->
Current dev build:
```
8.7.4-dev.11756220757.185b8cbf
```
## Screens
[Textarea](https://ionic-framework-git-ionic-49-ionic1.vercel.app/src/components/textarea/test/validation)
[Input](https://ionic-framework-git-ionic-49-ionic1.vercel.app/src/components/input/test/validation)
---------
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
Issue number: resolves #
---------
<!-- 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. -->
Currently, if you focus on something and then refresh with a refresher,
the browser will try to scroll to what's focused after refreshing. This
can be an unexpected and disrupting user experience.
https://github.com/user-attachments/assets/3ef5999d-d104-422a-a6a9-4f478912f48a
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
With these changes, we blur the active element to prevent the browser
from trying to scroll back to something off screen after refreshing.
Also, I did try to create regression tests for this, but playwright
actually doesn't currently seem to make it possible as far as I can tell
- that's actually what I spent most of my time on this issue trying to
do. Looks like the only way to trigger the refresher with playwright
uses mouse click events, which inherently blurs the active element. You
need to use cursor events for this to work, because cursor events do not
cause a blur on the active element.
https://github.com/user-attachments/assets/bd1a3bfc-9b48-4b3f-b8dc-6959eefc9107
## 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. -->
**Current dev build:**
```
8.7.3-dev.11755285796.12743331
```
Issue number: resolves#30231
---------
<!-- 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. -->
Currently, if you're using voiceover on Chrome or Firefox, you can
navigate the checkbox in such a way that it announces the checkbox
image, which provides no context to what you're actually selecting.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
With this change, you can no longer select the checkbox image.
## 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. -->
[Screen](https://ionic-framework-git-ionic-56-ionic1.vercel.app/src/components/checkbox/test/basic)
---------
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
Issue number: resolves#30592
---------
## What is the current behavior?
Reorder group is failing for Angular, React & Vue due to the change from
`children` to `__children`.
## What is the new behavior?
- Fallback to `children` if `__children` is undefined.
- Adds an e2e test for Angular (depends on
https://github.com/ionic-team/ionic-framework/pull/30594)
- Tasks have been created to migrate and add e2e tests for the other
frameworks
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
Dev build: `8.7.2-dev.11754087334.1815cf22`
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#30552
---------
<!-- 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. -->
Something caused a timing shift in v8.6.0 that messed up the timing
required for react router to set the active tab ID. Currently, when the
router goes to set the tab ID, it's possibly too early and the tab may
not exist yet, causing it to go unset.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
This PR is a workaround that allows tabs to check when they're rendered
if a tab should be selected as a fallback for the router not setting
them. I don't think the tabs, in the long run, should be responsible for
this, but I think this is a good intermediate step until the upcoming
react router upgrade, when we can look into a better solution for react
router that may require less timing precision.
This PR also adds regression tests for React to make sure this doesn't
happen again without getting noticed.
## 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. -->
**Current dev build:**
```
8.7.2-dev.11754338216.1a548096
```
This fixes the flaky/failing tests here:
`should not have visual regressions with a custom styled calendar`
<img width="1658" height="916" alt="CleanShot 2025-08-04 at 13 46 12@2x"
src="https://github.com/user-attachments/assets/b5d54ee8-b315-4db0-b09b-65d9cd2fa7ca"
/>
`should switch the calendar header when moving to a month with a
different number of days`
<img width="2104" height="1752" alt="CleanShot 2025-08-04 at 13 45
33@2x"
src="https://github.com/user-attachments/assets/8a0cdb0b-6e9d-4b5c-a2df-f9174431492b"
/>
You can run them locally using:
- `npm run test.e2e.docker src/components/datetime/test/datetime.e2e.ts
-- --repeat-each=10`
- `npm run test.e2e.docker
src/components/datetime/test/custom/datetime.e2e.ts -- --repeat-each=10`
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#30565
---------
## What is the current behavior?
Stencil is on v4.33.1
## What is the new behavior?
- Updates Stencil to v4.36.2
- Updates `children` references to `__children` in `reorder-group`
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
I searched through the repository for other components that may be
affected but did not find any.
Dev build: `8.7.1-dev.11753971948.1b297d94`
Reorder Example using dev build:
[StackBlitz](https://stackblitz.com/edit/5nrzhbja)
Router Example using dev build:
[StackBlitz](https://stackblitz.com/edit/rvpcflzx)
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#22469
---------
- Adds new responsive display classes with the following values: `none`, `inline`, `inline-block`, `block`, `flex`, `inline-flex`, `grid`, `inline-grid`, `table`, `table-cell`, `table-row`
- Adds new responsive flex util classes for the following properties: `align-content`, `align-items`, `align-self`, `justify-content`, `flex-direction`, `flex-wrap`, `flex`, `flex-grow` , `flex-shrink`, `order`
- Adds e2e tests to verify the correct classes are in the CSS files
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#29833
---------
- Adds the `border` property for customizing the border of highlighted dates
- Adds the `border` to the e2e test for highlightedDates
- Updates screenshots
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#23148resolves#27614
---------
The `ion-reorder-group` only emits an `ionItemReorder` event when the reorder gesture ends AND the item position has changed. There is no way to listen for when the gesture starts, is actively moving, or ends without the item changing position.
- Adds an `ionReorderStart` event that is fired without any details on the start of the gesture.
- Adds an `ionReorderMove` event that is fired continuously during gesture move and includes the `from` and `to` detail.
- Adds an `ionReorderEnd` event that is fired at the end of the gesture and always includes the `from` and `to` detail, even if they are the same.
- Deprecates the `ionItemReorder` event, recommending to use the `ionReorderEnd` instead.
- [ ] Yes
- [x] No
While this does not introduce a breaking change, it does deprecate the `ionItemReorder` event in favor of the `ionReorderEnd` event. This event behaves a bit differently since it is always emitted on end. If the `from` and `to` are the same, it will still emit them, so it's possible to check if they are the same to determine if `ionReorderEnd` fired without moving item positions.
----
Co-authored-by: sfinktah <sfinktah@github.spamtrak.org>
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#30543
---------
## What is the current behavior?
On desktop Safari and Android the segment view is not switching to the
right segment content when the height is dynamically set or read in as
0. This can be reproduced in the following StackBlitz on Android:
https://6dhropnr-aheyyprl.stackblitz.io/
## What is the new behavior?
- Sets `min-height` to `1px` on `ion-segment-content` so that it
continues to work with a dynamically set height
- Adds an e2e test for Safari to verify the correct content is displayed
when it contains a dynamically loaded image
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
Dev build: `8.6.2-dev.11752524287.1d61cd78`
[Preview](https://ionic-framework-git-fw-6586-ionic1.vercel.app/src/components/segment-view/test/dynamic-height)
---------
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?
<!-- Please describe the current behavior that you are modifying. -->
Currently, if you have multiple card modals open in portrait view and
then transition to landscape, the background will not be transformed
properly and will not cover the entire screen as expected.
https://github.com/user-attachments/assets/bb2c7015-adb6-4c3b-8bc5-13360275fcf4
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
Now, we're correctly targeting the right element and will transform it
as expected. This allows a more consistent UX for these transitions.
https://github.com/user-attachments/assets/fff72387-d78b-4df4-a234-d89b54f694c4
## 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. -->
[Relevant (broken) screen (main
branch)](https://ionic-framework-git-main-ionic1.vercel.app/src/components/modal/test/card?ionic:mode=ios)
[Relevant (fixed) screen (this
branch)](https://ionic-framework-git-fix-modal-landscape-background-ionic1.vercel.app/src/components/modal/test/card?ionic:mode=ios)
Issue number: resolves#29763
---------
<!-- 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. -->
If the nested content of an ion-item is conditionally rendered and goes
from containing zero interactive elements to one or more, a render is
not triggered in Angular and the item does not behave correctly for one
or more nested inputs.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- A mutation observer is created in `connectedCallback()` to watch for
changes in item's child list. When the `childList` changes, two pieces
of state that track whether the item needs to be interactive and whether
there are multiple interactive elements are updated.
- Add `disconnectedCallback()` and logic to disconnect Mutation
Observer.
- Create new function `totalNestedInputs()` with logic from existing
`setMultipleInputs` function to be used for both `setMultipleInputs` and
new function `setIsInteractive`.
## 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. -->
I opted for the MutationObserver over a `slotchange` listener because
the `slotchange` fires synchronously on any slot within the shadowRoot,
and the MutationObserver fires once on the item element itself. I
attempted to add the minimum amount of logic to achieve this but there
may be a more elegant solution that combines what `multipleInputs` and
`isInteractive` are doing but requires more changes to existing code.
Issue number: resolves#30389
---------
<!-- 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. -->
Currently, when the element an ion-modal was presented from is removed,
the modal stays presented and can be broken depending on the framework.
This is unlike #30540, where children of open modals were being kept
open. In this case, specifically the DOM element is being removed for
whatever reason and the modal is staying open.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
We're now identifying our parent component on load and watching it with
a mutation observer to determine if it gets removed from the DOM. If it
does, we trigger a dismiss. This, conveniently, works nicely with #30540
and will dismiss all children and grandchildren as well.
## 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 issue this resolves was already marked closed, but on closer
inspection I determined that was a mistake. I believed this issue was
related to another one I was dealing with and it is, but it wasn't quite
the same.
After this issue is merged, I believe we will have handled all avenues
of possibly ending up with broken modals because of parent elements or
modals being removed.
[Relevant Test
Page](https://ionic-framework-git-fix-remove-modal-when-parent-removed-ionic1.vercel.app/src/components/modal/test/inline)
**Current dev build:**
```
8.6.5-dev.11752329407.10f7fc80
```
Issue number: resolves#30459
---------
## What is the current behavior?
1. Typing `"12345"` in a 4-box input-otp with `type="text"` is
incorrectly triggering autofill detection on Android, causing `"45"` to
be distributed across the first two boxes instead of replacing the `"4"`
with the `"5"`.
**Current Behavior**: Type `"12345"` → `["4", "5", "", ""]` (incorrectly
distributed)
**Expected Behavior**: Type `"12345"` → `["1", "2", "3", "5"]`
(correctly replaces last character)
2. Typing an invalid character (like `"w"` when `type="number"`) in an
input box with a value is inserted, ignoring the input validation.
**Current Behavior**: Type `"2"` in the first box, focus it again, type
`"w"` → `"2w"` appears
**Expected Behavior**: Type `"2"` in the first box, focus it again, type
`"w"` → `"2"` remains (invalid character rejected)
## What is the new behavior?
- Fixes autofill detection on Android devices
- Fixes invalid character insertion in filled input boxes
- Improves cursor position handling when typing in a filled box
- Adds e2e tests for more coverage
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
Dev build: `8.6.5-dev.11752245814.1253279a`
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#30389
---------
<!-- 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. -->
Currently, when a child modal is present and a parent modal is somehow
dismissed, the child modal stays open. This can cause issues in some
frameworks like React and Angular, where this cuts the connection to the
child modal and it can no longer be dismissed programmatically.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
This change enables modals to identify their children and close the
children when they're closed. This prevents orphaned modals that can
cause a poor UX. Note: This fix is only for inline modals, which is the
biggest cause of the above issue.
## 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. -->
[Relevant test
page](https://ionic-framework-git-fw-6597-ionic1.vercel.app/src/components/modal/test/inline)
**Current dev build**:
```
8.6.5-dev.11752242329.17d249a3
```