diff --git a/docs/how_tos/i18n.rst b/docs/how_tos/i18n.rst
index ec301ac2..efeada31 100644
--- a/docs/how_tos/i18n.rst
+++ b/docs/how_tos/i18n.rst
@@ -44,17 +44,15 @@ These steps will allow your application to accept translation strings. See `fron
#. For places in your code where you need a display string, and it has to be a plain JavaScript string (e.g., a button label), you will need to do the following:
- #. Inject the ``intl`` object into your component:
+ #. Use a hook to access the ``intl`` object within your component:
- #. ``import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';``;
+ #. ``import { useIntl } from '@openedx/frontend-base';``;
- #. add ``intl: intlShape.isRequired`` to your component's ``propTypes``.
-
- #. instead of ``export Foo``, ``export injectIntl(Foo)`` .
+ #. write ``const intl = useIntl();`` near the beginning of your component.
#. Define your messages using ``defineMessages``. This function doesn't actually do anything; it's just a hook for the translation pipeline to be able to find your translation strings. You can call ``defineMessages`` wherever you want, but if you have a lot of them you might want to move them to a separate file. Either ``MyAppName.messages.js`` (if your entire app has only a few strings) or ``SomeComponent.messages.js`` will work. Your file should look like the example below. For your own sanity, using a short camel-case string for the property name is fine as long as ``id`` is globally unique in the MFE. Example::
- import { defineMessages } from '@edx/frontend-platform/i18n';
+ import { defineMessages } from '@openedx/frontend-base';
const messages = defineMessages({
'cartPayNow': {
diff --git a/package-lock.json b/package-lock.json
index cb245d16..19765913 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -66,7 +66,7 @@
"prop-types": "^15.8.1",
"react-dev-utils": "12.0.1",
"react-focus-on": "^3.10.2",
- "react-intl": "^6.6.6",
+ "react-intl": "^10.1.20",
"react-refresh": "0.18.0",
"react-refresh-typescript": "^2.0.9",
"react-responsive": "^10.0.0",
@@ -113,7 +113,7 @@
"nodemon": "^3.1.4"
},
"peerDependencies": {
- "@openedx/paragon": "^23.20.0",
+ "@openedx/paragon": "^23.22.2",
"@tanstack/react-query": "^5.81.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -2610,106 +2610,14 @@
}
},
"node_modules/@formatjs/intl": {
- "version": "2.10.15",
- "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.15.tgz",
- "integrity": "sha512-i6+xVqT+6KCz7nBfk4ybMXmbKO36tKvbMKtgFz9KV+8idYFyFbfwKooYk8kGjyA5+T5f1kEPQM5IDLXucTAQ9g==",
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-4.1.18.tgz",
+ "integrity": "sha512-d+AFsn+luyMAUTQImPJEK76bhEvzFKRG/1PCf1Q6sCH3ojHyHgJJkfvUFElpbDkihtm4uedK7/zoG24EL285nw==",
"license": "MIT",
"dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/fast-memoize": "2.2.3",
- "@formatjs/icu-messageformat-parser": "2.9.4",
- "@formatjs/intl-displaynames": "6.8.5",
- "@formatjs/intl-listformat": "7.7.5",
- "intl-messageformat": "10.7.7",
- "tslib": "2"
- },
- "peerDependencies": {
- "typescript": "^4.7 || 5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@formatjs/intl-displaynames": {
- "version": "6.8.5",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-6.8.5.tgz",
- "integrity": "sha512-85b+GdAKCsleS6cqVxf/Aw/uBd+20EM0wDpgaxzHo3RIR3bxF4xCJqH/Grbzx8CXurTgDDZHPdPdwJC+May41w==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/intl-localematcher": "0.5.8",
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl-displaynames/node_modules/@formatjs/ecma402-abstract": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz",
- "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/fast-memoize": "2.2.3",
- "@formatjs/intl-localematcher": "0.5.8",
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl-displaynames/node_modules/@formatjs/fast-memoize": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz",
- "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl-displaynames/node_modules/@formatjs/intl-localematcher": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz",
- "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl-listformat": {
- "version": "7.7.5",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-7.7.5.tgz",
- "integrity": "sha512-Wzes10SMNeYgnxYiKsda4rnHP3Q3II4XT2tZyOgnH5fWuHDtIkceuWlRQNsvrI3uiwP4hLqp2XdQTCsfkhXulg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/intl-localematcher": "0.5.8",
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl-listformat/node_modules/@formatjs/ecma402-abstract": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz",
- "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/fast-memoize": "2.2.3",
- "@formatjs/intl-localematcher": "0.5.8",
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl-listformat/node_modules/@formatjs/fast-memoize": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz",
- "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl-listformat/node_modules/@formatjs/intl-localematcher": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz",
- "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
+ "@formatjs/fast-memoize": "3.1.7",
+ "@formatjs/icu-messageformat-parser": "3.5.16",
+ "intl-messageformat": "11.2.13"
}
},
"node_modules/@formatjs/intl-localematcher": {
@@ -2721,55 +2629,26 @@
"tslib": "^2.8.0"
}
},
- "node_modules/@formatjs/intl/node_modules/@formatjs/ecma402-abstract": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz",
- "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/fast-memoize": "2.2.3",
- "@formatjs/intl-localematcher": "0.5.8",
- "tslib": "2"
- }
- },
"node_modules/@formatjs/intl/node_modules/@formatjs/fast-memoize": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz",
- "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz",
+ "integrity": "sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==",
+ "license": "MIT"
},
"node_modules/@formatjs/intl/node_modules/@formatjs/icu-messageformat-parser": {
- "version": "2.9.4",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz",
- "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==",
+ "version": "3.5.16",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.16.tgz",
+ "integrity": "sha512-kl6b/4D56gjGZi4ZewSmvXbalHwjOUI5ogEHPZqw42goeXTTrL7/yuPzvdrvr0QigDtvaOeb+UeMf62jks43Yg==",
"license": "MIT",
"dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/icu-skeleton-parser": "1.8.8",
- "tslib": "2"
+ "@formatjs/icu-skeleton-parser": "2.1.11"
}
},
"node_modules/@formatjs/intl/node_modules/@formatjs/icu-skeleton-parser": {
- "version": "1.8.8",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz",
- "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "tslib": "2"
- }
- },
- "node_modules/@formatjs/intl/node_modules/@formatjs/intl-localematcher": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz",
- "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz",
+ "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==",
+ "license": "MIT"
},
"node_modules/@formatjs/ts-transformer": {
"version": "3.14.2",
@@ -4365,9 +4244,9 @@
}
},
"node_modules/@openedx/paragon": {
- "version": "23.21.1",
- "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.21.1.tgz",
- "integrity": "sha512-jD7fIaILgqiiDXuUTg5hXgZxI8Ei5x2l2fzSElCTGY7qEYQwd/F3am9UFDp/60mp84L9AlyNW21Hlj0X4e8lYA==",
+ "version": "23.23.0",
+ "resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-23.23.0.tgz",
+ "integrity": "sha512-dr4zDytE7YC/Hk3sIl3MBgLyeIJBZpPp0tI2x+SQ1d/tJXhyJk4pDOfG8bFbGHt4jaM/cwjwX25jaTUV1jszIg==",
"license": "Apache-2.0",
"peer": true,
"workspaces": [
@@ -4383,7 +4262,6 @@
"axios": "^1.0.0",
"bootstrap": "^4.6.2",
"chalk": "^4.1.2",
- "child_process": "^1.0.2",
"chroma-js": "^3.0.0",
"classnames": "^2.3.1",
"cli-progress": "^3.12.0",
@@ -4429,7 +4307,7 @@
"peerDependencies": {
"react": "^16.8.6 || ^17 || ^18",
"react-dom": "^16.8.6 || ^17 || ^18",
- "react-intl": "^5.25.1 || ^6.4.0"
+ "react-intl": "^5.25.1 || ^6.4.0 || ^10.1.20"
}
},
"node_modules/@openedx/paragon/node_modules/glob": {
@@ -5517,18 +5395,6 @@
"@types/tinycolor2": "*"
}
},
- "node_modules/@types/hoist-non-react-statics": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz",
- "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==",
- "license": "MIT",
- "dependencies": {
- "hoist-non-react-statics": "^3.3.0"
- },
- "peerDependencies": {
- "@types/react": "*"
- }
- },
"node_modules/@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -7644,13 +7510,6 @@
"license": "MIT",
"peer": true
},
- "node_modules/child_process": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
- "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==",
- "license": "ISC",
- "peer": true
- },
"node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
@@ -10975,21 +10834,6 @@
"he": "bin/he"
}
},
- "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==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "react-is": "^16.7.0"
- }
- },
- "node_modules/hoist-non-react-statics/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==",
- "license": "MIT"
- },
"node_modules/hpack.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
@@ -11580,66 +11424,35 @@
}
},
"node_modules/intl-messageformat": {
- "version": "10.7.7",
- "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.7.tgz",
- "integrity": "sha512-F134jIoeYMro/3I0h08D0Yt4N9o9pjddU/4IIxMMURqbAtI2wu70X8hvG1V48W49zXHXv3RKSF/po+0fDfsGjA==",
+ "version": "11.2.13",
+ "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.2.13.tgz",
+ "integrity": "sha512-JaPaE6TIX+TAS5XLhDUh41geLw4QfBHX4s5pW8Km+L9fVC8HzB9yOuhbh4EMR/F1+8C6b9qk4763Cv+LdOG1kg==",
"license": "BSD-3-Clause",
"dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/fast-memoize": "2.2.3",
- "@formatjs/icu-messageformat-parser": "2.9.4",
- "tslib": "2"
- }
- },
- "node_modules/intl-messageformat/node_modules/@formatjs/ecma402-abstract": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz",
- "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/fast-memoize": "2.2.3",
- "@formatjs/intl-localematcher": "0.5.8",
- "tslib": "2"
+ "@formatjs/fast-memoize": "3.1.7",
+ "@formatjs/icu-messageformat-parser": "3.5.16"
}
},
"node_modules/intl-messageformat/node_modules/@formatjs/fast-memoize": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz",
- "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz",
+ "integrity": "sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==",
+ "license": "MIT"
},
"node_modules/intl-messageformat/node_modules/@formatjs/icu-messageformat-parser": {
- "version": "2.9.4",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz",
- "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==",
+ "version": "3.5.16",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.16.tgz",
+ "integrity": "sha512-kl6b/4D56gjGZi4ZewSmvXbalHwjOUI5ogEHPZqw42goeXTTrL7/yuPzvdrvr0QigDtvaOeb+UeMf62jks43Yg==",
"license": "MIT",
"dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/icu-skeleton-parser": "1.8.8",
- "tslib": "2"
+ "@formatjs/icu-skeleton-parser": "2.1.11"
}
},
"node_modules/intl-messageformat/node_modules/@formatjs/icu-skeleton-parser": {
- "version": "1.8.8",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz",
- "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "tslib": "2"
- }
- },
- "node_modules/intl-messageformat/node_modules/@formatjs/intl-localematcher": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz",
- "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz",
+ "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==",
+ "license": "MIT"
},
"node_modules/invariant": {
"version": "2.2.4",
@@ -17000,81 +16813,34 @@
}
},
"node_modules/react-intl": {
- "version": "6.8.9",
- "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.8.9.tgz",
- "integrity": "sha512-TUfj5E7lyUDvz/GtovC9OMh441kBr08rtIbgh3p0R8iF3hVY+V2W9Am7rb8BpJ/29BH1utJOqOOhmvEVh3GfZg==",
+ "version": "10.1.20",
+ "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-10.1.20.tgz",
+ "integrity": "sha512-dvD9F7CqjlB/cIWakFzScGVPDmhWk34cFWY0etWuVNc07Zmc56OKjQwqu9q74evbttSto5wFXchZtvdRXy/Tkg==",
"license": "BSD-3-Clause",
"dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/icu-messageformat-parser": "2.9.4",
- "@formatjs/intl": "2.10.15",
- "@formatjs/intl-displaynames": "6.8.5",
- "@formatjs/intl-listformat": "7.7.5",
- "@types/hoist-non-react-statics": "3",
- "@types/react": "16 || 17 || 18",
- "hoist-non-react-statics": "3",
- "intl-messageformat": "10.7.7",
- "tslib": "2"
+ "@formatjs/icu-messageformat-parser": "3.5.16",
+ "@formatjs/intl": "4.1.18",
+ "intl-messageformat": "11.2.13"
},
"peerDependencies": {
- "react": "^16.6.0 || 17 || 18",
- "typescript": "^4.7 || 5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/react-intl/node_modules/@formatjs/ecma402-abstract": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz",
- "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/fast-memoize": "2.2.3",
- "@formatjs/intl-localematcher": "0.5.8",
- "tslib": "2"
- }
- },
- "node_modules/react-intl/node_modules/@formatjs/fast-memoize": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz",
- "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
+ "@types/react": ">=18.0.0",
+ "react": ">=18.0.0"
}
},
"node_modules/react-intl/node_modules/@formatjs/icu-messageformat-parser": {
- "version": "2.9.4",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz",
- "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==",
+ "version": "3.5.16",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.16.tgz",
+ "integrity": "sha512-kl6b/4D56gjGZi4ZewSmvXbalHwjOUI5ogEHPZqw42goeXTTrL7/yuPzvdrvr0QigDtvaOeb+UeMf62jks43Yg==",
"license": "MIT",
"dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "@formatjs/icu-skeleton-parser": "1.8.8",
- "tslib": "2"
+ "@formatjs/icu-skeleton-parser": "2.1.11"
}
},
"node_modules/react-intl/node_modules/@formatjs/icu-skeleton-parser": {
- "version": "1.8.8",
- "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz",
- "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==",
- "license": "MIT",
- "dependencies": {
- "@formatjs/ecma402-abstract": "2.2.4",
- "tslib": "2"
- }
- },
- "node_modules/react-intl/node_modules/@formatjs/intl-localematcher": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz",
- "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2"
- }
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz",
+ "integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==",
+ "license": "MIT"
},
"node_modules/react-is": {
"version": "17.0.2",
diff --git a/package.json b/package.json
index 49832f58..bb353fdf 100644
--- a/package.json
+++ b/package.json
@@ -116,7 +116,7 @@
"prop-types": "^15.8.1",
"react-dev-utils": "12.0.1",
"react-focus-on": "^3.10.2",
- "react-intl": "^6.6.6",
+ "react-intl": "^10.1.20",
"react-refresh": "0.18.0",
"react-refresh-typescript": "^2.0.9",
"react-responsive": "^10.0.0",
@@ -160,7 +160,7 @@
"nodemon": "^3.1.4"
},
"peerDependencies": {
- "@openedx/paragon": "^23.20.0",
+ "@openedx/paragon": "^23.23.0",
"@tanstack/react-query": "^5.81.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
diff --git a/runtime/i18n/index.js b/runtime/i18n/index.ts
similarity index 55%
rename from runtime/i18n/index.js
rename to runtime/i18n/index.ts
index 0aa71cc2..32228608 100644
--- a/runtime/i18n/index.js
+++ b/runtime/i18n/index.ts
@@ -23,66 +23,6 @@
*
*/
-/**
- * @name createIntl
- * @kind function
- * @see {@link https://formatjs.io/docs/react-intl/api#createIntl Intl}
- */
-
-/**
- * @name FormattedDate
- * @kind class
- * @see {@link https://formatjs.io/docs/react-intl/components/#formatteddate Intl}
- */
-
-/**
- * @name FormattedTime
- * @kind class
- * @see {@link https://formatjs.io/docs/react-intl/components/#formattedtime Intl}
- */
-
-/**
- * @name FormattedRelativeTime
- * @kind class
- * @see {@link https://formatjs.io/docs/react-intl/components/#formattedrelativetime Intl}
- */
-
-/**
- * @name FormattedNumber
- * @kind class
- * @see {@link https://formatjs.io/docs/react-intl/components/#formattednumber Intl}
- */
-
-/**
- * @name FormattedPlural
- * @kind class
- * @see {@link https://formatjs.io/docs/react-intl/components/#formattedplural Intl}
- */
-
-/**
- * @name FormattedMessage
- * @kind class
- * @see {@link https://formatjs.io/docs/react-intl/components/#formattedmessage Intl}
- */
-
-/**
- * @name IntlProvider
- * @kind class
- * @see {@link https://formatjs.io/docs/react-intl/components/#intlprovider Intl}
- */
-
-/**
- * @name defineMessages
- * @kind function
- * @see {@link https://formatjs.io/docs/react-intl/api#definemessagesdefinemessage Intl}
- */
-
-/**
- * @name useIntl
- * @kind function
- * @see {@link https://formatjs.io/docs/react-intl/api#useIntl Intl}
- */
-
export {
createIntl,
defineMessages,
@@ -93,7 +33,10 @@ export {
FormattedRelativeTime,
FormattedTime,
IntlProvider,
- useIntl
+ useIntl,
+ type IntlConfig,
+ type ResolvedIntlConfig,
+ type IntlShape,
} from 'react-intl';
export {
@@ -104,14 +47,9 @@ export {
getPrimaryLanguageSubtag,
getSupportedLanguageList,
handleRtl,
- intlShape,
isRtl,
LOCALE_CHANGED,
LOCALE_TOPIC,
mergeMessages,
- updateLocale
+ updateLocale,
} from './lib';
-
-export {
- default as injectIntl
-} from './injectIntlWithShim';
diff --git a/runtime/i18n/injectIntlWithShim.jsx b/runtime/i18n/injectIntlWithShim.jsx
deleted file mode 100644
index b4717119..00000000
--- a/runtime/i18n/injectIntlWithShim.jsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import React from 'react';
-import { injectIntl } from 'react-intl';
-import { EnvironmentTypes } from '../../types';
-import { getSiteConfig } from '../config';
-import { getLoggingService } from '../logging';
-import { intlShape } from './lib';
-
-/**
- * This function wraps react-intl's injectIntl function in order to add error logging to the intl
- * property's formatMessage function.
- *
- * @memberof I18n
- */
-const injectIntlWithShim = (WrappedComponent) => {
- class ShimmedIntlComponent extends React.Component {
- constructor(props) {
- super(props);
- this.shimmedIntl = Object.create(this.props.intl, {
- formatMessage: {
- value: (definition, ...args) => {
- if (definition === undefined || definition.id === undefined) {
- const error = new Error('i18n error: An undefined message was supplied to intl.formatMessage.');
- if (getSiteConfig().environment === EnvironmentTypes.DEVELOPMENT) {
- console.error(error); // eslint-disable-line no-console
- return '!!! Missing message supplied to intl.formatMessage !!!';
- }
- getLoggingService().logError(error);
- return ''; // Fail silently in production
- }
- return this.props.intl.formatMessage(definition, ...args);
- },
- },
- });
- }
-
- render() {
- return ;
- }
- }
-
- ShimmedIntlComponent.propTypes = {
- intl: intlShape.isRequired,
- };
-
- return injectIntl(ShimmedIntlComponent);
-};
-
-export default injectIntlWithShim;
diff --git a/runtime/i18n/lib.ts b/runtime/i18n/lib.ts
index 41f39653..0d30a41e 100644
--- a/runtime/i18n/lib.ts
+++ b/runtime/i18n/lib.ts
@@ -1,5 +1,4 @@
import merge from 'lodash/merge';
-import PropTypes from 'prop-types';
import { MessageFormatElement } from 'react-intl';
import Cookies from 'universal-cookie';
@@ -51,18 +50,6 @@ const rtlLocales = [
let messages: Record | Record | undefined>;
-/**
- * @memberof module:Internationalization
- *
- * Prior versions of react-intl (our primary implementation of the i18n service) included a
- * PropTypes-based 'shape' for its `intl` object. This has since been removed. For legacy
- * compatibility, we include an `intlShape` export that is set to PropTypes.object. Usage of this
- * export is deprecated.
- *
- * @deprecated
- */
-export const intlShape = PropTypes.object;
-
/**
* @memberof module:Internationalization
*/
diff --git a/runtime/index.ts b/runtime/index.ts
index 2cc94a7d..c21c801d 100644
--- a/runtime/index.ts
+++ b/runtime/index.ts
@@ -67,15 +67,16 @@ export {
getPrimaryLanguageSubtag,
getSupportedLanguageList,
handleRtl,
- injectIntl,
IntlProvider,
- intlShape,
isRtl,
LOCALE_CHANGED,
LOCALE_TOPIC,
mergeMessages,
updateLocale,
- useIntl
+ useIntl,
+ type IntlConfig,
+ type ResolvedIntlConfig,
+ type IntlShape,
} from './i18n';
export {
diff --git a/runtime/jest.config.js b/runtime/jest.config.js
index 27050a5f..dc221e49 100644
--- a/runtime/jest.config.js
+++ b/runtime/jest.config.js
@@ -19,7 +19,7 @@ module.exports = {
'/setupTest.js',
],
transformIgnorePatterns: [
- '/node_modules/(?!(@openedx|@edx)/)',
+ '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)',
],
modulePathIgnorePatterns: [
'/dist/',
diff --git a/shell/header/helpButtonSlotOperation.test.tsx b/shell/header/helpButtonSlotOperation.test.tsx
index 3311f41f..9aac7aaf 100644
--- a/shell/header/helpButtonSlotOperation.test.tsx
+++ b/shell/header/helpButtonSlotOperation.test.tsx
@@ -19,6 +19,8 @@ describe('helpButtonSlotOperation', () => {
mergeAppConfig(TEST_APP_ID, { SUPPORT_URL: 'https://help.example.com/test' });
const op = helpButtonSlotOperation({ appId: TEST_APP_ID, role: TEST_ROLE });
+ // The following is for TypeScript, since `WidgetRendererProps` sometimes has 'element' and sometimes 'component'.
+ if (!('element' in op)) throw new Error(`Expected ${JSON.stringify(op)} to have an 'element'.`);
expect(isValidElement(op.element)).toBe(true);
const getUrl = (op.element as React.ReactElement<{ getUrl: () => string | undefined }>).props.getUrl;
diff --git a/shell/jest.config.js b/shell/jest.config.js
index 706927c3..20f2b543 100644
--- a/shell/jest.config.js
+++ b/shell/jest.config.js
@@ -20,7 +20,7 @@ module.exports = {
'setupTest.js',
],
transformIgnorePatterns: [
- '/node_modules/(?!(@openedx|@edx)/)',
+ '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)',
],
testPathIgnorePatterns: [
'/site.config.test.tsx',
diff --git a/tools/jest.config.js b/tools/jest.config.js
index af945138..d2c14450 100644
--- a/tools/jest.config.js
+++ b/tools/jest.config.js
@@ -7,7 +7,7 @@ module.exports = {
'cli/**/*.{js,jsx,ts,tsx}',
],
transformIgnorePatterns: [
- '/node_modules/(?!(@openedx|@edx)/)',
+ '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)',
],
modulePathIgnorePatterns: [
'/dist/',
diff --git a/tools/jest/jest.config.js b/tools/jest/jest.config.js
index f601ce3e..017f4243 100644
--- a/tools/jest/jest.config.js
+++ b/tools/jest/jest.config.js
@@ -17,7 +17,7 @@ module.exports = {
'/node_modules/',
],
transformIgnorePatterns: [
- '/node_modules/(?!(@openedx|@edx)/)',
+ '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)',
],
modulePathIgnorePatterns: [
'/dist/',