Skip to content

Commit 20cae5b

Browse files
authored
chore(git): sync with main (#31120)
Sync next with main.
2 parents d1ad1ad + 9344b51 commit 20cae5b

35 files changed

Lines changed: 289 additions & 101 deletions

.github/workflows/assign-issues.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
issues: write
1212
steps:
1313
- name: 'Auto-assign issue'
14-
uses: pozil/auto-assign-issue@39c06395cbac76e79afc4ad4e5c5c6db6ecfdd2e # v2.2.0
14+
uses: pozil/auto-assign-issue@70adb98ca8b3941524e9ecde48e89067c4f96736 # v3.0.0
1515
with:
1616
assignees: brandyscarney, thetaPC, ShaneK
1717
numOfAssignee: 1

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [8.8.6](https://github.com/ionic-team/ionic-framework/compare/v8.8.5...v8.8.6) (2026-05-06)
7+
8+
9+
### Bug Fixes
10+
11+
* **action-sheet:** restore action-sheet-selected class on non-radio buttons ([#31109](https://github.com/ionic-team/ionic-framework/issues/31109)) ([c18502f](https://github.com/ionic-team/ionic-framework/commit/c18502f3efdec5440a11289235a93c62ce27ab89)), closes [#31090](https://github.com/ionic-team/ionic-framework/issues/31090)
12+
* **datetime:** prevent hidden-state observer from tearing down ready class on initial entry ([#31108](https://github.com/ionic-team/ionic-framework/issues/31108)) ([30b479a](https://github.com/ionic-team/ionic-framework/commit/30b479a53acbc16961002df256bec358dc11e7fa))
13+
* **segment:** segment drag would set disabled segment button checked ([#31112](https://github.com/ionic-team/ionic-framework/issues/31112)) ([44be424](https://github.com/ionic-team/ionic-framework/commit/44be424221bee11ffbe91c4b1fa0a4d56fe1ecac))
14+
15+
16+
17+
18+
619
## [8.8.5](https://github.com/ionic-team/ionic-framework/compare/v8.8.4...v8.8.5) (2026-04-29)
720

821

core/CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [8.8.6](https://github.com/ionic-team/ionic-framework/compare/v8.8.5...v8.8.6) (2026-05-06)
7+
8+
9+
### Bug Fixes
10+
11+
* **action-sheet:** restore action-sheet-selected class on non-radio buttons ([#31109](https://github.com/ionic-team/ionic-framework/issues/31109)) ([c18502f](https://github.com/ionic-team/ionic-framework/commit/c18502f3efdec5440a11289235a93c62ce27ab89)), closes [#31090](https://github.com/ionic-team/ionic-framework/issues/31090)
12+
* **datetime:** prevent hidden-state observer from tearing down ready class on initial entry ([#31108](https://github.com/ionic-team/ionic-framework/issues/31108)) ([30b479a](https://github.com/ionic-team/ionic-framework/commit/30b479a53acbc16961002df256bec358dc11e7fa))
13+
* **segment:** segment drag would set disabled segment button checked ([#31112](https://github.com/ionic-team/ionic-framework/issues/31112)) ([44be424](https://github.com/ionic-team/ionic-framework/commit/44be424221bee11ffbe91c4b1fa0a4d56fe1ecac))
14+
15+
16+
17+
18+
619
## [8.8.5](https://github.com/ionic-team/ionic-framework/compare/v8.8.4...v8.8.5) (2026-04-29)
720

821

core/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ionic/core",
3-
"version": "8.8.5",
3+
"version": "8.8.6",
44
"description": "Base components for Ionic",
55
"engines": {
66
"node": ">= 16"

core/scripts/vercel-build.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ generate_dir_index() {
6262
# Skip if an index.html already exists (it's an actual test page)
6363
[ -f "${dir}/index.html" ] && return
6464

65+
# Absolute hrefs based on url_path. Vercel does not redirect to add trailing
66+
# slashes, so a relative href like "basic/" from a URL without a trailing
67+
# slash resolves against the parent directory and breaks navigation.
68+
local parent_path="${url_path%/}"
69+
parent_path="${parent_path%/*}/"
70+
6571
local entries=""
6672
for child in "${dir}"/*/; do
6773
[ -d "${child}" ] || continue
@@ -70,7 +76,7 @@ generate_dir_index() {
7076
case "${name}" in *-snapshots|.*) continue ;; esac
7177
# Only include if there's at least one index.html somewhere underneath
7278
find "${child}" -name "index.html" -print -quit | grep -q . || continue
73-
entries="${entries}<a href=\"${name}/\">${name}/</a>\n"
79+
entries="${entries}<a href=\"${url_path}${name}/\">${name}/</a>\n"
7480
done
7581

7682
[ -z "${entries}" ] && return
@@ -92,7 +98,7 @@ generate_dir_index() {
9298
</head>
9399
<body>
94100
<h1>Index of ${url_path}</h1>
95-
<a class="up" href="../">../</a>
101+
<a class="up" href="${parent_path}">../</a>
96102
$(echo -e "${entries}")
97103
</body>
98104
</html>

core/src/components/action-sheet/action-sheet.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
584584
id={buttonId}
585585
class={{
586586
...buttonClass(b),
587-
'action-sheet-selected': isActiveRadio,
587+
...(isRadio && { 'action-sheet-selected': isActiveRadio }),
588588
}}
589589
onClick={() => {
590590
if (isRadio) {

core/src/components/action-sheet/test/basic/action-sheet.spec.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,36 @@ describe('action sheet: disabled buttons', () => {
5959
await expect(cancelButton.hasAttribute('disabled')).toBe(false);
6060
});
6161
});
62+
63+
describe('action sheet: selected role', () => {
64+
// https://github.com/ionic-team/ionic-framework/issues/31090
65+
it('should add the `action-sheet-selected` class to a button with `role="selected"`', async () => {
66+
const page = await newSpecPage({
67+
components: [ActionSheet],
68+
template: () => (
69+
<ion-action-sheet
70+
buttons={[
71+
{ text: 'Option A' },
72+
{ text: 'Option B', role: 'selected' },
73+
{ text: 'Option C' },
74+
{ text: 'Cancel', role: 'cancel' },
75+
]}
76+
overlayIndex={1}
77+
></ion-action-sheet>
78+
),
79+
});
80+
81+
const actionSheet = page.body.querySelector('ion-action-sheet')!;
82+
83+
await actionSheet.present();
84+
85+
const buttons = Array.from(actionSheet.querySelectorAll<HTMLButtonElement>('.action-sheet-button'));
86+
const selectedButton = buttons.find((btn) => btn.textContent?.trim() === 'Option B');
87+
88+
await expect(selectedButton).toBeDefined();
89+
await expect(selectedButton!.classList.contains('action-sheet-selected')).toBe(true);
90+
91+
const optionA = buttons.find((btn) => btn.textContent?.trim() === 'Option A');
92+
await expect(optionA!.classList.contains('action-sheet-selected')).toBe(false);
93+
});
94+
});

core/src/components/datetime/datetime.tsx

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ export class Datetime implements ComponentInterface {
140140
private todayParts!: DatetimeParts;
141141
private defaultParts!: DatetimeParts;
142142
private loadTimeout: ReturnType<typeof setTimeout> | undefined;
143+
/**
144+
* Set true only by `visibleCallback`. Lets `hiddenCallback` ignore the
145+
* synthetic "not intersecting" entry IntersectionObserver fires on
146+
* `observe()` when the host mounts offscreen.
147+
*/
148+
private hasBeenIntersecting = false;
143149

144150
private prevPresentation: string | null = null;
145151

@@ -1102,6 +1108,7 @@ export class Datetime implements ComponentInterface {
11021108
this.clearFocusVisible = undefined;
11031109
}
11041110
this.loadTimeoutCleanup();
1111+
this.hasBeenIntersecting = false;
11051112
}
11061113

11071114
/**
@@ -1145,8 +1152,23 @@ export class Datetime implements ComponentInterface {
11451152
return;
11461153
}
11471154

1155+
this.markReady();
1156+
};
1157+
1158+
private markReady = () => {
1159+
if (this.el.classList.contains('datetime-ready')) {
1160+
return;
1161+
}
11481162
this.initializeListeners();
11491163

1164+
/**
1165+
* TODO FW-2793: Datetime needs a frame to ensure that it
1166+
* can properly scroll contents into view. As a result
1167+
* we hide the scrollable content until after that frame
1168+
* so users do not see the content quickly shifting. The downside
1169+
* is that the content will pop into view a frame after. Maybe there
1170+
* is a better way to handle this?
1171+
*/
11501172
writeTask(() => {
11511173
this.el.classList.add('datetime-ready');
11521174
});
@@ -1175,19 +1197,8 @@ export class Datetime implements ComponentInterface {
11751197
return;
11761198
}
11771199

1178-
this.initializeListeners();
1179-
1180-
/**
1181-
* TODO FW-2793: Datetime needs a frame to ensure that it
1182-
* can properly scroll contents into view. As a result
1183-
* we hide the scrollable content until after that frame
1184-
* so users do not see the content quickly shifting. The downside
1185-
* is that the content will pop into view a frame after. Maybe there
1186-
* is a better way to handle this?
1187-
*/
1188-
writeTask(() => {
1189-
this.el.classList.add('datetime-ready');
1190-
});
1200+
this.hasBeenIntersecting = true;
1201+
this.markReady();
11911202
};
11921203
const visibleIO = new IntersectionObserver(visibleCallback, { threshold: 0.01, root: el });
11931204

@@ -1227,6 +1238,12 @@ export class Datetime implements ComponentInterface {
12271238
return;
12281239
}
12291240

1241+
// Ignore the initial "not intersecting" entry IntersectionObserver fires on observe().
1242+
if (!this.hasBeenIntersecting) {
1243+
return;
1244+
}
1245+
this.hasBeenIntersecting = false;
1246+
12301247
this.destroyInteractionListeners();
12311248

12321249
/**

core/src/components/datetime/test/basic/datetime.e2e.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
531531
*/
532532
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
533533
test.describe(title('datetime: IO fallback'), () => {
534-
test('should become ready even if IntersectionObserver never reports visible', async ({ page, skip }, testInfo) => {
535-
// TODO(FW-7284): Re-enable on WebKit after determining why it fails
536-
skip.browser('webkit', 'Wheel is not available in WebKit');
537-
534+
test('should become ready even if IntersectionObserver never reports visible', async ({ page }, testInfo) => {
538535
testInfo.annotations.push({
539536
type: 'issue',
540537
description: 'https://github.com/ionic-team/ionic-framework/issues/30706',

0 commit comments

Comments
 (0)