Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
- [Components](#version-9x-components)
- [Input](#version-9x-input)
- [Legacy Picker](#version-9x-legacy-picker)
- [Modal](#version-9x-modal)
- [Router Outlet](#version-9x-router-outlet)
- [Searchbar](#version-9x-searchbar)
- [Select](#version-9x-select)
Expand Down Expand Up @@ -73,6 +74,16 @@ The string form no longer behaves the same way. Because an HTML attribute coerce
- Remove any usages of `pickerController`. If using React, remove any usages of the `useIonPicker` hook. These controller-based APIs have been removed. Use the inline picker component instead.
- Remove any usages of the `PickerOptions`, `PickerButton`, `PickerColumn`, and `PickerColumnOption` type exports. These types were associated with the legacy picker and have been removed.

<h4 id="version-9x-modal">Modal</h4>

The `handleBehavior` property on `ion-modal` now defaults to `"cycle"` instead of `"none"`. For sheet modals that display a handle, this means the handle is now focusable and activating it (by click, keyboard, or screen reader) cycles the sheet through its available breakpoints. This matches the native iOS sheet behavior and keeps sheet modals operable for assistive technology users by default.

Sheet modals that relied on the handle being inert should set `handleBehavior="none"` to restore the previous behavior:

```html
<ion-modal handle-behavior="none"></ion-modal>
```

<h4 id="version-9x-router-outlet">Router Outlet</h4>

`ion-router-outlet` now exposes a `swipeGesture` property that controls the swipe-to-go-back gesture per outlet. This property defaults to `true` in `"ios"` mode and `false` in `"md"` mode.
Expand Down
2 changes: 1 addition & 1 deletion core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ ion-modal,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefin
ion-modal,prop,expandToScroll,boolean,true,false,false
ion-modal,prop,focusTrap,boolean,true,false,false
ion-modal,prop,handle,boolean | undefined,undefined,false,false
ion-modal,prop,handleBehavior,"cycle" | "none" | undefined,'none',false,false
ion-modal,prop,handleBehavior,"cycle" | "none" | undefined,'cycle',false,false
ion-modal,prop,htmlAttributes,undefined | { [key: string]: any; },undefined,false,false
ion-modal,prop,initialBreakpoint,number | undefined,undefined,false,false
ion-modal,prop,isOpen,boolean,false,false,false
Expand Down
8 changes: 4 additions & 4 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2003,8 +2003,8 @@ export namespace Components {
*/
"handle"?: boolean;
/**
* The interaction behavior for the sheet modal when the handle is pressed. Defaults to `"none"`, which means the modal will not change size or position when the handle is pressed. Set to `"cycle"` to let the modal cycle between available breakpoints when pressed. Handle behavior is unavailable when the `handle` property is set to `false` or when the `breakpoints` property is not set (using a fullscreen or card modal).
* @default 'none'
* The interaction behavior for the sheet modal when the handle is pressed. Handle behavior is unavailable when the `handle` property is set to `false` or when the `breakpoints` property is not set (using a fullscreen or card modal). Set to `"cycle"` to make the handle focusable and let the sheet modal cycle between available breakpoints when pressed. This keeps the sheet operable with assistive technology. Set to `"none"` to make the handle purely decorative when pressed and removed from the tab order. Defaults to `"cycle"`.
* @default 'cycle'
*/
"handleBehavior"?: ModalHandleBehavior;
/**
Expand Down Expand Up @@ -7152,8 +7152,8 @@ declare namespace LocalJSX {
*/
"handle"?: boolean;
/**
* The interaction behavior for the sheet modal when the handle is pressed. Defaults to `"none"`, which means the modal will not change size or position when the handle is pressed. Set to `"cycle"` to let the modal cycle between available breakpoints when pressed. Handle behavior is unavailable when the `handle` property is set to `false` or when the `breakpoints` property is not set (using a fullscreen or card modal).
* @default 'none'
* The interaction behavior for the sheet modal when the handle is pressed. Handle behavior is unavailable when the `handle` property is set to `false` or when the `breakpoints` property is not set (using a fullscreen or card modal). Set to `"cycle"` to make the handle focusable and let the sheet modal cycle between available breakpoints when pressed. This keeps the sheet operable with assistive technology. Set to `"none"` to make the handle purely decorative when pressed and removed from the tab order. Defaults to `"cycle"`.
* @default 'cycle'
*/
"handleBehavior"?: ModalHandleBehavior;
/**
Expand Down
17 changes: 12 additions & 5 deletions core/src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,20 @@ export class Modal implements ComponentInterface, OverlayInterface {
/**
* The interaction behavior for the sheet modal when the handle is pressed.
*
* Defaults to `"none"`, which means the modal will not change size or position when the handle is pressed.
* Set to `"cycle"` to let the modal cycle between available breakpoints when pressed.
* Handle behavior is unavailable when the `handle` property is set to
* `false` or when the `breakpoints` property is not set (using a
* fullscreen or card modal).
*
* Handle behavior is unavailable when the `handle` property is set to `false` or
* when the `breakpoints` property is not set (using a fullscreen or card modal).
* Set to `"cycle"` to make the handle focusable and let the sheet modal
* cycle between available breakpoints when pressed. This keeps the sheet
* operable with assistive technology.
*
* Set to `"none"` to make the handle purely decorative when pressed and
* removed from the tab order.
*
* Defaults to `"cycle"`.
*/
@Prop() handleBehavior?: ModalHandleBehavior = 'none';
@Prop() handleBehavior?: ModalHandleBehavior = 'cycle';

/**
* The component to display inside of the modal.
Expand Down
6 changes: 6 additions & 0 deletions core/src/components/modal/test/sheet/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@
>
Present Sheet Modal (HandleBehavior: Cycle)
</button>
<button
id="handle-behavior-none-modal"
onclick="presentModal({ handleBehavior: 'none', initialBreakpoint: 0.25, breakpoints: [0, 0.25, 0.5, 0.75, 1] })"
>
Present Sheet Modal (HandleBehavior: None)
</button>
<button id="custom-handle-modal" onclick="presentModal({ cssClass: 'custom-handle' })">
Present Sheet Modal (Custom Handle)
</button>
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/modal/test/sheet/modal.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
const modal = page.locator('ion-modal');

await page.click('#sheet-modal');
await page.click('#handle-behavior-none-modal');
await ionModalDidPresent.next();

const handle = page.locator('ion-modal .modal-handle');
Expand Down
Loading