From dec46b5d317080dd5d97dc056f0d8e6d4c8c45ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20M=2E?= Date: Fri, 3 Apr 2026 19:24:33 +0100 Subject: [PATCH 1/6] fix(tab-button): update dark palette focused background color (#31050) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue number: resolves resolves internal --------- ## What is the current behavior? In the dark palette, the `--ion-tab-bar-background-focused` CSS token was not defined. When a `ion-tab-button` receives focus, the `::after` overlay on `.button-native` falls back to `get-color-shade(#fff)` → `#e0e0e0` — a light grey that blends into the dark background and makes the focus indicator invisible. ## What is the new behavior? - `--ion-tab-bar-background-focused` is now defined in the dark palette: `#252525` for iOS and `#353535` for MD , providing a dark-appropriate focus indicator. The same token is added to `high-contrast-dark.scss` with the same values. - A screenshot e2e test is added under `tab-button/test/states/` (where the existing focused-state tests live) using `configs({ palettes: ['dark'] })` and `page.setContent()` with `class="ion-focused"` applied directly, matching the established pattern for focus-state testing in this component. ## Does this introduce a breaking change? - [ ] Yes - [X] No ## Other information The test triggers keyboard mode (required by `focus-visible.ts`) before focusing the inner `` element inside the tab button's shadow DOM, since calling `.focus()` on the host element is a no-op without `delegatesFocus`. - [Preview 1](https://ionic-framework-git-fw-6293-ionic1.vercel.app/src/components/tabs/test/basic?ionic:mode=ios&palette=dark) - [Preview 2](https://ionic-framework-git-fw-6293-ionic1.vercel.app/src/components/tabs/test/basic?ionic:mode=md&palette=dark) --------- Co-authored-by: ionitron Co-authored-by: Brandy Smith Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> --- .../tab-button/test/states/tab-button.e2e.ts | 22 ++++++++++++++++++ ...focus-ios-ltr-dark-Mobile-Chrome-linux.png | Bin 0 -> 1482 bytes ...ocus-ios-ltr-dark-Mobile-Firefox-linux.png | Bin 0 -> 1790 bytes ...focus-ios-ltr-dark-Mobile-Safari-linux.png | Bin 0 -> 1686 bytes ...-focus-md-ltr-dark-Mobile-Chrome-linux.png | Bin 0 -> 1305 bytes ...focus-md-ltr-dark-Mobile-Firefox-linux.png | Bin 0 -> 1538 bytes ...-focus-md-ltr-dark-Mobile-Safari-linux.png | Bin 0 -> 1432 bytes core/src/css/palettes/dark.scss | 2 ++ core/src/css/palettes/high-contrast-dark.scss | 2 ++ 9 files changed, 26 insertions(+) create mode 100644 core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Chrome-linux.png create mode 100644 core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Firefox-linux.png create mode 100644 core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Safari-linux.png create mode 100644 core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-md-ltr-dark-Mobile-Chrome-linux.png create mode 100644 core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-md-ltr-dark-Mobile-Firefox-linux.png create mode 100644 core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-md-ltr-dark-Mobile-Safari-linux.png diff --git a/core/src/components/tab-button/test/states/tab-button.e2e.ts b/core/src/components/tab-button/test/states/tab-button.e2e.ts index bd10cad844b..5af2a6f660b 100644 --- a/core/src/components/tab-button/test/states/tab-button.e2e.ts +++ b/core/src/components/tab-button/test/states/tab-button.e2e.ts @@ -80,3 +80,25 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c }); }); }); + +configs({ palettes: ['dark'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('tab-button: states in dark palette'), () => { + test.describe('focus', () => { + test('should render correct focus state in dark palette', async ({ page }) => { + await page.setContent( + ` + + + Favorites + + + `, + config + ); + + const tabBar = page.locator('ion-tab-bar'); + await expect(tabBar).toHaveScreenshot(screenshot('tab-button-focus')); + }); + }); + }); +}); diff --git a/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Chrome-linux.png b/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Chrome-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..14d96bb13658fd3abd2f2de83671402def9dfe3c GIT binary patch literal 1482 zcmai!c{~#e0LSO3C-H2Axk9{=Yx0;YOOD4JlL@6Va`c+bO>>RrPDO6gd_IIQ49zlS z9%YZpHH1A|jvVFVSab6{?~nIy@1Ni2`}uwU|7Ko6+KG$Givj=uafH1M3IGt$Ip$wQ z1dq33sbT^EIFX33xqKC0wlY2AsBlk_xxsy%oMjs4>nY{bi|Z@IsNC(zU;Y{hvlHrX z(P~g}TDqouX3IxnPgYzM4&3T$wiG?D8>s@O0QC*W*?KsK5y<>CBy@AUBZ^V%<=Jm0 z=SV=oq4Bq8p&G?BE}9nyB;fJI0DyVOGm|i4By(s8D1djn7|YLy{K*B7blyg!3w%!4 zM+_vWpC%#zwoU;&RJ8*10#yNi8Nj3qKi17~!4P$%Xs=z5f!*hc9`zMzq&%V;a?qWn zqsY_@WVP4X(v!ZYKx!C3SltxVeRgZlrryI?QIH8bw<5<;dtcF6`0-ox;z_0fzwyij z0h?qk(SISl^hzrTQ_IoI%R7Mo zaZwRXoG(fZY~V~Cd9SBcg5LE!rB};1KFdEb36)~yTDjW3kcK(H2EV6B&0BV9gjPU- zDEq1w1}P%W8bmKM)W*0rw2{z6Z-X)8P z$L`2#D}#%q)uQ!uABw|qa8;5-?*Iv;EUOGgGI+b)EBoeOJ^U^qOyRUpk9a)I-=xf# z;Je&ym+X?rT~>JDOgO8IeZhc{313=MceDL!2F2oRZ^Pr)?;IRp@peXnZslb^+Y1RL z^ANs^e;=kHT}cc2lyum1Q@a z*;%JSQPftYsPtu?L$v9w-v_UqH=~)Dg0!lQJT+w~StaF7MP898t>z5%p~aJFzEG9! zv$HX-a!+$5e zXesLu$#cqI!rQI~m7*@Z312LrIVe?@F)lNfWbPRnm75s59?p1_SZ>cyNJdQ49nU`z zGkrF1Bk-N8OPJyHN08ao*k-IEr`mC2o}cj{jA%@{C>!PuGh)R|ODhh{71^%(v}?dY zca`T@LWi~Q);gV2r}>I%B)W;zW?N!fGzTleRQuq*bIC{2V0>gexM(rAs0p%cT-{b{ zl+we642zG%bSona?K)p9;I))3@*IX8=Fjuh%*OLUevy uqW=lie|iOa9O9#+g*ai0V>tP5iiH5w1pWM_9+#lw2Y|3e+B91E5dQ&ex482F literal 0 HcmV?d00001 diff --git a/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Firefox-linux.png b/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Firefox-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..841928b47fabd10488053aaee8946bb7963fbe2e GIT binary patch literal 1790 zcmd6o{Xf%tAIHC2vu3R1W`s@~>lik2JGYs;Yje|<+?-v~q@^6>wqw#MqokuQH(57W zIGKo5?nUj;6wZYs>THjigzUJTn}cPD^ZgI5U$0+2kJk^+A71bG=k?ppg1V z002-vRIlRz03m?d1_1|8Vvb!N0Knh)c)16qGUX4Xe!(ZSv$Ovdn)1$~VZg$RS?+J< zYi+FFm)-BHjoSBk9-B5zx07;D0S%M@u(OrtzC z#rfpGW%LT^)ouwhIoGkn^kDL><}(yNpYM+_P|XKaQ#s_|om+qW;%_Wbh18*3LA!eE)(z2)V^B4_qf0aF-SdgQXx2G);iXN#>=0RJnNIT#;{lE6B84PA!H8<_4@;7c2KOI?zhB2a8Y(AuO(oQ zhglMde>#ry;WMsjtJLpYQZ?+mTT~v^#Yz*e&SlkMRC0^wY|N4>(>JjYYN3|b6KEhZBF8slG4I+X46=nH8Pnjbj4!;WfkzX{byx^BD^KG zCA+rQJ&(r}iRbh<-EvlahG>N3WF!lb*oVcaC}xYl(PRT}^%0&{=rG!z0ts=>nDZz)7YX5*b!mlszizx3o4 zwjfN6|H``VIDuc?D5vW(PYbQ ziR?pvsApyK9Fx!9*7Ka{yYz^{5fy(&QXn(Pha=oA3`lX@ni?}#_sXiO+8f6jlSYR^ zpC|l^ZVNa=(N~Ul?f%c~igML9I54n+zKp^1#BcYSMplcQ(pIa*eG8+)S`*T(n}s9b zD{Pw1T~{iV!$U(@xm;e{(B0i#gAcHjw*OR14yAq6hiZ;mdqTCv>X3%bbS=d91YSN8 ziEIkV(h53vuIhD9Pc0c5Zbr1Q5K9a#m@genHIRxIDe~bePSo_(dmaVQ>t+P1CJVEz zT$%dGuxcqc8(7Z}U;+@R#YDNZm7agagP}n@9x~|%%9=qnEH-$2%<+XitaB-gN{Pj3vAz>1aBSYbcV+=UP z2BwPxXEqox?Fbf0# zPy%PJV<4Id*+7-~Wk|Wx> z3MxQA4?~XF&*|3y-7IL7*Nu$#27rJ%DAmbl5uh73=<$Ep6&(_E0NV9lM|iea7w}&L Ne7tF1Pd!d${sU+KH;@1T literal 0 HcmV?d00001 diff --git a/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Safari-linux.png b/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-ios-ltr-dark-Mobile-Safari-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..86b46f9a31fa76252c5ba0992b24727b84501b46 GIT binary patch literal 1686 zcmb_dYgE!{6aQ;rE)tox$tK4w%gdX-YF>yG<<%%-MK(2)yd|4?SxVVZGbGo`5h2Ys zO)VE}^<8gic$Yv^H@uQsE{kMXW)ezNC~l=ey8rL{Wk2kEnCF>u=9y>CZ+?9`o3Rn7|9i#b8h9Acg8lsf-ULzw8k=c;_!GvUFpOha0ATb# zJkIw-I_K>(InjJ$*U+-2V2cZTsq918VQ#licW9hxOA0Q(q$nsn z{QK{+dwMVq;wvM4yRRQ31Gi%>9h==F@$KFW%Dy)Hy?b@~kbF7$HQh>HgD_c71yKln-NdNp!}> z#^yw5=o}Tjy1KkqB9Q=p$YgFF9)n`>Hy>v1+}R)8u%nga*nR(^Ci>+vdX9QC*%|di z_cNq7{l?^EkYP3e&(95Ojt)9`a%gM}1{$wlzdpwu96VB6Tbp%vcVko2fGWj|jq5de z3Wj9(eBE&3%5i(#{?boj&82!SCyB4ap4>47I}_j8(cywZ4QaL7i^JbjC<4ZsYm1Z( z$@L{jV&meNMMZFo)wb)$HUlD;MU{$7r&r|VLFjaPeM7?@E|IpnMBZg-$;MglE5Y|f zJ6kwMEBdoHtulO2C=~1H|09Jd?3x-If@GhmF$l@@lP9}NMqS+8a%VLQ;!+1Rmk5PI z6DX9u*N?eivD^9uv<37JFE^{zY9uE8r?Rr0&+ljChbCt|y*f2D<=D^&r&u)9*Y~U6 z$MMU{%D@lMNVt_Z9fw95{nFW4dSoZeoa-&O8RGWFA+iIqN= z#RV4506J5TK7amv&t+X1!S?WO(-(81d;)<0P_+uYc4dVAQ)pg7a`N!P$^kF0f>}-cg$u<5TT#{F z{F@aOPt&|mo}S-?g~_^vRmT_WWTfC=KQeg_h{&{jFvT-4I@+qHre`~VjFErsF$ zfj|gEqALcYw<|w#4wv0o0E5HVsmw27Mu|yDahERLO2=4qpIKFHEmI&k zB!2j?{h6fFJA)J%IrAZEG}hHJZB{RK@y24mmbfqLKFc#bI2_K{x_DYH4+se{Pfblt zNlVkNt;Abl(qpFOtg{Os{SW1ferpJ+ThwS4#(zEt{2`T2K7U^6ZMOqDDU}{^+`0D_ zL93G30U(J72M6W7%^e*#q*Cc@xW6Yij!ZTXxgd~8y%Vet%nWl$yBWAPEb64ljE!<( zFqr;ARI7zITKMo*E#9`I>fSws$Ym)VT$&dbh>{UXIPF)@+MU|_m8-m7Id%F9C{ zA_~ZeH*)^9p`oKgLqnOub-u4)R{Qhi4|Z9k3pVXzU)n*P(YHH!i@M_3wVA*bMvF;@CQ?m z88I0G}SBDPd0K1s^rDl%mc6L|$HA87BJ8%371X!$vL{p-?K3AXWEvGzM}~u6$*vECBqe#tJgEk*aKaUMka1@xt+iAJRJ?XJnv$^ z3g1xm>-?+Q1%gqfQn~HX!9Yn{eD;861^HhYpMM+1u>RtW6pQU^p&O7b9H&OoyM^1} OZUOK|h&Y~KOwL~jT{?0A literal 0 HcmV?d00001 diff --git a/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-md-ltr-dark-Mobile-Chrome-linux.png b/core/src/components/tab-button/test/states/tab-button.e2e.ts-snapshots/tab-button-focus-md-ltr-dark-Mobile-Chrome-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..e12f984796d8456670a880440b63edfb62d9215a GIT binary patch literal 1305 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 literal 0 HcmV?d00001 diff --git a/core/src/css/palettes/dark.scss b/core/src/css/palettes/dark.scss index 0c5ef08dd93..18179f2e2e8 100644 --- a/core/src/css/palettes/dark.scss +++ b/core/src/css/palettes/dark.scss @@ -126,6 +126,7 @@ $colors: ( --ion-text-color-step-900: #1a1a1a; --ion-text-color-step-950: #0d0d0d; --ion-item-background: #000000; + --ion-tab-bar-background-focused: #252525; --ion-card-background: #1c1c1d; } @@ -183,6 +184,7 @@ $colors: ( --ion-item-background: #1e1e1e; --ion-toolbar-background: #1f1f1f; --ion-tab-bar-background: #1f1f1f; + --ion-tab-bar-background-focused: #353535; --ion-card-background: #1e1e1e; } } diff --git a/core/src/css/palettes/high-contrast-dark.scss b/core/src/css/palettes/high-contrast-dark.scss index e0f3b8aeb57..c5533a12405 100644 --- a/core/src/css/palettes/high-contrast-dark.scss +++ b/core/src/css/palettes/high-contrast-dark.scss @@ -119,6 +119,7 @@ $lightest-text-color: $text-color; --ion-text-color-rgb: #{color-to-rgb-list($text-color)}; --ion-item-background: #000000; --ion-card-background: #1c1c1d; + --ion-tab-bar-background-focused: #252525; /// Only the item borders should increase in contrast /// Borders for elements like toolbars should remain the same @@ -185,6 +186,7 @@ $lightest-text-color: $text-color; --ion-item-background: #1e1e1e; --ion-toolbar-background: #1f1f1f; --ion-tab-bar-background: #1f1f1f; + --ion-tab-bar-background-focused: #353535; --ion-card-background: #1e1e1e; /// Only the item borders should increase in contrast From 308aef569d8c6ebc3ad2186bca6969da8e4b2a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Louren=C3=A7o?= Date: Tue, 7 Apr 2026 08:36:37 +0000 Subject: [PATCH 2/6] fix(datetime): multiple month selected and flakiness display (#31053) Issue number: resolves internal --------- ## What is the current behavior? Currently, the Datepicker keeps all the months visited as selected instead of only the one that is really selected On iOS devices, the month picker sometimes doesn't appear since the `datepicker-ready` class is not added ## What is the new behavior? Only the selected month appears selected in the month picker On iOS devices, an additional validation is done to add the `datepicker-ready` class ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information The [Basic](https://ionic-framework-7el9b9l3f-ionic1.vercel.app/src/components/datetime/test/basic/?ionic:theme=ionic) test should be used to test the multiple-month selection case --- core/src/components/datetime/datetime.tsx | 17 +++++++-- .../datetime/test/basic/datetime.e2e.ts | 37 +++++++++++++++++++ .../picker-column/picker-column.tsx | 6 +-- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx index c591972fd8d..e73cd55e0b8 100644 --- a/core/src/components/datetime/datetime.tsx +++ b/core/src/components/datetime/datetime.tsx @@ -1086,6 +1086,9 @@ export class Datetime implements ComponentInterface { connectedCallback() { this.clearFocusVisible = startFocusVisible(this.el).destroy; + this.loadTimeout = setTimeout(() => { + this.ensureReadyIfVisible(); + }, 100); } disconnectedCallback() { @@ -1093,9 +1096,7 @@ export class Datetime implements ComponentInterface { this.clearFocusVisible(); this.clearFocusVisible = undefined; } - if (this.loadTimeout) { - clearTimeout(this.loadTimeout); - } + this.loadTimeoutCleanup(); } /** @@ -1146,6 +1147,13 @@ export class Datetime implements ComponentInterface { }); }; + private loadTimeoutCleanup = () => { + if (this.loadTimeout) { + clearTimeout(this.loadTimeout); + this.loadTimeout = undefined; + } + }; + componentDidLoad() { const { el, intersectionTrackerRef } = this; @@ -1193,7 +1201,10 @@ export class Datetime implements ComponentInterface { * we still initialize listeners and mark the component as ready. * * We schedule this after everything has had a chance to run. + * + * We also clean up the load timeout to ensure that we don't have multiple timeouts running. */ + this.loadTimeoutCleanup(); this.loadTimeout = setTimeout(() => { this.ensureReadyIfVisible(); }, 100); diff --git a/core/src/components/datetime/test/basic/datetime.e2e.ts b/core/src/components/datetime/test/basic/datetime.e2e.ts index 6104d0014cf..bbc6033374f 100644 --- a/core/src/components/datetime/test/basic/datetime.e2e.ts +++ b/core/src/components/datetime/test/basic/datetime.e2e.ts @@ -349,6 +349,43 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { }); }); +/** + * This behavior does not differ across + * modes/directions. + */ + +configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('datetime: month picker selection'), () => { + test('datetime: month picker selection', async ({ page }) => { + await page.setContent( + ` + + `, + config + ); + + await page.locator('.datetime-ready').waitFor(); + + const nextMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button').nth(1); + const monthYearButton = page.locator('ion-datetime .calendar-month-year'); + + await expect(monthYearButton).toHaveText(/May 2022/); + + await nextMonthButton.click(); + await expect(monthYearButton).toHaveText(/June 2022/); + + await nextMonthButton.click(); + await expect(monthYearButton).toHaveText(/July 2022/); + + await monthYearButton.click(); + await page.waitForChanges(); + + const selectedMonthOptions = page.locator('.month-column ion-picker-column-option.option-active'); + await expect(selectedMonthOptions).toHaveCount(1); + }); + }); +}); + /** * This behavior does not differ across * modes/directions. diff --git a/core/src/components/picker-column/picker-column.tsx b/core/src/components/picker-column/picker-column.tsx index 905ba8cf81e..53d6ca90d17 100644 --- a/core/src/components/picker-column/picker-column.tsx +++ b/core/src/components/picker-column/picker-column.tsx @@ -1,7 +1,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from '@stencil/core'; import { doc } from '@utils/browser'; -import { getElementRoot, raf } from '@utils/helpers'; +import { raf } from '@utils/helpers'; import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '@utils/native/haptic'; import { isPlatform } from '@utils/platform'; import { createColorClasses } from '@utils/theme'; @@ -122,9 +122,7 @@ export class PickerColumn implements ComponentInterface { * Because this initial call to scrollActiveItemIntoView has to fire before * the scroll listener is set up, we need to manage the active class manually. */ - const oldActive = getElementRoot(el).querySelector( - `.${PICKER_ITEM_ACTIVE_CLASS}` - ); + const oldActive = el.querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`); if (oldActive) { this.setPickerItemActiveState(oldActive, false); } From f4ac4459f8317bd5eeff7d4809f9cb0991c8efd9 Mon Sep 17 00:00:00 2001 From: OS-jacobbell <228905018+OS-jacobbell@users.noreply.github.com> Date: Tue, 14 Apr 2026 07:27:28 -0600 Subject: [PATCH 3/6] fix(checkbox): show labels after page navigation (#31062) Issue number: resolves #31052 --------- ## What is the current behavior? After a page navigation, ion-checkbox's `onslotchange` event fires before the element's `textContent` has been updated. It is called again after `textContent` becomes readable on Safari, but is not called again after the `textContent` becomes readable on Chrome and Firefox. ## What is the new behavior? - Uses `MutationObserver` instead of `onslotchange` and fires specifically on character data changes. This ensures `hasLabelContent` is up to date. - `MutationObserver` does not fire on load, so `hasLabelContent` is initialized in `connectedCallback` ## Does this introduce a breaking change? - [ ] Yes - [X] No --- core/src/components/checkbox/checkbox.tsx | 68 ++++++++++++----------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/core/src/components/checkbox/checkbox.tsx b/core/src/components/checkbox/checkbox.tsx index 8a25b9200d5..99cb13c474a 100644 --- a/core/src/components/checkbox/checkbox.tsx +++ b/core/src/components/checkbox/checkbox.tsx @@ -151,44 +151,54 @@ export class Checkbox implements ComponentInterface { connectedCallback() { const { el } = this; - // Watch for class changes to update validation state. if (Build.isBrowser && typeof MutationObserver !== 'undefined') { - this.validationObserver = new MutationObserver(() => { - const newIsInvalid = checkInvalidState(el); - if (this.isInvalid !== newIsInvalid) { - this.isInvalid = newIsInvalid; - /** - * Screen readers tend to announce changes - * to `aria-describedby` when the attribute - * is changed during a blur event for a - * native form control. - * However, the announcement can be spotty - * when using a non-native form control - * and `forceUpdate()`. - * This is due to `forceUpdate()` internally - * rescheduling the DOM update to a lower - * priority queue regardless if it's called - * inside a Promise or not, thus causing - * the screen reader to potentially miss the - * change. - * By using a State variable inside a Promise, - * it guarantees a re-render immediately at - * a higher priority. - */ - Promise.resolve().then(() => { - this.hintTextId = this.getHintTextId(); - }); + this.validationObserver = new MutationObserver((mutations) => { + // Watch for label content changes + if (mutations.some((mutation) => mutation.type === 'characterData' || mutation.type === 'childList')) { + this.hasLabelContent = this.el.textContent !== ''; + } + // Watch for class changes to update validation state. + if (mutations.some((mutation) => mutation.type === 'attributes' && mutation.target === el)) { + const newIsInvalid = checkInvalidState(el); + if (this.isInvalid !== newIsInvalid) { + this.isInvalid = newIsInvalid; + /** + * Screen readers tend to announce changes + * to `aria-describedby` when the attribute + * is changed during a blur event for a + * native form control. + * However, the announcement can be spotty + * when using a non-native form control + * and `forceUpdate()`. + * This is due to `forceUpdate()` internally + * rescheduling the DOM update to a lower + * priority queue regardless if it's called + * inside a Promise or not, thus causing + * the screen reader to potentially miss the + * change. + * By using a State variable inside a Promise, + * it guarantees a re-render immediately at + * a higher priority. + */ + Promise.resolve().then(() => { + this.hintTextId = this.getHintTextId(); + }); + } } }); this.validationObserver.observe(el, { attributes: true, attributeFilter: ['class'], + characterData: true, + childList: true, + subtree: true, }); } // Always set initial state this.isInvalid = checkInvalidState(el); + this.hasLabelContent = this.el.textContent !== ''; } componentWillLoad() { @@ -267,10 +277,6 @@ export class Checkbox implements ComponentInterface { ev.stopPropagation(); }; - private onSlotChange = () => { - this.hasLabelContent = this.el.textContent !== ''; - }; - private getHintTextId(): string | undefined { const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this; @@ -387,7 +393,7 @@ export class Checkbox implements ComponentInterface { id={this.inputLabelId} onClick={this.onDivLabelClick} > - + {this.renderHintText()}
From b431b4c94450b1176fa4e97792861b66da88741c Mon Sep 17 00:00:00 2001 From: ionitron Date: Wed, 15 Apr 2026 18:12:24 +0000 Subject: [PATCH 4/6] v8.8.4 --- CHANGELOG.md | 13 +++++++++++++ core/CHANGELOG.md | 13 +++++++++++++ core/package-lock.json | 6 +++--- core/package.json | 2 +- lerna.json | 2 +- packages/angular-server/CHANGELOG.md | 8 ++++++++ packages/angular-server/package-lock.json | 8 ++++---- packages/angular-server/package.json | 4 ++-- packages/angular/CHANGELOG.md | 8 ++++++++ packages/angular/package-lock.json | 8 ++++---- packages/angular/package.json | 4 ++-- packages/docs/CHANGELOG.md | 8 ++++++++ packages/docs/package-lock.json | 6 +++--- packages/docs/package.json | 2 +- packages/react-router/CHANGELOG.md | 8 ++++++++ packages/react-router/package-lock.json | 8 ++++---- packages/react-router/package.json | 4 ++-- packages/react/CHANGELOG.md | 8 ++++++++ packages/react/package-lock.json | 8 ++++---- packages/react/package.json | 4 ++-- packages/vue-router/CHANGELOG.md | 8 ++++++++ packages/vue-router/package-lock.json | 8 ++++---- packages/vue-router/package.json | 4 ++-- packages/vue/CHANGELOG.md | 8 ++++++++ packages/vue/package-lock.json | 8 ++++---- packages/vue/package.json | 4 ++-- 26 files changed, 127 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fae4854106..84abbbee409 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + + +### Bug Fixes + +* **checkbox:** show labels after page navigation ([#31062](https://github.com/ionic-team/ionic-framework/issues/31062)) ([f4ac445](https://github.com/ionic-team/ionic-framework/commit/f4ac4459f8317bd5eeff7d4809f9cb0991c8efd9)), closes [#31052](https://github.com/ionic-team/ionic-framework/issues/31052) +* **datetime:** multiple month selected and flakiness display ([#31053](https://github.com/ionic-team/ionic-framework/issues/31053)) ([308aef5](https://github.com/ionic-team/ionic-framework/commit/308aef569d8c6ebc3ad2186bca6969da8e4b2a8d)) +* **tab-button:** update dark palette focused background color ([#31050](https://github.com/ionic-team/ionic-framework/issues/31050)) ([dec46b5](https://github.com/ionic-team/ionic-framework/commit/dec46b5d317080dd5d97dc056f0d8e6d4c8c45ac)) + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 1fd2212efdf..ee45ffd629a 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + + +### Bug Fixes + +* **checkbox:** show labels after page navigation ([#31062](https://github.com/ionic-team/ionic-framework/issues/31062)) ([f4ac445](https://github.com/ionic-team/ionic-framework/commit/f4ac4459f8317bd5eeff7d4809f9cb0991c8efd9)), closes [#31052](https://github.com/ionic-team/ionic-framework/issues/31052) +* **datetime:** multiple month selected and flakiness display ([#31053](https://github.com/ionic-team/ionic-framework/issues/31053)) ([308aef5](https://github.com/ionic-team/ionic-framework/commit/308aef569d8c6ebc3ad2186bca6969da8e4b2a8d)) +* **tab-button:** update dark palette focused background color ([#31050](https://github.com/ionic-team/ionic-framework/issues/31050)) ([dec46b5](https://github.com/ionic-team/ionic-framework/commit/dec46b5d317080dd5d97dc056f0d8e6d4c8c45ac)) + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) diff --git a/core/package-lock.json b/core/package-lock.json index 01a06435345..8bef7f2f1f7 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/core", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/core", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT", "dependencies": { "@stencil/core": "4.43.0", @@ -9829,4 +9829,4 @@ } } } -} +} \ No newline at end of file diff --git a/core/package.json b/core/package.json index 47566399094..4321a90686f 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "8.8.3", + "version": "8.8.4", "description": "Base components for Ionic", "engines": { "node": ">= 16" diff --git a/lerna.json b/lerna.json index e79ac7702c2..ba3e4cc2dcf 100644 --- a/lerna.json +++ b/lerna.json @@ -3,5 +3,5 @@ "core", "packages/*" ], - "version": "8.8.3" + "version": "8.8.4" } \ No newline at end of file diff --git a/packages/angular-server/CHANGELOG.md b/packages/angular-server/CHANGELOG.md index 68ecf941df3..e92a2268e2e 100644 --- a/packages/angular-server/CHANGELOG.md +++ b/packages/angular-server/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + +**Note:** Version bump only for package @ionic/angular-server + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) **Note:** Version bump only for package @ionic/angular-server diff --git a/packages/angular-server/package-lock.json b/packages/angular-server/package-lock.json index eaa09666b5b..62015e76228 100644 --- a/packages/angular-server/package-lock.json +++ b/packages/angular-server/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular-server", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular-server", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT", "dependencies": { - "@ionic/core": "^8.8.3" + "@ionic/core": "^8.8.4" }, "devDependencies": { "@angular-eslint/eslint-plugin": "^16.0.0", @@ -11289,4 +11289,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/angular-server/package.json b/packages/angular-server/package.json index 6e7325b33e3..2af2f292161 100644 --- a/packages/angular-server/package.json +++ b/packages/angular-server/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular-server", - "version": "8.8.3", + "version": "8.8.4", "description": "Angular SSR Module for Ionic", "keywords": [ "ionic", @@ -62,6 +62,6 @@ }, "prettier": "@ionic/prettier-config", "dependencies": { - "@ionic/core": "^8.8.3" + "@ionic/core": "^8.8.4" } } diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 66721281c95..0c73bb9366f 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + +**Note:** Version bump only for package @ionic/angular + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) **Note:** Version bump only for package @ionic/angular diff --git a/packages/angular/package-lock.json b/packages/angular/package-lock.json index 90b33a3e6b3..b9c31ace5a7 100644 --- a/packages/angular/package-lock.json +++ b/packages/angular/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/angular", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT", "dependencies": { - "@ionic/core": "^8.8.3", + "@ionic/core": "^8.8.4", "ionicons": "^8.0.13", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" @@ -9095,4 +9095,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/angular/package.json b/packages/angular/package.json index 2211afd24b3..3785f542d0a 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular", - "version": "8.8.3", + "version": "8.8.4", "description": "Angular specific wrappers for @ionic/core", "keywords": [ "ionic", @@ -48,7 +48,7 @@ } }, "dependencies": { - "@ionic/core": "^8.8.3", + "@ionic/core": "^8.8.4", "ionicons": "^8.0.13", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" diff --git a/packages/docs/CHANGELOG.md b/packages/docs/CHANGELOG.md index 588ab851d3d..2a483528e35 100644 --- a/packages/docs/CHANGELOG.md +++ b/packages/docs/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + +**Note:** Version bump only for package @ionic/docs + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) **Note:** Version bump only for package @ionic/docs diff --git a/packages/docs/package-lock.json b/packages/docs/package-lock.json index 6e6bd26dc7a..158656a20f7 100644 --- a/packages/docs/package-lock.json +++ b/packages/docs/package-lock.json @@ -1,13 +1,13 @@ { "name": "@ionic/docs", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/docs", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT" } } -} +} \ No newline at end of file diff --git a/packages/docs/package.json b/packages/docs/package.json index 91c1147613d..71eabacc599 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/docs", - "version": "8.8.3", + "version": "8.8.4", "description": "Pre-packaged API documentation for the Ionic docs.", "main": "core.json", "types": "core.d.ts", diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index d7185dd9b1d..4354d774ac4 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + +**Note:** Version bump only for package @ionic/react-router + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) **Note:** Version bump only for package @ionic/react-router diff --git a/packages/react-router/package-lock.json b/packages/react-router/package-lock.json index dc82458d0e3..94f944650a9 100644 --- a/packages/react-router/package-lock.json +++ b/packages/react-router/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react-router", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/react-router", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT", "dependencies": { - "@ionic/react": "^8.8.3", + "@ionic/react": "^8.8.4", "tslib": "*" }, "devDependencies": { @@ -6847,4 +6847,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/packages/react-router/package.json b/packages/react-router/package.json index e77fef9f281..ed337f5b494 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react-router", - "version": "8.8.3", + "version": "8.8.4", "description": "React Router wrapper for @ionic/react", "keywords": [ "ionic", @@ -36,7 +36,7 @@ "dist/" ], "dependencies": { - "@ionic/react": "^8.8.3", + "@ionic/react": "^8.8.4", "tslib": "*" }, "peerDependencies": { diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 0f8400c8511..dc8997adad5 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + +**Note:** Version bump only for package @ionic/react + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) **Note:** Version bump only for package @ionic/react diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 3395ac5f3dc..821b953f957 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/react", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT", "dependencies": { - "@ionic/core": "^8.8.3", + "@ionic/core": "^8.8.4", "ionicons": "^8.0.13", "tslib": "*" }, @@ -11916,4 +11916,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/react/package.json b/packages/react/package.json index a08514a5476..d7253110c7e 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react", - "version": "8.8.3", + "version": "8.8.4", "description": "React specific wrapper for @ionic/core", "keywords": [ "ionic", @@ -40,7 +40,7 @@ "css/" ], "dependencies": { - "@ionic/core": "^8.8.3", + "@ionic/core": "^8.8.4", "ionicons": "^8.0.13", "tslib": "*" }, diff --git a/packages/vue-router/CHANGELOG.md b/packages/vue-router/CHANGELOG.md index 00d1ab61982..ea8af11eccb 100644 --- a/packages/vue-router/CHANGELOG.md +++ b/packages/vue-router/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + +**Note:** Version bump only for package @ionic/vue-router + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) **Note:** Version bump only for package @ionic/vue-router diff --git a/packages/vue-router/package-lock.json b/packages/vue-router/package-lock.json index 9c7b1d57853..05b1320c660 100644 --- a/packages/vue-router/package-lock.json +++ b/packages/vue-router/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue-router", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue-router", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT", "dependencies": { - "@ionic/vue": "^8.8.3" + "@ionic/vue": "^8.8.4" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", @@ -12994,4 +12994,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index 96fbba44ad2..b1ae2a0db94 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue-router", - "version": "8.8.3", + "version": "8.8.4", "description": "Vue Router integration for @ionic/vue", "scripts": { "test.spec": "jest", @@ -44,7 +44,7 @@ }, "homepage": "https://github.com/ionic-team/ionic-framework#readme", "dependencies": { - "@ionic/vue": "^8.8.3" + "@ionic/vue": "^8.8.4" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 425c7e49817..30c774c6c81 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.8.4](https://github.com/ionic-team/ionic-framework/compare/v8.8.3...v8.8.4) (2026-04-15) + +**Note:** Version bump only for package @ionic/vue + + + + + ## [8.8.3](https://github.com/ionic-team/ionic-framework/compare/v8.8.2...v8.8.3) (2026-04-01) **Note:** Version bump only for package @ionic/vue diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index a5c15bc6024..d1aba690bf3 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue", - "version": "8.8.3", + "version": "8.8.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/vue", - "version": "8.8.3", + "version": "8.8.4", "license": "MIT", "dependencies": { - "@ionic/core": "^8.8.3", + "@ionic/core": "^8.8.4", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" }, @@ -4022,4 +4022,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/packages/vue/package.json b/packages/vue/package.json index 372305c4b78..277719e7c3b 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue", - "version": "8.8.3", + "version": "8.8.4", "description": "Vue specific wrapper for @ionic/core", "scripts": { "eslint": "eslint src", @@ -68,7 +68,7 @@ "vue-router": "^4.0.16" }, "dependencies": { - "@ionic/core": "^8.8.3", + "@ionic/core": "^8.8.4", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" }, From 7053da1a5e803f9095c28e6f8c3c4215bd0aad20 Mon Sep 17 00:00:00 2001 From: ionitron Date: Wed, 15 Apr 2026 18:13:11 +0000 Subject: [PATCH 5/6] chore(): update package lock files --- core/package-lock.json | 2 +- packages/angular-server/package-lock.json | 14 +++++------ packages/angular/package-lock.json | 8 +++--- packages/docs/package-lock.json | 2 +- packages/react-router/package-lock.json | 30 +++++++++++------------ packages/react/package-lock.json | 8 +++--- packages/vue-router/package-lock.json | 30 +++++++++++------------ packages/vue/package-lock.json | 8 +++--- 8 files changed, 51 insertions(+), 51 deletions(-) diff --git a/core/package-lock.json b/core/package-lock.json index 8bef7f2f1f7..007fed4a238 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -9829,4 +9829,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/angular-server/package-lock.json b/packages/angular-server/package-lock.json index 62015e76228..798964509f8 100644 --- a/packages/angular-server/package-lock.json +++ b/packages/angular-server/package-lock.json @@ -1031,9 +1031,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "license": "MIT", "dependencies": { "@stencil/core": "4.43.0", @@ -7309,9 +7309,9 @@ "dev": true }, "@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "requires": { "@stencil/core": "4.43.0", "ionicons": "^8.0.13", @@ -11289,4 +11289,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/angular/package-lock.json b/packages/angular/package-lock.json index b9c31ace5a7..1178f97c7da 100644 --- a/packages/angular/package-lock.json +++ b/packages/angular/package-lock.json @@ -1398,9 +1398,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "license": "MIT", "dependencies": { "@stencil/core": "4.43.0", @@ -9095,4 +9095,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/docs/package-lock.json b/packages/docs/package-lock.json index 158656a20f7..5110fe60ab6 100644 --- a/packages/docs/package-lock.json +++ b/packages/docs/package-lock.json @@ -10,4 +10,4 @@ "license": "MIT" } } -} \ No newline at end of file +} diff --git a/packages/react-router/package-lock.json b/packages/react-router/package-lock.json index 94f944650a9..37b215ff62c 100644 --- a/packages/react-router/package-lock.json +++ b/packages/react-router/package-lock.json @@ -238,9 +238,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "license": "MIT", "dependencies": { "@stencil/core": "4.43.0", @@ -418,12 +418,12 @@ } }, "node_modules/@ionic/react": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.3.tgz", - "integrity": "sha512-mqUftIoYROKSiqD9rOyF0XwR1/5dsGpAW/JD5bcPJqbNKx2bopb0/uiddeQ3Vbhi37tz5nsxzX0NB1+3cdx7hQ==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.4.tgz", + "integrity": "sha512-qlQNV6sRVIsq+vs33COKfzvMbNKRpPBGWYATv6vsNWmX7OhOm9tk7QSZl91LECvZRHMIe6Sqn9xMB+Aw/IBRfA==", "license": "MIT", "dependencies": { - "@ionic/core": "8.8.3", + "@ionic/core": "8.8.4", "ionicons": "^8.0.13", "tslib": "*" }, @@ -4178,9 +4178,9 @@ "dev": true }, "@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "requires": { "@stencil/core": "4.43.0", "ionicons": "^8.0.13", @@ -4284,11 +4284,11 @@ "requires": {} }, "@ionic/react": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.3.tgz", - "integrity": "sha512-mqUftIoYROKSiqD9rOyF0XwR1/5dsGpAW/JD5bcPJqbNKx2bopb0/uiddeQ3Vbhi37tz5nsxzX0NB1+3cdx7hQ==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.4.tgz", + "integrity": "sha512-qlQNV6sRVIsq+vs33COKfzvMbNKRpPBGWYATv6vsNWmX7OhOm9tk7QSZl91LECvZRHMIe6Sqn9xMB+Aw/IBRfA==", "requires": { - "@ionic/core": "8.8.3", + "@ionic/core": "8.8.4", "ionicons": "^8.0.13", "tslib": "*" } @@ -6847,4 +6847,4 @@ "dev": true } } -} \ No newline at end of file +} diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 821b953f957..487b165f5b4 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -736,9 +736,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "license": "MIT", "dependencies": { "@stencil/core": "4.43.0", @@ -11916,4 +11916,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/vue-router/package-lock.json b/packages/vue-router/package-lock.json index 05b1320c660..0dffc9612f6 100644 --- a/packages/vue-router/package-lock.json +++ b/packages/vue-router/package-lock.json @@ -673,9 +673,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "license": "MIT", "dependencies": { "@stencil/core": "4.43.0", @@ -868,12 +868,12 @@ } }, "node_modules/@ionic/vue": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.3.tgz", - "integrity": "sha512-6bwi2RodoxECt2Ef6C6km4ZkuH4TweyhF800/XpunOKjM2Iya3pD1j230KSRd35cJpAenGc1uplLdIZhAyMsWg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.4.tgz", + "integrity": "sha512-FZftTMul3zw7vjZHAxznheSu0sy0h6GSLtKNeU5U4XtziOaMYZ9dLP5TWsBjRVahAEtqn+n6493fYW4EPE+dvw==", "license": "MIT", "dependencies": { - "@ionic/core": "8.8.3", + "@ionic/core": "8.8.4", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" } @@ -8044,9 +8044,9 @@ "dev": true }, "@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "requires": { "@stencil/core": "4.43.0", "ionicons": "^8.0.13", @@ -8159,11 +8159,11 @@ "requires": {} }, "@ionic/vue": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.3.tgz", - "integrity": "sha512-6bwi2RodoxECt2Ef6C6km4ZkuH4TweyhF800/XpunOKjM2Iya3pD1j230KSRd35cJpAenGc1uplLdIZhAyMsWg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.4.tgz", + "integrity": "sha512-FZftTMul3zw7vjZHAxznheSu0sy0h6GSLtKNeU5U4XtziOaMYZ9dLP5TWsBjRVahAEtqn+n6493fYW4EPE+dvw==", "requires": { - "@ionic/core": "8.8.3", + "@ionic/core": "8.8.4", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" } @@ -12994,4 +12994,4 @@ "dev": true } } -} \ No newline at end of file +} diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index d1aba690bf3..b21f4c5a4ba 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -222,9 +222,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.3.tgz", - "integrity": "sha512-qvl+bRgZRvAJ35eW2iW0Vlo11T/EQsPazMU6z45QxJvcLukGJ59MwubjDTx6dPKteful4/FBzVt9etCvcNp8Gg==", + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.4.tgz", + "integrity": "sha512-RWts/72xtNNJDZQtntMRxB68KDctq76INV5OmLWWc0rlgcxOlNQDNH+lTBH7kV9vQ78JDVGSgi10ax3oQ3dIIQ==", "license": "MIT", "dependencies": { "@stencil/core": "4.43.0", @@ -4022,4 +4022,4 @@ "dev": true } } -} \ No newline at end of file +} From 12800cabfd22f785fcadb892fbbc91b5eff92dcd Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 15 Apr 2026 13:30:10 -0700 Subject: [PATCH 6/6] test(datetime): skip failing test --- core/src/components/datetime/test/basic/datetime.e2e.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/components/datetime/test/basic/datetime.e2e.ts b/core/src/components/datetime/test/basic/datetime.e2e.ts index bbc6033374f..4865e243092 100644 --- a/core/src/components/datetime/test/basic/datetime.e2e.ts +++ b/core/src/components/datetime/test/basic/datetime.e2e.ts @@ -440,7 +440,10 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => */ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { test.describe(title('datetime: IO fallback'), () => { - test('should become ready even if IntersectionObserver never reports visible', async ({ page }, testInfo) => { + test('should become ready even if IntersectionObserver never reports visible', async ({ page, skip }, testInfo) => { + // TODO(FW-7284): Re-enable on WebKit after determining why it fails + skip.browser('webkit', 'Wheel is not available in WebKit'); + testInfo.annotations.push({ type: 'issue', description: 'https://github.com/ionic-team/ionic-framework/issues/30706',