Compare commits
28 Commits
dev-build-
...
v7.4.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb47273f26 | ||
|
|
eee2115fd2 | ||
|
|
d0057352fe | ||
|
|
c70432e693 | ||
|
|
a1690441e5 | ||
|
|
e6031fbef0 | ||
|
|
d5f0c776df | ||
|
|
00767a02e4 | ||
|
|
3259da0de1 | ||
|
|
470c119a05 | ||
|
|
b297529afc | ||
|
|
7375dd6aba | ||
|
|
1167a9325f | ||
|
|
dc75392e9d | ||
|
|
865bd2a004 | ||
|
|
2429caa168 | ||
|
|
a8517f4fcf | ||
|
|
a04a11be35 | ||
|
|
f5df28e2c7 | ||
|
|
ac2c8e6c22 | ||
|
|
70e9177e2c | ||
|
|
51b7ceb5be | ||
|
|
597bec7534 | ||
|
|
eb41b556b5 | ||
|
|
355d95d4d8 | ||
|
|
078964447a | ||
|
|
45bcd4c22b | ||
|
|
71a7af0f52 |
11
.github/workflows/stencil-nightly.yml
vendored
@@ -8,7 +8,12 @@ on:
|
||||
# at 6:00 UTC (6:00 am UTC)
|
||||
- cron: '00 06 * * 1-5'
|
||||
workflow_dispatch:
|
||||
# allows for manual invocations in the GitHub UI
|
||||
inputs:
|
||||
npm_release_tag:
|
||||
required: true
|
||||
type: string
|
||||
description: What version should be pulled from NPM?
|
||||
default: nightly
|
||||
|
||||
# When pushing a new commit we should
|
||||
# cancel the previous test run to not
|
||||
@@ -24,7 +29,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-core-stencil-prerelease
|
||||
with:
|
||||
stencil-version: nightly
|
||||
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
|
||||
|
||||
test-core-clean-build:
|
||||
needs: [build-core-with-stencil-nightly]
|
||||
@@ -47,7 +52,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-spec
|
||||
with:
|
||||
stencil-version: nightly
|
||||
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
|
||||
|
||||
test-core-screenshot:
|
||||
strategy:
|
||||
|
||||
42
CHANGELOG.md
@@ -3,6 +3,48 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animation:** play method resolves when animation is stopped ([#28264](https://github.com/ionic-team/ionic-framework/issues/28264)) ([e6031fb](https://github.com/ionic-team/ionic-framework/commit/e6031fbef0698dac0a346cd6202c47f2abf54f95))
|
||||
* **checkbox, radio, toggle:** disabled elements are not interactive ([#28294](https://github.com/ionic-team/ionic-framework/issues/28294)) ([c70432e](https://github.com/ionic-team/ionic-framework/commit/c70432e6934bcf1d570e1f7cf671c52d2bb52a8b)), closes [#28293](https://github.com/ionic-team/ionic-framework/issues/28293)
|
||||
* **content:** fullscreen offset is computed correctly with tab bar ([#28245](https://github.com/ionic-team/ionic-framework/issues/28245)) ([7375dd6](https://github.com/ionic-team/ionic-framework/commit/7375dd6abafdf7457f23deb53ad5f016456a6af2)), closes [#21130](https://github.com/ionic-team/ionic-framework/issues/21130)
|
||||
* **core:** allow fullscreen scroll content to flow outside container for translucent tab bar ([#28246](https://github.com/ionic-team/ionic-framework/issues/28246)) ([b297529](https://github.com/ionic-team/ionic-framework/commit/b297529afc4b93a93f7eaecd31dd5a88a3de5f4e)), closes [#17676](https://github.com/ionic-team/ionic-framework/issues/17676)
|
||||
* **core:** swipe to go back gesture has priority over other horizontal swipe gestures ([#28304](https://github.com/ionic-team/ionic-framework/issues/28304)) ([d5f0c77](https://github.com/ionic-team/ionic-framework/commit/d5f0c776dfb5cb40b8119c596805dad3adb621e0)), closes [#28303](https://github.com/ionic-team/ionic-framework/issues/28303)
|
||||
* **header:** collapsible large title main header does not flicker on load ([#28277](https://github.com/ionic-team/ionic-framework/issues/28277)) ([3259da0](https://github.com/ionic-team/ionic-framework/commit/3259da0de181c8f82c38d9de13733213c77d398f)), closes [#27060](https://github.com/ionic-team/ionic-framework/issues/27060)
|
||||
* **menu:** do not error if disabled or swipeGesture is changed mid-animation ([#28268](https://github.com/ionic-team/ionic-framework/issues/28268)) ([a169044](https://github.com/ionic-team/ionic-framework/commit/a1690441e5bcee8176da32700de6f9e3fde9635e)), closes [#20092](https://github.com/ionic-team/ionic-framework/issues/20092) [#19676](https://github.com/ionic-team/ionic-framework/issues/19676) [#19000](https://github.com/ionic-team/ionic-framework/issues/19000)
|
||||
* **segment:** scroll to active segment-button on first load ([#28276](https://github.com/ionic-team/ionic-framework/issues/28276)) ([1167a93](https://github.com/ionic-team/ionic-framework/commit/1167a9325fb930b6c727bc26889f5488d9620062)), closes [#28096](https://github.com/ionic-team/ionic-framework/issues/28096)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **fab-button:** position is correct with custom sizes ([#28195](https://github.com/ionic-team/ionic-framework/issues/28195)) ([eb41b55](https://github.com/ionic-team/ionic-framework/commit/eb41b556b57c97139b9c36dc3e3be3711d8afaca)), closes [#22564](https://github.com/ionic-team/ionic-framework/issues/22564)
|
||||
* **range:** knob positions are correct on initial render with custom elements build ([#28257](https://github.com/ionic-team/ionic-framework/issues/28257)) ([ac2c8e6](https://github.com/ionic-team/ionic-framework/commit/ac2c8e6c22da4d0d8224def24ddef56ee9d26246)), closes [#25444](https://github.com/ionic-team/ionic-framework/issues/25444)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** Nav unmounts component while invoking popTo or popToRoot ([#27821](https://github.com/ionic-team/ionic-framework/issues/27821)) ([0edcb2c](https://github.com/ionic-team/ionic-framework/commit/0edcb2cd85133ae8c304c53c37ca829e5fbad447)), closes [#27798](https://github.com/ionic-team/ionic-framework/issues/27798)
|
||||
* **title:** large title uses custom font on transition ([#28231](https://github.com/ionic-team/ionic-framework/issues/28231)) ([71a7af0](https://github.com/ionic-team/ionic-framework/commit/71a7af0f52fe62937b1dea1ca2739e78801a2a6d))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,47 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animation:** play method resolves when animation is stopped ([#28264](https://github.com/ionic-team/ionic-framework/issues/28264)) ([e6031fb](https://github.com/ionic-team/ionic-framework/commit/e6031fbef0698dac0a346cd6202c47f2abf54f95))
|
||||
* **checkbox, radio, toggle:** disabled elements are not interactive ([#28294](https://github.com/ionic-team/ionic-framework/issues/28294)) ([c70432e](https://github.com/ionic-team/ionic-framework/commit/c70432e6934bcf1d570e1f7cf671c52d2bb52a8b)), closes [#28293](https://github.com/ionic-team/ionic-framework/issues/28293)
|
||||
* **content:** fullscreen offset is computed correctly with tab bar ([#28245](https://github.com/ionic-team/ionic-framework/issues/28245)) ([7375dd6](https://github.com/ionic-team/ionic-framework/commit/7375dd6abafdf7457f23deb53ad5f016456a6af2)), closes [#21130](https://github.com/ionic-team/ionic-framework/issues/21130)
|
||||
* **core:** allow fullscreen scroll content to flow outside container for translucent tab bar ([#28246](https://github.com/ionic-team/ionic-framework/issues/28246)) ([b297529](https://github.com/ionic-team/ionic-framework/commit/b297529afc4b93a93f7eaecd31dd5a88a3de5f4e)), closes [#17676](https://github.com/ionic-team/ionic-framework/issues/17676)
|
||||
* **core:** swipe to go back gesture has priority over other horizontal swipe gestures ([#28304](https://github.com/ionic-team/ionic-framework/issues/28304)) ([d5f0c77](https://github.com/ionic-team/ionic-framework/commit/d5f0c776dfb5cb40b8119c596805dad3adb621e0)), closes [#28303](https://github.com/ionic-team/ionic-framework/issues/28303)
|
||||
* **header:** collapsible large title main header does not flicker on load ([#28277](https://github.com/ionic-team/ionic-framework/issues/28277)) ([3259da0](https://github.com/ionic-team/ionic-framework/commit/3259da0de181c8f82c38d9de13733213c77d398f)), closes [#27060](https://github.com/ionic-team/ionic-framework/issues/27060)
|
||||
* **menu:** do not error if disabled or swipeGesture is changed mid-animation ([#28268](https://github.com/ionic-team/ionic-framework/issues/28268)) ([a169044](https://github.com/ionic-team/ionic-framework/commit/a1690441e5bcee8176da32700de6f9e3fde9635e)), closes [#20092](https://github.com/ionic-team/ionic-framework/issues/20092) [#19676](https://github.com/ionic-team/ionic-framework/issues/19676) [#19000](https://github.com/ionic-team/ionic-framework/issues/19000)
|
||||
* **segment:** scroll to active segment-button on first load ([#28276](https://github.com/ionic-team/ionic-framework/issues/28276)) ([1167a93](https://github.com/ionic-team/ionic-framework/commit/1167a9325fb930b6c727bc26889f5488d9620062)), closes [#28096](https://github.com/ionic-team/ionic-framework/issues/28096)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **fab-button:** position is correct with custom sizes ([#28195](https://github.com/ionic-team/ionic-framework/issues/28195)) ([eb41b55](https://github.com/ionic-team/ionic-framework/commit/eb41b556b57c97139b9c36dc3e3be3711d8afaca)), closes [#22564](https://github.com/ionic-team/ionic-framework/issues/22564)
|
||||
* **range:** knob positions are correct on initial render with custom elements build ([#28257](https://github.com/ionic-team/ionic-framework/issues/28257)) ([ac2c8e6](https://github.com/ionic-team/ionic-framework/commit/ac2c8e6c22da4d0d8224def24ddef56ee9d26246)), closes [#25444](https://github.com/ionic-team/ionic-framework/issues/25444)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **title:** large title uses custom font on transition ([#28231](https://github.com/ionic-team/ionic-framework/issues/28231)) ([71a7af0](https://github.com/ionic-team/ionic-framework/commit/71a7af0f52fe62937b1dea1ca2739e78801a2a6d))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
|
||||
|
||||
46
core/package-lock.json
generated
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.1",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.7.3",
|
||||
"@capacitor/core": "^5.4.1",
|
||||
"@capacitor/core": "^5.4.2",
|
||||
"@capacitor/haptics": "^5.0.6",
|
||||
"@capacitor/keyboard": "^5.0.6",
|
||||
"@capacitor/status-bar": "^5.0.6",
|
||||
@@ -27,7 +27,7 @@
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.8.2",
|
||||
"@stencil/react-output-target": "^0.5.3",
|
||||
"@stencil/sass": "^3.0.5",
|
||||
"@stencil/sass": "^3.0.6",
|
||||
"@stencil/vue-output-target": "^0.8.6",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^14.6.0",
|
||||
@@ -607,9 +607,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@capacitor/core": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.1.tgz",
|
||||
"integrity": "sha512-QG9gORuxw2WNcVpLHT1W3LzACOJvFWRuHcz4b9edzxehSELqiSQ4DoGWLp4PuNBBp2oV/fGA4FMNmfZ1jIAAWg==",
|
||||
"version": "5.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.2.tgz",
|
||||
"integrity": "sha512-XbR1vldJFzBWHeoGPpgfNy3Zhjf0NxXdHEaGNANWVBg0ZWG2gwFr1dcRALUUQtbwrEEkCCNiLYg4YiQPRk7SEQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -1630,9 +1630,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -1651,9 +1651,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/sass": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.5.tgz",
|
||||
"integrity": "sha512-9nyllMXOEvHywo6fP2iwXgnq32A+OOUE36Aq7iUjzwT3wdr04qsvupO1JNIyRvmvCDF15hOKXztrZH1/wDu2Zg==",
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.6.tgz",
|
||||
"integrity": "sha512-d+k8qCvDgzI/vIV7M5QavIS6b75X4yn+YQH80KA/L0oL/hKD8KeF3wMOd7P1nDhGLIGRNw5tBDbe0GeIsGVU7A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.0.0",
|
||||
@@ -10802,9 +10802,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@capacitor/core": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.1.tgz",
|
||||
"integrity": "sha512-QG9gORuxw2WNcVpLHT1W3LzACOJvFWRuHcz4b9edzxehSELqiSQ4DoGWLp4PuNBBp2oV/fGA4FMNmfZ1jIAAWg==",
|
||||
"version": "5.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.2.tgz",
|
||||
"integrity": "sha512-XbR1vldJFzBWHeoGPpgfNy3Zhjf0NxXdHEaGNANWVBg0ZWG2gwFr1dcRALUUQtbwrEEkCCNiLYg4YiQPRk7SEQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -11536,9 +11536,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz",
|
||||
"integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA=="
|
||||
},
|
||||
"@stencil/react-output-target": {
|
||||
"version": "0.5.3",
|
||||
@@ -11548,9 +11548,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@stencil/sass": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.5.tgz",
|
||||
"integrity": "sha512-9nyllMXOEvHywo6fP2iwXgnq32A+OOUE36Aq7iUjzwT3wdr04qsvupO1JNIyRvmvCDF15hOKXztrZH1/wDu2Zg==",
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.6.tgz",
|
||||
"integrity": "sha512-d+k8qCvDgzI/vIV7M5QavIS6b75X4yn+YQH80KA/L0oL/hKD8KeF3wMOd7P1nDhGLIGRNw5tBDbe0GeIsGVU7A==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -31,13 +31,13 @@
|
||||
"loader/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.1",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.7.3",
|
||||
"@capacitor/core": "^5.4.1",
|
||||
"@capacitor/core": "^5.4.2",
|
||||
"@capacitor/haptics": "^5.0.6",
|
||||
"@capacitor/keyboard": "^5.0.6",
|
||||
"@capacitor/status-bar": "^5.0.6",
|
||||
@@ -49,7 +49,7 @@
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.8.2",
|
||||
"@stencil/react-output-target": "^0.5.3",
|
||||
"@stencil/sass": "^3.0.5",
|
||||
"@stencil/sass": "^3.0.6",
|
||||
"@stencil/vue-output-target": "^0.8.6",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^14.6.0",
|
||||
@@ -95,6 +95,7 @@
|
||||
"test.spec": "stencil test --spec --max-workers=2",
|
||||
"test.spec.debug": "npx --node-arg=\"--inspect-brk\" stencil test --spec",
|
||||
"test.e2e": "npx playwright test",
|
||||
"test.e2e.update-snapshots": "npm run test.e2e -- --update-snapshots",
|
||||
"test.watch": "jest --watch --no-cache",
|
||||
"test.treeshake": "node scripts/treeshaking.js dist/index.js",
|
||||
"validate": "npm run lint && npm run test && npm run build && npm run test.treeshake"
|
||||
|
||||
1
core/src/components.d.ts
vendored
@@ -6976,6 +6976,7 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"mode"?: "ios" | "md";
|
||||
"onIonTabBarChanged"?: (event: IonTabBarCustomEvent<TabBarChangedEventDetail>) => void;
|
||||
"onIonTabBarLoaded"?: (event: IonTabBarCustomEvent<void>) => void;
|
||||
/**
|
||||
* The selected tab component
|
||||
*/
|
||||
|
||||
@@ -211,6 +211,10 @@ export class Checkbox implements ComponentInterface {
|
||||
};
|
||||
|
||||
private onClick = (ev: MouseEvent) => {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.toggleChecked(ev);
|
||||
};
|
||||
|
||||
|
||||
24
core/src/components/checkbox/test/checkbox.spec.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
|
||||
import { Checkbox } from '../checkbox';
|
||||
|
||||
describe('ion-checkbox: disabled', () => {
|
||||
it('clicking disabled checkbox should not toggle checked state', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Checkbox],
|
||||
html: `
|
||||
<ion-checkbox disabled="true">Checkbox</ion-checkbox>
|
||||
`,
|
||||
});
|
||||
|
||||
const checkbox = page.body.querySelector('ion-checkbox');
|
||||
|
||||
expect(checkbox.checked).toBe(false);
|
||||
|
||||
checkbox.click();
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(checkbox.checked).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Build, Component, Element, Event, Host, Listen, Method, Prop, forceUpdate, h, readTask } from '@stencil/core';
|
||||
import { componentOnReady } from '@utils/helpers';
|
||||
import { componentOnReady, hasLazyBuild } from '@utils/helpers';
|
||||
import { isPlatform } from '@utils/platform';
|
||||
import { isRTL } from '@utils/rtl';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
@@ -34,6 +34,9 @@ export class Content implements ComponentInterface {
|
||||
private isMainContent = true;
|
||||
private resizeTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
private tabsElement: HTMLElement | null = null;
|
||||
private tabsLoadCallback?: () => void;
|
||||
|
||||
// Detail is used in a hot loop in the scroll event, by allocating it here
|
||||
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
||||
// https://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html
|
||||
@@ -115,15 +118,61 @@ export class Content implements ComponentInterface {
|
||||
|
||||
connectedCallback() {
|
||||
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
||||
|
||||
/**
|
||||
* The fullscreen content offsets need to be
|
||||
* computed after the tab bar has loaded. Since
|
||||
* lazy evaluation means components are not hydrated
|
||||
* at the same time, we need to wait for the ionTabBarLoaded
|
||||
* event to fire. This does not impact dist-custom-elements
|
||||
* because there is no hydration there.
|
||||
*/
|
||||
if (hasLazyBuild(this.el)) {
|
||||
/**
|
||||
* We need to cache the reference to the tabs.
|
||||
* If just the content is unmounted then we won't
|
||||
* be able to query for the closest tabs on disconnectedCallback
|
||||
* since the content has been removed from the DOM tree.
|
||||
*/
|
||||
const closestTabs = (this.tabsElement = this.el.closest('ion-tabs'));
|
||||
if (closestTabs !== null) {
|
||||
/**
|
||||
* When adding and removing the event listener
|
||||
* we need to make sure we pass the same function reference
|
||||
* otherwise the event listener will not be removed properly.
|
||||
* We can't only pass `this.resize` because "this" in the function
|
||||
* context becomes a reference to IonTabs instead of IonContent.
|
||||
*
|
||||
* Additionally, we listen for ionTabBarLoaded on the IonTabs
|
||||
* instance rather than the IonTabBar instance. It's possible for
|
||||
* a tab bar to be conditionally rendered/mounted. Since ionTabBarLoaded
|
||||
* bubbles, we can catch any instances of child tab bars loading by listening
|
||||
* on IonTabs.
|
||||
*/
|
||||
this.tabsLoadCallback = () => this.resize();
|
||||
closestTabs.addEventListener('ionTabBarLoaded', this.tabsLoadCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.onScrollEnd();
|
||||
}
|
||||
|
||||
@Listen('appload', { target: 'window' })
|
||||
onAppLoad() {
|
||||
this.resize();
|
||||
if (hasLazyBuild(this.el)) {
|
||||
/**
|
||||
* The event listener and tabs caches need to
|
||||
* be cleared otherwise this will create a memory
|
||||
* leak where the IonTabs instance can never be
|
||||
* garbage collected.
|
||||
*/
|
||||
const { tabsElement, tabsLoadCallback } = this;
|
||||
if (tabsElement !== null && tabsLoadCallback !== undefined) {
|
||||
tabsElement.removeEventListener('ionTabBarLoaded', tabsLoadCallback);
|
||||
}
|
||||
|
||||
this.tabsElement = null;
|
||||
this.tabsLoadCallback = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.fab-button-small) {
|
||||
@include margin(($fab-size - $fab-small-size) * 0.5);
|
||||
@include margin($fab-button-small-margin);
|
||||
|
||||
width: #{$fab-small-size};
|
||||
height: #{$fab-small-size};
|
||||
|
||||
@@ -11,3 +11,6 @@ $fab-small-size: 40px !default;
|
||||
|
||||
/// @prop - Border radius of the FAB button
|
||||
$fab-border-radius: 50% !default;
|
||||
|
||||
/// @prop - Margin applied to the small FAB button
|
||||
$fab-button-small-margin: 8px !default;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
@include margin($fab-size + $fab-list-margin, 0);
|
||||
@include margin(calc(100% + #{$fab-list-margin}), 0);
|
||||
|
||||
display: none;
|
||||
position: absolute;
|
||||
@@ -13,8 +13,15 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
min-width: $fab-size;
|
||||
min-height: $fab-size;
|
||||
/**
|
||||
* The list should be centered relative to the parent
|
||||
* FAB button. We set minimum dimensions so the
|
||||
* FAB list can be centered relative to the small FAB button.
|
||||
* However, the small FAB button adds start/end margin, so we need
|
||||
* to account for that in the FAB list dimensions.
|
||||
*/
|
||||
min-width: $fab-small-size + ($fab-button-small-margin * 2);
|
||||
min-height: $fab-small-size + ($fab-button-small-margin * 2);
|
||||
}
|
||||
|
||||
:host(.fab-list-active) {
|
||||
@@ -59,14 +66,14 @@
|
||||
}
|
||||
|
||||
:host(.fab-list-side-start) {
|
||||
@include margin(0, $fab-size + $fab-list-margin);
|
||||
@include margin(0, calc(100% + #{$fab-list-margin}));
|
||||
@include position-horizontal(null, 0);
|
||||
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
:host(.fab-list-side-end) {
|
||||
@include margin(0, $fab-size + $fab-list-margin);
|
||||
@include margin(0, calc(100% + #{$fab-list-margin}));
|
||||
@include position(null, null, null, 0);
|
||||
|
||||
flex-direction: row;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import "./fab.vars";
|
||||
@import "../fab-list/fab-list.vars";
|
||||
|
||||
// Floating Action Button Container
|
||||
// --------------------------------------------------
|
||||
@@ -6,6 +7,9 @@
|
||||
:host {
|
||||
position: absolute;
|
||||
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
|
||||
z-index: $z-index-fixed-content;
|
||||
}
|
||||
|
||||
@@ -14,8 +18,8 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.fab-horizontal-center) {
|
||||
@include position(null, null, null, 50%);
|
||||
@include margin-horizontal(-$fab-size * 0.5, null);
|
||||
@include position(null, 0px, null, 0px);
|
||||
@include margin(null, auto);
|
||||
}
|
||||
|
||||
:host(.fab-horizontal-start) {
|
||||
@@ -38,22 +42,93 @@
|
||||
top: $fab-content-margin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the top value since edge
|
||||
* styles use margin-top.
|
||||
*/
|
||||
:host(.fab-vertical-top.fab-edge) {
|
||||
top: -$fab-size * 0.5;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to adjust the parent FAB button up by half
|
||||
* its height so that half of it sits on the header. As a result,
|
||||
* we target the slotted ion-fab-button instead of targeting the host.
|
||||
*/
|
||||
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-button) {
|
||||
margin-top: -50%;
|
||||
}
|
||||
|
||||
/**
|
||||
* The small FAB button adds top and bottom margin. We need to account for
|
||||
* that margin when we adjust the FAB button for edge styles since we
|
||||
* are overriding the margin-top value below.
|
||||
*/
|
||||
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-button.fab-button-small) {
|
||||
margin-top: calc((-100% + $fab-button-small-margin * 2) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since we are adjusting the FAB button we also need
|
||||
* to adjust the sibling ion-fab-list otherwise there will be
|
||||
* a gap between the parent FAB button and the associated list.
|
||||
*/
|
||||
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-start),
|
||||
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-end) {
|
||||
@include margin(-50%, null, null, null);
|
||||
}
|
||||
|
||||
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-top),
|
||||
:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-bottom) {
|
||||
@include margin(calc(50% + #{$fab-list-margin}) null, null, null);
|
||||
}
|
||||
|
||||
:host(.fab-vertical-bottom) {
|
||||
bottom: $fab-content-margin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the bottom value since edge
|
||||
* styles use margin-bottom.
|
||||
*/
|
||||
:host(.fab-vertical-bottom.fab-edge) {
|
||||
bottom: -$fab-size * 0.5;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to adjust the parent FAB button down by half
|
||||
* its height so that half of it sits on the footer. As a result,
|
||||
* we target the slotted ion-fab-button instead of targeting the host.
|
||||
*/
|
||||
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-button) {
|
||||
margin-bottom: -50%;
|
||||
}
|
||||
|
||||
/**
|
||||
* The small FAB button adds top and bottom margin. We need to account for
|
||||
* that margin when we adjust the FAB button for edge styles since we
|
||||
* are overriding the margin-bottom value below.
|
||||
*/
|
||||
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-button.fab-button-small) {
|
||||
margin-bottom: calc((-100% + $fab-button-small-margin * 2) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since we are adjusting the FAB button we also need
|
||||
* to adjust the sibling ion-fab-list otherwise there will be
|
||||
* a gap between the parent FAB button and the associated list.
|
||||
*/
|
||||
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-start),
|
||||
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-end) {
|
||||
@include margin(null, null, -50%, null);
|
||||
}
|
||||
|
||||
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-top),
|
||||
:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-bottom) {
|
||||
@include margin(null, null, calc(50% + #{$fab-list-margin}) null);
|
||||
}
|
||||
|
||||
:host(.fab-vertical-center) {
|
||||
@include margin(-$fab-size * 0.5, null, null, null);
|
||||
|
||||
top: 50%;
|
||||
@include position(0px, null, 0px, null);
|
||||
@include margin(auto, null);
|
||||
}
|
||||
|
||||
17
core/src/components/fab/test/custom-size/fab.e2e.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test, Viewports } from '@utils/test/playwright';
|
||||
|
||||
/**
|
||||
* This behavior does not vary across modes
|
||||
*/
|
||||
configs({ modes: ['ios'] }).forEach(({ title, config, screenshot }) => {
|
||||
test.describe(title('fab: custom size'), () => {
|
||||
test('should position fabs correctly with custom sizes', async ({ page }) => {
|
||||
await page.goto(`/src/components/fab/test/custom-size`, config);
|
||||
|
||||
await page.setViewportSize(Viewports.tablet.landscape);
|
||||
|
||||
await expect(page).toHaveScreenshot(screenshot(`fab-custom-size`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 68 KiB |
241
core/src/components/fab/test/custom-size/index.html
Normal file
@@ -0,0 +1,241 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Floating Action Button - Custom Size</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<style>
|
||||
.ruler-y {
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
|
||||
background: red;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
margin: 0 auto;
|
||||
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.ruler-x {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
|
||||
background: red;
|
||||
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
margin: 0 auto;
|
||||
|
||||
z-index: 10000;
|
||||
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
ion-fab-button {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Floating Action Button - Custom Size</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding" id="content">
|
||||
<div class="ruler-y"></div>
|
||||
<div class="ruler-x"></div>
|
||||
|
||||
<ion-fab vertical="top" horizontal="start" slot="fixed" edge="true">
|
||||
<ion-fab-button activated="true">
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-list side="bottom" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
<ion-fab-list side="end" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
</ion-fab>
|
||||
|
||||
<ion-fab vertical="top" horizontal="end" slot="fixed" edge="true">
|
||||
<ion-fab-button activated="true">
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-list side="start" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
<ion-fab-list side="bottom" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
</ion-fab>
|
||||
|
||||
<ion-fab vertical="bottom" horizontal="start" slot="fixed" edge="true">
|
||||
<ion-fab-button activated="true">
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-list side="top" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
<ion-fab-list side="end" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
</ion-fab>
|
||||
|
||||
<ion-fab vertical="bottom" horizontal="end" slot="fixed" edge="true">
|
||||
<ion-fab-button activated="true">
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-list side="start" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
<ion-fab-list side="top" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
</ion-fab>
|
||||
|
||||
<ion-fab vertical="center" horizontal="center" slot="fixed">
|
||||
<ion-fab-button activated="true">
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-list side="start" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
<ion-fab-list side="top" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
<ion-fab-list side="bottom" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
<ion-fab-list side="end" activated="true">
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button show="true">
|
||||
<ion-icon name="logo-instagram"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
</ion-fab>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-title>Floating Action Button - Basic</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
@@ -107,3 +107,28 @@
|
||||
.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main header is only hidden once the collapsible large
|
||||
* title is configured. As a result, if the main header loads
|
||||
* before the collapsible large title is configured then the
|
||||
* main header will be visible briefly before being hidden
|
||||
* by the collapsible large title.
|
||||
*
|
||||
* The following selector ensures that any main header
|
||||
* on a page with a collapsible large title is hidden
|
||||
* before the collapsible large title is configured.
|
||||
* Once the collapsible large title is configured the main
|
||||
* header will have the ".header-collapse-main" class, and
|
||||
* this selector will no longer apply.
|
||||
*
|
||||
* The :has(...) part of the selector ensures a couple things:
|
||||
* 1. This will only apply within a page view since the content
|
||||
* must be a subsequent-sibling of the header (~ ion-content).
|
||||
* 2. This will only apply when that content has a collapse header (ion-header[collapse="condense"])
|
||||
*
|
||||
* We use opacity: 0 to avoid a layout shift.
|
||||
*/
|
||||
ion-header:not(.header-collapse-main):has(~ ion-content ion-header[collapse="condense"]) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,15 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
|
||||
private didLoad = false;
|
||||
|
||||
/**
|
||||
* Flag used to determine if an open/close
|
||||
* operation was cancelled. For example, if
|
||||
* an app calls "menu.open" then disables the menu
|
||||
* part way through the animation, then this would
|
||||
* be considered a cancelled operation.
|
||||
*/
|
||||
private operationCancelled = false;
|
||||
|
||||
isAnimating = false;
|
||||
width!: number;
|
||||
_isOpen = false;
|
||||
@@ -432,6 +441,17 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
|
||||
await this.loadAnimation();
|
||||
await this.startAnimation(shouldOpen, animated);
|
||||
|
||||
/**
|
||||
* If the animation was cancelled then
|
||||
* return false because the operation
|
||||
* did not succeed.
|
||||
*/
|
||||
if (this.operationCancelled) {
|
||||
this.operationCancelled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.afterAnimation(shouldOpen);
|
||||
|
||||
return true;
|
||||
@@ -472,18 +492,24 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
const easingReverse = mode === 'ios' ? iosEasingReverse : mdEasingReverse;
|
||||
const ani = (this.animation as Animation)!
|
||||
.direction(isReversed ? 'reverse' : 'normal')
|
||||
.easing(isReversed ? easingReverse : easing)
|
||||
.onFinish(() => {
|
||||
if (ani.getDirection() === 'reverse') {
|
||||
ani.direction('normal');
|
||||
}
|
||||
});
|
||||
.easing(isReversed ? easingReverse : easing);
|
||||
|
||||
if (animated) {
|
||||
await ani.play();
|
||||
} else {
|
||||
ani.play({ sync: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* We run this after the play invocation
|
||||
* instead of using ani.onFinish so that
|
||||
* multiple onFinish callbacks do not get
|
||||
* run if an animation is played, stopped,
|
||||
* and then played again.
|
||||
*/
|
||||
if (ani.getDirection() === 'reverse') {
|
||||
ani.direction('normal');
|
||||
}
|
||||
}
|
||||
|
||||
private _isActive() {
|
||||
@@ -643,8 +669,6 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
}
|
||||
|
||||
private afterAnimation(isOpen: boolean) {
|
||||
assert(this.isAnimating, '_before() should be called while animating');
|
||||
|
||||
// keep opening/closing the menu disabled for a touch more yet
|
||||
// only add listeners/css if it's enabled and isOpen
|
||||
// and only remove listeners/css if it's not open
|
||||
@@ -713,10 +737,30 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
this.gesture.enable(isActive && this.swipeGesture);
|
||||
}
|
||||
|
||||
// Close menu immediately
|
||||
if (!isActive && this._isOpen) {
|
||||
// close if this menu is open, and should not be enabled
|
||||
this.forceClosing();
|
||||
/**
|
||||
* If the menu is disabled but it is still open
|
||||
* then we should close the menu immediately.
|
||||
* Additionally, if the menu is in the process
|
||||
* of animating {open, close} and the menu is disabled
|
||||
* then it should still be closed immediately.
|
||||
*/
|
||||
if (!isActive) {
|
||||
/**
|
||||
* It is possible to disable the menu while
|
||||
* it is mid-animation. When this happens, we
|
||||
* need to set the operationCancelled flag
|
||||
* so that this._setOpen knows to return false
|
||||
* and not run the "afterAnimation" callback.
|
||||
*/
|
||||
if (this.isAnimating) {
|
||||
this.operationCancelled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the menu is disabled then we should
|
||||
* forcibly close the menu even if it is open.
|
||||
*/
|
||||
this.afterAnimation(false);
|
||||
}
|
||||
|
||||
if (doc?.contains(this.el)) {
|
||||
@@ -730,19 +774,6 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
menuController._setActiveMenu(this);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!this.isAnimating, 'can not be animating');
|
||||
}
|
||||
|
||||
private forceClosing() {
|
||||
assert(this._isOpen, 'menu cannot be closed');
|
||||
|
||||
this.isAnimating = true;
|
||||
|
||||
const ani = (this.animation as Animation)!.direction('reverse');
|
||||
ani.play({ sync: true });
|
||||
|
||||
this.afterAnimation(false);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
41
core/src/components/menu/test/disable/index.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Menu - Disable</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-menu side="start" id="start-menu" menu-id="start-menu" content-id="main">
|
||||
<ion-header>
|
||||
<ion-toolbar color="primary">
|
||||
<ion-title>Menu</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding"> Menu Content </ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<div class="ion-page" id="main">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Menu - Disable</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">Content</ion-content>
|
||||
</div>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
66
core/src/components/menu/test/disable/menu.e2e.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
/**
|
||||
* This behavior does not vary across modes/directions
|
||||
*/
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('menu: disable'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(`/src/components/menu/test/disable`, config);
|
||||
});
|
||||
|
||||
test('should disable when menu is fully open', async ({ page }) => {
|
||||
const logs: string[] = [];
|
||||
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
logs.push(msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
const menu = page.locator('ion-menu');
|
||||
|
||||
// Should be visible on initial presentation
|
||||
await menu.evaluate((el: HTMLIonMenuElement) => el.open());
|
||||
await expect(menu).toBeVisible();
|
||||
|
||||
// Disabling menu should hide it
|
||||
await menu.evaluate((el: HTMLIonMenuElement) => (el.disabled = true));
|
||||
await expect(menu).toBeHidden();
|
||||
|
||||
// Re-enabling menu and opening it show make it visible
|
||||
await menu.evaluate((el: HTMLIonMenuElement) => (el.disabled = false));
|
||||
await menu.evaluate((el: HTMLIonMenuElement) => el.open());
|
||||
await expect(menu).toBeVisible();
|
||||
|
||||
expect(logs.length).toBe(0);
|
||||
});
|
||||
|
||||
test('should disable when menu is animating', async ({ page }) => {
|
||||
const logs: string[] = [];
|
||||
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
logs.push(msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
const menu = page.locator('ion-menu');
|
||||
|
||||
// Opening and quickly disabling menu should hide it
|
||||
menu.evaluate((el: HTMLIonMenuElement) => {
|
||||
el.open();
|
||||
setTimeout(() => (el.disabled = true), 0);
|
||||
});
|
||||
await expect(menu).toBeHidden();
|
||||
|
||||
// Re-enabling menu and opening it show make it visible
|
||||
await menu.evaluate((el: HTMLIonMenuElement) => (el.disabled = false));
|
||||
await menu.evaluate((el: HTMLIonMenuElement) => el.open());
|
||||
await expect(menu).toBeVisible();
|
||||
|
||||
expect(logs.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,5 @@
|
||||
position: absolute;
|
||||
|
||||
contain: layout size style;
|
||||
overflow: hidden;
|
||||
z-index: $z-index-page-container;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export async function testPickerColumn(
|
||||
await page.waitForChanges();
|
||||
|
||||
screenshots.push({
|
||||
name: `picker-${description}-column-diff-${i}-${page.getSnapshotSettings()}.png`,
|
||||
name: screenshot(`picker-${description}-column-diff-${i}`),
|
||||
screenshot: await page.screenshot(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ export class RadioGroup implements ComponentInterface {
|
||||
* using the `name` attribute.
|
||||
*/
|
||||
const selectedRadio = ev.target && (ev.target as HTMLElement).closest('ion-radio');
|
||||
if (selectedRadio) {
|
||||
if (selectedRadio && selectedRadio.disabled === false) {
|
||||
const currentValue = this.value;
|
||||
const newValue = selectedRadio.value;
|
||||
if (newValue !== currentValue) {
|
||||
|
||||
@@ -200,7 +200,11 @@ export class Radio implements ComponentInterface {
|
||||
};
|
||||
|
||||
private onClick = () => {
|
||||
const { radioGroup, checked } = this;
|
||||
const { radioGroup, checked, disabled } = this;
|
||||
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The legacy control uses a native input inside
|
||||
|
||||
@@ -31,3 +31,27 @@ describe('ion-radio', () => {
|
||||
expect(radio.classList.contains('radio-checked')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ion-radio: disabled', () => {
|
||||
it('clicking disabled radio should not set checked state', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Radio, RadioGroup],
|
||||
html: `
|
||||
<ion-radio-group>
|
||||
<ion-radio disabled="true" value="a">Radio</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
});
|
||||
|
||||
const radio = page.body.querySelector('ion-radio');
|
||||
const radioGroup = page.body.querySelector('ion-radio-group');
|
||||
|
||||
expect(radioGroup.value).toBe(undefined);
|
||||
|
||||
radio.click();
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(radioGroup.value).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -319,6 +319,7 @@ export class Range implements ComponentInterface {
|
||||
componentDidLoad() {
|
||||
this.originalIonInput = this.ionInput;
|
||||
this.setupGesture();
|
||||
this.updateRatio();
|
||||
this.didLoad = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,5 @@
|
||||
position: absolute;
|
||||
|
||||
contain: layout size style;
|
||||
overflow: hidden;
|
||||
z-index: $z-index-page-container;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Component, Element, Event, Method, Prop, Watch, h } from '@stencil/core
|
||||
import { getTimeGivenProgression } from '@utils/animation/cubic-bezier';
|
||||
import { attachComponent, detachComponent } from '@utils/framework-delegate';
|
||||
import { shallowEqualStringMap, hasLazyBuild } from '@utils/helpers';
|
||||
import { createLockController } from '@utils/lock-controller';
|
||||
import { transition } from '@utils/transition';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
@@ -24,11 +25,11 @@ import type { RouteID, RouterDirection, RouteWrite, NavOutlet } from '../router/
|
||||
shadow: true,
|
||||
})
|
||||
export class RouterOutlet implements ComponentInterface, NavOutlet {
|
||||
private readonly lockController = createLockController();
|
||||
private activeEl: HTMLElement | undefined;
|
||||
// TODO(FW-2832): types
|
||||
private activeComponent: any;
|
||||
private activeParams: any;
|
||||
private waitPromise?: Promise<void>;
|
||||
private gesture?: Gesture;
|
||||
private ani?: Animation;
|
||||
private gestureOrAnimationInProgress = false;
|
||||
@@ -140,7 +141,7 @@ export class RouterOutlet implements ComponentInterface, NavOutlet {
|
||||
leavingEl: HTMLElement | undefined,
|
||||
opts?: RouterOutletOptions
|
||||
): Promise<boolean> {
|
||||
const unlock = await this.lock();
|
||||
const unlock = await this.lockController.lock();
|
||||
let changed = false;
|
||||
try {
|
||||
changed = await this.transition(enteringEl, leavingEl, opts);
|
||||
@@ -285,18 +286,6 @@ export class RouterOutlet implements ComponentInterface, NavOutlet {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: FW-5048 - Remove this code in favor of using lock controller from utils
|
||||
private async lock() {
|
||||
const p = this.waitPromise;
|
||||
let resolve!: () => void;
|
||||
this.waitPromise = new Promise((r) => (resolve = r));
|
||||
|
||||
if (p !== undefined) {
|
||||
await p;
|
||||
}
|
||||
return resolve;
|
||||
}
|
||||
|
||||
render() {
|
||||
return <slot></slot>;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Listen, Prop, State, Watch, h, writeTask } from '@stencil/core';
|
||||
import type { Gesture, GestureDetail } from '@utils/gesture';
|
||||
import { raf } from '@utils/helpers';
|
||||
import { isRTL } from '@utils/rtl';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
@@ -83,31 +84,7 @@ export class Segment implements ComponentInterface {
|
||||
* Used by `ion-segment-button` to determine if the button should be checked.
|
||||
*/
|
||||
this.ionSelect.emit({ value });
|
||||
|
||||
if (this.scrollable) {
|
||||
const buttons = this.getButtons();
|
||||
const activeButton = buttons.find((button) => button.value === value);
|
||||
if (activeButton !== undefined) {
|
||||
/**
|
||||
* Scrollable segment buttons should be
|
||||
* centered within the view including
|
||||
* buttons that are partially offscreen.
|
||||
*/
|
||||
activeButton.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
inline: 'center',
|
||||
|
||||
/**
|
||||
* Segment should scroll on the
|
||||
* horizontal axis. `block: 'nearest'`
|
||||
* ensures that the vertical axis
|
||||
* does not scroll if the segment
|
||||
* as a whole is already in view.
|
||||
*/
|
||||
block: 'nearest',
|
||||
});
|
||||
}
|
||||
}
|
||||
this.scrollActiveButtonIntoView();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,6 +140,14 @@ export class Segment implements ComponentInterface {
|
||||
async componentDidLoad() {
|
||||
this.setCheckedClasses();
|
||||
|
||||
/**
|
||||
* We need to wait for the buttons to all be rendered
|
||||
* before we can scroll.
|
||||
*/
|
||||
raf(() => {
|
||||
this.scrollActiveButtonIntoView();
|
||||
});
|
||||
|
||||
this.gesture = (await import('../../utils/gesture')).createGesture({
|
||||
el: this.el,
|
||||
gestureName: 'segment',
|
||||
@@ -320,6 +305,35 @@ export class Segment implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
private scrollActiveButtonIntoView() {
|
||||
const { scrollable, value } = this;
|
||||
|
||||
if (scrollable) {
|
||||
const buttons = this.getButtons();
|
||||
const activeButton = buttons.find((button) => button.value === value);
|
||||
if (activeButton !== undefined) {
|
||||
/**
|
||||
* Scrollable segment buttons should be
|
||||
* centered within the view including
|
||||
* buttons that are partially offscreen.
|
||||
*/
|
||||
activeButton.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
inline: 'center',
|
||||
|
||||
/**
|
||||
* Segment should scroll on the
|
||||
* horizontal axis. `block: 'nearest'`
|
||||
* ensures that the vertical axis
|
||||
* does not scroll if the segment
|
||||
* as a whole is already in view.
|
||||
*/
|
||||
block: 'nearest',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setNextIndex(detail: GestureDetail, isEnd = false) {
|
||||
const rtl = isRTL(this.el);
|
||||
const activated = this.activated;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs().forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('segment: scrollable'), () => {
|
||||
test.describe(title('segment: scrollable (rendering)'), () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
@@ -45,3 +45,47 @@ configs().forEach(({ title, screenshot, config }) => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('segment: scrollable (functionality)'), () => {
|
||||
test('should scroll active button into view when value is already set', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-segment scrollable="true" value="8">
|
||||
<ion-segment-button value="1">
|
||||
<ion-label>First</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="2">
|
||||
<ion-label>Second</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="3">
|
||||
<ion-label>Third</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="4">
|
||||
<ion-label>Fourth</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="5">
|
||||
<ion-label>Fifth</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="6">
|
||||
<ion-label>Sixth</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="7">
|
||||
<ion-label>Seventh</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button id="activeButton" value="8">
|
||||
<ion-label>Eighth</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="9">
|
||||
<ion-label>Ninth</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const activeButton = page.locator('#activeButton');
|
||||
await expect(activeButton).toBeInViewport();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -316,29 +316,46 @@ export class Select implements ComponentInterface {
|
||||
|
||||
// focus selected option for popovers
|
||||
if (this.interface === 'popover') {
|
||||
let indexOfSelected = this.childOpts.map((o) => o.value).indexOf(this.value);
|
||||
indexOfSelected = indexOfSelected > -1 ? indexOfSelected : 0; // default to first option if nothing selected
|
||||
const selectedItem = overlay.querySelector<HTMLElement>(
|
||||
`.select-interface-option:nth-child(${indexOfSelected + 1})`
|
||||
);
|
||||
const indexOfSelected = this.childOpts.map((o) => o.value).indexOf(this.value);
|
||||
|
||||
if (selectedItem) {
|
||||
focusElement(selectedItem);
|
||||
if (indexOfSelected > -1) {
|
||||
const selectedItem = overlay.querySelector<HTMLElement>(
|
||||
`.select-interface-option:nth-child(${indexOfSelected + 1})`
|
||||
);
|
||||
|
||||
if (selectedItem) {
|
||||
focusElement(selectedItem);
|
||||
|
||||
/**
|
||||
* Browsers such as Firefox do not
|
||||
* correctly delegate focus when manually
|
||||
* focusing an element with delegatesFocus.
|
||||
* We work around this by manually focusing
|
||||
* the interactive element.
|
||||
* ion-radio and ion-checkbox are the only
|
||||
* elements that ion-select-popover uses, so
|
||||
* we only need to worry about those two components
|
||||
* when focusing.
|
||||
*/
|
||||
const interactiveEl = selectedItem.querySelector<HTMLElement>('ion-radio, ion-checkbox');
|
||||
if (interactiveEl) {
|
||||
interactiveEl.focus();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Browsers such as Firefox do not
|
||||
* correctly delegate focus when manually
|
||||
* focusing an element with delegatesFocus.
|
||||
* We work around this by manually focusing
|
||||
* the interactive element.
|
||||
* ion-radio and ion-checkbox are the only
|
||||
* elements that ion-select-popover uses, so
|
||||
* we only need to worry about those two components
|
||||
* when focusing.
|
||||
* If no value is set then focus the first enabled option.
|
||||
*/
|
||||
const interactiveEl = selectedItem.querySelector<HTMLElement>('ion-radio, ion-checkbox');
|
||||
if (interactiveEl) {
|
||||
interactiveEl.focus();
|
||||
const firstEnabledOption = overlay.querySelector<HTMLElement>(
|
||||
'ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)'
|
||||
);
|
||||
if (firstEnabledOption) {
|
||||
focusElement(firstEnabledOption.closest('ion-item')!);
|
||||
|
||||
/**
|
||||
* Focus the option for the same reason as we do above.
|
||||
*/
|
||||
firstEnabledOption.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
core/src/components/select/test/disabled/select.e2e.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('select: disabled options'), () => {
|
||||
test('should not focus a disabled option when no value is set', async ({ page, skip }) => {
|
||||
// TODO (FW-2979)
|
||||
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
||||
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/ionic-team/ionic-framework/issues/28284',
|
||||
});
|
||||
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-select interface="popover">
|
||||
<ion-select-option value="a" disabled="true">A</ion-select-option>
|
||||
<ion-select-option value="b">B</ion-select-option>
|
||||
</ion-select>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const select = page.locator('ion-select');
|
||||
const popover = page.locator('ion-popover');
|
||||
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
||||
|
||||
await select.click();
|
||||
await ionPopoverDidPresent.next();
|
||||
|
||||
const popoverOption = popover.locator('.select-interface-option:nth-of-type(2) ion-radio');
|
||||
await expect(popoverOption).toBeFocused();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -57,6 +57,14 @@ export class TabBar implements ComponentInterface {
|
||||
/** @internal */
|
||||
@Event() ionTabBarChanged!: EventEmitter<TabBarChangedEventDetail>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* This event is used in IonContent to correctly
|
||||
* calculate the fullscreen content offsets
|
||||
* when IonTabBar is used.
|
||||
*/
|
||||
@Event() ionTabBarLoaded!: EventEmitter<void>;
|
||||
|
||||
componentWillLoad() {
|
||||
this.selectedTabChanged();
|
||||
}
|
||||
@@ -82,6 +90,10 @@ export class TabBar implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.ionTabBarLoaded.emit();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { color, translucent, keyboardVisible } = this;
|
||||
const mode = getIonMode(this);
|
||||
|
||||
@@ -39,5 +39,40 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c
|
||||
|
||||
await expect(tabBar).toHaveScreenshot(screenshot(`tab-bar-translucent`));
|
||||
});
|
||||
test('should render translucent tab bar even when wrapped in a page container', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<style>
|
||||
ion-content {
|
||||
--background: linear-gradient(to right, orange, yellow, green, cyan, blue, violet);
|
||||
}
|
||||
</style>
|
||||
<ion-tabs>
|
||||
<div class="ion-page">
|
||||
<ion-content fullscreen="true">My Content</ion-content>
|
||||
</div>
|
||||
<ion-tab-bar slot="bottom" translucent="true" selected-tab="1">
|
||||
<ion-tab-button tab="1">
|
||||
<ion-label>Recents</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2">
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-badge>23</ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3">
|
||||
<ion-label>Settings</ion-label>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const tabBar = page.locator('ion-tab-bar');
|
||||
|
||||
await expect(tabBar).toHaveScreenshot(screenshot(`tab-bar-translucent-container`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
@@ -61,6 +61,7 @@
|
||||
|
||||
:host(.title-large.ion-cloned-element) {
|
||||
--color: #{$text-color};
|
||||
font-family: var(--ion-font-family);
|
||||
}
|
||||
|
||||
:host(.title-large) .toolbar-title {
|
||||
|
||||
@@ -41,3 +41,24 @@ describe('toggle', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ion-toggle: disabled', () => {
|
||||
it('clicking disabled toggle should not toggle checked state', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Toggle],
|
||||
html: `
|
||||
<ion-toggle disabled="true">Toggle</ion-toggle>
|
||||
`,
|
||||
});
|
||||
|
||||
const toggle = page.body.querySelector('ion-toggle');
|
||||
|
||||
expect(toggle.checked).toBe(false);
|
||||
|
||||
toggle.click();
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(toggle.checked).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -259,6 +259,10 @@ export class Toggle implements ComponentInterface {
|
||||
}
|
||||
|
||||
private onClick = (ev: MouseEvent) => {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
if (this.lastDrag + 300 < Date.now()) {
|
||||
|
||||
@@ -156,7 +156,6 @@ html.ios ion-modal.modal-card .ion-page {
|
||||
justify-content: space-between;
|
||||
|
||||
contain: layout size style;
|
||||
overflow: hidden;
|
||||
z-index: $z-index-page-container;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ interface AnimationOnFinishCallback {
|
||||
o?: AnimationCallbackOptions;
|
||||
}
|
||||
|
||||
type AnimationOnStopCallback = AnimationOnFinishCallback;
|
||||
|
||||
export const createAnimation = (animationId?: string): Animation => {
|
||||
let _delay: number | undefined;
|
||||
let _duration: number | undefined;
|
||||
@@ -63,6 +65,7 @@ export const createAnimation = (animationId?: string): Animation => {
|
||||
const id: string | undefined = animationId;
|
||||
const onFinishCallbacks: AnimationOnFinishCallback[] = [];
|
||||
const onFinishOneTimeCallbacks: AnimationOnFinishCallback[] = [];
|
||||
const onStopOneTimeCallbacks: AnimationOnStopCallback[] = [];
|
||||
const elements: HTMLElement[] = [];
|
||||
const childAnimations: Animation[] = [];
|
||||
const stylesheets: HTMLElement[] = [];
|
||||
@@ -134,6 +137,35 @@ export const createAnimation = (animationId?: string): Animation => {
|
||||
return numAnimationsRunning !== 0 && !paused;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Remove a callback from a chosen callback array
|
||||
* @param callbackToRemove: A reference to the callback that should be removed
|
||||
* @param callbackObjects: An array of callbacks that callbackToRemove should be removed from.
|
||||
*/
|
||||
const clearCallback = (
|
||||
callbackToRemove: AnimationLifecycle,
|
||||
callbackObjects: AnimationOnFinishCallback[] | AnimationOnStopCallback[]
|
||||
) => {
|
||||
const index = callbackObjects.findIndex((callbackObject) => callbackObject.c === callbackToRemove);
|
||||
|
||||
if (index > -1) {
|
||||
callbackObjects.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Add a callback to be fired when an animation is stopped/cancelled.
|
||||
* @param callback: A reference to the callback that should be fired
|
||||
* @param opts: Any options associated with this particular callback
|
||||
*/
|
||||
const onStop = (callback: AnimationLifecycle, opts?: AnimationCallbackOptions) => {
|
||||
onStopOneTimeCallbacks.push({ c: callback, o: opts });
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
const onFinish = (callback: AnimationLifecycle, opts?: AnimationCallbackOptions) => {
|
||||
const callbacks = opts?.oneTimeCallback ? onFinishOneTimeCallbacks : onFinishCallbacks;
|
||||
callbacks.push({ c: callback, o: opts });
|
||||
@@ -953,7 +985,34 @@ export const createAnimation = (animationId?: string): Animation => {
|
||||
shouldCalculateNumAnimations = false;
|
||||
}
|
||||
|
||||
onFinish(() => resolve(), { oneTimeCallback: true });
|
||||
/**
|
||||
* When one of these callbacks fires we
|
||||
* need to clear the other's callback otherwise
|
||||
* you can potentially get these callbacks
|
||||
* firing multiple times if the play method
|
||||
* is subsequently called.
|
||||
* Example:
|
||||
* animation.play() (onStop and onFinish callbacks are registered)
|
||||
* animation.stop() (onStop callback is fired, onFinish is not)
|
||||
* animation.play() (onStop and onFinish callbacks are registered)
|
||||
* Total onStop callbacks: 1
|
||||
* Total onFinish callbacks: 2
|
||||
*/
|
||||
const onStopCallback = () => {
|
||||
clearCallback(onFinishCallback, onFinishOneTimeCallbacks);
|
||||
resolve();
|
||||
};
|
||||
const onFinishCallback = () => {
|
||||
clearCallback(onStopCallback, onStopOneTimeCallbacks);
|
||||
resolve();
|
||||
};
|
||||
|
||||
/**
|
||||
* The play method resolves when an animation
|
||||
* run either finishes or is cancelled.
|
||||
*/
|
||||
onFinish(onFinishCallback, { oneTimeCallback: true });
|
||||
onStop(onStopCallback, { oneTimeCallback: true });
|
||||
|
||||
childAnimations.forEach((animation) => {
|
||||
animation.play();
|
||||
@@ -969,6 +1028,14 @@ export const createAnimation = (animationId?: string): Animation => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Stops an animation and resets it state to the
|
||||
* beginning. This does not fire any onFinish
|
||||
* callbacks because the animation did not finish.
|
||||
* However, since the animation was not destroyed
|
||||
* (i.e. the animation could run again) we do not
|
||||
* clear the onFinish callbacks.
|
||||
*/
|
||||
const stop = () => {
|
||||
childAnimations.forEach((animation) => {
|
||||
animation.stop();
|
||||
@@ -980,6 +1047,9 @@ export const createAnimation = (animationId?: string): Animation => {
|
||||
}
|
||||
|
||||
resetFlags();
|
||||
|
||||
onStopOneTimeCallbacks.forEach((onStopCallback) => onStopCallback.c(0, ani));
|
||||
onStopOneTimeCallbacks.length = 0;
|
||||
};
|
||||
|
||||
const from = (property: string, value: any) => {
|
||||
|
||||
@@ -4,6 +4,24 @@ import { processKeyframes } from '../animation-utils';
|
||||
import { getTimeGivenProgression } from '../cubic-bezier';
|
||||
|
||||
describe('Animation Class', () => {
|
||||
describe('play()', () => {
|
||||
it('should resolve when the animation is cancelled', async () => {
|
||||
// Tell Jest to expect 1 assertion for async code
|
||||
expect.assertions(1);
|
||||
const el = document.createElement('div');
|
||||
const animation = createAnimation()
|
||||
.addElement(el)
|
||||
.fromTo('transform', 'translateX(0px)', 'translateX(100px)')
|
||||
.duration(100000);
|
||||
|
||||
const animationPromise = animation.play();
|
||||
|
||||
animation.stop();
|
||||
|
||||
// Expect that the promise resolves and returns undefined
|
||||
expect(animationPromise).resolves.toEqual(undefined);
|
||||
});
|
||||
});
|
||||
describe('isRunning()', () => {
|
||||
let animation: Animation;
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -79,7 +79,11 @@ export const createSwipeBackGesture = (
|
||||
return createGesture({
|
||||
el,
|
||||
gestureName: 'goback-swipe',
|
||||
gesturePriority: 40,
|
||||
/**
|
||||
* Swipe to go back should have priority over other horizontal swipe
|
||||
* gestures. These gestures have a priority of 100 which is why 101 was chosen here.
|
||||
*/
|
||||
gesturePriority: 101,
|
||||
threshold: 10,
|
||||
canStart,
|
||||
onStart: onStartHandler,
|
||||
|
||||
@@ -6,5 +6,6 @@ This directory contains information on how to get the most out of Ionic's E2E te
|
||||
|
||||
| Directory | Description |
|
||||
| - | - |
|
||||
| [Usage Instructions](./usage-instructions.md) | How to run tests and update screenshots |
|
||||
| [Best Practices](./best-practices.md) | Contains information on conventions to follow as well as pitfalls to avoid when writing tests |
|
||||
| [API](./api.md) | Documents the custom functionality that has been built on top of Playwright |
|
||||
@@ -108,7 +108,6 @@ The [page fixture](https://playwright.dev/docs/test-fixtures) has been extended
|
||||
| `setIonViewport` | Resizes the browser window to fit the entire height of `ion-content` on screen. Only needed when taking fullsize screenshots with `ion-content`. |
|
||||
| `waitForChanges` | Waits for Stencil to re-render before proceeeding. This is typically only needed when you update a property on a component. |
|
||||
| `spyOnEvent` | Creates an event spy that can be used to wait for a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) to be emitted. |
|
||||
| `getSnapshotSettings` (DEPRECATED) | Returns information about the current test (such as mode or direction) to generate a unique screenshot name. Deprecated: Use the `screenshot` function provided by the test [generator](#generators) instead. |
|
||||
|
||||
<details>
|
||||
|
||||
|
||||
114
core/src/utils/test/playwright/docs/usage-instructions.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Usage Instructions
|
||||
|
||||
E2E tests verify Ionic components in a real browser. This is useful for testing user interaction and catching visual regressions. We use Playwright as it allows us to test in multiple browsers. Tests can be written and run using Playwright's public API.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Installing Dependencies](#installing-dependencies)
|
||||
- [Running Tests](#running-tests)
|
||||
- [Managing Screenshots](#managing-screenshots)
|
||||
- [Further Reading](#further-reading)
|
||||
|
||||
## Installing Dependencies
|
||||
|
||||
Follow these steps to install Playwright dependencies. These steps must also be run whenever the installed version of Playwright changes to ensure that you are testing with the correct browser binaries.
|
||||
|
||||
1. Install the Playwright dependency in the `core` directory: `npm ci`
|
||||
2. Download the correct browsers: `npx playwright install`
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Running All Test Files
|
||||
|
||||
All E2E tests can be run using the following command:
|
||||
|
||||
```shell
|
||||
npm run test.e2e
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> This command is a wrapper for `npx playwright test`. All data passed to `npm run test.e2e` can also be passed to `npx playwright test`.
|
||||
|
||||
### Running Specific Test Files
|
||||
|
||||
Specific test files can be run by passing the file paths or a directory that contains multiple test files. See [Managing Screenshots](#managing-screenshots) for generating ground truths before running screenshot tests.
|
||||
|
||||
**Specific Test Files**
|
||||
|
||||
```shell
|
||||
npm run test.e2e src/components/button/test/basic/button.e2e.ts src/components/button/test/a11y/button.e2e.ts
|
||||
```
|
||||
|
||||
**Test Directory with Multiple Files**
|
||||
|
||||
```shell
|
||||
# Will run all the test files in the `test` directory
|
||||
npm run test.e2e src/components/button/test
|
||||
```
|
||||
|
||||
## Managing Screenshots
|
||||
|
||||
### Generating or Updating Ground Truths (Local Development)
|
||||
|
||||
If you are running a test that takes a screenshot, you must first generate the reference screenshot from your reference branch. This is known as generating a "ground truth screenshot". All other screenshots will be compared to this ground truth. Alternatively, if the reference branch has changed since the last time you generated ground truths you may need to update your local ground truths.
|
||||
|
||||
For most types of work the reference branch is typically `main`. Features are merged into a different branch, so developers should use that as the reference branch. For example, if branch `foo` will be merged into `bar`, then the reference branch is `bar`.
|
||||
|
||||
The examples provided in the [Running Tests](#running-tests) section also apply here, allowing you to update screenshots for a specific test file.
|
||||
|
||||
Note that since you are generating the reference branch ground truth screenshots, you must be on the reference branch locally. Don't forget to pull the latest reference branch changes and then re-build using `npm run build`.
|
||||
|
||||
```shell
|
||||
npm run test.e2e.update-snapshots
|
||||
```
|
||||
|
||||
Optionally, you can pass a directory to only update the ground truths for that directory & subdirectories. This is useful when working on a specific component.
|
||||
|
||||
```shell
|
||||
npm run test.e2e.update-snapshots src/components/alert/
|
||||
```
|
||||
|
||||
From here, you can switch back to your branch and run the tests.
|
||||
|
||||
> [!NOTE]
|
||||
> Locally generated ground truths should not be committed to the repo. The `.gitignore` file prevents this from accidentally happening.
|
||||
|
||||
### Updating Ground Truths (CI)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Only Ionic Team members can update ground truths on the main repo. Ground truths cannot be updated on forked versions of the repo.
|
||||
|
||||
When making an intentional visual change, you will need to update the ground truth screenshots or add new ones. It is important that the ground truth and comparison screenshots are taken in the same environment, so do not update the ground truth screenshots locally and commit them to the repo.
|
||||
|
||||
Instead, use the [Update Reference Screenshots GitHub Action](https://github.com/ionic-team/ionic-framework/actions/workflows/update-screenshots.yml).
|
||||
|
||||
1. Click the **Run workflow** dropdown.
|
||||
2. Select your branch.
|
||||
3. Click **Run workflow**.
|
||||
|
||||
This workflow will re-run the screenshot tests. Instead of failing any tests with mismatched screenshots, it will take new ground truth screenshots. These ground truth screenshots will be pushed as a single commit to your branch once the workflow is completed.
|
||||
|
||||
### Verifying Screenshot Differences
|
||||
|
||||
When any of the screenshot tests fail, it means a potential regression was caught. Developers must manually verify the difference in the Playwright test report.
|
||||
|
||||
If the screenshots fail on CI then developers must download the build artifact. On the **Summary** page for a particular workflow, find the **Artifacts** section. Screenshot tests are currently parallelized across several test runners, and the results from each of those runners is included in an artifact with the following naming scheme:
|
||||
|
||||
```
|
||||
test-results-[current shard]-[total shards]
|
||||
|
||||
Example:
|
||||
|
||||
test-results-2-5 --> Test results from job runner 2 out of 5.
|
||||
```
|
||||
|
||||
Download the appropriate artifact and unzip the file.
|
||||
|
||||
In the newly created directory, open the `playwright-report/index.html` in your browser. From here, you will be able to see the tests that failed as well as the expected screenshot, the actual screenshot, and the pixel differences.
|
||||
|
||||
> [!WARNING]
|
||||
> It is recommended to verify the screenshot difference within the Playwright test report first. If you choose to try and reproduce the difference in a browser manually, make sure you are using the **exact** same browser version that Playwright is using.
|
||||
|
||||
## Further Reading
|
||||
|
||||
For more info on how to use Playwright, please see the [Playwright documentation](https://playwright.dev/docs/intro).
|
||||
@@ -1,33 +0,0 @@
|
||||
import type { Page, TestInfo } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* This provides metadata that can be used to
|
||||
* create a unique screenshot URL.
|
||||
* For example, we need to be able to differentiate
|
||||
* between iOS in LTR mode and iOS in RTL mode.
|
||||
*/
|
||||
export const getSnapshotSettings = (page: Page, testInfo: TestInfo) => {
|
||||
const url = page.url();
|
||||
const splitUrl = url.split('?');
|
||||
const paramsString = splitUrl[1];
|
||||
|
||||
const { mode, rtl } = testInfo.project.metadata;
|
||||
|
||||
/**
|
||||
* Account for custom settings when overriding
|
||||
* the mode/rtl setting. Fall back to the
|
||||
* project metadata if nothing was found. This
|
||||
* will happen if you call page.getSnapshotSettings
|
||||
* before page.goto.
|
||||
*/
|
||||
const urlToParams = new URLSearchParams(paramsString);
|
||||
const formattedMode = urlToParams.get('ionic:mode') ?? mode;
|
||||
const formattedRtl = urlToParams.get('rtl') ?? rtl;
|
||||
|
||||
/**
|
||||
* If encoded in the search params, the rtl value
|
||||
* can be `'true'` instead of `true`.
|
||||
*/
|
||||
const rtlString = formattedRtl === true || formattedRtl === 'true' ? 'rtl' : 'ltr';
|
||||
return `${formattedMode}-${rtlString}`;
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
export * from './wait-for-changes';
|
||||
export * from './goto';
|
||||
export * from './get-snapshot-settings';
|
||||
export * from './set-ion-viewport';
|
||||
export * from './spy-on-event';
|
||||
export * from './set-content';
|
||||
|
||||
@@ -78,11 +78,6 @@ export interface E2EPage extends Page {
|
||||
* Use this method when taking full-screen screenshots.
|
||||
*/
|
||||
setIonViewport: (options?: SetIonViewportOptions) => Promise<void>;
|
||||
/**
|
||||
* This provides metadata that can be used to create a unique screenshot URL.
|
||||
* For example, we need to be able to differentiate between iOS in LTR mode and iOS in RTL mode.
|
||||
*/
|
||||
getSnapshotSettings: () => string;
|
||||
/**
|
||||
* After changes have been made to a component, such as an update to a property or attribute,
|
||||
* we need to wait until the changes have been applied to the DOM.
|
||||
|
||||
@@ -10,15 +10,7 @@ import { test as base } from '@playwright/test';
|
||||
import { PageUtils } from '../press-keys';
|
||||
|
||||
import { initPageEvents } from './page/event-spy';
|
||||
import {
|
||||
getSnapshotSettings,
|
||||
goto as goToPage,
|
||||
setContent,
|
||||
setIonViewport,
|
||||
spyOnEvent,
|
||||
waitForChanges,
|
||||
locator,
|
||||
} from './page/utils';
|
||||
import { goto as goToPage, setContent, setIonViewport, spyOnEvent, waitForChanges, locator } from './page/utils';
|
||||
import type { LocatorOptions } from './page/utils';
|
||||
import type {
|
||||
E2EPage,
|
||||
@@ -57,7 +49,6 @@ export async function extendPageFixture(page: E2EPage, testInfo: TestInfo) {
|
||||
page.locator = (selector: string, options?: LocatorOptions) => locator(page, originalLocator, selector, options);
|
||||
|
||||
// Custom Ionic methods
|
||||
page.getSnapshotSettings = () => getSnapshotSettings(page, testInfo);
|
||||
page.setIonViewport = (options?: SetIonViewportOptions) => setIonViewport(page, options);
|
||||
page.waitForChanges = (timeoutMs?: number) => waitForChanges(page, timeoutMs);
|
||||
page.spyOnEvent = (eventName: string) => spyOnEvent(page, eventName);
|
||||
|
||||
@@ -4,6 +4,10 @@ export const Viewports = {
|
||||
width: 768,
|
||||
height: 900,
|
||||
},
|
||||
landscape: {
|
||||
width: 900,
|
||||
height: 768,
|
||||
},
|
||||
},
|
||||
// Based off https://github.com/ionic-team/ionic-framework/blob/2fe23d9d46c3593843c781c57340332e5a86fd64/core/src/components/split-pane/split-pane.tsx#L9-L13
|
||||
large: {
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
4
docs/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/docs",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "Pre-packaged API documentation for the Ionic docs.",
|
||||
"main": "core.json",
|
||||
"types": "core.d.ts",
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
"docs",
|
||||
"packages/*"
|
||||
],
|
||||
"version": "7.4.1"
|
||||
"version": "7.4.4"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
34
packages/angular-server/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1"
|
||||
"@ionic/core": "^7.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-eslint/eslint-plugin": "^14.0.0",
|
||||
@@ -1060,19 +1060,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -7342,19 +7342,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "Angular SSR Module for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -61,6 +61,6 @@
|
||||
},
|
||||
"prettier": "@ionic/prettier-config",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1"
|
||||
"@ionic/core": "^7.4.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
34
packages/angular/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1",
|
||||
"@ionic/core": "^7.4.4",
|
||||
"ionicons": "^7.0.0",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.3.0"
|
||||
@@ -1227,19 +1227,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -8104,19 +8104,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -47,7 +47,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1",
|
||||
"@ionic/core": "^7.4.4",
|
||||
"ionicons": "^7.0.0",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.3.0"
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
50
packages/react-router/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/react-router",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/react": "^7.4.1",
|
||||
"@ionic/react": "^7.4.4",
|
||||
"tslib": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -205,11 +205,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
@@ -401,11 +401,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/react": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.4.1.tgz",
|
||||
"integrity": "sha512-9ByyybeNJfchPCk7tz8/beKarjzF1yG7KZS1s2DMyUSFt7x2y3F3v6WrwG0xQgoYLNJYJIPmR+CKc/4eQeMbXA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.4.3.tgz",
|
||||
"integrity": "sha512-j33s8CFe3Cu3AQtIlZdI/W4+e5hDzjRcX6uwqRrizcMQS66Sj9Ik9RN5v3jV/9R8MHLElXZof/AhofNEhe7BTw==",
|
||||
"dependencies": {
|
||||
"@ionic/core": "7.4.1",
|
||||
"@ionic/core": "7.4.3",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
},
|
||||
@@ -486,9 +486,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -3663,11 +3663,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
@@ -3786,11 +3786,11 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@ionic/react": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.4.1.tgz",
|
||||
"integrity": "sha512-9ByyybeNJfchPCk7tz8/beKarjzF1yG7KZS1s2DMyUSFt7x2y3F3v6WrwG0xQgoYLNJYJIPmR+CKc/4eQeMbXA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.4.3.tgz",
|
||||
"integrity": "sha512-j33s8CFe3Cu3AQtIlZdI/W4+e5hDzjRcX6uwqRrizcMQS66Sj9Ik9RN5v3jV/9R8MHLElXZof/AhofNEhe7BTw==",
|
||||
"requires": {
|
||||
"@ionic/core": "7.4.1",
|
||||
"@ionic/core": "7.4.3",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
}
|
||||
@@ -3844,9 +3844,9 @@
|
||||
}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg=="
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "0.0.39",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "React Router wrapper for @ionic/react",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -37,7 +37,7 @@
|
||||
"dist/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/react": "^7.4.1",
|
||||
"@ionic/react": "^7.4.4",
|
||||
"tslib": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -3,6 +3,33 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** Nav unmounts component while invoking popTo or popToRoot ([#27821](https://github.com/ionic-team/ionic-framework/issues/27821)) ([0edcb2c](https://github.com/ionic-team/ionic-framework/commit/0edcb2cd85133ae8c304c53c37ca829e5fbad447)), closes [#27798](https://github.com/ionic-team/ionic-framework/issues/27798)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react
|
||||
|
||||
34
packages/react/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/react",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/react",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1",
|
||||
"@ionic/core": "^7.4.4",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
},
|
||||
@@ -697,19 +697,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -11778,19 +11778,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "React specific wrapper for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -41,7 +41,7 @@
|
||||
"css/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1",
|
||||
"@ionic/core": "^7.4.4",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
50
packages/vue-router/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/vue": "^7.4.1"
|
||||
"@ionic/vue": "^7.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
@@ -660,11 +660,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
@@ -871,11 +871,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/vue": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.4.1.tgz",
|
||||
"integrity": "sha512-yHmpBG69j+CCE7vpa6zyQ38vCMx68U/UZ90MAUPRYSvpCXGx0714YbSZ68S1JDU5bwz8h0Gv/zOfm/JWcYwzOA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.4.3.tgz",
|
||||
"integrity": "sha512-DV/SExC/e3rcLoowuYb5bwo4N/oP5fWHQo1xLP654I/879hlwPJlCxdWFtaE2OlT3aEix9ssLYeNiWaxuK+9dQ==",
|
||||
"dependencies": {
|
||||
"@ionic/core": "7.4.1",
|
||||
"@ionic/core": "7.4.3",
|
||||
"ionicons": "^7.0.0"
|
||||
}
|
||||
},
|
||||
@@ -1323,9 +1323,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -7697,11 +7697,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
@@ -7829,11 +7829,11 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@ionic/vue": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.4.1.tgz",
|
||||
"integrity": "sha512-yHmpBG69j+CCE7vpa6zyQ38vCMx68U/UZ90MAUPRYSvpCXGx0714YbSZ68S1JDU5bwz8h0Gv/zOfm/JWcYwzOA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.4.3.tgz",
|
||||
"integrity": "sha512-DV/SExC/e3rcLoowuYb5bwo4N/oP5fWHQo1xLP654I/879hlwPJlCxdWFtaE2OlT3aEix9ssLYeNiWaxuK+9dQ==",
|
||||
"requires": {
|
||||
"@ionic/core": "7.4.1",
|
||||
"@ionic/core": "7.4.3",
|
||||
"ionicons": "^7.0.0"
|
||||
}
|
||||
},
|
||||
@@ -8192,9 +8192,9 @@
|
||||
}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg=="
|
||||
},
|
||||
"@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "Vue Router integration for @ionic/vue",
|
||||
"scripts": {
|
||||
"test.spec": "jest",
|
||||
@@ -45,7 +45,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/ionic-team/ionic#readme",
|
||||
"dependencies": {
|
||||
"@ionic/vue": "^7.4.1"
|
||||
"@ionic/vue": "^7.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||
34
packages/vue/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1",
|
||||
"@ionic/core": "^7.4.4",
|
||||
"ionicons": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -207,11 +207,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
@@ -423,9 +423,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -3746,11 +3746,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.1.tgz",
|
||||
"integrity": "sha512-ZM18jm8nvyw7HAWhLYmJ9HABqtvzw9tIn2/Oq70XBMkayO9f3LzrgHvRoOqIAMS00QYuAZw+5XhpGAvcqh/sqA==",
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.4.3.tgz",
|
||||
"integrity": "sha512-JPQLGojKnI/L0UBVshRv86DOSDj61rJRFYQImU4IcgP/rw5ckxwt3iZ5NtdJl0eEDwu91n68aGJdU+TFJjMJgQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^4.3.0",
|
||||
"@stencil/core": "^4.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
@@ -3885,9 +3885,9 @@
|
||||
}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
|
||||
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
|
||||
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg=="
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.11",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.4",
|
||||
"description": "Vue specific wrapper for @ionic/core",
|
||||
"scripts": {
|
||||
"eslint": "eslint src",
|
||||
@@ -66,7 +66,7 @@
|
||||
"vue-router": "^4.0.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.4.1",
|
||||
"@ionic/core": "^7.4.4",
|
||||
"ionicons": "^7.0.0"
|
||||
},
|
||||
"vetur": {
|
||||
|
||||