diff --git a/CHANGELOG.md b/CHANGELOG.md index d04b799720e..cf58db4c907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + + +### Bug Fixes + +* **core:** use Capacitor safe-area CSS variables on older WebViews ([#30865](https://github.com/ionic-team/ionic-framework/issues/30865)) ([8573bf8](https://github.com/ionic-team/ionic-framework/commit/8573bf8083f75eda13c954a56731a6aac8ca5724)) +* **header:** show iOS condense header when app is in MD mode ([#30690](https://github.com/ionic-team/ionic-framework/issues/30690)) ([f83b000](https://github.com/ionic-team/ionic-framework/commit/f83b0005309400d674e43c497bdffbcb9d2c4d94)), closes [#29929](https://github.com/ionic-team/ionic-framework/issues/29929) +* **input-password-toggle:** improve screen reader announcements ([#30885](https://github.com/ionic-team/ionic-framework/issues/30885)) ([12ede4b](https://github.com/ionic-team/ionic-framework/commit/12ede4b79c8d5cffc2b014c7c8a0d2ef1d3bf90d)) +* **modal:** dismiss top-most overlay when multiple IDs match ([#30883](https://github.com/ionic-team/ionic-framework/issues/30883)) ([3b60a1d](https://github.com/ionic-team/ionic-framework/commit/3b60a1d68a1df1606ffee0bde7db7a206bac404a)), closes [#30030](https://github.com/ionic-team/ionic-framework/issues/30030) + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index b1138a8c984..b0bbcba688b 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + + +### Bug Fixes + +* **core:** use Capacitor safe-area CSS variables on older WebViews ([#30865](https://github.com/ionic-team/ionic-framework/issues/30865)) ([8573bf8](https://github.com/ionic-team/ionic-framework/commit/8573bf8083f75eda13c954a56731a6aac8ca5724)) +* **header:** show iOS condense header when app is in MD mode ([#30690](https://github.com/ionic-team/ionic-framework/issues/30690)) ([f83b000](https://github.com/ionic-team/ionic-framework/commit/f83b0005309400d674e43c497bdffbcb9d2c4d94)), closes [#29929](https://github.com/ionic-team/ionic-framework/issues/29929) +* **input-password-toggle:** improve screen reader announcements ([#30885](https://github.com/ionic-team/ionic-framework/issues/30885)) ([12ede4b](https://github.com/ionic-team/ionic-framework/commit/12ede4b79c8d5cffc2b014c7c8a0d2ef1d3bf90d)) +* **modal:** dismiss top-most overlay when multiple IDs match ([#30883](https://github.com/ionic-team/ionic-framework/issues/30883)) ([3b60a1d](https://github.com/ionic-team/ionic-framework/commit/3b60a1d68a1df1606ffee0bde7db7a206bac404a)), closes [#30030](https://github.com/ionic-team/ionic-framework/issues/30030) + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) **Note:** Version bump only for package @ionic/core diff --git a/core/package-lock.json b/core/package-lock.json index 76636b537e9..516a11f687c 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/core", - "version": "8.7.14", + "version": "8.7.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/core", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT", "dependencies": { "@phosphor-icons/core": "^2.1.1", diff --git a/core/package.json b/core/package.json index 937d92072b1..e3dbed7b163 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "8.7.14", + "version": "8.7.15", "description": "Base components for Ionic", "engines": { "node": ">= 16" diff --git a/core/src/components/app/test/safe-area/app.e2e.ts b/core/src/components/app/test/safe-area/app.e2e.ts index 270b7820e9d..8778a0ecb7a 100644 --- a/core/src/components/app/test/safe-area/app.e2e.ts +++ b/core/src/components/app/test/safe-area/app.e2e.ts @@ -18,20 +18,66 @@ configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ co await expect(page).toHaveScreenshot(screenshot(`app-${screenshotModifier}-diff`)); }; + test.beforeEach(async ({ page }) => { await page.goto(`/src/components/app/test/safe-area`, config); }); - test('should not have visual regressions with action sheet', async ({ page }) => { - await testOverlay(page, '#show-action-sheet', 'ionActionSheetDidPresent', 'action-sheet'); - }); - test('should not have visual regressions with menu', async ({ page }) => { - await testOverlay(page, '#show-menu', 'ionDidOpen', 'menu'); - }); - test('should not have visual regressions with picker', async ({ page }) => { - await testOverlay(page, '#show-picker', 'ionPickerDidPresent', 'picker'); + + test.describe(title('Ionic safe area variables'), () => { + test.beforeEach(async ({ page }) => { + const htmlTag = page.locator('html'); + const hasSafeAreaClass = await htmlTag.evaluate((el) => el.classList.contains('safe-area')); + + expect(hasSafeAreaClass).toBe(true); + }); + + test('should not have visual regressions with action sheet', async ({ page }) => { + await testOverlay(page, '#show-action-sheet', 'ionActionSheetDidPresent', 'action-sheet'); + }); + test('should not have visual regressions with menu', async ({ page }) => { + await testOverlay(page, '#show-menu', 'ionDidOpen', 'menu'); + }); + test('should not have visual regressions with picker', async ({ page }) => { + await testOverlay(page, '#show-picker', 'ionPickerDidPresent', 'picker'); + }); + test('should not have visual regressions with toast', async ({ page }) => { + await testOverlay(page, '#show-toast', 'ionToastDidPresent', 'toast'); + }); }); - test('should not have visual regressions with toast', async ({ page }) => { - await testOverlay(page, '#show-toast', 'ionToastDidPresent', 'toast'); + + test.describe(title('Capacitor safe area variables'), () => { + test('should use safe-area-inset vars when safe-area class is not defined', async ({ page }) => { + await page.evaluate(() => { + const html = document.documentElement; + + // Remove the safe area class + html.classList.remove('safe-area'); + + // Set the safe area inset variables + html.style.setProperty('--safe-area-inset-top', '10px'); + html.style.setProperty('--safe-area-inset-bottom', '20px'); + html.style.setProperty('--safe-area-inset-left', '30px'); + html.style.setProperty('--safe-area-inset-right', '40px'); + }); + + const top = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-top').trim() + ); + const bottom = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-bottom').trim() + ); + const left = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-left').trim() + ); + const right = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-right').trim() + ); + + expect(top).toBe('10px'); + expect(bottom).toBe('20px'); + expect(left).toBe('30px'); + expect(right).toBe('40px'); + }); }); }); }); diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx index 77ed273c432..de3e7586e9d 100644 --- a/core/src/components/button/button.tsx +++ b/core/src/components/button/button.tsx @@ -174,6 +174,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf */ @Watch('aria-checked') @Watch('aria-label') + @Watch('aria-pressed') onAriaChanged(newValue: string, _oldValue: string, propName: string) { this.inheritedAttributes = { ...this.inheritedAttributes, diff --git a/core/src/components/header/header.md.scss b/core/src/components/header/header.md.scss index 49d700192eb..1d670924ff6 100644 --- a/core/src/components/header/header.md.scss +++ b/core/src/components/header/header.md.scss @@ -8,7 +8,7 @@ box-shadow: $header-md-box-shadow; } -.header-collapse-condense { +.header-md.header-collapse-condense { display: none; } diff --git a/core/src/components/header/test/condense-modal/header.e2e.ts b/core/src/components/header/test/condense-modal/header.e2e.ts new file mode 100644 index 00000000000..72cc6a7b706 --- /dev/null +++ b/core/src/components/header/test/condense-modal/header.e2e.ts @@ -0,0 +1,71 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * This test verifies that collapsible headers with mode="ios" work correctly + * when both iOS and MD stylesheets are loaded. The bug occurred because + * `.header-collapse-condense { display: none }` in the MD stylesheet was not + * scoped to `.header-md`, causing it to hide iOS condense headers when both + * stylesheets were present. + */ +configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('header: condense with iOS mode override'), () => { + test('should show iOS condense header when both MD and iOS styles are loaded', async ({ page }) => { + test.info().annotations.push({ + type: 'issue', + description: 'https://github.com/ionic-team/ionic-framework/issues/29929', + }); + + // Include both an MD header and an iOS modal to force both stylesheets to load + await page.setContent( + ` + + + + MD Header + + + + + + + + Header + + + + + + Large Header + + +

