mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
10 Commits
ionic-modu
...
sp/react-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e917e9fdf2 | ||
|
|
d12f35705f | ||
|
|
cb8e54e9ac | ||
|
|
8bc66d1db3 | ||
|
|
f4561d57c6 | ||
|
|
0a2a8b0f09 | ||
|
|
0ba5219c09 | ||
|
|
4ecd533aef | ||
|
|
b6d47ff035 | ||
|
|
35e2de2ce2 |
289
packages/react-router/package-lock.json
generated
289
packages/react-router/package-lock.json
generated
@@ -19,7 +19,7 @@
|
||||
"@types/node": "^14.0.14",
|
||||
"@types/react": "^17.0.79",
|
||||
"@types/react-dom": "^17.0.25",
|
||||
"@types/react-router": "^5.0.3",
|
||||
"@types/react-router": "^6.0.0",
|
||||
"@types/react-router-dom": "^5.1.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||
"@typescript-eslint/parser": "^5.48.2",
|
||||
@@ -27,8 +27,8 @@
|
||||
"prettier": "^2.8.3",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router": "^5.0.1",
|
||||
"react-router-dom": "^5.0.1",
|
||||
"react-router": "^6.0.0",
|
||||
"react-router-dom": "^6.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^4.2.0",
|
||||
"typescript": "^4.0.5"
|
||||
@@ -36,8 +36,8 @@
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.6",
|
||||
"react-dom": ">=16.8.6",
|
||||
"react-router": "^5.0.1",
|
||||
"react-router-dom": "^5.0.1"
|
||||
"react-router": "^6.0.0",
|
||||
"react-router-dom": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@@ -152,18 +152,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
|
||||
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.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",
|
||||
@@ -462,6 +450,15 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz",
|
||||
"integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-typescript": {
|
||||
"version": "11.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz",
|
||||
@@ -2337,29 +2334,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/history": {
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
||||
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"loose-envify": "^1.2.0",
|
||||
"resolve-pathname": "^3.0.0",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0",
|
||||
"value-equal": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
@@ -2664,12 +2638,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -2994,15 +2962,6 @@
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
||||
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isarray": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-type": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
@@ -3057,17 +3016,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
@@ -3122,56 +3070,38 @@
|
||||
"react": "17.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz",
|
||||
"integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==",
|
||||
"version": "6.25.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz",
|
||||
"integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.13",
|
||||
"history": "^4.9.0",
|
||||
"hoist-non-react-statics": "^3.1.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
"path-to-regexp": "^1.7.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-is": "^16.6.0",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0"
|
||||
"@remix-run/router": "1.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=15"
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz",
|
||||
"integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==",
|
||||
"version": "6.25.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz",
|
||||
"integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.13",
|
||||
"history": "^4.9.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-router": "5.3.4",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0"
|
||||
"@remix-run/router": "1.18.0",
|
||||
"react-router": "6.25.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=15"
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
||||
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/regexp.prototype.flags": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
|
||||
@@ -3236,12 +3166,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-pathname": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
||||
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
@@ -3636,18 +3560,6 @@
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tiny-invariant": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
|
||||
"integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@@ -3830,12 +3742,6 @@
|
||||
"integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/value-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
||||
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@@ -3990,15 +3896,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
|
||||
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
}
|
||||
},
|
||||
"@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
@@ -4198,6 +4095,12 @@
|
||||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@remix-run/router": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz",
|
||||
"integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==",
|
||||
"dev": true
|
||||
},
|
||||
"@rollup/plugin-typescript": {
|
||||
"version": "11.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz",
|
||||
@@ -5511,29 +5414,6 @@
|
||||
"function-bind": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"history": {
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
||||
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"loose-envify": "^1.2.0",
|
||||
"resolve-pathname": "^3.0.0",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0",
|
||||
"value-equal": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
@@ -5742,12 +5622,6 @@
|
||||
"call-bind": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -6006,15 +5880,6 @@
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
||||
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isarray": "0.0.1"
|
||||
}
|
||||
},
|
||||
"path-type": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
@@ -6045,17 +5910,6 @@
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
@@ -6087,50 +5941,25 @@
|
||||
"scheduler": "^0.20.2"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"react-router": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz",
|
||||
"integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==",
|
||||
"version": "6.25.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz",
|
||||
"integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.13",
|
||||
"history": "^4.9.0",
|
||||
"hoist-non-react-statics": "^3.1.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
"path-to-regexp": "^1.7.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-is": "^16.6.0",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0"
|
||||
"@remix-run/router": "1.18.0"
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz",
|
||||
"integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==",
|
||||
"version": "6.25.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz",
|
||||
"integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.13",
|
||||
"history": "^4.9.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-router": "5.3.4",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0"
|
||||
"@remix-run/router": "1.18.0",
|
||||
"react-router": "6.25.1"
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
||||
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
|
||||
"dev": true
|
||||
},
|
||||
"regexp.prototype.flags": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
|
||||
@@ -6171,12 +6000,6 @@
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve-pathname": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
||||
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==",
|
||||
"dev": true
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
@@ -6462,18 +6285,6 @@
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"tiny-invariant": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
|
||||
"integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==",
|
||||
"dev": true
|
||||
},
|
||||
"tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
|
||||
"dev": true
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@@ -6612,12 +6423,6 @@
|
||||
"integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==",
|
||||
"dev": true
|
||||
},
|
||||
"value-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
||||
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==",
|
||||
"dev": true
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.6",
|
||||
"react-dom": ">=16.8.6",
|
||||
"react-router": "^5.0.1",
|
||||
"react-router-dom": "^5.0.1"
|
||||
"react-router": "^6.0.0",
|
||||
"react-router-dom": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
@@ -52,7 +52,7 @@
|
||||
"@types/node": "^14.0.14",
|
||||
"@types/react": "^17.0.79",
|
||||
"@types/react-dom": "^17.0.25",
|
||||
"@types/react-router": "^5.0.3",
|
||||
"@types/react-router": "^6.0.0",
|
||||
"@types/react-router-dom": "^5.1.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||
"@typescript-eslint/parser": "^5.48.2",
|
||||
@@ -60,8 +60,8 @@
|
||||
"prettier": "^2.8.3",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router": "^5.0.1",
|
||||
"react-router-dom": "^5.0.1",
|
||||
"react-router": "^6.0.0",
|
||||
"react-router-dom": "^6.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^4.2.0",
|
||||
"typescript": "^4.0.5"
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Action as HistoryAction, History, Location as HistoryLocation } fr
|
||||
import { createHashHistory as createHistory } from 'history';
|
||||
import React from 'react';
|
||||
import type { BrowserRouterProps } from 'react-router-dom';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { HashRouter } from 'react-router-dom';
|
||||
|
||||
import { IonRouter } from './IonRouter';
|
||||
|
||||
@@ -45,9 +45,9 @@ export class IonReactHashRouter extends React.Component<IonReactHashRouterProps>
|
||||
render() {
|
||||
const { children, ...props } = this.props;
|
||||
return (
|
||||
<Router history={this.history} {...props}>
|
||||
<HashRouter history={this.history} {...props}>
|
||||
<IonRouter registerHistoryListener={this.registerHistoryListener}>{children}</IonRouter>
|
||||
</Router>
|
||||
</HashRouter>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Action as HistoryAction, Location as HistoryLocation, MemoryHistory } from 'history';
|
||||
import React from 'react';
|
||||
import type { MemoryRouterProps } from 'react-router';
|
||||
import { Router } from 'react-router';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
|
||||
import { IonRouter } from './IonRouter';
|
||||
|
||||
@@ -43,9 +43,9 @@ export class IonReactMemoryRouter extends React.Component<IonReactMemoryRouterPr
|
||||
render() {
|
||||
const { children, ...props } = this.props;
|
||||
return (
|
||||
<Router {...props}>
|
||||
<MemoryRouter {...props}>
|
||||
<IonRouter registerHistoryListener={this.registerHistoryListener}>{children}</IonRouter>
|
||||
</Router>
|
||||
</MemoryRouter>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { Action as HistoryAction, History, Location as HistoryLocation } from 'history';
|
||||
import { createBrowserHistory as createHistory } from 'history';
|
||||
import React from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import type { BrowserRouterProps } from 'react-router-dom';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { BrowserRouter, useLocation, useNavigationType } from 'react-router-dom';
|
||||
|
||||
import { IonRouter } from './IonRouter';
|
||||
|
||||
@@ -10,44 +10,41 @@ interface IonReactRouterProps extends BrowserRouterProps {
|
||||
history?: History;
|
||||
}
|
||||
|
||||
export class IonReactRouter extends React.Component<IonReactRouterProps> {
|
||||
historyListenHandler?: (location: HistoryLocation, action: HistoryAction) => void;
|
||||
history: History;
|
||||
/**
|
||||
* `IonReactRouter` is Ionic's routing container component. It is a wrapper around `BrowserRouter` from `react-router-dom`.
|
||||
*/
|
||||
export const IonReactRouter = ({ children, ...rest }: PropsWithChildren<IonReactRouterProps>) => {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<IonInnerReactRouter {...rest}>{children}</IonInnerReactRouter>
|
||||
</BrowserRouter>
|
||||
);
|
||||
};
|
||||
|
||||
constructor(props: IonReactRouterProps) {
|
||||
super(props);
|
||||
const { history, ...rest } = props;
|
||||
this.history = history || createHistory(rest);
|
||||
this.history.listen(this.handleHistoryChange.bind(this));
|
||||
this.registerHistoryListener = this.registerHistoryListener.bind(this);
|
||||
}
|
||||
/**
|
||||
* Browser router provides the context APIs for the hooks to work.
|
||||
*/
|
||||
const IonInnerReactRouter = ({ children }: PropsWithChildren<IonReactRouterProps>) => {
|
||||
const location = useLocation();
|
||||
const navigationType = useNavigationType();
|
||||
|
||||
/**
|
||||
* history@4.x passes separate location and action
|
||||
* params. history@5.x passes location and action
|
||||
* together as a single object.
|
||||
* TODO: If support for React Router <=5 is dropped
|
||||
* this logic is no longer needed. We can just assume
|
||||
* a single object with both location and action.
|
||||
*/
|
||||
handleHistoryChange(location: HistoryLocation, action: HistoryAction) {
|
||||
const historyListenHandler = useRef<(location: HistoryLocation, action: HistoryAction) => void>();
|
||||
|
||||
const registerHistoryListener = (cb: (location: HistoryLocation, action: HistoryAction) => void) => {
|
||||
historyListenHandler.current = cb;
|
||||
};
|
||||
|
||||
const handleHistoryChange = (location: HistoryLocation, action: HistoryAction) => {
|
||||
const locationValue = (location as any).location || location;
|
||||
const actionValue = (location as any).action || action;
|
||||
if (this.historyListenHandler) {
|
||||
this.historyListenHandler(locationValue, actionValue);
|
||||
if (historyListenHandler.current) {
|
||||
historyListenHandler.current(locationValue, actionValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
registerHistoryListener(cb: (location: HistoryLocation, action: HistoryAction) => void) {
|
||||
this.historyListenHandler = cb;
|
||||
}
|
||||
useEffect(() => {
|
||||
handleHistoryChange(location, navigationType);
|
||||
}, [location, navigationType]);
|
||||
|
||||
render() {
|
||||
const { children, ...props } = this.props;
|
||||
return (
|
||||
<Router history={this.history} {...props}>
|
||||
<IonRouter registerHistoryListener={this.registerHistoryListener}>{children}</IonRouter>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
}
|
||||
return <IonRouter registerHistoryListener={registerHistoryListener}>{children}</IonRouter>;
|
||||
};
|
||||
|
||||
@@ -2,29 +2,8 @@ import type { IonRouteProps } from '@ionic/react';
|
||||
import React from 'react';
|
||||
import { Route } from 'react-router';
|
||||
|
||||
export class IonRouteInner extends React.PureComponent<IonRouteProps> {
|
||||
render() {
|
||||
return (
|
||||
<Route
|
||||
path={this.props.path}
|
||||
exact={this.props.exact}
|
||||
render={this.props.render}
|
||||
{
|
||||
/**
|
||||
* `computedMatch` is a private API in react-router v5 that
|
||||
* has been removed in v6.
|
||||
*
|
||||
* This needs to be removed when we support v6.
|
||||
*
|
||||
* TODO: FW-647
|
||||
*/
|
||||
...((this.props as any).computedMatch !== undefined
|
||||
? {
|
||||
computedMatch: (this.props as any).computedMatch,
|
||||
}
|
||||
: {})
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
export const IonRouteInner = ({ path, render }: IonRouteProps) => {
|
||||
return (
|
||||
<Route path={path} children={render} />
|
||||
)
|
||||
}
|
||||
@@ -1,16 +1,9 @@
|
||||
import type {
|
||||
AnimationBuilder,
|
||||
RouteAction,
|
||||
RouteInfo,
|
||||
RouteManagerContextState,
|
||||
RouterDirection,
|
||||
ViewItem,
|
||||
} from '@ionic/react';
|
||||
import type { AnimationBuilder, RouteAction, RouteInfo, RouteManagerContextState, RouterDirection } from '@ionic/react';
|
||||
import { LocationHistory, NavManager, RouteManagerContext, generateId, getConfig } from '@ionic/react';
|
||||
import type { Action as HistoryAction, Location as HistoryLocation } from 'history';
|
||||
import React from 'react';
|
||||
import type { RouteComponentProps } from 'react-router-dom';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import { IonRouteInner } from './IonRouteInner';
|
||||
import { ReactRouterViewStack } from './ReactRouterViewStack';
|
||||
@@ -21,157 +14,110 @@ export interface LocationState {
|
||||
routerOptions?: { as?: string; unmount?: boolean };
|
||||
}
|
||||
|
||||
interface IonRouteProps extends RouteComponentProps<{}, {}, LocationState> {
|
||||
interface IonRouterProps {
|
||||
registerHistoryListener: (cb: (location: HistoryLocation<any>, action: HistoryAction) => void) => void;
|
||||
}
|
||||
|
||||
interface IonRouteState {
|
||||
routeInfo: RouteInfo;
|
||||
}
|
||||
export const IonRouter = ({ children, registerHistoryListener }: PropsWithChildren<IonRouterProps>) => {
|
||||
const location = useLocation();
|
||||
const params = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
class IonRouterInner extends React.PureComponent<IonRouteProps, IonRouteState> {
|
||||
currentTab?: string;
|
||||
exitViewFromOtherOutletHandlers: ((pathname: string) => ViewItem | undefined)[] = [];
|
||||
incomingRouteParams?: Partial<RouteInfo>;
|
||||
locationHistory = new LocationHistory();
|
||||
viewStack = new ReactRouterViewStack();
|
||||
routeMangerContextState: RouteManagerContextState = {
|
||||
canGoBack: () => this.locationHistory.canGoBack(),
|
||||
clearOutlet: this.viewStack.clear,
|
||||
findViewItemByPathname: this.viewStack.findViewItemByPathname,
|
||||
getChildrenToRender: this.viewStack.getChildrenToRender,
|
||||
goBack: () => this.handleNavigateBack(),
|
||||
createViewItem: this.viewStack.createViewItem,
|
||||
findViewItemByRouteInfo: this.viewStack.findViewItemByRouteInfo,
|
||||
findLeavingViewItemByRouteInfo: this.viewStack.findLeavingViewItemByRouteInfo,
|
||||
addViewItem: this.viewStack.add,
|
||||
unMountViewItem: this.viewStack.remove,
|
||||
};
|
||||
const didMountRef = useRef(false);
|
||||
const locationHistory = useRef(new LocationHistory());
|
||||
const currentTab = useRef<string | undefined>(undefined);
|
||||
const viewStack = useRef(new ReactRouterViewStack());
|
||||
const incomingRouteParams = useRef<Partial<RouteInfo> | null>(null);
|
||||
|
||||
constructor(props: IonRouteProps) {
|
||||
super(props);
|
||||
const [routeInfo, setRouteInfo] = useState({
|
||||
id: generateId('routeInfo'),
|
||||
pathname: location.pathname,
|
||||
search: location.search,
|
||||
});
|
||||
|
||||
const routeInfo = {
|
||||
id: generateId('routeInfo'),
|
||||
pathname: this.props.location.pathname,
|
||||
search: this.props.location.search,
|
||||
};
|
||||
useEffect(() => {
|
||||
didMountRef.current = true;
|
||||
}, []);
|
||||
|
||||
this.locationHistory.add(routeInfo);
|
||||
this.handleChangeTab = this.handleChangeTab.bind(this);
|
||||
this.handleResetTab = this.handleResetTab.bind(this);
|
||||
this.handleNativeBack = this.handleNativeBack.bind(this);
|
||||
this.handleNavigate = this.handleNavigate.bind(this);
|
||||
this.handleNavigateBack = this.handleNavigateBack.bind(this);
|
||||
this.props.registerHistoryListener(this.handleHistoryChange.bind(this));
|
||||
this.handleSetCurrentTab = this.handleSetCurrentTab.bind(this);
|
||||
|
||||
this.state = {
|
||||
routeInfo,
|
||||
};
|
||||
}
|
||||
|
||||
handleChangeTab(tab: string, path?: string, routeOptions?: any) {
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
|
||||
const routeInfo = this.locationHistory.getCurrentRouteInfoForTab(tab);
|
||||
const [pathname, search] = path.split('?');
|
||||
if (routeInfo) {
|
||||
this.incomingRouteParams = { ...routeInfo, routeAction: 'push', routeDirection: 'none' };
|
||||
if (routeInfo.pathname === pathname) {
|
||||
this.incomingRouteParams.routeOptions = routeOptions;
|
||||
this.props.history.push(routeInfo.pathname + (routeInfo.search || ''));
|
||||
} else {
|
||||
this.incomingRouteParams.pathname = pathname;
|
||||
this.incomingRouteParams.search = search ? '?' + search : undefined;
|
||||
this.incomingRouteParams.routeOptions = routeOptions;
|
||||
this.props.history.push(pathname + (search ? '?' + search : ''));
|
||||
}
|
||||
} else {
|
||||
this.handleNavigate(pathname, 'push', 'none', undefined, routeOptions, tab);
|
||||
}
|
||||
}
|
||||
|
||||
handleHistoryChange(location: HistoryLocation<LocationState>, action: HistoryAction) {
|
||||
const handleHistoryChange = (location: HistoryLocation<LocationState>, action: HistoryAction) => {
|
||||
let leavingLocationInfo: RouteInfo;
|
||||
if (this.incomingRouteParams) {
|
||||
if (this.incomingRouteParams.routeAction === 'replace') {
|
||||
leavingLocationInfo = this.locationHistory.previous();
|
||||
if (incomingRouteParams) {
|
||||
if (incomingRouteParams.current?.routeAction === 'replace') {
|
||||
leavingLocationInfo = locationHistory.current.previous();
|
||||
} else {
|
||||
leavingLocationInfo = this.locationHistory.current();
|
||||
leavingLocationInfo = locationHistory.current.current();
|
||||
}
|
||||
} else {
|
||||
leavingLocationInfo = this.locationHistory.current();
|
||||
leavingLocationInfo = locationHistory.current.current();
|
||||
}
|
||||
|
||||
const leavingUrl = leavingLocationInfo.pathname + leavingLocationInfo.search;
|
||||
if (leavingUrl !== location.pathname) {
|
||||
if (!this.incomingRouteParams) {
|
||||
if (!incomingRouteParams.current) {
|
||||
if (action === 'REPLACE') {
|
||||
this.incomingRouteParams = {
|
||||
incomingRouteParams.current = {
|
||||
routeAction: 'replace',
|
||||
routeDirection: 'none',
|
||||
tab: this.currentTab,
|
||||
tab: currentTab.current,
|
||||
};
|
||||
}
|
||||
if (action === 'POP') {
|
||||
const currentRoute = this.locationHistory.current();
|
||||
const currentRoute = locationHistory.current.current();
|
||||
if (currentRoute && currentRoute.pushedByRoute) {
|
||||
const prevInfo = this.locationHistory.findLastLocation(currentRoute);
|
||||
this.incomingRouteParams = { ...prevInfo, routeAction: 'pop', routeDirection: 'back' };
|
||||
const prevInfo = locationHistory.current.findLastLocation(currentRoute);
|
||||
incomingRouteParams.current = { ...prevInfo, routeAction: 'pop', routeDirection: 'back' };
|
||||
} else {
|
||||
this.incomingRouteParams = {
|
||||
incomingRouteParams.current = {
|
||||
routeAction: 'pop',
|
||||
routeDirection: 'none',
|
||||
tab: this.currentTab,
|
||||
tab: currentTab.current,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!this.incomingRouteParams) {
|
||||
this.incomingRouteParams = {
|
||||
if (!incomingRouteParams.current) {
|
||||
incomingRouteParams.current = {
|
||||
routeAction: 'push',
|
||||
routeDirection: location.state?.direction || 'forward',
|
||||
routeOptions: location.state?.routerOptions,
|
||||
tab: this.currentTab,
|
||||
tab: currentTab.current,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let routeInfo: RouteInfo;
|
||||
|
||||
if (this.incomingRouteParams?.id) {
|
||||
if (incomingRouteParams.current?.id) {
|
||||
routeInfo = {
|
||||
...(this.incomingRouteParams as RouteInfo),
|
||||
...(incomingRouteParams.current as RouteInfo),
|
||||
lastPathname: leavingLocationInfo.pathname,
|
||||
};
|
||||
this.locationHistory.add(routeInfo);
|
||||
locationHistory.current.add(routeInfo);
|
||||
} else {
|
||||
const isPushed =
|
||||
this.incomingRouteParams.routeAction === 'push' && this.incomingRouteParams.routeDirection === 'forward';
|
||||
incomingRouteParams.current?.routeAction === 'push' &&
|
||||
incomingRouteParams.current.routeDirection === 'forward';
|
||||
routeInfo = {
|
||||
id: generateId('routeInfo'),
|
||||
...this.incomingRouteParams,
|
||||
...incomingRouteParams,
|
||||
lastPathname: leavingLocationInfo.pathname,
|
||||
pathname: location.pathname,
|
||||
search: location.search,
|
||||
params: this.props.match.params,
|
||||
params: params as any, // TODO @sean fix type of route info for params
|
||||
prevRouteLastPathname: leavingLocationInfo.lastPathname,
|
||||
};
|
||||
if (isPushed) {
|
||||
routeInfo.tab = leavingLocationInfo.tab;
|
||||
routeInfo.pushedByRoute = leavingLocationInfo.pathname;
|
||||
} else if (routeInfo.routeAction === 'pop') {
|
||||
const r = this.locationHistory.findLastLocation(routeInfo);
|
||||
const r = locationHistory.current.findLastLocation(routeInfo);
|
||||
routeInfo.pushedByRoute = r?.pushedByRoute;
|
||||
} else if (routeInfo.routeAction === 'push' && routeInfo.tab !== leavingLocationInfo.tab) {
|
||||
// If we are switching tabs grab the last route info for the tab and use its pushedByRoute
|
||||
const lastRoute = this.locationHistory.getCurrentRouteInfoForTab(routeInfo.tab);
|
||||
const lastRoute = locationHistory.current.getCurrentRouteInfoForTab(routeInfo.tab);
|
||||
routeInfo.pushedByRoute = lastRoute?.pushedByRoute;
|
||||
} else if (routeInfo.routeAction === 'replace') {
|
||||
// Make sure to set the lastPathname, etc.. to the current route so the page transitions out
|
||||
const currentRouteInfo = this.locationHistory.current();
|
||||
const currentRouteInfo = locationHistory.current.current();
|
||||
|
||||
/**
|
||||
* If going from /home to /child, then replacing from
|
||||
@@ -198,58 +144,79 @@ class IonRouterInner extends React.PureComponent<IonRouteProps, IonRouteState> {
|
||||
routeInfo.routeAnimation = routeInfo.routeAnimation || currentRouteInfo?.routeAnimation;
|
||||
}
|
||||
|
||||
this.locationHistory.add(routeInfo);
|
||||
locationHistory.current.add(routeInfo);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
routeInfo,
|
||||
});
|
||||
setRouteInfo(routeInfo);
|
||||
}
|
||||
|
||||
this.incomingRouteParams = undefined;
|
||||
}
|
||||
incomingRouteParams.current = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* history@4.x uses goBack(), history@5.x uses back()
|
||||
* TODO: If support for React Router <=5 is dropped
|
||||
* this logic is no longer needed. We can just
|
||||
* assume back() is available.
|
||||
*/
|
||||
handleNativeBack() {
|
||||
const history = this.props.history as any;
|
||||
const goBack = history.goBack || history.back;
|
||||
goBack();
|
||||
}
|
||||
const handleResetTab = (tab: string, originalHref: string, originalRouteOptions: any) => {
|
||||
const routeInfo = locationHistory.current.getFirstRouteInfoForTab(tab);
|
||||
if (routeInfo) {
|
||||
const newRouteInfo = { ...routeInfo };
|
||||
newRouteInfo.pathname = originalHref;
|
||||
newRouteInfo.routeOptions = originalRouteOptions;
|
||||
incomingRouteParams.current = { ...newRouteInfo, routeAction: 'pop', routeDirection: 'back' };
|
||||
navigate(newRouteInfo.pathname + (newRouteInfo.search || ''));
|
||||
}
|
||||
};
|
||||
|
||||
handleNavigate(
|
||||
path: string,
|
||||
routeAction: RouteAction,
|
||||
routeDirection?: RouterDirection,
|
||||
routeAnimation?: AnimationBuilder,
|
||||
routeOptions?: any,
|
||||
tab?: string
|
||||
) {
|
||||
this.incomingRouteParams = Object.assign(this.incomingRouteParams || {}, {
|
||||
routeAction,
|
||||
routeDirection,
|
||||
routeOptions,
|
||||
routeAnimation,
|
||||
tab,
|
||||
});
|
||||
const handleChangeTab = (tab: string, path?: string, routeOptions?: any) => {
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (routeAction === 'push') {
|
||||
this.props.history.push(path);
|
||||
const routeInfo = locationHistory.current.getCurrentRouteInfoForTab(tab);
|
||||
const [pathname, search] = path.split('?');
|
||||
if (routeInfo) {
|
||||
const routeParams = {
|
||||
...routeInfo,
|
||||
routeAction: 'push' as RouteAction,
|
||||
routeDirection: 'none' as RouterDirection,
|
||||
};
|
||||
if (routeInfo.pathname === pathname) {
|
||||
incomingRouteParams.current = {
|
||||
...routeParams,
|
||||
routeOptions,
|
||||
};
|
||||
|
||||
navigate(routeInfo.pathname + (routeInfo.search || ''));
|
||||
} else {
|
||||
incomingRouteParams.current = {
|
||||
...routeParams,
|
||||
pathname,
|
||||
search: search ? '?' + search : undefined,
|
||||
routeOptions,
|
||||
};
|
||||
|
||||
navigate(pathname + (search ? '?' + search : ''));
|
||||
}
|
||||
} else {
|
||||
this.props.history.replace(path);
|
||||
handleNavigate(pathname, 'push', 'none', undefined, routeOptions, tab);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleNavigateBack(defaultHref: string | RouteInfo = '/', routeAnimation?: AnimationBuilder) {
|
||||
const handleSetCurrentTab = (tab: string) => {
|
||||
currentTab.current = tab;
|
||||
const ri = { ...locationHistory.current.current() };
|
||||
if (ri.tab !== tab) {
|
||||
ri.tab = tab;
|
||||
locationHistory.current.update(ri);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNativeBack = () => {
|
||||
navigate(-1);
|
||||
};
|
||||
|
||||
const handleNavigateBack = (defaultHref: string | RouteInfo = '/', routeAnimation?: AnimationBuilder) => {
|
||||
const config = getConfig();
|
||||
defaultHref = defaultHref ? defaultHref : config && config.get('backButtonDefaultHref' as any);
|
||||
const routeInfo = this.locationHistory.current();
|
||||
const routeInfo = locationHistory.current.current();
|
||||
if (routeInfo && routeInfo.pushedByRoute) {
|
||||
const prevInfo = this.locationHistory.findLastLocation(routeInfo);
|
||||
const prevInfo = locationHistory.current.findLastLocation(routeInfo);
|
||||
if (prevInfo) {
|
||||
/**
|
||||
* This needs to be passed to handleNavigate
|
||||
@@ -257,7 +224,7 @@ class IonRouterInner extends React.PureComponent<IonRouteProps, IonRouteState> {
|
||||
* will be overridden.
|
||||
*/
|
||||
const incomingAnimation = routeAnimation || routeInfo.routeAnimation;
|
||||
this.incomingRouteParams = {
|
||||
incomingRouteParams.current = {
|
||||
...prevInfo,
|
||||
routeAction: 'pop',
|
||||
routeDirection: 'back',
|
||||
@@ -273,68 +240,75 @@ class IonRouterInner extends React.PureComponent<IonRouteProps, IonRouteState> {
|
||||
*/
|
||||
(prevInfo.pathname === routeInfo.pushedByRoute && routeInfo.tab === '' && prevInfo.tab === '')
|
||||
) {
|
||||
/**
|
||||
* history@4.x uses goBack(), history@5.x uses back()
|
||||
* TODO: If support for React Router <=5 is dropped
|
||||
* this logic is no longer needed. We can just
|
||||
* assume back() is available.
|
||||
*/
|
||||
const history = this.props.history as any;
|
||||
const goBack = history.goBack || history.back;
|
||||
goBack();
|
||||
navigate(-1);
|
||||
} else {
|
||||
this.handleNavigate(prevInfo.pathname + (prevInfo.search || ''), 'pop', 'back', incomingAnimation);
|
||||
handleNavigate(prevInfo.pathname + (prevInfo.search || ''), 'pop', 'back', incomingAnimation);
|
||||
}
|
||||
} else {
|
||||
this.handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation);
|
||||
handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation);
|
||||
}
|
||||
} else {
|
||||
this.handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation);
|
||||
handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNavigate = (
|
||||
path: string,
|
||||
routeAction: RouteAction,
|
||||
routeDirection?: RouterDirection,
|
||||
routeAnimation?: AnimationBuilder,
|
||||
routeOptions?: any,
|
||||
tab?: string
|
||||
) => {
|
||||
incomingRouteParams.current = Object.assign(incomingRouteParams.current || {}, {
|
||||
routeAction,
|
||||
routeDirection,
|
||||
routeOptions,
|
||||
routeAnimation,
|
||||
tab,
|
||||
});
|
||||
|
||||
navigate(path, { replace: routeAction !== 'push' });
|
||||
};
|
||||
|
||||
if (!didMountRef.current) {
|
||||
locationHistory.current.add(routeInfo);
|
||||
|
||||
registerHistoryListener(handleHistoryChange);
|
||||
}
|
||||
|
||||
handleResetTab(tab: string, originalHref: string, originalRouteOptions: any) {
|
||||
const routeInfo = this.locationHistory.getFirstRouteInfoForTab(tab);
|
||||
if (routeInfo) {
|
||||
const newRouteInfo = { ...routeInfo };
|
||||
newRouteInfo.pathname = originalHref;
|
||||
newRouteInfo.routeOptions = originalRouteOptions;
|
||||
this.incomingRouteParams = { ...newRouteInfo, routeAction: 'pop', routeDirection: 'back' };
|
||||
this.props.history.push(newRouteInfo.pathname + (newRouteInfo.search || ''));
|
||||
}
|
||||
}
|
||||
const routeMangerContextValue: RouteManagerContextState = {
|
||||
canGoBack: () => locationHistory.current.canGoBack(),
|
||||
clearOutlet: viewStack.current.clear,
|
||||
findViewItemByPathname: viewStack.current.findViewItemByPathname,
|
||||
getChildrenToRender: viewStack.current.getChildrenToRender,
|
||||
goBack: () => handleNavigateBack(),
|
||||
createViewItem: viewStack.current.createViewItem,
|
||||
findViewItemByRouteInfo: viewStack.current.findViewItemByRouteInfo,
|
||||
findLeavingViewItemByRouteInfo: viewStack.current.findLeavingViewItemByRouteInfo,
|
||||
addViewItem: viewStack.current.add,
|
||||
unMountViewItem: viewStack.current.remove,
|
||||
};
|
||||
|
||||
handleSetCurrentTab(tab: string) {
|
||||
this.currentTab = tab;
|
||||
const ri = { ...this.locationHistory.current() };
|
||||
if (ri.tab !== tab) {
|
||||
ri.tab = tab;
|
||||
this.locationHistory.update(ri);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<RouteManagerContext.Provider value={routeMangerContextValue}>
|
||||
<NavManager
|
||||
ionRoute={IonRouteInner}
|
||||
ionRedirect={{}}
|
||||
stackManager={StackManager}
|
||||
routeInfo={routeInfo}
|
||||
onNativeBack={handleNativeBack}
|
||||
onNavigateBack={handleNavigateBack}
|
||||
onNavigate={handleNavigate}
|
||||
onSetCurrentTab={handleSetCurrentTab}
|
||||
onChangeTab={handleChangeTab}
|
||||
onResetTab={handleResetTab}
|
||||
locationHistory={locationHistory.current}
|
||||
>
|
||||
{children}
|
||||
</NavManager>
|
||||
</RouteManagerContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<RouteManagerContext.Provider value={this.routeMangerContextState}>
|
||||
<NavManager
|
||||
ionRoute={IonRouteInner}
|
||||
ionRedirect={{}}
|
||||
stackManager={StackManager}
|
||||
routeInfo={this.state.routeInfo!}
|
||||
onNativeBack={this.handleNativeBack}
|
||||
onNavigateBack={this.handleNavigateBack}
|
||||
onNavigate={this.handleNavigate}
|
||||
onSetCurrentTab={this.handleSetCurrentTab}
|
||||
onChangeTab={this.handleChangeTab}
|
||||
onResetTab={this.handleResetTab}
|
||||
locationHistory={this.locationHistory}
|
||||
>
|
||||
{this.props.children}
|
||||
</NavManager>
|
||||
</RouteManagerContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const IonRouter = withRouter(IonRouterInner);
|
||||
IonRouter.displayName = 'IonRouter';
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import type { RouteInfo, ViewItem } from '@ionic/react';
|
||||
import { IonRoute, ViewLifeCycleManager, ViewStacks, generateId } from '@ionic/react';
|
||||
import React from 'react';
|
||||
import { Route } from 'react-router';
|
||||
|
||||
import { findRoutesNode } from './utils/findRoutesNode';
|
||||
import { matchPath } from './utils/matchPath';
|
||||
|
||||
export class ReactRouterViewStack extends ViewStacks {
|
||||
@@ -44,42 +46,32 @@ export class ReactRouterViewStack extends ViewStacks {
|
||||
const viewItems = this.getViewItemsForOutlet(outletId);
|
||||
|
||||
// Sync latest routes with viewItems
|
||||
React.Children.forEach(ionRouterOutlet.props.children, (child: React.ReactElement) => {
|
||||
const viewItem = viewItems.find((v) => {
|
||||
return matchComponent(child, v.routeData.childProps.path || v.routeData.childProps.from);
|
||||
});
|
||||
if (viewItem) {
|
||||
viewItem.reactElement = child;
|
||||
React.Children.forEach(findRoutesNode(ionRouterOutlet.props.children), (child: React.ReactElement) => {
|
||||
if (child.type === Route) {
|
||||
const viewItem = viewItems.find((v) => {
|
||||
return matchComponent(child, v.routeData.childProps.path || v.routeData.childProps.from);
|
||||
});
|
||||
if (viewItem) {
|
||||
viewItem.reactElement = child;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const children = viewItems.map((viewItem) => {
|
||||
let clonedChild;
|
||||
if (viewItem.ionRoute && !viewItem.disableIonPageManagement) {
|
||||
clonedChild = (
|
||||
<ViewLifeCycleManager
|
||||
key={`view-${viewItem.id}`}
|
||||
mount={viewItem.mount}
|
||||
removeView={() => this.remove(viewItem)}
|
||||
>
|
||||
{React.cloneElement(viewItem.reactElement, {
|
||||
computedMatch: viewItem.routeData.match,
|
||||
})}
|
||||
</ViewLifeCycleManager>
|
||||
);
|
||||
} else {
|
||||
const clonedChild = (
|
||||
<ViewLifeCycleManager
|
||||
key={`view-${viewItem.id}`}
|
||||
mount={viewItem.mount}
|
||||
removeView={() => this.remove(viewItem)}
|
||||
>
|
||||
{React.cloneElement(viewItem.reactElement, {
|
||||
computedMatch: viewItem.routeData.match,
|
||||
})}
|
||||
</ViewLifeCycleManager>
|
||||
);
|
||||
|
||||
if (!viewItem.ionRoute || viewItem.disableIonPageManagement) {
|
||||
const match = matchComponent(viewItem.reactElement, routeInfo.pathname);
|
||||
clonedChild = (
|
||||
<ViewLifeCycleManager
|
||||
key={`view-${viewItem.id}`}
|
||||
mount={viewItem.mount}
|
||||
removeView={() => this.remove(viewItem)}
|
||||
>
|
||||
{React.cloneElement(viewItem.reactElement, {
|
||||
computedMatch: viewItem.routeData.match,
|
||||
})}
|
||||
</ViewLifeCycleManager>
|
||||
);
|
||||
|
||||
if (!match && viewItem.routeData.match) {
|
||||
viewItem.routeData.match = undefined;
|
||||
@@ -152,8 +144,9 @@ export class ReactRouterViewStack extends ViewStacks {
|
||||
*
|
||||
* To validate this, we need to check if the path and url match the view item's route data.
|
||||
*/
|
||||
const hasParameter = match.path.includes(':');
|
||||
if (!hasParameter || (hasParameter && match.url === v.routeData?.match?.url)) {
|
||||
// changed from match.path
|
||||
const hasParameter = match.params && Object.keys(match.params).length > 0;
|
||||
if (!hasParameter || (hasParameter && match.pathname === v.routeData?.match?.url)) {
|
||||
viewItem = v;
|
||||
return true;
|
||||
}
|
||||
@@ -165,11 +158,11 @@ export class ReactRouterViewStack extends ViewStacks {
|
||||
// try to find a route that doesn't have a path or from prop, that will be our default route
|
||||
if (!v.routeData.childProps.path && !v.routeData.childProps.from) {
|
||||
match = {
|
||||
path: pathname,
|
||||
url: pathname,
|
||||
isExact: true,
|
||||
pathname: pathname,
|
||||
// url: pathname,
|
||||
// isExact: true,
|
||||
params: {},
|
||||
};
|
||||
} as any;
|
||||
viewItem = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { RouteInfo, StackContextState, ViewItem } from '@ionic/react';
|
||||
import { RouteManagerContext, StackContext, generateId, getConfig } from '@ionic/react';
|
||||
import React from 'react';
|
||||
import { Route } from 'react-router';
|
||||
|
||||
import { clonePageElement } from './clonePageElement';
|
||||
import { findRoutesNode } from './utils/findRoutesNode';
|
||||
import { matchPath } from './utils/matchPath';
|
||||
|
||||
// TODO(FW-2959): types
|
||||
@@ -110,12 +112,17 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
}
|
||||
}
|
||||
|
||||
const enteringRoute = matchRoute(this.ionRouterOutlet?.props.children, routeInfo) as React.ReactElement;
|
||||
const enteringRoute = findRouteByRouteInfo(this.ionRouterOutlet?.props.children, routeInfo) as React.ReactElement;
|
||||
|
||||
if (enteringRoute === undefined) {
|
||||
console.warn('Could not match a route for', routeInfo, this.ionRouterOutlet?.props.children);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enteringViewItem) {
|
||||
enteringViewItem.reactElement = enteringRoute;
|
||||
enteringViewItem.reactElement = enteringRoute.props.element;
|
||||
} else if (enteringRoute) {
|
||||
enteringViewItem = this.context.createViewItem(this.id, enteringRoute, routeInfo);
|
||||
enteringViewItem = this.context.createViewItem(this.id, enteringRoute.props.element, routeInfo);
|
||||
this.context.addViewItem(enteringViewItem);
|
||||
}
|
||||
|
||||
@@ -133,7 +140,7 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
* If the route data does not match the current path, the parent router outlet
|
||||
* is attempting to transition and we cancel the operation.
|
||||
*/
|
||||
if (enteringViewItem.routeData.match.url !== routeInfo.pathname) {
|
||||
if (enteringViewItem.routeData.match.pathname !== routeInfo.pathname) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -430,30 +437,38 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
|
||||
export default StackManager;
|
||||
|
||||
function matchRoute(node: React.ReactNode, routeInfo: RouteInfo) {
|
||||
/**
|
||||
* Finds the <Route /> node matching the current route info.
|
||||
* If no <Route /> can be matched, a fallback node is returned.
|
||||
*/
|
||||
function findRouteByRouteInfo(node: React.ReactNode, routeInfo: RouteInfo) {
|
||||
let matchedNode: React.ReactNode;
|
||||
React.Children.forEach(node as React.ReactElement, (child: React.ReactElement) => {
|
||||
const match = matchPath({
|
||||
pathname: routeInfo.pathname,
|
||||
componentProps: child.props,
|
||||
});
|
||||
if (match) {
|
||||
matchedNode = child;
|
||||
let fallbackNode: React.ReactNode;
|
||||
|
||||
// <Route /> nodes are rendered inside of a <Routes /> node
|
||||
const routesNode = findRoutesNode(node) ?? node;
|
||||
|
||||
React.Children.forEach(routesNode, (child: React.ReactElement) => {
|
||||
// Ignore any non-<Route /> nodes
|
||||
if (child.type === Route) {
|
||||
const match = matchPath({
|
||||
pathname: routeInfo.pathname,
|
||||
componentProps: child.props,
|
||||
});
|
||||
|
||||
if (match) {
|
||||
matchedNode = child;
|
||||
}
|
||||
|
||||
if (!(child.props.path || child.props.from)) {
|
||||
// If we haven't found a node
|
||||
// try to find one that doesn't have a path or from prop, that will be our not found route
|
||||
fallbackNode = child;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (matchedNode) {
|
||||
return matchedNode;
|
||||
}
|
||||
// If we haven't found a node
|
||||
// try to find one that doesn't have a path or from prop, that will be our not found route
|
||||
React.Children.forEach(node as React.ReactElement, (child: React.ReactElement) => {
|
||||
if (!(child.props.path || child.props.from)) {
|
||||
matchedNode = child;
|
||||
}
|
||||
});
|
||||
|
||||
return matchedNode;
|
||||
return matchedNode ?? fallbackNode;
|
||||
}
|
||||
|
||||
function matchComponent(node: React.ReactElement, pathname: string, forceExact?: boolean) {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
import { Routes } from "react-router";
|
||||
|
||||
export const findRoutesNode = (node: React.ReactNode) => {
|
||||
// Finds the <Routes /> component node
|
||||
let routesNode: React.ReactNode;
|
||||
React.Children.forEach(node as React.ReactElement, (child: React.ReactElement) => {
|
||||
if (child.type === Routes) {
|
||||
routesNode = child;
|
||||
}
|
||||
});
|
||||
if (routesNode) {
|
||||
return (routesNode as React.ReactElement).props.children;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
@@ -21,23 +21,23 @@ interface MatchPathOptions {
|
||||
*/
|
||||
export const matchPath = ({
|
||||
pathname,
|
||||
componentProps,
|
||||
componentProps
|
||||
}: MatchPathOptions): false | ReturnType<typeof reactRouterMatchPath> => {
|
||||
const { exact, component } = componentProps;
|
||||
const { exact: caseSensitive, path, from } = componentProps;
|
||||
|
||||
const path = componentProps.path || componentProps.from;
|
||||
/***
|
||||
* The props to match against, they are identical
|
||||
* to the matching props `Route` accepts. It could also be a string
|
||||
* or an array of strings as shortcut for `{ path }`.
|
||||
*/
|
||||
const matchProps = {
|
||||
exact,
|
||||
path,
|
||||
component,
|
||||
};
|
||||
if (!pathname) {
|
||||
console.warn('Attempt to match path on an undefined pathname', {
|
||||
path: componentProps.path,
|
||||
from: componentProps.from,
|
||||
});
|
||||
// TODO @sean this is new behavior, need to debug where it is coming from
|
||||
return false;
|
||||
}
|
||||
|
||||
const match = reactRouterMatchPath(pathname, matchProps);
|
||||
const match = reactRouterMatchPath({
|
||||
path: path ?? from ?? '',
|
||||
caseSensitive
|
||||
}, pathname);
|
||||
|
||||
if (!match) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user