diff --git a/packages/antd/package-lock.json b/packages/antd/package-lock.json index b125f6f0dc..e5f74612a5 100644 --- a/packages/antd/package-lock.json +++ b/packages/antd/package-lock.json @@ -3556,16 +3556,6 @@ "regenerator-runtime": "^0.13.4" } }, - "@babel/runtime-corejs2": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.13.10.tgz", - "integrity": "sha512-rZw5P1ZewO6XZTDxtXuAuAFUqfNXyM8HO/9WiaDd34Anka0uFTpo0RvBLeV775AEE/zKw3LQB+poZw/O9lrZBg==", - "dev": true, - "requires": { - "core-js": "^2.6.5", - "regenerator-runtime": "^0.13.4" - } - }, "@babel/runtime-corejs3": { "version": "7.9.2", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz", @@ -3852,22 +3842,20 @@ } }, "@rjsf/core": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-2.5.1.tgz", - "integrity": "sha512-km8NYScXNONaL5BiSLS6wyDj49pOLZtn0iXg7Zxlm921uuf3o2AAX5SuZS5kB4Zj2zlrVMrXESexfX6bxdDYHw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-3.0.0.tgz", + "integrity": "sha512-QSvyVMDiwd7neVnIMOte4tZUvtDWgLDYKOsq1tgCsIFh+RXskd3AEBf6IsK8w6Wg36Om7YalDqqrtXbk9z+rLw==", "dev": true, "requires": { - "@babel/runtime-corejs2": "^7.8.7", - "@types/json-schema": "^7.0.4", + "@types/json-schema": "^7.0.7", "ajv": "^6.7.0", - "core-js": "^2.5.7", + "core-js-pure": "^3.6.5", "json-schema-merge-allof": "^0.6.0", "jsonpointer": "^4.0.1", "lodash": "^4.17.15", + "nanoid": "^3.1.23", "prop-types": "^15.7.2", - "react-app-polyfill": "^1.0.4", - "react-is": "^16.9.0", - "shortid": "^2.2.14" + "react-is": "^16.9.0" } }, "@types/babel__core": { @@ -4459,7 +4447,8 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true + "dev": true, + "optional": true }, "asn1": { "version": "0.2.4", @@ -9592,9 +9581,9 @@ "optional": true }, "nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==", + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", "dev": true }, "nanomatch": { @@ -10906,37 +10895,6 @@ "prop-types": "^15.6.2" } }, - "react-app-polyfill": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz", - "integrity": "sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g==", - "dev": true, - "requires": { - "core-js": "^3.5.0", - "object-assign": "^4.1.1", - "promise": "^8.0.3", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.3", - "whatwg-fetch": "^3.0.0" - }, - "dependencies": { - "core-js": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.1.tgz", - "integrity": "sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA==", - "dev": true - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "requires": { - "asap": "~2.0.6" - } - } - } - }, "react-dom": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", @@ -11553,15 +11511,6 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, - "shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "dev": true, - "requires": { - "nanoid": "^2.1.0" - } - }, "side-channel": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", @@ -13244,12 +13193,6 @@ "iconv-lite": "0.4.24" } }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", - "dev": true - }, "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", diff --git a/packages/antd/package.json b/packages/antd/package.json index 988f343c59..b5e29c963a 100644 --- a/packages/antd/package.json +++ b/packages/antd/package.json @@ -28,7 +28,7 @@ }, "peerDependencies": { "@ant-design/icons": "^4.0.0", - "@rjsf/core": "^2.0.0", + "@rjsf/core": "^3.0.0", "antd": "^4.0.0", "antd-dayjs-webpack-plugin": "1.0.0", "dayjs": "^1.8.0", diff --git a/packages/antd/src/widgets/EmailWidget/index.js b/packages/antd/src/widgets/EmailWidget/index.js index 0f277b32d3..0291047e4e 100644 --- a/packages/antd/src/widgets/EmailWidget/index.js +++ b/packages/antd/src/widgets/EmailWidget/index.js @@ -1,5 +1,5 @@ import React from 'react'; - +import { utils } from '@rjsf/core'; import Input from 'antd/lib/input'; const INPUT_STYLE = { @@ -24,8 +24,7 @@ const EmailWidget = ({ }) => { const { readonlyAsDisabled = true } = formContext; - const handleChange = ({ target }) => - onChange(target.value === '' ? options.emptyValue : target.value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const handleBlur = ({ target }) => onBlur(id, target.value); @@ -37,7 +36,7 @@ const EmailWidget = ({ id={id} name={id} onBlur={!readonly ? handleBlur : undefined} - onChange={!readonly ? handleChange : undefined} + onChange={!readonly ? onEventChange : undefined} onFocus={!readonly ? handleFocus : undefined} placeholder={placeholder} style={INPUT_STYLE} diff --git a/packages/antd/src/widgets/PasswordWidget/index.js b/packages/antd/src/widgets/PasswordWidget/index.js index 6171832a1c..b928a13f6d 100644 --- a/packages/antd/src/widgets/PasswordWidget/index.js +++ b/packages/antd/src/widgets/PasswordWidget/index.js @@ -1,5 +1,5 @@ import React from 'react'; - +import {utils} from '@rjsf/core'; import Input from 'antd/lib/input'; const PasswordWidget = ({ @@ -20,10 +20,7 @@ const PasswordWidget = ({ }) => { const { readonlyAsDisabled = true } = formContext; - const emptyValue = options.emptyValue || ''; - - const handleChange = ({ target }) => - onChange(target.value === '' ? emptyValue : target.value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const handleBlur = ({ target }) => onBlur(id, target.value); @@ -35,7 +32,7 @@ const PasswordWidget = ({ id={id} name={id} onBlur={!readonly ? handleBlur : undefined} - onChange={!readonly ? handleChange : undefined} + onChange={!readonly ? onEventChange : undefined} onFocus={!readonly ? handleFocus : undefined} placeholder={placeholder} value={value || ''} diff --git a/packages/antd/src/widgets/RangeWidget/index.js b/packages/antd/src/widgets/RangeWidget/index.js index 4b58f7b28c..b8e9401799 100644 --- a/packages/antd/src/widgets/RangeWidget/index.js +++ b/packages/antd/src/widgets/RangeWidget/index.js @@ -1,8 +1,7 @@ /* eslint-disable no-else-return */ import React from 'react'; - -import { utils } from '@rjsf/core'; import Slider from 'antd/lib/slider'; +import { utils } from '@rjsf/core'; const { rangeSpec } = utils; @@ -26,10 +25,7 @@ const RangeWidget = ({ const { min, max, step } = rangeSpec(schema); - const emptyValue = options.emptyValue || ''; - - const handleChange = (nextValue) => - onChange(nextValue === '' ? emptyValue : nextValue); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const handleBlur = () => onBlur(id, value); @@ -43,7 +39,7 @@ const RangeWidget = ({ max={max} min={min} onBlur={!readonly ? handleBlur : undefined} - onChange={!readonly ? handleChange : undefined} + onChange={!readonly ? onEventChange : undefined} onFocus={!readonly ? handleFocus : undefined} placeholder={placeholder} range={false} diff --git a/packages/antd/src/widgets/TextWidget/index.js b/packages/antd/src/widgets/TextWidget/index.js index 05e64540a1..dd41fcb206 100644 --- a/packages/antd/src/widgets/TextWidget/index.js +++ b/packages/antd/src/widgets/TextWidget/index.js @@ -1,5 +1,5 @@ import React from 'react'; - +import {utils} from '@rjsf/core'; import Input from 'antd/lib/input'; import InputNumber from 'antd/lib/input-number'; @@ -27,8 +27,7 @@ const TextWidget = ({ const handleNumberChange = (nextValue) => onChange(nextValue); - const handleTextChange = ({ target }) => - onChange(target.value === '' ? options.emptyValue : target.value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const handleBlur = ({ target }) => onBlur(id, target.value); @@ -53,7 +52,7 @@ const TextWidget = ({ id={id} name={id} onBlur={!readonly ? handleBlur : undefined} - onChange={!readonly ? handleTextChange : undefined} + onChange={!readonly ? onEventChange : undefined} onFocus={!readonly ? handleFocus : undefined} placeholder={placeholder} style={INPUT_STYLE} diff --git a/packages/antd/src/widgets/TextareaWidget/index.js b/packages/antd/src/widgets/TextareaWidget/index.js index fa0f3c9bcc..49cf36513a 100644 --- a/packages/antd/src/widgets/TextareaWidget/index.js +++ b/packages/antd/src/widgets/TextareaWidget/index.js @@ -1,5 +1,5 @@ import React from 'react'; - +import {utils} from '@rjsf/core'; import Input from 'antd/lib/input'; const INPUT_STYLE = { @@ -24,8 +24,7 @@ const TextareaWidget = ({ }) => { const { readonlyAsDisabled = true } = formContext; - const handleChange = ({ target }) => - onChange(target.value === '' ? options.emptyValue : target.value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const handleBlur = ({ target }) => onBlur(id, target.value); @@ -37,7 +36,7 @@ const TextareaWidget = ({ id={id} name={id} onBlur={!readonly ? handleBlur : undefined} - onChange={!readonly ? handleChange : undefined} + onChange={!readonly ? onEventChange : undefined} onFocus={!readonly ? handleFocus : undefined} placeholder={placeholder} rows={options.rows || 4} diff --git a/packages/antd/src/widgets/URLWidget/index.js b/packages/antd/src/widgets/URLWidget/index.js index 3dab394f1f..1a7e3ba761 100644 --- a/packages/antd/src/widgets/URLWidget/index.js +++ b/packages/antd/src/widgets/URLWidget/index.js @@ -1,5 +1,5 @@ import React from 'react'; - +import {utils} from '@rjsf/core'; import Input from 'antd/lib/input'; const INPUT_STYLE = { @@ -24,8 +24,7 @@ const URLWidget = ({ }) => { const { readonlyAsDisabled = true } = formContext; - const handleChange = ({ target }) => - onChange(target.value === '' ? options.emptyValue : target.value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const handleBlur = ({ target }) => onBlur(id, target.value); @@ -37,7 +36,7 @@ const URLWidget = ({ id={id} name={id} onBlur={!readonly ? handleBlur : undefined} - onChange={!readonly ? handleChange : undefined} + onChange={!readonly ? onEventChange : undefined} onFocus={!readonly ? handleFocus : undefined} placeholder={placeholder} style={INPUT_STYLE} diff --git a/packages/bootstrap-4/package-lock.json b/packages/bootstrap-4/package-lock.json index 0fd03dad13..9edb14945c 100644 --- a/packages/bootstrap-4/package-lock.json +++ b/packages/bootstrap-4/package-lock.json @@ -1809,24 +1809,6 @@ "regenerator-runtime": "^0.13.2" } }, - "@babel/runtime-corejs2": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.13.10.tgz", - "integrity": "sha512-rZw5P1ZewO6XZTDxtXuAuAFUqfNXyM8HO/9WiaDd34Anka0uFTpo0RvBLeV775AEE/zKw3LQB+poZw/O9lrZBg==", - "dev": true, - "requires": { - "core-js": "^2.6.5", - "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true - } - } - }, "@babel/runtime-corejs3": { "version": "7.13.10", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.13.10.tgz", @@ -2481,30 +2463,20 @@ } }, "@rjsf/core": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-2.5.1.tgz", - "integrity": "sha512-km8NYScXNONaL5BiSLS6wyDj49pOLZtn0iXg7Zxlm921uuf3o2AAX5SuZS5kB4Zj2zlrVMrXESexfX6bxdDYHw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-3.0.0.tgz", + "integrity": "sha512-QSvyVMDiwd7neVnIMOte4tZUvtDWgLDYKOsq1tgCsIFh+RXskd3AEBf6IsK8w6Wg36Om7YalDqqrtXbk9z+rLw==", "dev": true, "requires": { - "@babel/runtime-corejs2": "^7.8.7", - "@types/json-schema": "^7.0.4", + "@types/json-schema": "^7.0.7", "ajv": "^6.7.0", - "core-js": "^2.5.7", + "core-js-pure": "^3.6.5", "json-schema-merge-allof": "^0.6.0", "jsonpointer": "^4.0.1", "lodash": "^4.17.15", + "nanoid": "^3.1.23", "prop-types": "^15.7.2", - "react-app-polyfill": "^1.0.4", - "react-is": "^16.9.0", - "shortid": "^2.2.14" - }, - "dependencies": { - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true - } + "react-is": "^16.9.0" } }, "@rollup/plugin-babel": { @@ -3096,12 +3068,6 @@ "function-bind": "^1.1.1" } }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -4226,12 +4192,6 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, "core-js-compat": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.3.6.tgz", @@ -8771,9 +8731,9 @@ "dev": true }, "nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==", + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", "dev": true }, "nanomatch": { @@ -9392,15 +9352,6 @@ } } }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "requires": { - "asap": "~2.0.6" - } - }, "prompts": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", @@ -9460,15 +9411,6 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, - "raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dev": true, - "requires": { - "performance-now": "^2.1.0" - } - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -9489,28 +9431,6 @@ "prop-types": "^15.6.2" } }, - "react-app-polyfill": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz", - "integrity": "sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g==", - "dev": true, - "requires": { - "core-js": "^3.5.0", - "object-assign": "^4.1.1", - "promise": "^8.0.3", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.3", - "whatwg-fetch": "^3.0.0" - }, - "dependencies": { - "core-js": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.0.tgz", - "integrity": "sha512-MQx/7TLgmmDVamSyfE+O+5BHvG1aUGj/gHhLn1wVtm2B5u1eVIPvh7vkfjwWKNCjrTJB8+He99IntSQ1qP+vYQ==", - "dev": true - } - } - }, "react-bootstrap": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.1.tgz", @@ -10379,15 +10299,6 @@ "dev": true, "optional": true }, - "shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "dev": true, - "requires": { - "nanoid": "^2.1.0" - } - }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -12438,12 +12349,6 @@ "iconv-lite": "0.4.24" } }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", - "dev": true - }, "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", diff --git a/packages/bootstrap-4/src/PasswordWidget/PasswordWidget.tsx b/packages/bootstrap-4/src/PasswordWidget/PasswordWidget.tsx index 2f5002421f..b887226438 100644 --- a/packages/bootstrap-4/src/PasswordWidget/PasswordWidget.tsx +++ b/packages/bootstrap-4/src/PasswordWidget/PasswordWidget.tsx @@ -2,7 +2,7 @@ import React from "react"; import Form from "react-bootstrap/Form"; -import { WidgetProps } from "@rjsf/core"; +import {utils, WidgetProps} from "@rjsf/core"; const PasswordWidget = ({ id, @@ -19,10 +19,7 @@ const PasswordWidget = ({ schema, rawErrors = [], }: WidgetProps) => { - const _onChange = ({ - target: { value }, - }: React.ChangeEvent) => - onChange(value === "" ? options.emptyValue : value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const _onBlur = ({ target: { value } }: React.FocusEvent) => onBlur(id, value); const _onFocus = ({ @@ -46,7 +43,7 @@ const PasswordWidget = ({ value={value ? value : ""} onFocus={_onFocus} onBlur={_onBlur} - onChange={_onChange} + onChange={onEventChange} /> ); diff --git a/packages/bootstrap-4/src/RangeWidget/RangeWidget.tsx b/packages/bootstrap-4/src/RangeWidget/RangeWidget.tsx index 2c7c9a41bc..4ff27d259e 100644 --- a/packages/bootstrap-4/src/RangeWidget/RangeWidget.tsx +++ b/packages/bootstrap-4/src/RangeWidget/RangeWidget.tsx @@ -2,8 +2,7 @@ import React from "react"; import Form from "react-bootstrap/Form"; -import { utils } from "@rjsf/core"; -import { WidgetProps } from "@rjsf/core"; +import { WidgetProps, utils } from "@rjsf/core"; const { rangeSpec } = utils; @@ -22,10 +21,7 @@ const RangeWidget = ({ }: WidgetProps) => { let sliderProps = { value, label, id, ...rangeSpec(schema) }; - const _onChange = ({ - target: { value }, - }: React.ChangeEvent) => - onChange(value === "" ? options.emptyValue : value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const _onBlur = ({ target: { value } }: React.FocusEvent) => onBlur(id, value); const _onFocus = ({ @@ -43,7 +39,7 @@ const RangeWidget = ({ required={required} disabled={disabled} readOnly={readonly} - onChange={_onChange} + onChange={onEventChange} onBlur={_onBlur} onFocus={_onFocus} {...sliderProps} diff --git a/packages/bootstrap-4/src/TextWidget/TextWidget.tsx b/packages/bootstrap-4/src/TextWidget/TextWidget.tsx index 3dfe7e968f..8bcbd19893 100644 --- a/packages/bootstrap-4/src/TextWidget/TextWidget.tsx +++ b/packages/bootstrap-4/src/TextWidget/TextWidget.tsx @@ -2,7 +2,7 @@ import React from "react"; import Form from "react-bootstrap/Form"; -import { WidgetProps } from "@rjsf/core"; +import {utils, WidgetProps} from "@rjsf/core"; export interface TextWidgetProps extends WidgetProps { type?: string; @@ -26,17 +26,14 @@ const TextWidget = ({ rawErrors = [], }: TextWidgetProps) => { - const _onChange = ({ - target: { value }, - }: React.ChangeEvent) => - onChange(value === "" ? options.emptyValue : value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const _onBlur = ({ target: { value } }: React.FocusEvent) => onBlur(id, value); const _onFocus = ({ target: { value }, }: React.FocusEvent) => onFocus(id, value); const inputType = (type || schema.type) === 'string' ? 'text' : `${type || schema.type}` - + // const classNames = [rawErrors.length > 0 ? "is-invalid" : "", type === 'file' ? 'custom-file-label': ""] return ( @@ -55,7 +52,7 @@ const TextWidget = ({ list={schema.examples ? `examples_${id}` : undefined} type={inputType} value={value || value === 0 ? value : ""} - onChange={_onChange} + onChange={onEventChange} onBlur={_onBlur} onFocus={_onFocus} diff --git a/packages/bootstrap-4/src/TextareaWidget/TextareaWidget.tsx b/packages/bootstrap-4/src/TextareaWidget/TextareaWidget.tsx index 02f47725c7..67bc700977 100644 --- a/packages/bootstrap-4/src/TextareaWidget/TextareaWidget.tsx +++ b/packages/bootstrap-4/src/TextareaWidget/TextareaWidget.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { WidgetProps } from "@rjsf/core"; +import {utils, WidgetProps} from "@rjsf/core"; import FormControl from "react-bootstrap/FormControl"; import InputGroup from "react-bootstrap/InputGroup"; @@ -24,10 +24,7 @@ const TextareaWidget = ({ schema, rawErrors = [], }: CustomWidgetProps) => { - const _onChange = ({ - target: { value }, - }: React.ChangeEvent) => - onChange(value === "" ? options.emptyValue : value); + const {onEventChange} = utils.hooks.useEmptyValueOnChange({onChange, options, value}); const _onBlur = ({ target: { value }, }: React.FocusEvent) => onBlur(id, value); @@ -58,7 +55,7 @@ const TextareaWidget = ({ required={required} autoFocus={autofocus} rows={options.rows || 5} - onChange={_onChange} + onChange={onEventChange} onBlur={_onBlur} onFocus={_onFocus} /> diff --git a/packages/bootstrap-4/test/__snapshots__/Array.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/Array.test.tsx.snap index 61d991d212..df92115825 100644 --- a/packages/bootstrap-4/test/__snapshots__/Array.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/Array.test.tsx.snap @@ -195,7 +195,6 @@ exports[`array fields fixed array 1`] = ` disabled={false} id="root_0" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -233,7 +232,6 @@ exports[`array fields fixed array 1`] = ` disabled={false} id="root_1" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} diff --git a/packages/bootstrap-4/test/__snapshots__/ColorWidget.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/ColorWidget.test.tsx.snap index 1c5ae85855..8031ac1f4d 100644 --- a/packages/bootstrap-4/test/__snapshots__/ColorWidget.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/ColorWidget.test.tsx.snap @@ -16,7 +16,6 @@ exports[`ColorWidget simple 1`] = ` disabled={false} id="_id" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={true} diff --git a/packages/bootstrap-4/test/__snapshots__/DateTimeWidget.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/DateTimeWidget.test.tsx.snap index f44369da16..5710206bb7 100644 --- a/packages/bootstrap-4/test/__snapshots__/DateTimeWidget.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/DateTimeWidget.test.tsx.snap @@ -16,7 +16,6 @@ exports[`DateTimeWidget simple 1`] = ` disabled={false} id="_id" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={true} diff --git a/packages/bootstrap-4/test/__snapshots__/DateWidget.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/DateWidget.test.tsx.snap index 0f265a23be..bdf54c047a 100644 --- a/packages/bootstrap-4/test/__snapshots__/DateWidget.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/DateWidget.test.tsx.snap @@ -16,7 +16,6 @@ exports[`DateWidget simple 1`] = ` disabled={false} id="_id" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={true} diff --git a/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap index abb92593dd..70948cfa9e 100644 --- a/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap @@ -241,7 +241,6 @@ exports[`single fields format color 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -283,7 +282,6 @@ exports[`single fields format date 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -325,7 +323,6 @@ exports[`single fields format datetime 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -437,7 +434,6 @@ exports[`single fields number field 0 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -479,7 +475,6 @@ exports[`single fields number field 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -521,7 +516,6 @@ exports[`single fields password field 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} readOnly={false} type="password" @@ -697,7 +691,6 @@ exports[`single fields string field format data-url 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -739,7 +732,6 @@ exports[`single fields string field format email 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -781,7 +773,6 @@ exports[`single fields string field format uri 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -823,7 +814,6 @@ exports[`single fields string field regular 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -865,7 +855,6 @@ exports[`single fields string field with placeholder 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="placeholder" readOnly={false} @@ -907,7 +896,6 @@ exports[`single fields textarea field 1`] = ` disabled={false} id="root" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} diff --git a/packages/bootstrap-4/test/__snapshots__/Object.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/Object.test.tsx.snap index a05eed2ea7..b6a8266b45 100644 --- a/packages/bootstrap-4/test/__snapshots__/Object.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/Object.test.tsx.snap @@ -41,7 +41,6 @@ exports[`object fields object 1`] = ` disabled={false} id="root_a" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} @@ -82,7 +81,6 @@ exports[`object fields object 1`] = ` disabled={false} id="root_b" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={false} diff --git a/packages/bootstrap-4/test/__snapshots__/TextAreaWidget.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/TextAreaWidget.test.tsx.snap index 35fa7c811a..8e2cce73aa 100644 --- a/packages/bootstrap-4/test/__snapshots__/TextAreaWidget.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/TextAreaWidget.test.tsx.snap @@ -23,7 +23,6 @@ Array [ disabled={false} id="_id" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={true} @@ -58,7 +57,6 @@ Array [ disabled={false} id="_id" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={true} @@ -86,7 +84,6 @@ Array [ disabled={false} id="_id" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={true} diff --git a/packages/bootstrap-4/test/__snapshots__/TextWidget.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/TextWidget.test.tsx.snap index 911d884845..e7c4a6289f 100644 --- a/packages/bootstrap-4/test/__snapshots__/TextWidget.test.tsx.snap +++ b/packages/bootstrap-4/test/__snapshots__/TextWidget.test.tsx.snap @@ -16,7 +16,6 @@ exports[`TextWidget simple 1`] = ` disabled={false} id="_id" onBlur={[Function]} - onChange={[Function]} onFocus={[Function]} placeholder="" readOnly={true} diff --git a/packages/core/index.d.ts b/packages/core/index.d.ts index 17f2f01875..6464b170ee 100644 --- a/packages/core/index.d.ts +++ b/packages/core/index.d.ts @@ -1,5 +1,7 @@ // Originally from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/@rjsf/core/index.d.ts +import {UseEmptyValueOnChangeProps} from "@rjsf/core"; + declare module '@rjsf/core' { import * as React from 'react'; import { JSONSchema7, JSONSchema7Definition, JSONSchema7Type, JSONSchema7TypeName } from 'json-schema'; @@ -286,6 +288,22 @@ declare module '@rjsf/core' { export module utils { + type UseEmptyValueOnChangeProps = { + onChange: (props:any) => void, + options:NonNullable, + value: any + }; + + type UseEmptyValueOnChangeReturnValue = { + onEventChange: (event: React.ChangeEvent) => void, + }; + + type UtilsHooks = { + useEmptyValueOnChange: (props: UseEmptyValueOnChangeProps) => UseEmptyValueOnChangeReturnValue; + }; + + export const hooks: UtilsHooks; + export const ADDITIONAL_PROPERTY_FLAG: string; export function canExpand(schema: JSONSchema7, uiSchema: UiSchema, formData: any): boolean; diff --git a/packages/core/package.json b/packages/core/package.json index 7b633f9680..6012476432 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -14,7 +14,7 @@ "precommit": "lint-staged", "publish-to-npm": "npm run build && npm publish", "start": "concurrently \"npm:build:* -- --watch\"", - "tdd": "cross-env NODE_ENV=test mocha --require @babel/register --watch --require ./test/setup-jsdom.js test/**/*_test.js", + "tdd": "cross-env BABEL_ENV=test NODE_ENV=test mocha --require @babel/register --watch --require ./test/setup-jsdom.js test/**/*_test.js", "test": "cross-env BABEL_ENV=test NODE_ENV=test mocha --require @babel/register --require ./test/setup-jsdom.js test/**/*_test.js", "test-coverage": "cross-env NODE_ENV=test nyc --reporter=lcov mocha --require @babel/register --require ./test/setup-jsdom.js test/**/*_test.js", "test-debug": "cross-env NODE_ENV=test mocha --require @babel/register --require ./test/setup-jsdom.js --debug-brk --inspect test/Form_test.js" diff --git a/packages/core/src/components/widgets/BaseInput.js b/packages/core/src/components/widgets/BaseInput.js index 0d728f3f45..886a5ad255 100644 --- a/packages/core/src/components/widgets/BaseInput.js +++ b/packages/core/src/components/widgets/BaseInput.js @@ -1,5 +1,6 @@ import React from "react"; import PropTypes from "prop-types"; +import { hooks } from '../../utils'; function BaseInput(props) { // Note: since React 15.2.0 we can't forward unknown element attributes, so we @@ -21,9 +22,12 @@ function BaseInput(props) { formContext, registry, rawErrors, + onChange, ...inputProps } = props; + const { eventOnChange } = hooks.useEmptyValueOnChange({ onChange, options, value }); + // If options.inputType is set use that as the input type if (options.inputType) { inputProps.type = options.inputType; @@ -62,10 +66,6 @@ function BaseInput(props) { inputProps.max = schema.maximum; } - const _onChange = ({ target: { value } }) => { - return props.onChange(value === "" ? options.emptyValue : value); - }; - return [ onBlur(inputProps.id, event.target.value))} onFocus={onFocus && (event => onFocus(inputProps.id, event.target.value))} />, diff --git a/packages/core/src/components/widgets/TextareaWidget.js b/packages/core/src/components/widgets/TextareaWidget.js index ff349e9f2f..7c7c11c57c 100644 --- a/packages/core/src/components/widgets/TextareaWidget.js +++ b/packages/core/src/components/widgets/TextareaWidget.js @@ -1,5 +1,6 @@ import React from "react"; import PropTypes from "prop-types"; +import { hooks } from '../../utils'; function TextareaWidget(props) { const { @@ -15,9 +16,7 @@ function TextareaWidget(props) { onBlur, onFocus, } = props; - const _onChange = ({ target: { value } }) => { - return onChange(value === "" ? options.emptyValue : value); - }; + const { eventOnChange } = hooks.useEmptyValueOnChange({ onChange, options, value }); return (