Compare commits

..

13 Commits

Author SHA1 Message Date
Shawn Taylor
ef95520e08 Rename tag; upsert instead of recreate 2023-09-22 14:18:01 -04:00
Shawn Taylor
604c0246c9 Try to recreate comment 2023-09-22 13:51:07 -04:00
Shawn Taylor
0f5d5df9e1 Try to recreate comment 2023-09-22 13:20:28 -04:00
Shawn Taylor
b22a670d77 Combine actions 2023-09-22 13:16:12 -04:00
Shawn Taylor
8178a9df96 Continue on error 2023-09-22 13:14:38 -04:00
Shawn Taylor
59a911bcb0 Try to recreate comment 2023-09-22 13:04:16 -04:00
Shawn Taylor
e7aedce8b7 Merge branch 'main' into dev-build-comment 2023-09-22 12:07:00 -04:00
Shawn Taylor
e17879fb23 output pr number 2023-09-21 17:45:42 -04:00
Shawn Taylor
d0abe6681c fix step 2023-09-21 17:29:00 -04:00
Shawn Taylor
41200ed7ed Get PR 2023-09-21 16:47:54 -04:00
Shawn Taylor
5c9e1d3c83 Checkout 2023-09-21 15:04:24 -04:00
Shawn Taylor
e2fa2e565c Comment on PR 2023-09-21 13:44:17 -04:00
Shawn Taylor
288b237a31 Add empty job 2023-09-21 13:37:25 -04:00
488 changed files with 2333 additions and 9482 deletions

View File

@@ -1,4 +1,4 @@
name: 'Ionic Dev Build'
name: "Ionic Dev Build"
on:
workflow_dispatch:
@@ -40,3 +40,26 @@ jobs:
steps:
- run: echo ${{ needs.create-dev-hash.outputs.dev-hash }}
comment-on-pr:
runs-on: ubuntu-latest
needs: [create-dev-hash, release-ionic]
continue-on-error: true
outputs:
pr-number: ${{ steps.PR.outputs.number }}
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: 8BitJonny/gh-get-current-pr@2.2.0
id: PR
- name: Comment on PR
uses: thollander/actions-comment-pull-request@v2
with:
message: |
A dev build has been generated for this PR. To use the dev build, update your Ionic packages to the following version:
```
${{ needs.create-dev-hash.outputs.dev-hash }}
```
pr_number: ${{ steps.PR.outputs.number }}
comment_tag: dev-build

View File

@@ -8,12 +8,7 @@ on:
# at 6:00 UTC (6:00 am UTC)
- cron: '00 06 * * 1-5'
workflow_dispatch:
inputs:
npm_release_tag:
required: true
type: string
description: What version should be pulled from NPM?
default: nightly
# allows for manual invocations in the GitHub UI
# When pushing a new commit we should
# cancel the previous test run to not
@@ -29,7 +24,7 @@ jobs:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-core-stencil-prerelease
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
stencil-version: nightly
test-core-clean-build:
needs: [build-core-with-stencil-nightly]
@@ -52,7 +47,7 @@ jobs:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-spec
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
stencil-version: nightly
test-core-screenshot:
strategy:

View File

@@ -3,30 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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)

View File

@@ -3,29 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [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)

View File

@@ -394,7 +394,7 @@ ion-datetime,prop,disabled,boolean,false,false,false
ion-datetime,prop,doneText,string,'Done',false,false
ion-datetime,prop,firstDayOfWeek,number,0,false,false
ion-datetime,prop,highlightedDates,((dateIsoString: string) => DatetimeHighlightStyle | undefined) | DatetimeHighlight[] | undefined,undefined,false,false
ion-datetime,prop,hourCycle,"h11" | "h12" | "h23" | "h24" | undefined,undefined,false,false
ion-datetime,prop,hourCycle,"h12" | "h23" | undefined,undefined,false,false
ion-datetime,prop,hourValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,isDateEnabled,((dateIsoString: string) => boolean) | undefined,undefined,false,false
ion-datetime,prop,locale,string,'default',false,false
@@ -1445,7 +1445,6 @@ ion-toast,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefin
ion-toast,prop,message,IonicSafeString | string | undefined,undefined,false,false
ion-toast,prop,mode,"ios" | "md",undefined,false,false
ion-toast,prop,position,"bottom" | "middle" | "top",'bottom',false,false
ion-toast,prop,positionAnchor,HTMLElement | string | undefined,undefined,false,false
ion-toast,prop,translucent,boolean,false,false,false
ion-toast,prop,trigger,string | undefined,undefined,false,false
ion-toast,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>

590
core/package-lock.json generated
View File

