mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2025-06-26 21:30:33 -04:00
refactor: [UEPR-55] updated react-intl from v2 to v6
This commit is contained in:
parent
5f12985de8
commit
fed5087e9d
13 changed files with 476 additions and 343 deletions
package-lock.jsonpackage.json
src
components
color-picker
coming-soon
fixed-tools
mode-tools
paint-editor
tool-select-base
containers
lib
playground/reducers
test/__mocks__
webpack.config.js
206
package-lock.json
generated
206
package-lock.json
generated
|
@ -54,7 +54,7 @@
|
||||||
"raf": "3.4.1",
|
"raf": "3.4.1",
|
||||||
"react": "16.14.0",
|
"react": "16.14.0",
|
||||||
"react-dom": "16.14.0",
|
"react-dom": "16.14.0",
|
||||||
"react-intl": "2.9.0",
|
"react-intl": "^6.6.8",
|
||||||
"react-intl-redux": "2.4.1",
|
"react-intl-redux": "2.4.1",
|
||||||
"react-popover": "0.5.10",
|
"react-popover": "0.5.10",
|
||||||
"react-redux": "5.1.2",
|
"react-redux": "5.1.2",
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^16",
|
"react": "^16",
|
||||||
"react-dom": "^16",
|
"react-dom": "^16",
|
||||||
"react-intl": "^2",
|
"react-intl": "^6",
|
||||||
"react-intl-redux": "^0.7 || ^2.0.0",
|
"react-intl-redux": "^0.7 || ^2.0.0",
|
||||||
"react-popover": "^0.5",
|
"react-popover": "^0.5",
|
||||||
"react-redux": "^5",
|
"react-redux": "^5",
|
||||||
|
@ -2829,6 +2829,100 @@
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@formatjs/ecma402-abstract": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/intl-localematcher": "0.5.4",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/fast-memoize": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/icu-messageformat-parser": {
|
||||||
|
"version": "2.7.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz",
|
||||||
|
"integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"@formatjs/icu-skeleton-parser": "1.8.2",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/icu-skeleton-parser": {
|
||||||
|
"version": "1.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz",
|
||||||
|
"integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/intl": {
|
||||||
|
"version": "2.10.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.4.tgz",
|
||||||
|
"integrity": "sha512-56483O+HVcL0c7VucAS2tyH020mt9XTozZO67cwtGg0a7KWDukS/FzW3OnvaHmTHDuYsoPIzO+ZHVfU6fT/bJw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"@formatjs/fast-memoize": "2.2.0",
|
||||||
|
"@formatjs/icu-messageformat-parser": "2.7.8",
|
||||||
|
"@formatjs/intl-displaynames": "6.6.8",
|
||||||
|
"@formatjs/intl-listformat": "7.5.7",
|
||||||
|
"intl-messageformat": "10.5.14",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^4.7 || 5"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/intl-displaynames": {
|
||||||
|
"version": "6.6.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-6.6.8.tgz",
|
||||||
|
"integrity": "sha512-Lgx6n5KxN16B3Pb05z3NLEBQkGoXnGjkTBNCZI+Cn17YjHJ3fhCeEJJUqRlIZmJdmaXQhjcQVDp6WIiNeRYT5g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"@formatjs/intl-localematcher": "0.5.4",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/intl-listformat": {
|
||||||
|
"version": "7.5.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-7.5.7.tgz",
|
||||||
|
"integrity": "sha512-MG2TSChQJQT9f7Rlv+eXwUFiG24mKSzmF144PLb8m8OixyXqn4+YWU+5wZracZGCgVTVmx8viCf7IH3QXoiB2g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"@formatjs/intl-localematcher": "0.5.4",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/intl-localematcher": {
|
||||||
|
"version": "0.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||||
|
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.14",
|
"version": "0.11.14",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||||
|
@ -5482,6 +5576,16 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/hoist-non-react-statics": {
|
||||||
|
"version": "3.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
|
||||||
|
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/istanbul-lib-coverage": {
|
"node_modules/@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
||||||
|
@ -5565,6 +5669,22 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/prop-types": {
|
||||||
|
"version": "15.7.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
||||||
|
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/react": {
|
||||||
|
"version": "18.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.6.tgz",
|
||||||
|
"integrity": "sha512-CnGaRYNu2iZlkGXGrOYtdg5mLK8neySj0woZ4e2wF/eli2E6Sazmq5X+Nrj6OBrrFVQfJWTUFeqAzoRhWQXYvg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/stack-utils": {
|
"node_modules/@types/stack-utils": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
||||||
|
@ -9183,6 +9303,12 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/csstype": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/cyclist": {
|
"node_modules/cyclist": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz",
|
||||||
|
@ -14965,21 +15091,16 @@
|
||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/intl-format-cache": {
|
|
||||||
"version": "2.2.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/intl-format-cache/-/intl-format-cache-2.2.9.tgz",
|
|
||||||
"integrity": "sha512-Zv/u8wRpekckv0cLkwpVdABYST4hZNTDaX7reFetrYTJwxExR2VyTqQm+l0WmL0Qo8Mjb9Tf33qnfj0T7pjxdQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/intl-messageformat": {
|
"node_modules/intl-messageformat": {
|
||||||
"version": "2.2.0",
|
"version": "10.5.14",
|
||||||
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.14.tgz",
|
||||||
"integrity": "sha512-I+tSvHnXqJYjDfNmY95tpFMj30yoakC6OXAo+wu/wTMy6tA/4Fd4mvV7Uzs4cqK/Ap29sHhwjcY+78a8eifcXw==",
|
"integrity": "sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"intl-messageformat-parser": "1.4.0"
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
|
"@formatjs/fast-memoize": "2.2.0",
|
||||||
|
"@formatjs/icu-messageformat-parser": "2.7.8",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/intl-messageformat-parser": {
|
"node_modules/intl-messageformat-parser": {
|
||||||
|
@ -14990,25 +15111,6 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/intl-messageformat/node_modules/intl-messageformat-parser": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-/XkqFHKezO6UcF4Av2/Lzfrez18R0jyw7kRFhSeB/YRakdrgSc9QfFZUwNJI9swMwMoNPygK1ArC5wdFSjPw+A==",
|
|
||||||
"deprecated": "We've written a new parser that's 6x faster and is backwards compatible. Please use @formatjs/icu-messageformat-parser",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/intl-relativeformat": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/intl-relativeformat/-/intl-relativeformat-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-4bV/7kSKaPEmu6ArxXf9xjv1ny74Zkwuey8Pm01NH4zggPP7JHwg2STk8Y3JdspCKRDriwIyLRfEXnj2ZLr4Bw==",
|
|
||||||
"deprecated": "This package has been deprecated, please see migration guide at 'https://github.com/formatjs/formatjs/tree/master/packages/intl-relativeformat#migration-guide'",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"intl-messageformat": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/into-stream": {
|
"node_modules/into-stream": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz",
|
||||||
|
@ -26408,21 +26510,30 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-intl": {
|
"node_modules/react-intl": {
|
||||||
"version": "2.9.0",
|
"version": "6.6.8",
|
||||||
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.8.tgz",
|
||||||
"integrity": "sha512-27jnDlb/d2A7mSJwrbOBnUgD+rPep+abmoJE511Tf8BnoONIAUehy/U1zZCHGO17mnOwMWxqN4qC0nW11cD6rA==",
|
"integrity": "sha512-M0pkhzcgV31h++2901BiRXWl69hp2zPyLxRrSwRjd1ErXbNoubz/f4M6DrRTd4OiSUrT4ajRQzrmtS5plG4FtA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hoist-non-react-statics": "^3.3.0",
|
"@formatjs/ecma402-abstract": "2.0.0",
|
||||||
"intl-format-cache": "^2.0.5",
|
"@formatjs/icu-messageformat-parser": "2.7.8",
|
||||||
"intl-messageformat": "^2.1.0",
|
"@formatjs/intl": "2.10.4",
|
||||||
"intl-relativeformat": "^2.1.0",
|
"@formatjs/intl-displaynames": "6.6.8",
|
||||||
"invariant": "^2.1.1"
|
"@formatjs/intl-listformat": "7.5.7",
|
||||||
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
|
"@types/react": "16 || 17 || 18",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"intl-messageformat": "10.5.14",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"prop-types": "^15.5.4",
|
"react": "^16.6.0 || 17 || 18",
|
||||||
"react": "^0.14.9 || ^15.0.0 || ^16.0.0"
|
"typescript": "^4.7 || 5"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-intl-redux": {
|
"node_modules/react-intl-redux": {
|
||||||
|
@ -26430,7 +26541,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-intl-redux/-/react-intl-redux-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-intl-redux/-/react-intl-redux-2.4.1.tgz",
|
||||||
"integrity": "sha512-EYTNmHJTnTam4phQj1nTdJvcdVjz+F56nLl6JtpqWsKzG5ZnQh/hoqLLJUjP0dgeNKSESIcjhYsTyBWDUwjo0A==",
|
"integrity": "sha512-EYTNmHJTnTam4phQj1nTdJvcdVjz+F56nLl6JtpqWsKzG5ZnQh/hoqLLJUjP0dgeNKSESIcjhYsTyBWDUwjo0A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.17.9",
|
"@babel/runtime": "^7.17.9",
|
||||||
"prop-types": "^15.8.1"
|
"prop-types": "^15.8.1"
|
||||||
|
@ -31912,6 +32022,12 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/tty-browserify": {
|
"node_modules/tty-browserify": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^16",
|
"react": "^16",
|
||||||
"react-dom": "^16",
|
"react-dom": "^16",
|
||||||
"react-intl": "^2",
|
"react-intl": "^6",
|
||||||
"react-intl-redux": "^0.7 || ^2.0.0",
|
"react-intl-redux": "^0.7 || ^2.0.0",
|
||||||
"react-popover": "^0.5",
|
"react-popover": "^0.5",
|
||||||
"react-redux": "^5",
|
"react-redux": "^5",
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
"raf": "3.4.1",
|
"raf": "3.4.1",
|
||||||
"react": "16.14.0",
|
"react": "16.14.0",
|
||||||
"react-dom": "16.14.0",
|
"react-dom": "16.14.0",
|
||||||
"react-intl": "2.9.0",
|
"react-intl": "^6.6.8",
|
||||||
"react-intl-redux": "2.4.1",
|
"react-intl-redux": "2.4.1",
|
||||||
"react-popover": "0.5.10",
|
"react-popover": "0.5.10",
|
||||||
"react-redux": "5.1.2",
|
"react-redux": "5.1.2",
|
||||||
|
@ -121,7 +121,10 @@
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/__mocks__/fileMock.js",
|
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/__mocks__/fileMock.js",
|
||||||
"\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
|
"\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
|
||||||
}
|
},
|
||||||
|
"transformIgnorePatterns": [
|
||||||
|
"/node_modules/(?!intl-messageformat|intl-messageformat-parser).+\\.js$"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"jest-junit": {
|
"jest-junit": {
|
||||||
"outputDirectory": "./test/results"
|
"outputDirectory": "./test/results"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-intl';
|
import {defineMessages, FormattedMessage, injectIntl} from 'react-intl';
|
||||||
|
import intlShape from '../../lib/intl-shape.js';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import parseColor from 'parse-color';
|
import parseColor from 'parse-color';
|
||||||
|
|
|
@ -4,7 +4,8 @@ See #13 */
|
||||||
|
|
||||||
import bindAll from 'lodash.bindall';
|
import bindAll from 'lodash.bindall';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-intl';
|
import {defineMessages, injectIntl, FormattedMessage} from 'react-intl';
|
||||||
|
import intlShape from '../../lib/intl-shape.js';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactTooltip from 'react-tooltip';
|
import ReactTooltip from 'react-tooltip';
|
||||||
|
|
|
@ -11,7 +11,7 @@ import BufferedInputHOC from '../forms/buffered-input-hoc.jsx';
|
||||||
import Button from '../button/button.jsx';
|
import Button from '../button/button.jsx';
|
||||||
import ButtonGroup from '../button-group/button-group.jsx';
|
import ButtonGroup from '../button-group/button-group.jsx';
|
||||||
import Dropdown from '../dropdown/dropdown.jsx';
|
import Dropdown from '../dropdown/dropdown.jsx';
|
||||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
import {defineMessages, useIntl} from 'react-intl';
|
||||||
import Formats, {isVector} from '../../lib/format';
|
import Formats, {isVector} from '../../lib/format';
|
||||||
import Input from '../forms/input.jsx';
|
import Input from '../forms/input.jsx';
|
||||||
import InputGroup from '../input-group/input-group.jsx';
|
import InputGroup from '../input-group/input-group.jsx';
|
||||||
|
@ -87,13 +87,14 @@ const messages = defineMessages({
|
||||||
const FixedToolsComponent = props => {
|
const FixedToolsComponent = props => {
|
||||||
const redoDisabled = !props.canRedo();
|
const redoDisabled = !props.canRedo();
|
||||||
const undoDisabled = !props.canUndo();
|
const undoDisabled = !props.canUndo();
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
{/* Name field */}
|
{/* Name field */}
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<MediaQuery minWidth={layout.fullSizeEditorMinWidth}>
|
<MediaQuery minWidth={layout.fullSizeEditorMinWidth}>
|
||||||
<Label text={props.intl.formatMessage(messages.costume)}>
|
<Label text={intl.formatMessage(messages.costume)}>
|
||||||
<BufferedInput
|
<BufferedInput
|
||||||
className={styles.costumeInput}
|
className={styles.costumeInput}
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -128,7 +129,7 @@ const FixedToolsComponent = props => {
|
||||||
onClick={props.onUndo}
|
onClick={props.onUndo}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt={props.intl.formatMessage(messages.undo)}
|
alt={intl.formatMessage(messages.undo)}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
styles.buttonGroupButtonIcon,
|
styles.buttonGroupButtonIcon,
|
||||||
styles.undoIcon
|
styles.undoIcon
|
||||||
|
@ -150,7 +151,7 @@ const FixedToolsComponent = props => {
|
||||||
onClick={props.onRedo}
|
onClick={props.onRedo}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt={props.intl.formatMessage(messages.redo)}
|
alt={intl.formatMessage(messages.redo)}
|
||||||
className={styles.buttonGroupButtonIcon}
|
className={styles.buttonGroupButtonIcon}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
src={redoIcon}
|
src={redoIcon}
|
||||||
|
@ -164,16 +165,16 @@ const FixedToolsComponent = props => {
|
||||||
<InputGroup className={styles.modDashedBorder}>
|
<InputGroup className={styles.modDashedBorder}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!shouldShowGroup()}
|
disabled={!shouldShowGroup()}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={groupIcon}
|
imgSrc={groupIcon}
|
||||||
title={props.intl.formatMessage(messages.group)}
|
title={intl.formatMessage(messages.group)}
|
||||||
onClick={props.onGroup}
|
onClick={props.onGroup}
|
||||||
/>
|
/>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!shouldShowUngroup()}
|
disabled={!shouldShowUngroup()}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={ungroupIcon}
|
imgSrc={ungroupIcon}
|
||||||
title={props.intl.formatMessage(messages.ungroup)}
|
title={intl.formatMessage(messages.ungroup)}
|
||||||
onClick={props.onUngroup}
|
onClick={props.onUngroup}
|
||||||
/>
|
/>
|
||||||
</InputGroup> : null
|
</InputGroup> : null
|
||||||
|
@ -184,16 +185,16 @@ const FixedToolsComponent = props => {
|
||||||
<InputGroup className={styles.modDashedBorder}>
|
<InputGroup className={styles.modDashedBorder}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!shouldShowBringForward()}
|
disabled={!shouldShowBringForward()}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={sendForwardIcon}
|
imgSrc={sendForwardIcon}
|
||||||
title={props.intl.formatMessage(messages.forward)}
|
title={intl.formatMessage(messages.forward)}
|
||||||
onClick={props.onSendForward}
|
onClick={props.onSendForward}
|
||||||
/>
|
/>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!shouldShowSendBackward()}
|
disabled={!shouldShowSendBackward()}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={sendBackwardIcon}
|
imgSrc={sendBackwardIcon}
|
||||||
title={props.intl.formatMessage(messages.backward)}
|
title={intl.formatMessage(messages.backward)}
|
||||||
onClick={props.onSendBackward}
|
onClick={props.onSendBackward}
|
||||||
/>
|
/>
|
||||||
</InputGroup> : null
|
</InputGroup> : null
|
||||||
|
@ -204,16 +205,16 @@ const FixedToolsComponent = props => {
|
||||||
<InputGroup className={styles.row}>
|
<InputGroup className={styles.row}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!shouldShowBringForward()}
|
disabled={!shouldShowBringForward()}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={sendFrontIcon}
|
imgSrc={sendFrontIcon}
|
||||||
title={props.intl.formatMessage(messages.front)}
|
title={intl.formatMessage(messages.front)}
|
||||||
onClick={props.onSendToFront}
|
onClick={props.onSendToFront}
|
||||||
/>
|
/>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!shouldShowSendBackward()}
|
disabled={!shouldShowSendBackward()}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={sendBackIcon}
|
imgSrc={sendBackIcon}
|
||||||
title={props.intl.formatMessage(messages.back)}
|
title={intl.formatMessage(messages.back)}
|
||||||
onClick={props.onSendToBack}
|
onClick={props.onSendToBack}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
@ -252,7 +253,7 @@ const FixedToolsComponent = props => {
|
||||||
draggable={false}
|
draggable={false}
|
||||||
src={sendFrontIcon}
|
src={sendFrontIcon}
|
||||||
/>
|
/>
|
||||||
<span>{props.intl.formatMessage(messages.front)}</span>
|
<span>{intl.formatMessage(messages.front)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className={classNames(styles.modMenuItem, {
|
className={classNames(styles.modMenuItem, {
|
||||||
|
@ -266,7 +267,7 @@ const FixedToolsComponent = props => {
|
||||||
draggable={false}
|
draggable={false}
|
||||||
src={sendBackIcon}
|
src={sendBackIcon}
|
||||||
/>
|
/>
|
||||||
<span>{props.intl.formatMessage(messages.back)}</span>
|
<span>{intl.formatMessage(messages.back)}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* To be rotation point */}
|
{/* To be rotation point */}
|
||||||
|
@ -285,7 +286,7 @@ const FixedToolsComponent = props => {
|
||||||
}
|
}
|
||||||
tipSize={.01}
|
tipSize={.01}
|
||||||
>
|
>
|
||||||
{props.intl.formatMessage(messages.more)}
|
{intl.formatMessage(messages.more)}
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</MediaQuery> : null
|
</MediaQuery> : null
|
||||||
|
@ -298,7 +299,6 @@ FixedToolsComponent.propTypes = {
|
||||||
canRedo: PropTypes.func.isRequired,
|
canRedo: PropTypes.func.isRequired,
|
||||||
canUndo: PropTypes.func.isRequired,
|
canUndo: PropTypes.func.isRequired,
|
||||||
format: PropTypes.oneOf(Object.keys(Formats)),
|
format: PropTypes.oneOf(Object.keys(Formats)),
|
||||||
intl: intlShape,
|
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
onGroup: PropTypes.func.isRequired,
|
onGroup: PropTypes.func.isRequired,
|
||||||
onRedo: PropTypes.func.isRequired,
|
onRedo: PropTypes.func.isRequired,
|
||||||
|
@ -321,4 +321,4 @@ const mapStateToProps = state => ({
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps
|
mapStateToProps
|
||||||
)(injectIntl(FixedToolsComponent));
|
)(FixedToolsComponent);
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {setShapesFilled} from '../../reducers/fill-bitmap-shapes';
|
||||||
import FontDropdown from '../../containers/font-dropdown.jsx';
|
import FontDropdown from '../../containers/font-dropdown.jsx';
|
||||||
import LiveInputHOC from '../forms/live-input-hoc.jsx';
|
import LiveInputHOC from '../forms/live-input-hoc.jsx';
|
||||||
import Label from '../forms/label.jsx';
|
import Label from '../forms/label.jsx';
|
||||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
import {defineMessages, useIntl} from 'react-intl';
|
||||||
import Input from '../forms/input.jsx';
|
import Input from '../forms/input.jsx';
|
||||||
import InputGroup from '../input-group/input-group.jsx';
|
import InputGroup from '../input-group/input-group.jsx';
|
||||||
import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx';
|
import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx';
|
||||||
|
@ -43,6 +43,7 @@ import {MAX_STROKE_WIDTH} from '../../reducers/stroke-width';
|
||||||
|
|
||||||
const LiveInput = LiveInputHOC(Input);
|
const LiveInput = LiveInputHOC(Input);
|
||||||
const ModeToolsComponent = props => {
|
const ModeToolsComponent = props => {
|
||||||
|
const intl = useIntl();
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
brushSize: {
|
brushSize: {
|
||||||
defaultMessage: 'Size',
|
defaultMessage: 'Size',
|
||||||
|
@ -122,7 +123,7 @@ const ModeToolsComponent = props => {
|
||||||
<div className={classNames(props.className, styles.modeTools)}>
|
<div className={classNames(props.className, styles.modeTools)}>
|
||||||
<div>
|
<div>
|
||||||
<img
|
<img
|
||||||
alt={props.intl.formatMessage(currentMessage)}
|
alt={intl.formatMessage(currentMessage)}
|
||||||
className={styles.modeToolsIcon}
|
className={styles.modeToolsIcon}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
src={currentIcon}
|
src={currentIcon}
|
||||||
|
@ -151,7 +152,7 @@ const ModeToolsComponent = props => {
|
||||||
<div className={classNames(props.className, styles.modeTools)}>
|
<div className={classNames(props.className, styles.modeTools)}>
|
||||||
<div>
|
<div>
|
||||||
<img
|
<img
|
||||||
alt={props.intl.formatMessage(messages.eraserSize)}
|
alt={intl.formatMessage(messages.eraserSize)}
|
||||||
className={styles.modeToolsIcon}
|
className={styles.modeToolsIcon}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
src={currentIcon}
|
src={currentIcon}
|
||||||
|
@ -175,24 +176,24 @@ const ModeToolsComponent = props => {
|
||||||
<InputGroup className={classNames(styles.modDashedBorder, styles.modLabeledIconHeight)}>
|
<InputGroup className={classNames(styles.modDashedBorder, styles.modLabeledIconHeight)}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!props.hasSelectedUncurvedPoints}
|
disabled={!props.hasSelectedUncurvedPoints}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={curvedPointIcon}
|
imgSrc={curvedPointIcon}
|
||||||
title={props.intl.formatMessage(messages.curved)}
|
title={intl.formatMessage(messages.curved)}
|
||||||
onClick={props.onCurvePoints}
|
onClick={props.onCurvePoints}
|
||||||
/>
|
/>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!props.hasSelectedUnpointedPoints}
|
disabled={!props.hasSelectedUnpointedPoints}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={straightPointIcon}
|
imgSrc={straightPointIcon}
|
||||||
title={props.intl.formatMessage(messages.pointed)}
|
title={intl.formatMessage(messages.pointed)}
|
||||||
onClick={props.onPointPoints}
|
onClick={props.onPointPoints}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<InputGroup className={classNames(styles.modLabeledIconHeight)}>
|
<InputGroup className={classNames(styles.modLabeledIconHeight)}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={deleteIcon}
|
imgSrc={deleteIcon}
|
||||||
title={props.intl.formatMessage(messages.delete)}
|
title={intl.formatMessage(messages.delete)}
|
||||||
onClick={props.onDelete}
|
onClick={props.onDelete}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
@ -205,38 +206,38 @@ const ModeToolsComponent = props => {
|
||||||
<div className={classNames(props.className, styles.modeTools)}>
|
<div className={classNames(props.className, styles.modeTools)}>
|
||||||
<InputGroup className={classNames(styles.modDashedBorder, styles.modLabeledIconHeight)}>
|
<InputGroup className={classNames(styles.modDashedBorder, styles.modLabeledIconHeight)}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={copyIcon}
|
imgSrc={copyIcon}
|
||||||
title={props.intl.formatMessage(messages.copy)}
|
title={intl.formatMessage(messages.copy)}
|
||||||
onClick={props.onCopyToClipboard}
|
onClick={props.onCopyToClipboard}
|
||||||
/>
|
/>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
disabled={!(props.clipboardItems.length > 0)}
|
disabled={!(props.clipboardItems.length > 0)}
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={pasteIcon}
|
imgSrc={pasteIcon}
|
||||||
title={props.intl.formatMessage(messages.paste)}
|
title={intl.formatMessage(messages.paste)}
|
||||||
onClick={props.onPasteFromClipboard}
|
onClick={props.onPasteFromClipboard}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<InputGroup className={classNames(styles.modDashedBorder, styles.modLabeledIconHeight)}>
|
<InputGroup className={classNames(styles.modDashedBorder, styles.modLabeledIconHeight)}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
hideLabel={hideLabel(props.intl.locale)}
|
hideLabel={hideLabel(intl.locale)}
|
||||||
imgSrc={deleteIcon}
|
imgSrc={deleteIcon}
|
||||||
title={props.intl.formatMessage(messages.delete)}
|
title={intl.formatMessage(messages.delete)}
|
||||||
onClick={props.onDelete}
|
onClick={props.onDelete}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<InputGroup className={classNames(styles.modLabeledIconHeight)}>
|
<InputGroup className={classNames(styles.modLabeledIconHeight)}>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
hideLabel={props.intl.locale !== 'en'}
|
hideLabel={intl.locale !== 'en'}
|
||||||
imgSrc={flipHorizontalIcon}
|
imgSrc={flipHorizontalIcon}
|
||||||
title={props.intl.formatMessage(messages.flipHorizontal)}
|
title={intl.formatMessage(messages.flipHorizontal)}
|
||||||
onClick={props.onFlipHorizontal}
|
onClick={props.onFlipHorizontal}
|
||||||
/>
|
/>
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
hideLabel={props.intl.locale !== 'en'}
|
hideLabel={intl.locale !== 'en'}
|
||||||
imgSrc={flipVerticalIcon}
|
imgSrc={flipVerticalIcon}
|
||||||
title={props.intl.formatMessage(messages.flipVertical)}
|
title={intl.formatMessage(messages.flipVertical)}
|
||||||
onClick={props.onFlipVertical}
|
onClick={props.onFlipVertical}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
@ -266,7 +267,7 @@ const ModeToolsComponent = props => {
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
highlighted={props.fillBitmapShapes}
|
highlighted={props.fillBitmapShapes}
|
||||||
imgSrc={fillIcon}
|
imgSrc={fillIcon}
|
||||||
title={props.intl.formatMessage(messages.filled)}
|
title={intl.formatMessage(messages.filled)}
|
||||||
onClick={props.onFillShapes}
|
onClick={props.onFillShapes}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
@ -274,13 +275,13 @@ const ModeToolsComponent = props => {
|
||||||
<LabeledIconButton
|
<LabeledIconButton
|
||||||
highlighted={!props.fillBitmapShapes}
|
highlighted={!props.fillBitmapShapes}
|
||||||
imgSrc={outlineIcon}
|
imgSrc={outlineIcon}
|
||||||
title={props.intl.formatMessage(messages.outlined)}
|
title={intl.formatMessage(messages.outlined)}
|
||||||
onClick={props.onOutlineShapes}
|
onClick={props.onOutlineShapes}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
{props.fillBitmapShapes ? null : (
|
{props.fillBitmapShapes ? null : (
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<Label text={props.intl.formatMessage(messages.thickness)}>
|
<Label text={intl.formatMessage(messages.thickness)}>
|
||||||
<LiveInput
|
<LiveInput
|
||||||
range
|
range
|
||||||
small
|
small
|
||||||
|
@ -315,7 +316,6 @@ ModeToolsComponent.propTypes = {
|
||||||
format: PropTypes.oneOf(Object.keys(Formats)),
|
format: PropTypes.oneOf(Object.keys(Formats)),
|
||||||
hasSelectedUncurvedPoints: PropTypes.bool,
|
hasSelectedUncurvedPoints: PropTypes.bool,
|
||||||
hasSelectedUnpointedPoints: PropTypes.bool,
|
hasSelectedUnpointedPoints: PropTypes.bool,
|
||||||
intl: intlShape.isRequired,
|
|
||||||
mode: PropTypes.string.isRequired,
|
mode: PropTypes.string.isRequired,
|
||||||
onBitBrushSliderChange: PropTypes.func.isRequired,
|
onBitBrushSliderChange: PropTypes.func.isRequired,
|
||||||
onBitEraserSliderChange: PropTypes.func.isRequired,
|
onBitEraserSliderChange: PropTypes.func.isRequired,
|
||||||
|
@ -367,4 +367,4 @@ const mapDispatchToProps = dispatch => ({
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps
|
||||||
)(injectIntl(ModeToolsComponent));
|
)(ModeToolsComponent);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import paper from '@scratch/paper';
|
import paper from '@scratch/paper';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
import {defineMessages, useIntl} from 'react-intl';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
@ -55,56 +55,29 @@ const messages = defineMessages({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const PaintEditorComponent = props => (
|
const PaintEditorComponent = props => {
|
||||||
<div
|
const intl = useIntl();
|
||||||
className={styles.editorContainer}
|
return (
|
||||||
dir={props.rtl ? 'rtl' : 'ltr'}
|
<div
|
||||||
>
|
className={styles.editorContainer}
|
||||||
{props.canvas !== null ? ( // eslint-disable-line no-negated-condition
|
dir={props.rtl ? 'rtl' : 'ltr'}
|
||||||
<div className={styles.editorContainerTop}>
|
>
|
||||||
{/* First row */}
|
{props.canvas !== null ? ( // eslint-disable-line no-negated-condition
|
||||||
<div className={styles.row}>
|
<div className={styles.editorContainerTop}>
|
||||||
<FixedToolsContainer
|
{/* First row */}
|
||||||
canRedo={props.canRedo}
|
|
||||||
canUndo={props.canUndo}
|
|
||||||
name={props.name}
|
|
||||||
onRedo={props.onRedo}
|
|
||||||
onUndo={props.onUndo}
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
onUpdateName={props.onUpdateName}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/* Second Row */}
|
|
||||||
{isVector(props.format) ?
|
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<InputGroup
|
<FixedToolsContainer
|
||||||
className={classNames(
|
canRedo={props.canRedo}
|
||||||
styles.row,
|
canUndo={props.canUndo}
|
||||||
styles.modDashedBorder,
|
name={props.name}
|
||||||
styles.modLabeledIconHeight
|
onRedo={props.onRedo}
|
||||||
)}
|
onUndo={props.onUndo}
|
||||||
>
|
onUpdateImage={props.onUpdateImage}
|
||||||
{/* fill */}
|
onUpdateName={props.onUpdateName}
|
||||||
<FillColorIndicatorComponent
|
/>
|
||||||
className={styles.modMarginAfter}
|
</div>
|
||||||
onUpdateImage={props.onUpdateImage}
|
{/* Second Row */}
|
||||||
/>
|
{isVector(props.format) ?
|
||||||
{/* stroke */}
|
|
||||||
<StrokeColorIndicatorComponent
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
{/* stroke width */}
|
|
||||||
<StrokeWidthIndicatorComponent
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
<InputGroup className={styles.modModeTools}>
|
|
||||||
<ModeToolsContainer
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
</div> :
|
|
||||||
isBitmap(props.format) ?
|
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<InputGroup
|
<InputGroup
|
||||||
className={classNames(
|
className={classNames(
|
||||||
|
@ -118,136 +91,151 @@ const PaintEditorComponent = props => (
|
||||||
className={styles.modMarginAfter}
|
className={styles.modMarginAfter}
|
||||||
onUpdateImage={props.onUpdateImage}
|
onUpdateImage={props.onUpdateImage}
|
||||||
/>
|
/>
|
||||||
|
{/* stroke */}
|
||||||
|
<StrokeColorIndicatorComponent
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
{/* stroke width */}
|
||||||
|
<StrokeWidthIndicatorComponent
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<InputGroup className={styles.modModeTools}>
|
<InputGroup className={styles.modModeTools}>
|
||||||
<ModeToolsContainer
|
<ModeToolsContainer
|
||||||
onUpdateImage={props.onUpdateImage}
|
onUpdateImage={props.onUpdateImage}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</div> : null
|
</div> :
|
||||||
}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div className={styles.topAlignRow}>
|
|
||||||
{/* Modes */}
|
|
||||||
{props.canvas !== null && isVector(props.format) ? ( // eslint-disable-line no-negated-condition
|
|
||||||
<div className={styles.modeSelector}>
|
|
||||||
<SelectMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<ReshapeMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<BrushMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<EraserMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<FillMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<TextMode
|
|
||||||
textArea={props.textArea}
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<LineMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<OvalMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<RectMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{props.canvas !== null && isBitmap(props.format) ? ( // eslint-disable-line no-negated-condition
|
|
||||||
<div className={styles.modeSelector}>
|
|
||||||
<BitBrushMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<BitLineMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<BitOvalMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<BitRectMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<TextMode
|
|
||||||
isBitmap
|
|
||||||
textArea={props.textArea}
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<BitFillMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<BitEraserMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<BitSelectMode
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div className={styles.controlsContainer}>
|
|
||||||
{/* Canvas */}
|
|
||||||
<ScrollableCanvas
|
|
||||||
canvas={props.canvas}
|
|
||||||
hideScrollbars={props.isEyeDropping}
|
|
||||||
style={styles.canvasContainer}
|
|
||||||
>
|
|
||||||
<PaperCanvas
|
|
||||||
canvasRef={props.setCanvas}
|
|
||||||
image={props.image}
|
|
||||||
imageFormat={props.imageFormat}
|
|
||||||
imageId={props.imageId}
|
|
||||||
rotationCenterX={props.rotationCenterX}
|
|
||||||
rotationCenterY={props.rotationCenterY}
|
|
||||||
zoomLevelId={props.zoomLevelId}
|
|
||||||
onUpdateImage={props.onUpdateImage}
|
|
||||||
/>
|
|
||||||
<textarea
|
|
||||||
className={styles.textArea}
|
|
||||||
ref={props.setTextArea}
|
|
||||||
spellCheck={false}
|
|
||||||
/>
|
|
||||||
{props.isEyeDropping &&
|
|
||||||
props.colorInfo !== null &&
|
|
||||||
!props.colorInfo.hideLoupe ? (
|
|
||||||
<Box className={styles.colorPickerWrapper}>
|
|
||||||
<Loupe
|
|
||||||
colorInfo={props.colorInfo}
|
|
||||||
pixelRatio={paper.project.view.pixelRatio}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
</ScrollableCanvas>
|
|
||||||
<div className={styles.canvasControls}>
|
|
||||||
{isVector(props.format) ?
|
|
||||||
<Button
|
|
||||||
className={styles.bitmapButton}
|
|
||||||
onClick={props.onSwitchToBitmap}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
className={styles.bitmapButtonIcon}
|
|
||||||
draggable={false}
|
|
||||||
src={bitmapIcon}
|
|
||||||
/>
|
|
||||||
<span className={styles.buttonText}>
|
|
||||||
{props.intl.formatMessage(messages.bitmap)}
|
|
||||||
</span>
|
|
||||||
</Button> :
|
|
||||||
isBitmap(props.format) ?
|
isBitmap(props.format) ?
|
||||||
|
<div className={styles.row}>
|
||||||
|
<InputGroup
|
||||||
|
className={classNames(
|
||||||
|
styles.row,
|
||||||
|
styles.modDashedBorder,
|
||||||
|
styles.modLabeledIconHeight
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{/* fill */}
|
||||||
|
<FillColorIndicatorComponent
|
||||||
|
className={styles.modMarginAfter}
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
<InputGroup className={styles.modModeTools}>
|
||||||
|
<ModeToolsContainer
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
</div> : null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<div className={styles.topAlignRow}>
|
||||||
|
{/* Modes */}
|
||||||
|
{props.canvas !== null && isVector(props.format) ? ( // eslint-disable-line no-negated-condition
|
||||||
|
<div className={styles.modeSelector}>
|
||||||
|
<SelectMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<ReshapeMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<BrushMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<EraserMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<FillMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<TextMode
|
||||||
|
textArea={props.textArea}
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<LineMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<OvalMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<RectMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{props.canvas !== null && isBitmap(props.format) ? ( // eslint-disable-line no-negated-condition
|
||||||
|
<div className={styles.modeSelector}>
|
||||||
|
<BitBrushMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<BitLineMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<BitOvalMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<BitRectMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<TextMode
|
||||||
|
isBitmap
|
||||||
|
textArea={props.textArea}
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<BitFillMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<BitEraserMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<BitSelectMode
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<div className={styles.controlsContainer}>
|
||||||
|
{/* Canvas */}
|
||||||
|
<ScrollableCanvas
|
||||||
|
canvas={props.canvas}
|
||||||
|
hideScrollbars={props.isEyeDropping}
|
||||||
|
style={styles.canvasContainer}
|
||||||
|
>
|
||||||
|
<PaperCanvas
|
||||||
|
canvasRef={props.setCanvas}
|
||||||
|
image={props.image}
|
||||||
|
imageFormat={props.imageFormat}
|
||||||
|
imageId={props.imageId}
|
||||||
|
rotationCenterX={props.rotationCenterX}
|
||||||
|
rotationCenterY={props.rotationCenterY}
|
||||||
|
zoomLevelId={props.zoomLevelId}
|
||||||
|
onUpdateImage={props.onUpdateImage}
|
||||||
|
/>
|
||||||
|
<textarea
|
||||||
|
className={styles.textArea}
|
||||||
|
ref={props.setTextArea}
|
||||||
|
spellCheck={false}
|
||||||
|
/>
|
||||||
|
{props.isEyeDropping &&
|
||||||
|
props.colorInfo !== null &&
|
||||||
|
!props.colorInfo.hideLoupe ? (
|
||||||
|
<Box className={styles.colorPickerWrapper}>
|
||||||
|
<Loupe
|
||||||
|
colorInfo={props.colorInfo}
|
||||||
|
pixelRatio={paper.project.view.pixelRatio}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
</ScrollableCanvas>
|
||||||
|
<div className={styles.canvasControls}>
|
||||||
|
{isVector(props.format) ?
|
||||||
<Button
|
<Button
|
||||||
className={styles.bitmapButton}
|
className={styles.bitmapButton}
|
||||||
onClick={props.onSwitchToVector}
|
onClick={props.onSwitchToBitmap}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
className={styles.bitmapButtonIcon}
|
className={styles.bitmapButtonIcon}
|
||||||
|
@ -255,53 +243,68 @@ const PaintEditorComponent = props => (
|
||||||
src={bitmapIcon}
|
src={bitmapIcon}
|
||||||
/>
|
/>
|
||||||
<span className={styles.buttonText}>
|
<span className={styles.buttonText}>
|
||||||
{props.intl.formatMessage(messages.vector)}
|
{intl.formatMessage(messages.bitmap)}
|
||||||
</span>
|
</span>
|
||||||
</Button> : null
|
</Button> :
|
||||||
}
|
isBitmap(props.format) ?
|
||||||
{/* Zoom controls */}
|
<Button
|
||||||
<InputGroup className={styles.zoomControls}>
|
className={styles.bitmapButton}
|
||||||
<ButtonGroup>
|
onClick={props.onSwitchToVector}
|
||||||
<Button
|
>
|
||||||
className={styles.buttonGroupButton}
|
<img
|
||||||
onClick={props.onZoomOut}
|
className={styles.bitmapButtonIcon}
|
||||||
>
|
draggable={false}
|
||||||
<img
|
src={bitmapIcon}
|
||||||
alt="Zoom Out"
|
/>
|
||||||
className={styles.buttonGroupButtonIcon}
|
<span className={styles.buttonText}>
|
||||||
draggable={false}
|
{intl.formatMessage(messages.vector)}
|
||||||
src={zoomOutIcon}
|
</span>
|
||||||
/>
|
</Button> : null
|
||||||
</Button>
|
}
|
||||||
<Button
|
{/* Zoom controls */}
|
||||||
className={styles.buttonGroupButton}
|
<InputGroup className={styles.zoomControls}>
|
||||||
onClick={props.onZoomReset}
|
<ButtonGroup>
|
||||||
>
|
<Button
|
||||||
<img
|
className={styles.buttonGroupButton}
|
||||||
alt="Zoom Reset"
|
onClick={props.onZoomOut}
|
||||||
className={styles.buttonGroupButtonIcon}
|
>
|
||||||
draggable={false}
|
<img
|
||||||
src={zoomResetIcon}
|
alt="Zoom Out"
|
||||||
/>
|
className={styles.buttonGroupButtonIcon}
|
||||||
</Button>
|
draggable={false}
|
||||||
<Button
|
src={zoomOutIcon}
|
||||||
className={styles.buttonGroupButton}
|
/>
|
||||||
onClick={props.onZoomIn}
|
</Button>
|
||||||
>
|
<Button
|
||||||
<img
|
className={styles.buttonGroupButton}
|
||||||
alt="Zoom In"
|
onClick={props.onZoomReset}
|
||||||
className={styles.buttonGroupButtonIcon}
|
>
|
||||||
draggable={false}
|
<img
|
||||||
src={zoomInIcon}
|
alt="Zoom Reset"
|
||||||
/>
|
className={styles.buttonGroupButtonIcon}
|
||||||
</Button>
|
draggable={false}
|
||||||
</ButtonGroup>
|
src={zoomResetIcon}
|
||||||
</InputGroup>
|
/>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className={styles.buttonGroupButton}
|
||||||
|
onClick={props.onZoomIn}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Zoom In"
|
||||||
|
className={styles.buttonGroupButtonIcon}
|
||||||
|
draggable={false}
|
||||||
|
src={zoomInIcon}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
</InputGroup>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
};
|
||||||
|
|
||||||
PaintEditorComponent.propTypes = {
|
PaintEditorComponent.propTypes = {
|
||||||
canRedo: PropTypes.func.isRequired,
|
canRedo: PropTypes.func.isRequired,
|
||||||
|
@ -315,7 +318,6 @@ PaintEditorComponent.propTypes = {
|
||||||
]),
|
]),
|
||||||
imageFormat: PropTypes.string,
|
imageFormat: PropTypes.string,
|
||||||
imageId: PropTypes.string,
|
imageId: PropTypes.string,
|
||||||
intl: intlShape,
|
|
||||||
isEyeDropping: PropTypes.bool,
|
isEyeDropping: PropTypes.bool,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
onRedo: PropTypes.func.isRequired,
|
onRedo: PropTypes.func.isRequired,
|
||||||
|
@ -336,4 +338,4 @@ PaintEditorComponent.propTypes = {
|
||||||
zoomLevelId: PropTypes.string
|
zoomLevelId: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export default injectIntl(PaintEditorComponent);
|
export default PaintEditorComponent;
|
||||||
|
|
|
@ -1,31 +1,34 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {injectIntl, intlShape} from 'react-intl';
|
import {useIntl} from 'react-intl';
|
||||||
|
|
||||||
import Button from '../button/button.jsx';
|
import Button from '../button/button.jsx';
|
||||||
|
|
||||||
import styles from './tool-select-base.css';
|
import styles from './tool-select-base.css';
|
||||||
|
|
||||||
const ToolSelectComponent = props => (
|
const ToolSelectComponent = props => {
|
||||||
<Button
|
const intl = useIntl();
|
||||||
className={
|
return (
|
||||||
classNames(props.className, styles.modToolSelect, {
|
<Button
|
||||||
[styles.isSelected]: props.isSelected
|
className={
|
||||||
})
|
classNames(props.className, styles.modToolSelect, {
|
||||||
}
|
[styles.isSelected]: props.isSelected
|
||||||
disabled={props.disabled}
|
})
|
||||||
title={props.intl.formatMessage(props.imgDescriptor)}
|
}
|
||||||
onClick={props.onMouseDown}
|
disabled={props.disabled}
|
||||||
>
|
title={intl.formatMessage(props.imgDescriptor)}
|
||||||
<img
|
onClick={props.onMouseDown}
|
||||||
alt={props.intl.formatMessage(props.imgDescriptor)}
|
>
|
||||||
className={styles.toolSelectIcon}
|
<img
|
||||||
draggable={false}
|
alt={intl.formatMessage(props.imgDescriptor)}
|
||||||
src={props.imgSrc}
|
className={styles.toolSelectIcon}
|
||||||
/>
|
draggable={false}
|
||||||
</Button>
|
src={props.imgSrc}
|
||||||
);
|
/>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
ToolSelectComponent.propTypes = {
|
ToolSelectComponent.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
|
@ -36,9 +39,8 @@ ToolSelectComponent.propTypes = {
|
||||||
id: PropTypes.string
|
id: PropTypes.string
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
imgSrc: PropTypes.string.isRequired,
|
imgSrc: PropTypes.string.isRequired,
|
||||||
intl: intlShape.isRequired,
|
|
||||||
isSelected: PropTypes.bool.isRequired,
|
isSelected: PropTypes.bool.isRequired,
|
||||||
onMouseDown: PropTypes.func.isRequired
|
onMouseDown: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default injectIntl(ToolSelectComponent);
|
export default ToolSelectComponent;
|
||||||
|
|
|
@ -2,7 +2,8 @@ import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import bindAll from 'lodash.bindall';
|
import bindAll from 'lodash.bindall';
|
||||||
import parseColor from 'parse-color';
|
import parseColor from 'parse-color';
|
||||||
import {injectIntl, intlShape} from 'react-intl';
|
import {injectIntl} from 'react-intl';
|
||||||
|
import intlShape from '../lib/intl-shape.js';
|
||||||
|
|
||||||
import {getSelectedLeafItems} from '../helper/selection';
|
import {getSelectedLeafItems} from '../helper/selection';
|
||||||
import Formats, {isBitmap} from '../lib/format';
|
import Formats, {isBitmap} from '../lib/format';
|
||||||
|
|
10
src/lib/intl-shape.js
Normal file
10
src/lib/intl-shape.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
// intlShape was removed in react-intl@3 and replaced with a TypeScript interface.
|
||||||
|
// These are some of the commonly used properties from the intl object.
|
||||||
|
const intlShape = PropTypes.shape({
|
||||||
|
locale: PropTypes.string.isRequired,
|
||||||
|
formatMessage: PropTypes.func.isRequired
|
||||||
|
});
|
||||||
|
|
||||||
|
export default intlShape;
|
|
@ -1,15 +1,8 @@
|
||||||
import {addLocaleData} from 'react-intl';
|
|
||||||
import {updateIntl as superUpdateIntl} from 'react-intl-redux';
|
import {updateIntl as superUpdateIntl} from 'react-intl-redux';
|
||||||
import {IntlProvider, intlReducer} from 'react-intl-redux';
|
import {IntlProvider, intlReducer} from 'react-intl-redux';
|
||||||
|
|
||||||
import localeData from 'scratch-l10n';
|
|
||||||
import paintMessages from 'scratch-l10n/locales/paint-editor-msgs';
|
import paintMessages from 'scratch-l10n/locales/paint-editor-msgs';
|
||||||
|
|
||||||
Object.keys(localeData).forEach(locale => {
|
|
||||||
// TODO: will need to handle locales not in the default intl - see www/custom-locales
|
|
||||||
addLocaleData(localeData[locale].localeData);
|
|
||||||
});
|
|
||||||
|
|
||||||
const intlInitialState = {
|
const intlInitialState = {
|
||||||
intl: {
|
intl: {
|
||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
|
|
1
test/__mocks__/react-intl.js
vendored
1
test/__mocks__/react-intl.js
vendored
|
@ -11,7 +11,6 @@ const intl = {
|
||||||
formatRelative: ({defaultMessage}) => defaultMessage,
|
formatRelative: ({defaultMessage}) => defaultMessage,
|
||||||
formatNumber: ({defaultMessage}) => defaultMessage,
|
formatNumber: ({defaultMessage}) => defaultMessage,
|
||||||
formatPlural: ({defaultMessage}) => defaultMessage,
|
formatPlural: ({defaultMessage}) => defaultMessage,
|
||||||
formatHTMLMessage: ({defaultMessage}) => defaultMessage,
|
|
||||||
now: () => 0
|
now: () => 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,12 @@ const base = {
|
||||||
rules: [{
|
rules: [{
|
||||||
test: /\.jsx?$/,
|
test: /\.jsx?$/,
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
include: path.resolve(__dirname, 'src'),
|
include: [
|
||||||
|
path.resolve(__dirname, 'src'),
|
||||||
|
path.join(__dirname, 'node_modules/react-intl'),
|
||||||
|
path.join(__dirname, 'node_modules/intl-messageformat'),
|
||||||
|
path.join(__dirname, 'node_modules/intl-messageformat-parser')
|
||||||
|
],
|
||||||
options: {
|
options: {
|
||||||
plugins: ['transform-object-rest-spread'],
|
plugins: ['transform-object-rest-spread'],
|
||||||
presets: [
|
presets: [
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue