## What is the current behavior?
Checkbox and toggle components are not validated to be ticked/on in
`packages/angular/test/base/src/app/lazy/template-form`. This prevents
the error text from being displayed. While they have the `required`
attribute, this only applies to accessibility for
[checkbox](https://ionicframework.com/docs/api/checkbox#required) and
[toggle](https://ionicframework.com/docs/api/toggle#required).
## What is the new behavior?
- Use an Angular validator directive for checkbox and toggle.
- Make template-form an Angular module so the validator directive can be
imported.
## Does this introduce a breaking change?
- [ ] Yes
- [X] No
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->
Checkbox's render function applies the `label-text-wrapper-hidden` css
class when there is no label text to prevent extra margin from being
added. The render function is not re-evaluated if the label is updated.
This causes a problem in Angular where dynamic variables get applied
after the page is loaded, and a checkbox using a variable as a label
gets stuck with its label hidden until something else triggers a
re-render, e.g. ticking the box.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- The checkbox will be re-rendered, and css classes will be updated,
when the label text is changed.
- Updated tests to check that the label is visible after changing from
blank to having content.
## 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.
-->
Issue number: internal
---------
## What is the current behavior?
Currently, the 8.8 refresher events are not exported to Angular
## What is the new behavior?
With this change, we export the new events and also add Angular tests to
validate that they work and will continue working in the future.
## Does this introduce a breaking change?
- [ ] Yes
- [X] No
Issue number: resolves internal
---------
## What is the current behavior?
When an accordion item was set as disabled, it was still possible to
focus using keyboard navigation.
## What is the new behavior?
When an accordion item is disabled, `tabindex` is set as -1 to stop
being focusable using the keyboard navigation.
## Does this introduce a breaking change?
- [ ] Yes
- [ ] No
## Other information
[preview](https://ionic-framework-qznd9tqne-ionic1.vercel.app/src/components/accordion-group/test/states/)
---------
Co-authored-by: Maria Hutt <maria.hutt@outsystems.com>
Issue number: resolves#30735
---------
## What is the current behavior?
Toast's wrapper and content divs do not have part attributes.
## What is the new behavior?
- Adds `wrapper` and `content` parts to Toast.
## 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
This PR was originally opened by @Hurubon here in #30737. It was lost in
`feature-8.8` due to a bad merge, so this PR is to re-apply this feature
so it can go out in 8.8.1 (it was originally supposed to go out in
8.8.0)
Co-authored-by: Hurubon <58346722+Hurubon@users.noreply.github.com>
Co-authored-by: Hurubon <58346722+Hurubon@users.noreply.github.com>
Issue number: internal
---------
## What is the current behavior?
The sheet and card modal can be dragged to view content. However, there
are no events that determine when drag has started or ended.
## What is the new behavior?
- Added drag events for sheet and card modal: `ionDragStart`, `ionDragMove`, `ionDragEnd`
- Added a drag interface
- Added tests
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Shane <shane@shanessite.net>
Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
Issue number: resolves#29862
---------
## What is the current behavior?
Range exposes a single part for both knobs & pins. This makes it impossible to style the knobs/pins differently when dual knobs is enabled.
## What is the new behavior?
- Fixes a bug where the knobs would swap A & B when they cross over each other
- Fixes the focus behavior so that dual knobs act the same as a single knob range when focusing a knob
- Adds the following classes to the host element when `dualKnobs` is enabled:
- `range-dual-knobs`
- `range-pressed-a` when the knob with name A is pressed
- `range-pressed-b` when the knob with name B is pressed
- `range-pressed-lower` when the lower knob is pressed
- `range-pressed-upper` when the upper knob is pressed
- Adds parts for the following:
- `knob-handle-a` — The container for the knob with the static `A` identity when `dualKnobs` is `true`. This identity does not change, even if the knobs cross and swap which one represents the lower or upper value.
- `knob-handle-b` — The container for the knob with the static `B` identity when `dualKnobs` is `true`. This identity does not change, even if the knobs cross and swap which one represents the lower or upper value.
- `knob-handle-lower` — The container for the knob whose current `value` is `lower` when `dualKnobs` is `true`. The lower and upper parts swap which knob handle they refer to when the knobs cross.
- `knob-handle-upper` — The container for the knob whose current `value` is `upper` when `dualKnobs` is `true`. The lower and upper parts swap which knob handle they refer to when the knobs cross.
- `pin-a` — The value indicator above the knob with the static `A` identity when `dualKnobs` is `true`. This identity does not change, even if the knobs cross and swap which one represents the lower or upper value.
- `pin-b` — The value indicator above the knob with the static `B` identity when `dualKnobs` is `true`. This identity does not change, even if the knobs cross and swap which one represents the lower or upper value.
- `pin-lower` — The value indicator above the knob whose current `value` is `lower` when `dualKnobs` is `true`. The lower and upper parts swap which pin they refer to when the knobs cross.
- `pin-upper` — The value indicator above the knob whose current `value` is `upper` when `dualKnobs` is `true`. The lower and upper parts swap which pin they refer to when the knobs cross.
- `knob-a` — The visual knob for the static `A` identity when `dualKnobs` is `true`. This identity does not change, even if the knobs cross and swap which one represents the lower or upper value.
- `knob-b` — The visual knob for the static `B` identity when `dualKnobs` is `true`. This identity does not change, even if the knobs cross and swap which one represents the lower or upper value.
- `knob-lower` — The visual knob whose current `value` is `lower` when `dualKnobs` is `true`. The lower and upper parts swap which knob they refer to when the knobs cross.
- `knob-upper` — The visual knob whose current `value` is `upper` when `dualKnobs` is `true`. The lower and upper parts swap which knob they refer to when the knobs cross.
- `activated` — Added to the knob-handle, knob, and pin when the knob is active. Only one set has this part at a time when `dualKnobs` is `true`.
- `focused` — Added to the knob-handle, knob, and pin that currently has focus. Only one set has this part at a time when `dualKnobs` is `true`.
- `hover` — Added to the knob-handle, knob, and pin when the knob has hover. Only one set has this part at a time when `dualKnobs` is `true`.
- `pressed` — Added to the knob-handle, knob, and pin that is currently being pressed to drag. Only one set has this part at a time when `dualKnobs` is `true`.
- Adds e2e tests for the following:
- customizing label part
- customizing bar parts
- customizing pin parts
- customizing tick parts
- customizing knob parts
- customizing dual knob a & b parts
- customizing dual knob lower & upper parts
- verifies that a & b parts stay on the original elements but lower & upper parts swap when the values swap
- Adds spec tests for the following:
- css classes
- value state classes
- boolean property classes
- pressed state classes
- shadow parts
- static shadow parts
- verifies the shadow parts exist based on the existence of certain range properties
- state shadow parts
- verifies the shadow parts exist based on the state of the range knob (pressed, focused, activated, hover)
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: N/A
---------
## What is the current behavior?
The inner structural element of list-header is not exposed as a shadow part, preventing users from being able to customize its styles directly.
## What is the new behavior?
- Exposes `inner` shadow part
- Adds e2e test coverage for customizing the shadow part
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: N/A
---------
## What is the current behavior?
The inner structural elements of item-option are not exposed as shadow parts, preventing users from being able to customize their styles directly.
## What is the new behavior?
- Exposes `inner` and `container` shadow parts
- Adds e2e test coverage for customizing the shadow parts
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: N/A
---------
## What is the current behavior?
The inner structural elements of item-divider are not exposed as shadow parts, preventing users from being able to customize their styles directly.
## What is the new behavior?
- Exposes `inner` and `container` shadow parts
- Adds e2e test coverage for customizing the shadow parts
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: N/A
---------
## What is the current behavior?
The inner structural elements of item are not exposed as shadow parts, preventing users from being able to customize their styles directly.
## What is the new behavior?
- Exposes `inner` and `container` shadow parts
- Adds e2e test coverage for customizing the shadow parts
- Removes css variables test, combining it with the shadow parts test
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Adds guidelines document establishing standardized naming conventions for CSS Shadow Parts in Ionic Framework components.
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
resolves#30279resolves#30359
## What is the current behavior?
While Ionic's `stencil.config.ts` sets `experimentalSlotFixes: true`,
the fixes never get applied at runtime. Ionic is using an external
runtime, so Ionic components import `defineCustomElement` from
`@stencil/core/internal/client` at runtime and this code has no
awareness of the project's stencil configuration.
This leads to a `NotFoundError` (Failed to execute 'removeChild' on
'Node') when filtering or dynamically removing radios in an
`ion-radio-group`. The error occurs because `ion-radio-group` wraps its
slotted content in an internal `<div>`.
## What is the new behavior?
By setting `externalRuntime: false`, Stencil generates a
project-specific file with `defineCustomElement` that components import.
This file has the project's build settings baked in, correctly applying
slot fixes.
Additionally, the internal wrapper `<div>` around the slotted content in
`ion-radio-group` is removed. With slot fixes correctly applied and the
wrapper removed, radios can be filtered or dynamically removed without
triggering `NotFoundError` or `DOMExceptions`.
## Does this introduce a breaking change?
- [ ] Yes
- [X] No
## Other information
External Runtime is enabled by default and designed for projects that
import Stencil components from multiple sources. This is flawed because
those components will not be running with the runtime settings for which
they were made.
Issue number: resolves#24524
---------
<!-- 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?
There is no way to know when the refresher has fully returned to its
inactive state after a pull gesture. The existing `ionStart` event fires
when pulling begins, but there is no corresponding end event. Watching
the progress property is insufficient because hitting zero doesn’t
necessarily mean the user has completed the pull gesture.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
Two new events are added to the refresher component:
- `ionPullStart`: Emitted when the user begins pulling down (same as
`ionStart`, which is now deprecated)
- `ionPullEnd`: Emitted when the refresher returns to inactive state,
with a `reason` property of `'complete'` or `'cancel'` indicating
whether the refresh operation completed successfully or was cancelled
This allows you to know both when the user is no longer touching the
screen AND when the refresher is ready to be pulled again.
## 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. -->
Test page:
https://ionic-framework-git-fw-6591-ionic1.vercel.app/src/components/refresher/test/basic/index.html
Current dev build:
```
8.7.17-dev.11770319814.172b4f50
```
---------
Co-authored-by: Patrick McDonald <764290+WhatsThatItsPat@users.noreply.github.com>
Issue number: resolves#30860
## What is the current behavior?
We have flaky tests in an ionic angular project that root cause are not
cleaned up timeouts.
I commented out the timeout in the searchbar componentWillLoad method.
and after several runs no flaky tests at all.
My guess -> test runs faster than the 300ms it takes til the timeout
runs. Everything is cleaned up, but not the ionic timeouts (i think i
saw something similar in other components)
## What is the new behavior?
Timeouts are cleaned on disconnect.
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
## Other information
Testrunner is vitest + angular 20 and latest ionic version 8.x
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?
When a CanDeactivate guard cancels a back navigation (like when it's
initiated by ion-back-button), the NavController’s explicit direction
state (back) is never consumed because consumeTransition() is not called
for canceled navigations. This stale direction leaks into the next
forward navigation, causing it to be incorrectly treated as a back/root
navigation.
## What is the new behavior?
The NavController now listens for NavigationCancel and NavigationError
router events and resets direction, animated, and animationBuilder back
to their defaults. This ensures stale state from a canceled navigation
does not affect subsequent navigations. The reset puts the NavController
into 'auto' mode, which correctly uses guessDirection for the next
navigation.
## 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
Current dev build:
```
8.7.18-dev.11771020096.1ca03a6d
```
Issue number: resolves#28411
---------
<!-- 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 modal is displayed on tablet-sized screens (>= 768px × >= 600px),
the `--ion-safe-area-*` CSS variables are explicitly set to 0px. This
was intended for inset modals that don't touch screen edges, but it
breaks safe area handling on newer iPads with Face ID/home indicators,
causing content to overlap with system UI elements.
## What is the new behavior?
Modals now dynamically handle safe-area insets based on their type and
position. This has to be done because modals that don't touch the edges
cannot have a safe area applied (because it will add unnecessary
padding), but modals that do touch the edges need to apply safe area
correctly or the edges will be obstructed by whatever is in the safe
area.
## 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. -->
[Modals test
page](https://ionic-framework-git-fw-6830-2-ionic1.vercel.app/src/components/modal/test/safe-area/index.html)
[Popovers test
page](https://ionic-framework-git-fw-6830-2-ionic1.vercel.app/src/components/popover/test/safe-area/index.html)
Current dev build:
```
8.7.18-dev.11770674094.18396f54
```
---------
Co-authored-by: ionitron <hi@ionicframework.com>
Issue number: resolves#30290
---------
## What is the current behavior?
The segment view swipe gesture can only be disabled by adding the `disabled` property and setting `opacity: 1`.
## What is the new behavior?
- Adds a new property, `swipeGesture`, to disable swiping on the segment view
- Adds an e2e test which verifies the styles blocking the swipe are correctly applied when `swipeGesture` is `false`
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Issue number: resolves#30638
---------
<!-- 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 using `ModalController.create()` or `PopoverController.create()` in
Angular, components rendered inside overlays cannot access non-global
services or tokens from the component tree. For example, route-scoped
services or Angular's Dir directive for bidirectional text support are
not accessible from within a modal, requiring complex workarounds with
wrapper components.
## What is the new behavior?
`ModalController.create()` and `PopoverController.create()` now accept
an optional injector property that allows passing a custom Angular
Injector. This enables overlay components to access services and tokens
that are not available in the root injector, such as route-scoped
services or the Dir directive from Angular CDK.
```typescript
const customInjector = Injector.create({
providers: [{ provide: MyService, useValue: myServiceInstance }],
parent: this.injector,
});
```
```typescript
const modal = await this.modalController.create({
component: MyModalComponent,
injector: customInjector,
});
```
## 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.17-dev.11769628168.11eca7cd
```
<!-- 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 Stencil Nightly Build workflow tests Ionic with the latest nightly
build of Stencil. The first step of the workflow updates Stencil, builds
Ionic core, and uploads the build files. Later steps download these
build files. Core's updated package.json is not uploaded with the build
files, so later steps are installing an old Stencil version, leading to
conflicts.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
Add core's package.json to the artifact upload. This will make all later
steps use the correct Stencil version.
Seven of the tests run `git diff` to ensure tests did not cause changes
in tracked files. Core's package.json would register as a change, so a
new step reverts package.json before running `git diff`.
## 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 | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://redirect.github.com/actions/checkout) |
action | patch | `v6.0.1` → `v6.0.2` |
---
### Release Notes
<details>
<summary>actions/checkout (actions/checkout)</summary>
###
[`v6.0.2`](https://redirect.github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v602)
[Compare
Source](https://redirect.github.com/actions/checkout/compare/v6.0.1...v6.0.2)
- Fix tag handling: preserve annotations and explicit fetch-tags by
[@​ericsciple](https://redirect.github.com/ericsciple) in
[#​2356](https://redirect.github.com/actions/checkout/pull/2356)
</details>
---
### Configuration
📅 **Schedule**: Branch creation - "every weekday before 11am" (UTC),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- 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:eyJjcmVhdGVkSW5WZXIiOiI0Mi44NS4xIiwidXBkYXRlZEluVmVyIjoiNDIuODUuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## What is the current behavior?
Content does not reflect the `fullscreen` property or add a class when it is enabled, making it harder to style.
## What is the new behavior?
- Adds `content-fullscreen` class to content when `fullscreen` is true
- Adds an e2e test verifying the class is applied
---------
Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>