@@ -1,21 +1,21 @@
{
"name": "@ionic/core",
"version": "7.4.3",
"version": "7.4.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/core",
"version": "7.4.3",
"version": "7.4.1",
"license": "MIT",
"dependencies": {
"@stencil/core": "^4.4.0",
"ionicons": "^7.1.2",
"@stencil/core": "^4.3.0",
"ionicons": "7.1.0",
"tslib": "^2.1.0"
},
"devDependencies": {
"@axe-core/playwright": "^4.7.3",
"@capacitor/core": "^5.4.2",
"@capacitor/core": "^5.4.1",
"@capacitor/haptics": "^5.0.6",
"@capacitor/keyboard": "^5.0.6",
"@capacitor/status-bar": "^5.0.6",
@@ -27,12 +27,12 @@
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.8.2",
"@stencil/react-output-target": "^0.5.3",
"@stencil/sass": "^3.0.6",
"@stencil/sass": "^3.0.5",
"@stencil/vue-output-target": "^0.8.6",
"@types/jest": "^27.5.2",
"@types/node": "^14.6.0",
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"clean-css-cli": "^5.6.1",
"domino": "^2.1.6",
"eslint": "^7.32.0",
@@ -47,7 +47,8 @@
"sass": "^1.26.10",
"serve": "^14.0.1",
"stylelint": "^13.13.1",
"stylelint-order": "^4.1.0"
"stylelint-order": "^4.1.0",
"typescript": "^4.0.5"
}
},
"custom-rules": {
@@ -606,9 +607,9 @@
"dev": true
},
"node_modules/@capacitor/core": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.2.tgz",
"integrity": "sha512-XbR1vldJFzBWHeoGPpgfNy3Zhjf0NxXdHEaGNANWVBg0ZWG2gwFr1dcRALUUQtbwrEEkCCNiLYg4YiQPRk7SEQ==",
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.1.tgz",
"integrity": "sha512-QG9gORuxw2WNcVpLHT1W3LzACOJvFWRuHcz4b9edzxehSELqiSQ4DoGWLp4PuNBBp2oV/fGA4FMNmfZ1jIAAWg==",
"dev": true,
"dependencies": {
"tslib": "^2.1.0"
@@ -641,30 +642,6 @@
"@capacitor/core": "^5.0.0"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
"dev": true,
"dependencies": {
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
"node_modules/@eslint-community/regexpp": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz",
"integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
"node_modules/@eslint/eslintrc": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
@@ -1653,9 +1630,9 @@
}
},
"node_modules/@stencil/core": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A==",
"bin": {
"stencil": "bin/stencil"
},
@@ -1674,9 +1651,9 @@
}
},
"node_modules/@stencil/sass": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.6.tgz",
"integrity": "sha512-d+k8qCvDgzI/vIV7M5QavIS6b75X4yn+YQH80KA/L0oL/hKD8KeF3wMOd7P1nDhGLIGRNw5tBDbe0GeIsGVU7A==",
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.5.tgz",
"integrity": "sha512-9nyllMXOEvHywo6fP2iwXgnq32A+OOUE36Aq7iUjzwT3wdr04qsvupO1JNIyRvmvCDF15hOKXztrZH1/wDu2Zg==",
"dev": true,
"engines": {
"node": ">=12.0.0",
@@ -1808,9 +1785,9 @@
}
},
"node_modules/@types/json-schema": {
"version": "7.0.13",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
"integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
"node_modules/@types/json5": {
@@ -1867,12 +1844,6 @@
"@types/node": "*"
}
},
"node_modules/@types/semver": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz",
"integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==",
"dev": true
},
"node_modules/@types/stack-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
@@ -1892,33 +1863,31 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz",
"integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz",
"integrity": "sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "6.7.2",
"@typescript-eslint/type-utils": "6.7.2",
"@typescript-eslint/utils": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
"natural-compare": "^1.4.0",
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/type-utils": "5.17.0",
"@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
"regexpp": "^3.2.0",
"semver": "^7.3.5",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
"eslint": "^7.0.0 || ^8.0.0"
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -1926,6 +1895,30 @@
}
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz",
"integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.17.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -1944,9 +1937,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -2098,26 +2091,25 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz",
"integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz",
"integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.7.2",
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/typescript-estree": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2",
"debug": "^4.3.4"
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.17.0",
"debug": "^4.3.2"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0"
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -2143,16 +2135,16 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz",
"integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz",
"integrity": "sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2"
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.17.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
@@ -2160,25 +2152,24 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz",
"integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz",
"integrity": "sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "6.7.2",
"@typescript-eslint/utils": "6.7.2",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
"@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0"
"eslint": "*"
},
"peerDependenciesMeta": {
"typescript": {
@@ -2186,6 +2177,30 @@
}
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz",
"integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.17.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -2204,12 +2219,12 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz",
"integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.17.0.tgz",
"integrity": "sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
@@ -2217,21 +2232,21 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz",
"integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz",
"integrity": "sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2",
"debug": "^4.3.4",
"globby": "^11.1.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.17.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
"semver": "^7.3.5",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
@@ -2261,49 +2276,9 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@typescript-eslint/utils": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz",
"integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "6.7.2",
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/typescript-estree": "6.7.2",
"semver": "^7.5.4"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/utils/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -2316,16 +2291,16 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz",
"integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz",
"integrity": "sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.7.2",
"eslint-visitor-keys": "^3.4.1"
"@typescript-eslint/types": "5.17.0",
"eslint-visitor-keys": "^3.0.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
@@ -4179,15 +4154,12 @@
}
},
"node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/@babel/code-frame": {
@@ -5009,12 +4981,6 @@
"integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
"dev": true
},
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
"node_modules/hard-rejection": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
@@ -5211,9 +5177,9 @@
}
},
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -5328,9 +5294,9 @@
}
},
"node_modules/ionicons": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.1.2.tgz",
"integrity": "sha512-zZ4njAqSP39H8RRvZhJvkHsv7cBjYE/VfInH218Osf2UVxJITSOutTTd25MW+tAXKN5fheYzclUXUsF55JHUDg==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.1.0.tgz",
"integrity": "sha512-iE4GuEdEHARJpp0sWL7WJZCzNCf5VxpNRhAjW0fLnZPnNL5qZOJUcfup2Z2Ty7Jk8Q5hacrHfGEB1lCwOdXqGg==",
"dependencies": {
"@stencil/core": "^2.18.0"
}
@@ -9758,18 +9724,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/ts-api-utils": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
"integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
"dev": true,
"engines": {
"node": ">=16.13.0"
},
"peerDependencies": {
"typescript": ">=4.2.0"
}
},
"node_modules/tsconfig-paths": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
@@ -9872,17 +9826,16 @@
}
},
"node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
"dev": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
"node": ">=4.2.0"
}
},
"node_modules/unbox-primitive": {
@@ -10849,9 +10802,9 @@
"dev": true
},
"@capacitor/core": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.2.tgz",
"integrity": "sha512-XbR1vldJFzBWHeoGPpgfNy3Zhjf0NxXdHEaGNANWVBg0ZWG2gwFr1dcRALUUQtbwrEEkCCNiLYg4YiQPRk7SEQ==",
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.1.tgz",
"integrity": "sha512-QG9gORuxw2WNcVpLHT1W3LzACOJvFWRuHcz4b9edzxehSELqiSQ4DoGWLp4PuNBBp2oV/fGA4FMNmfZ1jIAAWg==",
"dev": true,
"requires": {
"tslib": "^2.1.0"
@@ -10878,21 +10831,6 @@
"dev": true,
"requires": {}
},
"@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^3.3.0"
}
},
"@eslint-community/regexpp": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz",
"integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==",
"dev": true
},
"@eslint/eslintrc": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
@@ -11598,9 +11536,9 @@
"requires": {}
},
"@stencil/core": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.0.tgz",
"integrity": "sha512-YlLyCqGBsMEuZb3XTO/STT0TX9eSwjoVhCJgtjVfQOF+ebIMVlojTh40CmDveWiWbth687cbr6S2heeussV8Sg=="
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.3.0.tgz",
"integrity": "sha512-WYjftKg5fuqO7mf3nTl1aCRurkeMmfEF38WcBG4VLF6UPQ+MA76/koedGR2LGhATGByx+pbxR4iRxAr2Bspc9A=="
},
"@stencil/react-output-target": {
"version": "0.5.3",
@@ -11610,9 +11548,9 @@
"requires": {}
},
"@stencil/sass": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.6.tgz",
"integrity": "sha512-d+k8qCvDgzI/vIV7M5QavIS6b75X4yn+YQH80KA/L0oL/hKD8KeF3wMOd7P1nDhGLIGRNw5tBDbe0GeIsGVU7A==",
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-3.0.5.tgz",
"integrity": "sha512-9nyllMXOEvHywo6fP2iwXgnq32A+OOUE36Aq7iUjzwT3wdr04qsvupO1JNIyRvmvCDF15hOKXztrZH1/wDu2Zg==",
"dev": true,
"requires": {}
},
@@ -11729,9 +11667,9 @@
}
},
"@types/json-schema": {
"version": "7.0.13",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
"integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
"@types/json5": {
@@ -11788,12 +11726,6 @@
"@types/node": "*"
}
},
"@types/semver": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz",
"integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==",
"dev": true
},
"@types/stack-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
@@ -11813,24 +11745,36 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz",
"integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz",
"integrity": "sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==",
"dev": true,
"requires": {
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "6.7.2",
"@typescript-eslint/type-utils": "6.7.2",
"@typescript-eslint/utils": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
"natural-compare": "^1.4.0",
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/type-utils": "5.17.0",
"@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
"regexpp": "^3.2.0",
"semver": "^7.3.5",
"tsutils": "^3.21.0"
},
"dependencies": {
"@typescript-eslint/utils": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz",
"integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.17.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -11841,9 +11785,9 @@
}
},
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -11933,16 +11877,15 @@
}
},
"@typescript-eslint/parser": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz",
"integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz",
"integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "6.7.2",
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/typescript-estree": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2",
"debug": "^4.3.4"
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.17.0",
"debug": "^4.3.2"
},
"dependencies": {
"debug": {
@@ -11957,27 +11900,40 @@
}
},
"@typescript-eslint/scope-manager": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz",
"integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz",
"integrity": "sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==",
"dev": true,
"requires": {
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2"
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.17.0"
}
},
"@typescript-eslint/type-utils": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz",
"integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz",
"integrity": "sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "6.7.2",
"@typescript-eslint/utils": "6.7.2",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
"@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2",
"tsutils": "^3.21.0"
},
"dependencies": {
"@typescript-eslint/utils": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz",
"integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.17.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -11990,24 +11946,24 @@
}
},
"@typescript-eslint/types": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz",
"integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.17.0.tgz",
"integrity": "sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz",
"integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz",
"integrity": "sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==",
"dev": true,
"requires": {
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/visitor-keys": "6.7.2",
"debug": "^4.3.4",
"globby": "^11.1.0",
"@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.17.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
"semver": "^7.5.4",
"ts-api-utils": "^1.0.1"
"semver": "^7.3.5",
"tsutils": "^3.21.0"
},
"dependencies": {
"debug": {
@@ -12020,35 +11976,9 @@
}
},
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"@typescript-eslint/utils": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz",
"integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "6.7.2",
"@typescript-eslint/types": "6.7.2",
"@typescript-eslint/typescript-estree": "6.7.2",
"semver": "^7.5.4"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -12057,13 +11987,13 @@
}
},
"@typescript-eslint/visitor-keys": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz",
"integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==",
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz",
"integrity": "sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "6.7.2",
"eslint-visitor-keys": "^3.4.1"
"@typescript-eslint/types": "5.17.0",
"eslint-visitor-keys": "^3.0.0"
}
},
"@zeit/schemas": {
@@ -13612,9 +13542,9 @@
}
},
"eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
"dev": true
},
"espree": {
@@ -14064,12 +13994,6 @@
"integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
"dev": true
},
"graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
"hard-rejection": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
@@ -14212,9 +14136,9 @@
}
},
"ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true
},
"import-fresh": {
@@ -14297,9 +14221,9 @@
}
},
"ionicons": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.1.2.tgz",
"integrity": "sha512-zZ4njAqSP39H8RRvZhJvkHsv7cBjYE/VfInH218Osf2UVxJITSOutTTd25MW+tAXKN5fheYzclUXUsF55JHUDg==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.1.0.tgz",
"integrity": "sha512-iE4GuEdEHARJpp0sWL7WJZCzNCf5VxpNRhAjW0fLnZPnNL5qZOJUcfup2Z2Ty7Jk8Q5hacrHfGEB1lCwOdXqGg==",
"requires": {
"@stencil/core": "^2.18.0"
},
@@ -17576,13 +17500,6 @@
"integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==",
"dev": true
},
"ts-api-utils": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
"integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
"dev": true,
"requires": {}
},
"tsconfig-paths": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
@@ -17665,11 +17582,10 @@
}
},
"typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true,
"peer": true
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
"dev": true
},
"unbox-primitive": {
"version": "1.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "7.4.3",
"version": "7.4.1",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -31,13 +31,13 @@
"loader/"
],
"dependencies": {
"@stencil/core": "^4.4.0",
"ionicons": "^7.1.2",
"@stencil/core": "^4.3.0",
"ionicons": "7.1.0",
"tslib": "^2.1.0"
},
"devDependencies": {
"@axe-core/playwright": "^4.7.3",
"@capacitor/core": "^5.4.2",
"@capacitor/core": "^5.4.1",
"@capacitor/haptics": "^5.0.6",
"@capacitor/keyboard": "^5.0.6",
"@capacitor/status-bar": "^5.0.6",
@@ -49,12 +49,12 @@
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.8.2",
"@stencil/react-output-target": "^0.5.3",
"@stencil/sass": "^3.0.6",
"@stencil/sass": "^3.0.5",
"@stencil/vue-output-target": "^0.8.6",
"@types/jest": "^27.5.2",
"@types/node": "^14.6.0",
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"clean-css-cli": "^5.6.1",
"domino": "^2.1.6",
"eslint": "^7.32.0",
@@ -69,7 +69,8 @@
"sass": "^1.26.10",
"serve": "^14.0.1",
"stylelint": "^13.13.1",
"stylelint-order": "^4.1.0"
"stylelint-order": "^4.1.0",
"typescript": "^4.0.5"
},
"scripts": {
"build": "npm run clean && npm run build.css && stencil build --es5 --docs-json dist/docs.json",
@@ -94,7 +95,6 @@
"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"

View File

@@ -15,7 +15,7 @@ import { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./compo
import { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
import { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
import { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
import { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
import { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
import { SpinnerTypes } from "./components/spinner/spinner-configs";
import { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
import { CounterFormatter } from "./components/item/item-interface";
@@ -39,7 +39,7 @@ import { SelectChangeEventDetail, SelectCompareFn, SelectInterface } from "./com
import { SelectPopoverOption } from "./components/select-popover/select-popover-interface";
import { TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout } from "./components/tab-bar/tab-bar-interface";
import { TextareaChangeEventDetail, TextareaInputEventDetail } from "./components/textarea/textarea-interface";
import { ToastButton, ToastDismissOptions, ToastLayout, ToastPosition, ToastPresentOptions } from "./components/toast/toast-interface";
import { ToastButton, ToastLayout, ToastPosition } from "./components/toast/toast-interface";
import { ToggleChangeEventDetail } from "./components/toggle/toggle-interface";
export { AccordionGroupChangeEventDetail } from "./components/accordion-group/accordion-group-interface";
export { AnimationBuilder, AutocompleteTypes, Color, ComponentProps, ComponentRef, FrameworkDelegate, StyleEventDetail, TextFieldTypes } from "./interface";
@@ -51,7 +51,7 @@ export { RouteID, RouterDirection, RouterEventDetail, RouteWrite } from "./compo
export { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/breadcrumb-interface";
export { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
export { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
export { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
export { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimePresentation, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
export { SpinnerTypes } from "./components/spinner/spinner-configs";
export { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
export { CounterFormatter } from "./components/item/item-interface";
@@ -75,7 +75,7 @@ export { SelectChangeEventDetail, SelectCompareFn, SelectInterface } from "./com
export { SelectPopoverOption } from "./components/select-popover/select-popover-interface";
export { TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout } from "./components/tab-bar/tab-bar-interface";
export { TextareaChangeEventDetail, TextareaInputEventDetail } from "./components/textarea/textarea-interface";
export { ToastButton, ToastDismissOptions, ToastLayout, ToastPosition, ToastPresentOptions } from "./components/toast/toast-interface";
export { ToastButton, ToastLayout, ToastPosition } from "./components/toast/toast-interface";
export { ToggleChangeEventDetail } from "./components/toggle/toggle-interface";
export namespace Components {
interface IonAccordion {
@@ -865,7 +865,7 @@ export namespace Components {
/**
* The hour cycle of the `ion-datetime`. If no value is set, this is specified by the current locale.
*/
"hourCycle"?: DatetimeHourCycle;
"hourCycle"?: 'h23' | 'h12';
/**
* Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers.
*/
@@ -3157,13 +3157,9 @@ export namespace Components {
"onWillDismiss": <T = any>() => Promise<OverlayEventDetail<T>>;
"overlayIndex": number;
/**
* The starting position of the toast on the screen. Can be tweaked further using the `positionAnchor` property.
* The position of the toast on the screen.
*/
"position": ToastPosition;
/**
* The element to anchor the toast's position to. Can be set as a direct reference or the ID of the element. With `position="bottom"`, the toast will sit above the chosen element. With `position="top"`, the toast will sit below the chosen element. With `position="middle"`, the value of `positionAnchor` is ignored.
*/
"positionAnchor"?: HTMLElement | string;
/**
* Present the toast overlay after it has been created.
*/
@@ -4893,7 +4889,7 @@ declare namespace LocalJSX {
/**
* The hour cycle of the `ion-datetime`. If no value is set, this is specified by the current locale.
*/
"hourCycle"?: DatetimeHourCycle;
"hourCycle"?: 'h23' | 'h12';
/**
* Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers.
*/
@@ -6980,7 +6976,6 @@ declare namespace LocalJSX {
*/
"mode"?: "ios" | "md";
"onIonTabBarChanged"?: (event: IonTabBarCustomEvent<TabBarChangedEventDetail>) => void;
"onIonTabBarLoaded"?: (event: IonTabBarCustomEvent<void>) => void;
/**
* The selected tab component
*/
@@ -7312,13 +7307,9 @@ declare namespace LocalJSX {
"onWillPresent"?: (event: IonToastCustomEvent<void>) => void;
"overlayIndex": number;
/**
* The starting position of the toast on the screen. Can be tweaked further using the `positionAnchor` property.
* The position of the toast on the screen.
*/
"position"?: ToastPosition;
/**
* The element to anchor the toast's position to. Can be set as a direct reference or the ID of the element. With `position="bottom"`, the toast will sit above the chosen element. With `position="top"`, the toast will sit below the chosen element. With `position="middle"`, the value of `positionAnchor` is ignored.
*/
"positionAnchor"?: HTMLElement | string;
/**
* If `true`, the toast will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
*/

View File

@@ -228,15 +228,6 @@ export class Alert implements ComponentInterface, OverlayInterface {
onKeydown(ev: any) {
const inputTypes = new Set(this.processedInputs.map((i) => i.type));
/**
* Based on keyboard navigation requirements, the
* checkbox should not respond to the enter keydown event.
*/
if (inputTypes.has('checkbox') && ev.key === 'Enter') {
ev.preventDefault();
return;
}
// The only inputs we want to navigate between using arrow keys are the radios
// ignore the keydown event if it is not on a radio button
if (

View File

@@ -76,22 +76,5 @@ configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
await expect(alertButton).toHaveAttribute('aria-labelledby', 'close-label');
await expect(alertButton).toHaveAttribute('aria-label', 'close button');
});
test('should not toggle the checkbox when pressing the Enter key', async ({ page }) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
const button = page.locator('#checkbox');
await button.click();
await didPresent.next();
const alertCheckbox = page.locator('ion-alert .alert-checkbox');
const ariaChecked = await alertCheckbox.getAttribute('aria-checked');
await expect(alertCheckbox).toHaveAttribute('aria-checked', ariaChecked!);
await alertCheckbox.press('Enter');
await expect(alertCheckbox).toHaveAttribute('aria-checked', ariaChecked!);
});
});
});

View File

@@ -25,7 +25,6 @@
<ion-button id="noMessage" expand="block" onclick="presentNoMessage()">No Message</ion-button>
<ion-button id="customAria" expand="block" onclick="presentCustomAria()">Custom Aria</ion-button>
<ion-button id="ariaLabelButton" expand="block" onclick="presentAriaLabelButton()">Aria Label Button</ion-button>
<ion-button id="checkbox" expand="block" onclick="presentAlertCheckbox()">Checkbox</ion-button>
</main>
<script>
@@ -95,21 +94,6 @@
],
});
}
function presentAlertCheckbox() {
openAlert({
header: 'Checkbox',
inputs: [
{
type: 'checkbox',
label: 'Checkbox 1',
value: 'value1',
checked: true,
},
],
buttons: ['OK'],
});
}
</script>
</body>
</html>

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -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, hasLazyBuild } from '@utils/helpers';
import { componentOnReady } from '@utils/helpers';
import { isPlatform } from '@utils/platform';
import { isRTL } from '@utils/rtl';
import { createColorClasses, hostContext } from '@utils/theme';
@@ -34,9 +34,6 @@ 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
@@ -118,61 +115,15 @@ 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();
}
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;
}
@Listen('appload', { target: 'window' })
onAppLoad() {
this.resize();
}
/**

View File

@@ -9,7 +9,7 @@ import type { Color } from '../../interface';
import type { DatetimePresentation } from '../datetime/datetime-interface';
import { getToday } from '../datetime/utils/data';
import { getMonthAndYear, getMonthDayAndYear, getLocalizedDateTime, getLocalizedTime } from '../datetime/utils/format';
import { getHourCycle } from '../datetime/utils/helpers';
import { is24Hour } from '../datetime/utils/helpers';
import { parseDate } from '../datetime/utils/parse';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
@@ -218,7 +218,7 @@ export class DatetimeButton implements ComponentInterface {
* warning in the console.
*/
const firstParsedDatetime = parsedDatetimes[0];
const computedHourCycle = getHourCycle(locale, hourCycle);
const use24Hour = is24Hour(locale, hourCycle);
this.dateText = this.timeText = undefined;
@@ -226,7 +226,7 @@ export class DatetimeButton implements ComponentInterface {
case 'date-time':
case 'time-date':
const dateText = getMonthDayAndYear(locale, firstParsedDatetime);
const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
const timeText = getLocalizedTime(locale, firstParsedDatetime, use24Hour);
if (preferWheel) {
this.dateText = `${dateText} ${timeText}`;
} else {
@@ -250,7 +250,7 @@ export class DatetimeButton implements ComponentInterface {
}
break;
case 'time':
this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle);
this.timeText = getLocalizedTime(locale, firstParsedDatetime, use24Hour);
break;
case 'month-year':
this.dateText = getMonthAndYear(locale, firstParsedDatetime);

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -34,5 +34,3 @@ export type DatetimeHighlightStyle =
export type DatetimeHighlight = { date: string } & DatetimeHighlightStyle;
export type DatetimeHighlightCallback = (dateIsoString: string) => DatetimeHighlightStyle | undefined;
export type DatetimeHourCycle = 'h11' | 'h12' | 'h23' | 'h24';

View File

@@ -19,7 +19,6 @@ import type {
DatetimeHighlight,
DatetimeHighlightStyle,
DatetimeHighlightCallback,
DatetimeHourCycle,
} from './datetime-interface';
import { isSameDay, warnIfValueOutOfBounds, isBefore, isAfter } from './utils/comparison';
import {
@@ -34,7 +33,7 @@ import {
getCombinedDateColumnData,
} from './utils/data';
import { formatValue, getLocalizedTime, getMonthAndDay, getMonthAndYear } from './utils/format';
import { isLocaleDayPeriodRTL, isMonthFirstLocale, getNumDaysInMonth, getHourCycle } from './utils/helpers';
import { is24Hour, isLocaleDayPeriodRTL, isMonthFirstLocale, getNumDaysInMonth } from './utils/helpers';
import {
calculateHourFromAMPM,
convertDataToISO,
@@ -423,7 +422,7 @@ export class Datetime implements ComponentInterface {
* The hour cycle of the `ion-datetime`. If no value is set, this is
* specified by the current locale.
*/
@Prop() hourCycle?: DatetimeHourCycle;
@Prop() hourCycle?: 'h23' | 'h12';
/**
* If `cover`, the `ion-datetime` will expand to cover the full width of its container.
@@ -2238,7 +2237,7 @@ export class Datetime implements ComponentInterface {
private renderTimeOverlay() {
const { hourCycle, isTimePopoverOpen, locale } = this;
const computedHourCycle = getHourCycle(locale, hourCycle);
const use24Hour = is24Hour(locale, hourCycle);
const activePart = this.getActivePartsWithFallback();
return [
@@ -2271,7 +2270,7 @@ export class Datetime implements ComponentInterface {
}
}}
>
{getLocalizedTime(locale, activePart, computedHourCycle)}
{getLocalizedTime(locale, activePart, use24Hour)}
</button>,
<ion-popover
alignment="center"

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,125 +1,4 @@
import {
generateMonths,
getDaysOfWeek,
generateTime,
getToday,
getCombinedDateColumnData,
getTimeColumnsData,
} from '../utils/data';
// The minutes are the same across all hour cycles, so we don't check those
describe('getTimeColumnsData()', () => {
it('should generate formatted h12 hours and AM/PM data data', () => {
const refParts = { month: 5, year: 2021, day: 1, hour: 4, minute: 30 };
const results = getTimeColumnsData('en-US', refParts, 'h12');
expect(results.hoursData).toEqual([
{ text: '12', value: 0 },
{ text: '1', value: 1 },
{ text: '2', value: 2 },
{ text: '3', value: 3 },
{ text: '4', value: 4 },
{ text: '5', value: 5 },
{ text: '6', value: 6 },
{ text: '7', value: 7 },
{ text: '8', value: 8 },
{ text: '9', value: 9 },
{ text: '10', value: 10 },
{ text: '11', value: 11 },
]);
expect(results.dayPeriodData).toEqual([
{ text: 'AM', value: 'am' },
{ text: 'PM', value: 'pm' },
]);
});
it('should generate formatted h23 hours and AM/PM data data', () => {
const refParts = { month: 5, year: 2021, day: 1, hour: 4, minute: 30 };
const results = getTimeColumnsData('en-US', refParts, 'h23');
expect(results.hoursData).toEqual([
{ text: '00', value: 0 },
{ text: '01', value: 1 },
{ text: '02', value: 2 },
{ text: '03', value: 3 },
{ text: '04', value: 4 },
{ text: '05', value: 5 },
{ text: '06', value: 6 },
{ text: '07', value: 7 },
{ text: '08', value: 8 },
{ text: '09', value: 9 },
{ text: '10', value: 10 },
{ text: '11', value: 11 },
{ text: '12', value: 12 },
{ text: '13', value: 13 },
{ text: '14', value: 14 },
{ text: '15', value: 15 },
{ text: '16', value: 16 },
{ text: '17', value: 17 },
{ text: '18', value: 18 },
{ text: '19', value: 19 },
{ text: '20', value: 20 },
{ text: '21', value: 21 },
{ text: '22', value: 22 },
{ text: '23', value: 23 },
]);
expect(results.dayPeriodData).toEqual([]);
});
it('should generate formatted h11 hours and AM/PM data data', () => {
const refParts = { month: 5, year: 2021, day: 1, hour: 4, minute: 30 };
const results = getTimeColumnsData('en-US', refParts, 'h11');
expect(results.hoursData).toEqual([
{ text: '0', value: 0 },
{ text: '1', value: 1 },
{ text: '2', value: 2 },
{ text: '3', value: 3 },
{ text: '4', value: 4 },
{ text: '5', value: 5 },
{ text: '6', value: 6 },
{ text: '7', value: 7 },
{ text: '8', value: 8 },
{ text: '9', value: 9 },
{ text: '10', value: 10 },
{ text: '11', value: 11 },
]);
expect(results.dayPeriodData).toEqual([
{ text: 'AM', value: 'am' },
{ text: 'PM', value: 'pm' },
]);
});
it('should generate formatted h24 hours and AM/PM data data', () => {
const refParts = { month: 5, year: 2021, day: 1, hour: 4, minute: 30 };
const results = getTimeColumnsData('en-US', refParts, 'h24');
expect(results.hoursData).toEqual([
{ text: '01', value: 1 },
{ text: '02', value: 2 },
{ text: '03', value: 3 },
{ text: '04', value: 4 },
{ text: '05', value: 5 },
{ text: '06', value: 6 },
{ text: '07', value: 7 },
{ text: '08', value: 8 },
{ text: '09', value: 9 },
{ text: '10', value: 10 },
{ text: '11', value: 11 },
{ text: '12', value: 12 },
{ text: '13', value: 13 },
{ text: '14', value: 14 },
{ text: '15', value: 15 },
{ text: '16', value: 16 },
{ text: '17', value: 17 },
{ text: '18', value: 18 },
{ text: '19', value: 19 },
{ text: '20', value: 20 },
{ text: '21', value: 21 },
{ text: '22', value: 22 },
{ text: '23', value: 23 },
{ text: '24', value: 0 },
]);
expect(results.dayPeriodData).toEqual([]);
});
});
import { generateMonths, getDaysOfWeek, generateTime, getToday, getCombinedDateColumnData } from '../utils/data';
describe('generateMonths()', () => {
it('should generate correct month data', () => {
@@ -162,7 +41,7 @@ describe('generateTime()', () => {
hour: 5,
minute: 43,
};
const { hours, minutes } = generateTime('en-US', today);
const { hours, minutes } = generateTime(today);
expect(hours.length).toEqual(12);
expect(minutes.length).toEqual(60);
@@ -182,7 +61,7 @@ describe('generateTime()', () => {
hour: 2,
minute: 40,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', min);
const { hours, minutes } = generateTime(today, 'h12', min);
expect(hours.length).toEqual(10);
expect(minutes.length).toEqual(60);
@@ -202,7 +81,7 @@ describe('generateTime()', () => {
hour: 2,
minute: 40,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', min);
const { hours, minutes } = generateTime(today, 'h12', min);
expect(hours.length).toEqual(12);
expect(minutes.length).toEqual(60);
@@ -222,7 +101,7 @@ describe('generateTime()', () => {
hour: 7,
minute: 44,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', undefined, max);
const { hours, minutes } = generateTime(today, 'h12', undefined, max);
expect(hours.length).toEqual(8);
expect(minutes.length).toEqual(45);
@@ -242,7 +121,7 @@ describe('generateTime()', () => {
hour: 2,
minute: 40,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', undefined, max);
const { hours, minutes } = generateTime(today, 'h12', undefined, max);
expect(hours.length).toEqual(12);
expect(minutes.length).toEqual(60);
@@ -262,7 +141,7 @@ describe('generateTime()', () => {
hour: 2,
minute: 40,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', min);
const { hours, minutes } = generateTime(today, 'h12', min);
expect(hours.length).toEqual(0);
expect(minutes.length).toEqual(0);
@@ -282,7 +161,7 @@ describe('generateTime()', () => {
hour: 2,
minute: 40,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', undefined, max);
const { hours, minutes } = generateTime(today, 'h12', undefined, max);
expect(hours.length).toEqual(0);
expect(minutes.length).toEqual(0);
@@ -306,7 +185,7 @@ describe('generateTime()', () => {
year: 2021,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', min, max);
const { hours, minutes } = generateTime(today, 'h12', min, max);
expect(hours.length).toEqual(12);
expect(minutes.length).toEqual(60);
@@ -320,7 +199,7 @@ describe('generateTime()', () => {
minute: 43,
};
const { hours, minutes } = generateTime('en-US', today, 'h12', undefined, undefined, [1, 2, 3], [10, 15, 20]);
const { hours, minutes } = generateTime(today, 'h12', undefined, undefined, [1, 2, 3], [10, 15, 20]);
expect(hours).toStrictEqual([1, 2, 3]);
expect(minutes).toStrictEqual([10, 15, 20]);
@@ -350,7 +229,7 @@ describe('generateTime()', () => {
minute: 14,
};
const { am, pm } = generateTime('en-US', today, 'h12', min, max);
const { am, pm } = generateTime(today, 'h12', min, max);
expect(am).toBe(true);
expect(pm).toBe(true);
@@ -374,7 +253,7 @@ describe('generateTime()', () => {
minute: 50,
};
const { hours } = generateTime('en-US', refValue, 'h23', minParts);
const { hours } = generateTime(refValue, 'h23', minParts);
expect(hours).toStrictEqual([19, 20, 21, 22, 23]);
});
@@ -397,7 +276,7 @@ describe('generateTime()', () => {
minute: 30,
};
const { hours, minutes } = generateTime('en-US', refValue, 'h23', minParts);
const { hours, minutes } = generateTime(refValue, 'h23', minParts);
expect(hours).toStrictEqual([19, 20, 21, 22, 23]);
expect(minutes.length).toEqual(60);
@@ -429,7 +308,7 @@ describe('generateTime()', () => {
minute: 40,
};
const { hours } = generateTime('en-US', refValue, 'h23', minParts, maxParts);
const { hours } = generateTime(refValue, 'h23', minParts, maxParts);
expect(hours).toStrictEqual([19, 20]);
});
@@ -451,7 +330,7 @@ describe('generateTime()', () => {
minute: 2,
};
const { minutes } = generateTime('en-US', refValue, 'h23', undefined, maxParts);
const { minutes } = generateTime(refValue, 'h23', undefined, maxParts);
expect(minutes).toStrictEqual([0, 1, 2]);
});
@@ -473,7 +352,7 @@ describe('generateTime()', () => {
minute: 2,
};
const { minutes } = generateTime('en-US', refValue, 'h23', undefined, maxParts);
const { minutes } = generateTime(refValue, 'h23', undefined, maxParts);
expect(minutes.length).toEqual(60);
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -56,17 +56,11 @@ describe('getMonthAndDay()', () => {
describe('getFormattedHour()', () => {
it('should only add padding if using 24 hour time', () => {
expect(getFormattedHour(1, 'h11')).toEqual('1');
expect(getFormattedHour(1, 'h12')).toEqual('1');
expect(getFormattedHour(1, 'h23')).toEqual('01');
expect(getFormattedHour(1, 'h24')).toEqual('01');
});
expect(getFormattedHour(0, true)).toEqual('00');
expect(getFormattedHour(0, false)).toEqual('12');
it('should return correct hour value for hour cycle', () => {
expect(getFormattedHour(0, 'h11')).toEqual('0');
expect(getFormattedHour(0, 'h12')).toEqual('12');
expect(getFormattedHour(0, 'h23')).toEqual('00');
expect(getFormattedHour(0, 'h24')).toEqual('24');
expect(getFormattedHour(10, true)).toEqual('10');
expect(getFormattedHour(10, false)).toEqual('10');
});
});
@@ -117,7 +111,7 @@ describe('getLocalizedTime', () => {
minute: 40,
};
expect(getLocalizedTime('en-US', datetimeParts, 'h12')).toEqual('1:40 PM');
expect(getLocalizedTime('en-US', datetimeParts, false)).toEqual('1:40 PM');
});
it('should localize the time to AM', () => {
@@ -129,7 +123,7 @@ describe('getLocalizedTime', () => {
minute: 40,
};
expect(getLocalizedTime('en-US', datetimeParts, 'h12')).toEqual('9:40 AM');
expect(getLocalizedTime('en-US', datetimeParts, false)).toEqual('9:40 AM');
});
it('should avoid Chromium bug when using 12 hour time in a 24 hour locale', () => {
@@ -141,7 +135,7 @@ describe('getLocalizedTime', () => {
minute: 0,
};
expect(getLocalizedTime('en-GB', datetimeParts, 'h12')).toEqual('12:00 am');
expect(getLocalizedTime('en-GB', datetimeParts, false)).toEqual('12:00 am');
});
it('should parse time-only values correctly', () => {
const datetimeParts = {
@@ -149,7 +143,7 @@ describe('getLocalizedTime', () => {
minute: 40,
};
expect(getLocalizedTime('en-US', datetimeParts, 'h12')).toEqual('10:40 PM');
expect(getLocalizedTime('en-US', datetimeParts, 'h23')).toEqual('22:40');
expect(getLocalizedTime('en-US', datetimeParts, false)).toEqual('10:40 PM');
expect(getLocalizedTime('en-US', datetimeParts, true)).toEqual('22:40');
});
});

View File

@@ -1,4 +1,4 @@
import { isLeapYear, getNumDaysInMonth, is24Hour, isMonthFirstLocale, getHourCycle } from '../utils/helpers';
import { isLeapYear, getNumDaysInMonth, is24Hour, isMonthFirstLocale } from '../utils/helpers';
describe('daysInMonth()', () => {
it('should return correct days in month for month and year', () => {
@@ -37,29 +37,14 @@ describe('isLeapYear()', () => {
describe('is24Hour()', () => {
it('should return true if the locale uses 24 hour time', () => {
expect(is24Hour('h11')).toBe(false);
expect(is24Hour('h12')).toBe(false);
expect(is24Hour('h23')).toBe(true);
expect(is24Hour('h24')).toBe(true);
});
});
describe('getHourCycle()', () => {
it('should return the correct hour cycle', () => {
expect(getHourCycle('en-US')).toBe('h12');
expect(getHourCycle('en-US', 'h23')).toBe('h23');
expect(getHourCycle('en-US', 'h12')).toBe('h12');
expect(getHourCycle('en-US-u-hc-h23')).toBe('h23');
expect(getHourCycle('en-GB')).toBe('h23');
expect(getHourCycle('en-GB', 'h23')).toBe('h23');
expect(getHourCycle('en-GB', 'h12')).toBe('h12');
expect(getHourCycle('en-GB-u-hc-h12')).toBe('h12');
expect(getHourCycle('en-GB', 'h11')).toBe('h11');
expect(getHourCycle('en-GB-u-hc-h11')).toBe('h11');
expect(getHourCycle('en-GB', 'h24')).toBe('h24');
expect(getHourCycle('en-GB-u-hc-h24')).toBe('h24');
expect(is24Hour('en-US')).toBe(false);
expect(is24Hour('en-US', 'h23')).toBe(true);
expect(is24Hour('en-US', 'h12')).toBe(false);
expect(is24Hour('en-US-u-hc-h23')).toBe(true);
expect(is24Hour('en-GB')).toBe(true);
expect(is24Hour('en-GB', 'h23')).toBe(true);
expect(is24Hour('en-GB', 'h12')).toBe(false);
expect(is24Hour('en-GB-u-hc-h12')).toBe(false);
});
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -25,27 +25,5 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
const timeButton = page.locator('ion-datetime .time-body');
await expect(timeButton).toHaveText('4:30 PM');
});
test('should set the h11 hour cycle correctly', async ({ page }) => {
await page.setContent(
`
<ion-datetime hour-cycle="h11" value="2022-01-01T00:30:00"></ion-datetime>
`,
config
);
const timeButton = page.locator('ion-datetime .time-body');
await expect(timeButton).toHaveText('0:30 AM');
});
test('should set the h24 hour cycle correctly', async ({ page }) => {
await page.setContent(
`
<ion-datetime hour-cycle="h24" value="2022-01-01T00:30:00"></ion-datetime>
`,
config
);
const timeButton = page.locator('ion-datetime .time-body');
await expect(timeButton).toHaveText('24:30');
});
});
});

View File

@@ -51,14 +51,6 @@
<h2>h12 Hour cycle</h2>
<ion-datetime hour-cycle="h12"></ion-datetime>
</div>
<div class="grid-item">
<h2>h11 Hour cycle</h2>
<ion-datetime hour-cycle="h11"></ion-datetime>
</div>
<div class="grid-item">
<h2>h24 Hour cycle</h2>
<ion-datetime hour-cycle="h24"></ion-datetime>
</div>
<div class="grid-item">
<h2>h23 Hour cycle (Extension Tag)</h2>
<ion-datetime locale="en-US-u-hc-h23"></ion-datetime>

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,6 +1,6 @@
import type { Mode } from '../../../interface';
import type { PickerColumnItem } from '../../picker-column-internal/picker-column-internal-interfaces';
import type { DatetimeParts, DatetimeHourCycle } from '../datetime-interface';
import type { DatetimeParts } from '../datetime-interface';
import { isAfter, isBefore, isSameDay } from './comparison';
import {
@@ -11,7 +11,7 @@ import {
getTodayLabel,
getYear,
} from './format';
import { getNumDaysInMonth, is24Hour, getHourCycle } from './helpers';
import { getNumDaysInMonth, is24Hour } from './helpers';
import { getNextMonth, getPreviousMonth, getInternalHourValue } from './manipulation';
/**
@@ -44,19 +44,9 @@ const minutes = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
];
// h11 hour system uses 0-11. Midnight starts at 0:00am.
const hour11 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
// h12 hour system uses 0-12. Midnight starts at 12:00am.
const hour12 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
// h23 hour system uses 0-23. Midnight starts at 0:00.
const hour23 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
// h24 hour system uses 1-24. Midnight starts at 24:00.
const hour24 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0];
/**
* Given a locale and a mode,
* return an array with formatted days
@@ -135,42 +125,21 @@ export const getDaysOfMonth = (month: number, year: number, firstDayOfWeek: numb
return days;
};
/**
* Returns an array of pre-defined hour
* values based on the provided hourCycle.
*/
const getHourData = (hourCycle: DatetimeHourCycle) => {
switch (hourCycle) {
case 'h11':
return hour11;
case 'h12':
return hour12;
case 'h23':
return hour23;
case 'h24':
return hour24;
default:
throw new Error(`Invalid hour cycle "${hourCycle}"`);
}
};
/**
* Given a local, reference datetime parts and option
* max/min bound datetime parts, calculate the acceptable
* hour and minute values according to the bounds and locale.
*/
export const generateTime = (
locale: string,
refParts: DatetimeParts,
hourCycle: DatetimeHourCycle = 'h12',
hourCycle: 'h12' | 'h23' = 'h12',
minParts?: DatetimeParts,
maxParts?: DatetimeParts,
hourValues?: number[],
minuteValues?: number[]
) => {
const computedHourCycle = getHourCycle(locale, hourCycle);
const use24Hour = is24Hour(computedHourCycle);
let processedHours = getHourData(computedHourCycle);
const use24Hour = hourCycle === 'h23';
let processedHours = use24Hour ? hour23 : hour12;
let processedMinutes = minutes;
let isAMAllowed = true;
let isPMAllowed = true;
@@ -571,18 +540,16 @@ export const getCombinedDateColumnData = (
export const getTimeColumnsData = (
locale: string,
refParts: DatetimeParts,
hourCycle?: DatetimeHourCycle,
hourCycle?: 'h23' | 'h12',
minParts?: DatetimeParts,
maxParts?: DatetimeParts,
allowedHourValues?: number[],
allowedMinuteValues?: number[]
): { [key: string]: PickerColumnItem[] } => {
const computedHourCycle = getHourCycle(locale, hourCycle);
const use24Hour = is24Hour(computedHourCycle);
const use24Hour = is24Hour(locale, hourCycle);
const { hours, minutes, am, pm } = generateTime(
locale,
refParts,
computedHourCycle,
use24Hour ? 'h23' : 'h12',
minParts,
maxParts,
allowedHourValues,
@@ -591,7 +558,7 @@ export const getTimeColumnsData = (
const hoursItems = hours.map((hour) => {
return {
text: getFormattedHour(hour, computedHourCycle),
text: getFormattedHour(hour, use24Hour),
value: getInternalHourValue(hour, use24Hour, refParts.ampm),
};
});

View File

@@ -1,6 +1,5 @@
import type { DatetimeParts, DatetimeHourCycle } from '../datetime-interface';
import type { DatetimeParts } from '../datetime-interface';
import { is24Hour } from './helpers';
import { convertDataToISO } from './manipulation';
const getFormattedDayPeriod = (dayPeriod?: string) => {
@@ -11,7 +10,7 @@ const getFormattedDayPeriod = (dayPeriod?: string) => {
return dayPeriod.toUpperCase();
};
export const getLocalizedTime = (locale: string, refParts: DatetimeParts, hourCycle: DatetimeHourCycle): string => {
export const getLocalizedTime = (locale: string, refParts: DatetimeParts, use24Hour: boolean): string => {
const timeParts: Pick<DatetimeParts, 'hour' | 'minute'> = {
hour: refParts.hour,
minute: refParts.minute,
@@ -35,7 +34,7 @@ export const getLocalizedTime = (locale: string, refParts: DatetimeParts, hourCy
* We use hourCycle here instead of hour12 due to:
* https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
*/
hourCycle,
hourCycle: use24Hour ? 'h23' : 'h12',
/**
* Setting Z at the end indicates that this
* date string is in the UTC time zone. This
@@ -84,36 +83,20 @@ export const addTimePadding = (value: number): string => {
* 12 hour times it ensures that
* hour 0 is formatted as '12'.
*/
export const getFormattedHour = (hour: number, hourCycle: DatetimeHourCycle): string => {
/**
* Midnight for h11 starts at 0:00am
* Midnight for h12 starts at 12:00am
* Midnight for h23 starts at 00:00
* Midnight for h24 starts at 24:00
*/
if (hour === 0) {
switch (hourCycle) {
case 'h11':
return '0';
case 'h12':
return '12';
case 'h23':
return '00';
case 'h24':
return '24';
default:
throw new Error(`Invalid hour cycle "${hourCycle}"`);
}
}
const use24Hour = is24Hour(hourCycle);
/**
* h23 and h24 use 24 hour times.
*/
export const getFormattedHour = (hour: number, use24Hour: boolean): string => {
if (use24Hour) {
return addTimePadding(hour);
}
/**
* If using 12 hour
* format, make sure hour
* 0 is formatted as '12'.
*/
if (hour === 0) {
return '12';
}
return hour.toString();
};

View File

@@ -1,4 +1,10 @@
import type { DatetimeHourCycle } from '../datetime-interface';
/**
* Typescript 4.x does not recognize hourCycle as a valid option.
* See https://github.com/microsoft/TypeScript/issues/34399.
*/
interface DatetimeFormatOptions extends Intl.ResolvedDateTimeFormatOptions {
hourCycle?: 'h11' | 'h12' | 'h23' | 'h24';
}
/**
* Determines if given year is a
@@ -10,19 +16,13 @@ export const isLeapYear = (year: number) => {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};
/**
* Determines the hour cycle for a user.
* If the hour cycle is explicitly defined, just use that.
* Otherwise, we try to derive it from either the specified
* locale extension tags or from Intl.DateTimeFormat directly.
*/
export const getHourCycle = (locale: string, hourCycle?: DatetimeHourCycle) => {
export const is24Hour = (locale: string, hourCycle?: 'h23' | 'h12') => {
/**
* If developer has explicitly enabled 24-hour time
* If developer has explicitly enabled h23 time
* then return early and do not look at the system default.
*/
if (hourCycle !== undefined) {
return hourCycle;
return hourCycle === 'h23';
}
/**
@@ -32,9 +32,9 @@ export const getHourCycle = (locale: string, hourCycle?: DatetimeHourCycle) => {
* option into the locale string. Example: `en-US-u-hc-h23`
*/
const formatted = new Intl.DateTimeFormat(locale, { hour: 'numeric' });
const options = formatted.resolvedOptions();
const options = formatted.resolvedOptions() as DatetimeFormatOptions;
if (options.hourCycle !== undefined) {
return options.hourCycle;
return options.hourCycle === 'h23';
}
/**
@@ -50,34 +50,7 @@ export const getHourCycle = (locale: string, hourCycle?: DatetimeHourCycle) => {
throw new Error('Hour value not found from DateTimeFormat');
}
/**
* Midnight for h11 starts at 0:00am
* Midnight for h12 starts at 12:00am
* Midnight for h23 starts at 00:00
* Midnight for h24 starts at 24:00
*/
switch (hour.value) {
case '0':
return 'h11';
case '12':
return 'h12';
case '00':
return 'h23';
case '24':
return 'h24';
default:
throw new Error(`Invalid hour cycle "${hourCycle}"`);
}
};
/**
* Determine if the hour cycle uses a 24-hour format.
* Returns true for h23 and h24. Returns false otherwise.
* If you don't know the hourCycle, use getHourCycle above
* and pass the result into this function.
*/
export const is24Hour = (hourCycle: DatetimeHourCycle) => {
return hourCycle === 'h23' || hourCycle === 'h24';
return hour.value === '00';
};
/**

View File

@@ -199,7 +199,7 @@
// --------------------------------------------------
:host(.fab-button-small) {
@include margin($fab-button-small-margin);
@include margin(($fab-size - $fab-small-size) * 0.5);
width: #{$fab-small-size};
height: #{$fab-small-size};

View File

@@ -11,6 +11,3 @@ $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;

View File

@@ -4,7 +4,7 @@
// --------------------------------------------------
:host {
@include margin(calc(100% + #{$fab-list-margin}), 0);
@include margin($fab-size + $fab-list-margin, 0);
display: none;
position: absolute;
@@ -13,15 +13,8 @@
flex-direction: column;
align-items: center;
/**
* 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);
min-width: $fab-size;
min-height: $fab-size;
}
:host(.fab-list-active) {
@@ -66,14 +59,14 @@
}
:host(.fab-list-side-start) {
@include margin(0, calc(100% + #{$fab-list-margin}));
@include margin(0, $fab-size + $fab-list-margin);
@include position-horizontal(null, 0);
flex-direction: row-reverse;
}
:host(.fab-list-side-end) {
@include margin(0, calc(100% + #{$fab-list-margin}));
@include margin(0, $fab-size + $fab-list-margin);
@include position(null, null, null, 0);
flex-direction: row;

View File

@@ -1,5 +1,4 @@
@import "./fab.vars";
@import "../fab-list/fab-list.vars";
// Floating Action Button Container
// --------------------------------------------------
@@ -7,9 +6,6 @@
:host {
position: absolute;
width: fit-content;
height: fit-content;
z-index: $z-index-fixed-content;
}
@@ -18,8 +14,8 @@
// --------------------------------------------------
:host(.fab-horizontal-center) {
@include position(null, 0px, null, 0px);
@include margin(null, auto);
@include position(null, null, null, 50%);
@include margin-horizontal(-$fab-size * 0.5, null);
}
:host(.fab-horizontal-start) {
@@ -42,93 +38,22 @@
top: $fab-content-margin;
}
/**
* Reset the top value since edge
* styles use margin-top.
*/
:host(.fab-vertical-top.fab-edge) {
top: 0;
top: -$fab-size * 0.5;
}
/**
* 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: 0;
bottom: -$fab-size * 0.5;
}
/**
* 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 position(0px, null, 0px, null);
@include margin(auto, null);
@include margin(-$fab-size * 0.5, null, null, null);
top: 50%;
}

View File

@@ -1,17 +0,0 @@
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`));
});
});
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -1,241 +0,0 @@
<!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>

View File

@@ -107,28 +107,3 @@
.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;
}

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -30,6 +30,7 @@ export interface MenuControllerI {
_setOpen(menu: MenuI, shouldOpen: boolean, animated: boolean): Promise<boolean>;
_register(menu: MenuI): void;
_unregister(menu: MenuI): void;
_setActiveMenu(menu: MenuI): void;
getMenus(): Promise<HTMLIonMenuElement[]>;
getOpenSync(): HTMLIonMenuElement | undefined;

View File

@@ -1,6 +1,7 @@
import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Build, Component, Element, Event, Host, Listen, Method, Prop, State, Watch, h } from '@stencil/core';
import { getTimeGivenProgression } from '@utils/animation/cubic-bezier';
import { doc } from '@utils/browser';
import { GESTURE_CONTROLLER } from '@utils/gesture';
import type { Attributes } from '@utils/helpers';
import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from '@utils/helpers';
@@ -39,15 +40,6 @@ 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;
@@ -440,17 +432,6 @@ 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;
@@ -491,24 +472,18 @@ 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);
.easing(isReversed ? easingReverse : easing)
.onFinish(() => {
if (ani.getDirection() === 'reverse') {
ani.direction('normal');
}
});
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() {
@@ -668,6 +643,8 @@ 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
@@ -736,31 +713,36 @@ export class Menu implements ComponentInterface, MenuI {
this.gesture.enable(isActive && this.swipeGesture);
}
/**
* 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);
// Close menu immediately
if (!isActive && this._isOpen) {
// close if this menu is open, and should not be enabled
this.forceClosing();
}
if (doc?.contains(this.el)) {
/**
* Only set the active menu if the menu element is
* present in the DOM. Otherwise if it was destructively
* re-hydrated (through Angular Universal), then ignore
* setting the removed node as the active menu.
*/
if (!this.disabled) {
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() {

View File

@@ -1,41 +0,0 @@
<!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>

View File

@@ -1,66 +0,0 @@
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);
});
});
});

View File

@@ -1,74 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Menu - Multiple</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>
<script type="module">
import { menuController } from '../../../../dist/ionic/index.esm.js';
window.menuController = menuController;
</script>
</head>
<body>
<ion-app>
<ion-menu side="start" menu-id="primary-menu" id="primary-menu" content-id="main">
<ion-header>
<ion-toolbar color="primary">
<ion-title>Primary</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding"> Menu Content </ion-content>
</ion-menu>
<ion-menu side="start" menu-id="secondary-menu" id="secondary-menu" content-id="main">
<ion-header>
<ion-toolbar color="secondary">
<ion-title>Secondary</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding"> Menu Content </ion-content>
</ion-menu>
<ion-menu disabled="true" side="end" menu-id="success-menu" id="success-menu" content-id="main">
<ion-header>
<ion-toolbar color="success">
<ion-title>Success</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding"> Menu Content </ion-content>
</ion-menu>
<ion-menu disabled="true" side="end" menu-id="danger-menu" id="danger-menu" content-id="main">
<ion-header>
<ion-toolbar color="danger">
<ion-title>Danger</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 menu="primary-menu" color="primary"></ion-menu-button>
<ion-menu-button menu="secondary-menu" color="secondary"></ion-menu-button>
</ion-buttons>
<ion-title>Menu - Multiple</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">Content</ion-content>
</div>
</ion-app>
</body>
<scrip
</html>

View File

@@ -1,79 +0,0 @@
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: multiple'), () => {
test.beforeEach(async ({ page }, testInfo) => {
testInfo.annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/18974',
});
await page.goto(`/src/components/menu/test/multiple`, config);
});
test('should present each menu on the same side individually', async ({ page }) => {
const primaryMenu = page.locator('ion-menu#primary-menu');
const secondaryMenu = page.locator('ion-menu#secondary-menu');
await primaryMenu.evaluate((el: HTMLIonMenuElement) => el.open());
await expect(primaryMenu).toBeVisible();
await primaryMenu.evaluate((el: HTMLIonMenuElement) => el.close());
await expect(primaryMenu).toBeHidden();
await secondaryMenu.evaluate((el: HTMLIonMenuElement) => el.open());
await expect(secondaryMenu).toBeVisible();
await secondaryMenu.evaluate((el: HTMLIonMenuElement) => el.close());
await expect(secondaryMenu).toBeHidden();
});
test('should close first menu when showing another menu on same side', async ({ page }) => {
const primaryMenu = page.locator('ion-menu#primary-menu');
const secondaryMenu = page.locator('ion-menu#secondary-menu');
await primaryMenu.evaluate((el: HTMLIonMenuElement) => el.open());
await expect(primaryMenu).toBeVisible();
await secondaryMenu.evaluate((el: HTMLIonMenuElement) => el.open());
await expect(primaryMenu).toBeHidden();
await expect(secondaryMenu).toBeVisible();
});
test('passing side to the menuController when multiple menus have that side should result in a warning', async ({
page,
}) => {
const logs: string[] = [];
page.on('console', (msg) => {
if (msg.type() === 'warning') {
logs.push(msg.text());
}
});
await page.evaluate(() => (window as any).menuController.open('start'));
expect(logs.length).toBe(1);
});
test('passing side to the menuController when multiple disabled menus have that side should result in a warning', async ({
page,
}) => {
const logs: string[] = [];
page.on('console', (msg) => {
if (msg.type() === 'warning') {
logs.push(msg.text());
}
});
await page.evaluate(() => (window as any).menuController.open('end'));
expect(logs.length).toBe(1);
});
});
});

View File

@@ -6,5 +6,6 @@
position: absolute;
contain: layout size style;
overflow: hidden;
z-index: $z-index-page-container;
}

View File

@@ -901,7 +901,6 @@ export class Nav implements NavOutlet {
: undefined;
const mode = getIonMode(this);
const enteringEl = enteringView.element!;
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
const leavingEl = leavingView && leavingView.element!;
const animationOpts: TransitionOptions = {
mode,

View File

@@ -39,7 +39,7 @@ export async function testPickerColumn(
await page.waitForChanges();
screenshots.push({
name: screenshot(`picker-${description}-column-diff-${i}`),
name: `picker-${description}-column-diff-${i}-${page.getSnapshotSettings()}.png`,
screenshot: await page.screenshot(),
});
}

View File

@@ -319,7 +319,6 @@ export class Range implements ComponentInterface {
componentDidLoad() {
this.originalIonInput = this.ionInput;
this.setupGesture();
this.updateRatio();
this.didLoad = true;
}

View File

@@ -6,5 +6,6 @@
position: absolute;
contain: layout size style;
overflow: hidden;
z-index: $z-index-page-container;
}

Some files were not shown because too many files have changed in this diff Show More