Content

+
+
+ `, + config + ); + + const modal = page.locator('ion-modal'); + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await modal.evaluate((el: HTMLIonModalElement) => el.present()); + await ionModalDidPresent.next(); + + const largeTitleHeader = modal.locator('#largeTitleHeader'); + + // The large title header should be visible, not hidden by MD styles + await expect(largeTitleHeader).toBeVisible(); + + // Verify it has the iOS mode class + await expect(largeTitleHeader).toHaveClass(/header-ios/); + + // Verify it does NOT have display: none applied + // This would fail if the MD stylesheet's unscoped .header-collapse-condense rule applies + const display = await largeTitleHeader.evaluate((el) => { + return window.getComputedStyle(el).display; + }); + expect(display).not.toBe('none'); + }); + }); +}); diff --git a/core/src/components/input-password-toggle/input-password-toggle.tsx b/core/src/components/input-password-toggle/input-password-toggle.tsx index 5badee21602..2cf3678d2a4 100644 --- a/core/src/components/input-password-toggle/input-password-toggle.tsx +++ b/core/src/components/input-password-toggle/input-password-toggle.tsx @@ -169,9 +169,8 @@ export class InputPasswordToggle implements ComponentInterface { color={color} fill="clear" shape="round" - aria-checked={isPasswordVisible ? 'true' : 'false'} aria-label={isPasswordVisible ? 'Hide password' : 'Show password'} - role="switch" + aria-pressed={isPasswordVisible ? 'true' : 'false'} type="button" onPointerDown={(ev) => { /** diff --git a/core/src/components/input-password-toggle/test/a11y/input-password-toggle.e2e.ts b/core/src/components/input-password-toggle/test/a11y/input-password-toggle.e2e.ts index 0493509dc24..da9846ef9d8 100644 --- a/core/src/components/input-password-toggle/test/a11y/input-password-toggle.e2e.ts +++ b/core/src/components/input-password-toggle/test/a11y/input-password-toggle.e2e.ts @@ -22,7 +22,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { }); test.describe(title('input password toggle: aria attributes'), () => { - test('should inherit aria attributes to inner button on load', async ({ page }) => { + test('should have correct aria attributes on load', async ({ page }) => { await page.setContent( ` @@ -35,9 +35,9 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { const nativeButton = page.locator('ion-input-password-toggle button'); await expect(nativeButton).toHaveAttribute('aria-label', 'Show password'); - await expect(nativeButton).toHaveAttribute('aria-checked', 'false'); + await expect(nativeButton).toHaveAttribute('aria-pressed', 'false'); }); - test('should inherit aria attributes to inner button after toggle', async ({ page }) => { + test('should update aria attributes after toggle', async ({ page }) => { await page.setContent( ` @@ -51,7 +51,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { await nativeButton.click(); await expect(nativeButton).toHaveAttribute('aria-label', 'Hide password'); - await expect(nativeButton).toHaveAttribute('aria-checked', 'true'); + await expect(nativeButton).toHaveAttribute('aria-pressed', 'true'); }); }); }); diff --git a/core/src/components/modal/test/dismiss-behavior/index.html b/core/src/components/modal/test/dismiss-behavior/index.html new file mode 100644 index 00000000000..448b84457d9 --- /dev/null +++ b/core/src/components/modal/test/dismiss-behavior/index.html @@ -0,0 +1,97 @@ + + + + + Modal - Dismiss Behavior + + + + + + + + + + +
+ + + Modal - Dismiss Behavior + + + + + + +
+
+ + + + diff --git a/core/src/components/modal/test/dismiss-behavior/modal.e2e.ts b/core/src/components/modal/test/dismiss-behavior/modal.e2e.ts new file mode 100644 index 00000000000..7969317c447 --- /dev/null +++ b/core/src/components/modal/test/dismiss-behavior/modal.e2e.ts @@ -0,0 +1,58 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('modal: dismiss behavior'), () => { + test.describe(title('modal: default dismiss'), () => { + test('should dismiss the last presented modal when the default dismiss button is clicked', async ({ page }) => { + await page.goto('/src/components/modal/test/dismiss-behavior', config); + + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss'); + + await page.click('#present-first-modal'); + await ionModalDidPresent.next(); + const firstModal = page.locator('ion-modal[data-testid="modal-1"]'); + await expect(firstModal).toBeVisible(); + + await page.click('#present-next-modal'); + await ionModalDidPresent.next(); + const secondModal = page.locator('ion-modal[data-testid="modal-2"]'); + await expect(secondModal).toBeVisible(); + + await page.click('ion-modal[data-testid="modal-2"] ion-button.dismiss-default'); + await ionModalDidDismiss.next(); + await secondModal.waitFor({ state: 'detached' }); + + await expect(firstModal).toBeVisible(); + await expect(secondModal).toBeHidden(); + }); + }); + + test.describe(title('modal: dismiss by id'), () => { + test('should dismiss the last presented modal when the dismiss by id button is clicked', async ({ page }) => { + await page.goto('/src/components/modal/test/dismiss-behavior', config); + + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss'); + + await page.click('#present-first-modal'); + await ionModalDidPresent.next(); + const firstModal = page.locator('ion-modal[data-testid="modal-1"]'); + await expect(firstModal).toBeVisible(); + + await page.click('#present-next-modal'); + await ionModalDidPresent.next(); + const secondModal = page.locator('ion-modal[data-testid="modal-2"]'); + await expect(secondModal).toBeVisible(); + + await page.click('ion-modal[data-testid="modal-2"] ion-button.dismiss-by-id'); + await ionModalDidDismiss.next(); + await secondModal.waitFor({ state: 'detached' }); + + await expect(firstModal).toBeVisible(); + await expect(secondModal).toBeHidden(); + }); + }); + }); +}); diff --git a/core/src/components/modal/test/modal-id.spec.tsx b/core/src/components/modal/test/modal-id.spec.tsx index 43f1a9eaa16..93b6d34fa91 100644 --- a/core/src/components/modal/test/modal-id.spec.tsx +++ b/core/src/components/modal/test/modal-id.spec.tsx @@ -1,7 +1,7 @@ +import { h } from '@stencil/core'; import { newSpecPage } from '@stencil/core/testing'; import { Modal } from '../modal'; -import { h } from '@stencil/core'; describe('modal: id', () => { it('modal should be assigned an incrementing id', async () => { @@ -52,4 +52,21 @@ describe('modal: id', () => { const alert = page.body.querySelector('ion-modal')!; expect(alert.id).toBe(id); }); + + it('should allow multiple modals with the same id', async () => { + const sharedId = 'shared-modal-id'; + + const page = await newSpecPage({ + components: [Modal], + template: () => [ + , + , + ], + }); + + const modals = page.body.querySelectorAll('ion-modal'); + expect(modals.length).toBe(2); + expect(modals[0].id).toBe(sharedId); + expect(modals[1].id).toBe(sharedId); + }); }); diff --git a/core/src/css/core.scss b/core/src/css/core.scss index 2d75bc86cf0..eee7fc1ac64 100644 --- a/core/src/css/core.scss +++ b/core/src/css/core.scss @@ -227,10 +227,12 @@ html.plt-ios.plt-pwa { @supports (padding-top: env(safe-area-inset-top)) { html { - --ion-safe-area-top: env(safe-area-inset-top); - --ion-safe-area-bottom: env(safe-area-inset-bottom); - --ion-safe-area-left: env(safe-area-inset-left); - --ion-safe-area-right: env(safe-area-inset-right); + // `--safe-area-inset-*` are set by Capacitor + // @see https://capacitorjs.com/docs/apis/system-bars#android-note + --ion-safe-area-top: var(--safe-area-inset-top, env(safe-area-inset-top)); + --ion-safe-area-bottom: var(--safe-area-inset-bottom, env(safe-area-inset-bottom)); + --ion-safe-area-left: var(--safe-area-inset-left, env(safe-area-inset-left)); + --ion-safe-area-right: var(--safe-area-inset-right, env(safe-area-inset-right)); } } diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 1271a999285..affb791837a 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -473,7 +473,9 @@ export const getPresentedOverlay = ( id?: string ): HTMLIonOverlayElement | undefined => { const overlays = getPresentedOverlays(doc, overlayTag); - return id === undefined ? overlays[overlays.length - 1] : overlays.find((o) => o.id === id); + // If no id is provided, return the last presented overlay + // Otherwise, return the last overlay with the given id + return (id === undefined ? overlays : overlays.filter((o: HTMLIonOverlayElement) => o.id === id)).slice(-1)[0]; }; /** diff --git a/lerna.json b/lerna.json index f1a42eb9adb..cec6780d8e0 100644 --- a/lerna.json +++ b/lerna.json @@ -3,5 +3,5 @@ "core", "packages/*" ], - "version": "8.7.14" + "version": "8.7.15" } \ No newline at end of file diff --git a/packages/angular-server/CHANGELOG.md b/packages/angular-server/CHANGELOG.md index b85cf7b4af2..6e2c47e231f 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.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + +**Note:** Version bump only for package @ionic/angular-server + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) **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 3d9097f3bca..400af1cf1ea 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.7.14", + "version": "8.7.15", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular-server", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.14" + "@ionic/core": "^8.7.15" }, "devDependencies": { "@angular-eslint/eslint-plugin": "^16.0.0", @@ -1031,9 +1031,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", @@ -7309,9 +7309,9 @@ "dev": true }, "@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "requires": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", diff --git a/packages/angular-server/package.json b/packages/angular-server/package.json index 7cd4bc6cdc5..34f4f41b9f5 100644 --- a/packages/angular-server/package.json +++ b/packages/angular-server/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular-server", - "version": "8.7.14", + "version": "8.7.15", "description": "Angular SSR Module for Ionic", "keywords": [ "ionic", @@ -62,6 +62,6 @@ }, "prettier": "@ionic/prettier-config", "dependencies": { - "@ionic/core": "^8.7.14" + "@ionic/core": "^8.7.15" } } diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 012bd397c46..8c81042f2f5 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.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + +**Note:** Version bump only for package @ionic/angular + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) **Note:** Version bump only for package @ionic/angular diff --git a/packages/angular/package-lock.json b/packages/angular/package-lock.json index 43082656525..2b5f26d0449 100644 --- a/packages/angular/package-lock.json +++ b/packages/angular/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular", - "version": "8.7.14", + "version": "8.7.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/angular", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.14", + "@ionic/core": "^8.7.15", "ionicons": "^8.0.13", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" @@ -1398,9 +1398,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", diff --git a/packages/angular/package.json b/packages/angular/package.json index a5b9322d46b..3e681522ec3 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular", - "version": "8.7.14", + "version": "8.7.15", "description": "Angular specific wrappers for @ionic/core", "keywords": [ "ionic", @@ -48,7 +48,7 @@ } }, "dependencies": { - "@ionic/core": "^8.7.14", + "@ionic/core": "^8.7.15", "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 31769f43b2b..632712133a7 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.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + +**Note:** Version bump only for package @ionic/docs + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) **Note:** Version bump only for package @ionic/docs diff --git a/packages/docs/package-lock.json b/packages/docs/package-lock.json index 696bf80792b..98e0630e216 100644 --- a/packages/docs/package-lock.json +++ b/packages/docs/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/docs", - "version": "8.7.14", + "version": "8.7.15", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/docs", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT" } } diff --git a/packages/docs/package.json b/packages/docs/package.json index bb42b1bff7f..e7a085be4bf 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/docs", - "version": "8.7.14", + "version": "8.7.15", "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 0fa577225a1..55ae3dde0c1 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.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + +**Note:** Version bump only for package @ionic/react-router + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) **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 22ea0283288..a0a96db917f 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.7.14", + "version": "8.7.15", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/react-router", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT", "dependencies": { - "@ionic/react": "^8.7.14", + "@ionic/react": "^8.7.15", "tslib": "*" }, "devDependencies": { @@ -238,9 +238,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", @@ -418,12 +418,12 @@ } }, "node_modules/@ionic/react": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.14.tgz", - "integrity": "sha512-8lJZz+GbwDs0HEZuSjFQkg2+fGNdVrISh9N+SAlKRajtea4wva3hBjDUl21iE/u32W7xOslTGdZ9zIdAPYjHlg==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.15.tgz", + "integrity": "sha512-3W5DAN3OMe2w32AGlW8zvKZHNY/dLCWhVLL9485VKtsYvgUc9nkG8dYDvQGc6c17PEDVrMy+IAl4H9hLgJhYnQ==", "license": "MIT", "dependencies": { - "@ionic/core": "8.7.14", + "@ionic/core": "8.7.15", "ionicons": "^8.0.13", "tslib": "*" }, @@ -4178,9 +4178,9 @@ "dev": true }, "@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "requires": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", @@ -4284,11 +4284,11 @@ "requires": {} }, "@ionic/react": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.14.tgz", - "integrity": "sha512-8lJZz+GbwDs0HEZuSjFQkg2+fGNdVrISh9N+SAlKRajtea4wva3hBjDUl21iE/u32W7xOslTGdZ9zIdAPYjHlg==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.15.tgz", + "integrity": "sha512-3W5DAN3OMe2w32AGlW8zvKZHNY/dLCWhVLL9485VKtsYvgUc9nkG8dYDvQGc6c17PEDVrMy+IAl4H9hLgJhYnQ==", "requires": { - "@ionic/core": "8.7.14", + "@ionic/core": "8.7.15", "ionicons": "^8.0.13", "tslib": "*" } diff --git a/packages/react-router/package.json b/packages/react-router/package.json index d52d5364f02..d3c93c20a76 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react-router", - "version": "8.7.14", + "version": "8.7.15", "description": "React Router wrapper for @ionic/react", "keywords": [ "ionic", @@ -36,7 +36,7 @@ "dist/" ], "dependencies": { - "@ionic/react": "^8.7.14", + "@ionic/react": "^8.7.15", "tslib": "*" }, "peerDependencies": { diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 7916238f80f..d198346bb0b 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.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + +**Note:** Version bump only for package @ionic/react + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 39d3a60c664..f10c3cf0873 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react", - "version": "8.7.14", + "version": "8.7.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/react", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.14", + "@ionic/core": "^8.7.15", "ionicons": "^8.0.13", "tslib": "*" }, @@ -736,9 +736,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", diff --git a/packages/react/package.json b/packages/react/package.json index 1404de8d4a5..68819b74b8a 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react", - "version": "8.7.14", + "version": "8.7.15", "description": "React specific wrapper for @ionic/core", "keywords": [ "ionic", @@ -40,7 +40,7 @@ "css/" ], "dependencies": { - "@ionic/core": "^8.7.14", + "@ionic/core": "^8.7.15", "ionicons": "^8.0.13", "tslib": "*" }, diff --git a/packages/vue-router/CHANGELOG.md b/packages/vue-router/CHANGELOG.md index 38c7bd11d99..f56cb248703 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.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + +**Note:** Version bump only for package @ionic/vue-router + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) **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 a6d92ecc54c..bfd04a619b7 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.7.14", + "version": "8.7.15", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue-router", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT", "dependencies": { - "@ionic/vue": "^8.7.14" + "@ionic/vue": "^8.7.15" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", @@ -673,9 +673,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", @@ -868,12 +868,12 @@ } }, "node_modules/@ionic/vue": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.14.tgz", - "integrity": "sha512-4KYsOr55N8B95zMayS036EsExD6r3i9gwXrWKa6zwKH1QowIde3oQBVzaVyQvMoebaZP5LskpeAJKgHYDTKGrg==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.15.tgz", + "integrity": "sha512-F94GoGBsLoFFkJLe+W401SynIfUzEL1Z+Y4YUQ2EGpulnFpY4tXKzDhRNrisPnM0k3BWQRh8AA8fwTtMqEiISw==", "license": "MIT", "dependencies": { - "@ionic/core": "8.7.14", + "@ionic/core": "8.7.15", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" } @@ -8044,9 +8044,9 @@ "dev": true }, "@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "requires": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", @@ -8159,11 +8159,11 @@ "requires": {} }, "@ionic/vue": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.14.tgz", - "integrity": "sha512-4KYsOr55N8B95zMayS036EsExD6r3i9gwXrWKa6zwKH1QowIde3oQBVzaVyQvMoebaZP5LskpeAJKgHYDTKGrg==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.15.tgz", + "integrity": "sha512-F94GoGBsLoFFkJLe+W401SynIfUzEL1Z+Y4YUQ2EGpulnFpY4tXKzDhRNrisPnM0k3BWQRh8AA8fwTtMqEiISw==", "requires": { - "@ionic/core": "8.7.14", + "@ionic/core": "8.7.15", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" } diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index fd9211fe98d..6b55532cb9b 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue-router", - "version": "8.7.14", + "version": "8.7.15", "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.7.14" + "@ionic/vue": "^8.7.15" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 8ec7d30f7e5..436bae11c08 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.7.15](https://github.com/ionic-team/ionic-framework/compare/v8.7.14...v8.7.15) (2025-12-23) + +**Note:** Version bump only for package @ionic/vue + + + + + ## [8.7.14](https://github.com/ionic-team/ionic-framework/compare/v8.7.13...v8.7.14) (2025-12-17) diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index db7070b2a80..f19fe970e0b 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue", - "version": "8.7.14", + "version": "8.7.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/vue", - "version": "8.7.14", + "version": "8.7.15", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.14", + "@ionic/core": "^8.7.15", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" }, @@ -222,9 +222,9 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.14", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.14.tgz", - "integrity": "sha512-9CHfow8n19tmfSllUHj3NITqKQGrZHHEF/iyG7xPOlQ9SQ2V4bzd3rHIZ3CKVet1Z/y4HLe0uRShZnmFkSujng==", + "version": "8.7.15", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.15.tgz", + "integrity": "sha512-u1w9c6dx2iuatXIW5X1JY0ighDhQPjBwOHZsrOcnpm891pktuEjJDdyhDulWFa6kKVkXw1q7khwxXBEurvKc2g==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", diff --git a/packages/vue/package.json b/packages/vue/package.json index 45f3764c4f1..04bd5518ab0 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue", - "version": "8.7.14", + "version": "8.7.15", "description": "Vue specific wrapper for @ionic/core", "scripts": { "eslint": "eslint src", @@ -68,7 +68,7 @@ "vue-router": "^4.0.16" }, "dependencies": { - "@ionic/core": "^8.7.14", + "@ionic/core": "^8.7.15", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" },