From 2a116fb3d20a8bf68e42c25fc97fa3e3de3ce288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Zendran?= <37419008+zendranm@users.noreply.github.com> Date: Mon, 17 Jun 2024 08:52:40 +0200 Subject: [PATCH] Deprecate `uniforms-material` theme (#1338) --- .github/labeler.yml | 5 - README.md | 1 - docs/installation.mdx | 1 - package-lock.json | 467 ---------- package.json | 2 - packages/uniforms-material/README.md | 11 - .../uniforms-material/__tests__/DateField.tsx | 93 -- .../__tests__/ErrorField.tsx | 99 --- .../__tests__/ErrorsField.tsx | 100 --- .../uniforms-material/__tests__/NestField.tsx | 98 --- .../__tests__/SelectField.tsx | 814 ------------------ .../__tests__/_createContext.ts | 38 - .../__tests__/_createSchema.ts | 6 - .../uniforms-material/__tests__/_mount.tsx | 14 - .../uniforms-material/__tests__/index.tsx | 98 --- packages/uniforms-material/package.json | 42 - packages/uniforms-material/src/AutoField.tsx | 43 - packages/uniforms-material/src/AutoFields.tsx | 37 - packages/uniforms-material/src/AutoForm.tsx | 13 - packages/uniforms-material/src/BaseForm.tsx | 13 - packages/uniforms-material/src/BoolField.tsx | 80 -- packages/uniforms-material/src/DateField.tsx | 86 -- packages/uniforms-material/src/ErrorField.tsx | 44 - .../uniforms-material/src/ErrorsField.tsx | 49 -- .../uniforms-material/src/HiddenField.tsx | 35 - .../uniforms-material/src/ListAddField.tsx | 66 -- .../uniforms-material/src/ListDelField.tsx | 53 -- packages/uniforms-material/src/ListField.tsx | 56 -- .../uniforms-material/src/ListItemField.tsx | 38 - .../uniforms-material/src/LongTextField.tsx | 48 -- packages/uniforms-material/src/NestField.tsx | 40 - packages/uniforms-material/src/NumField.tsx | 66 -- packages/uniforms-material/src/QuickForm.tsx | 28 - packages/uniforms-material/src/RadioField.tsx | 89 -- .../uniforms-material/src/SelectField.tsx | 241 ------ .../uniforms-material/src/SubmitField.tsx | 38 - packages/uniforms-material/src/TextField.tsx | 49 -- .../uniforms-material/src/ValidatedForm.tsx | 13 - .../src/ValidatedQuickForm.tsx | 5 - packages/uniforms-material/src/index.ts | 24 - packages/uniforms-material/src/types.ts | 7 - packages/uniforms-material/src/wrapField.tsx | 39 - packages/uniforms-material/tsconfig.cjs.json | 12 - packages/uniforms-material/tsconfig.esm.json | 12 - packages/uniforms/__suites__/BoolField.tsx | 79 -- reproductions/App.tsx | 1 - reproductions/package.json | 3 - tsconfig.build.json | 2 - tsconfig.global.json | 2 - website/components/ExampleCustomizer.tsx | 1 - website/components/Playground.tsx | 10 +- website/components/TutorialForm.tsx | 1 - website/lib/styles.tsx | 1 - website/lib/universal.tsx | 2 - website/package.json | 3 - website/pages-parts/LandingPage/WhyUs.tsx | 1 - 56 files changed, 3 insertions(+), 3316 deletions(-) delete mode 100644 packages/uniforms-material/README.md delete mode 100644 packages/uniforms-material/__tests__/DateField.tsx delete mode 100644 packages/uniforms-material/__tests__/ErrorField.tsx delete mode 100644 packages/uniforms-material/__tests__/ErrorsField.tsx delete mode 100644 packages/uniforms-material/__tests__/NestField.tsx delete mode 100644 packages/uniforms-material/__tests__/SelectField.tsx delete mode 100644 packages/uniforms-material/__tests__/_createContext.ts delete mode 100644 packages/uniforms-material/__tests__/_createSchema.ts delete mode 100644 packages/uniforms-material/__tests__/_mount.tsx delete mode 100644 packages/uniforms-material/__tests__/index.tsx delete mode 100644 packages/uniforms-material/package.json delete mode 100644 packages/uniforms-material/src/AutoField.tsx delete mode 100644 packages/uniforms-material/src/AutoFields.tsx delete mode 100644 packages/uniforms-material/src/AutoForm.tsx delete mode 100644 packages/uniforms-material/src/BaseForm.tsx delete mode 100644 packages/uniforms-material/src/BoolField.tsx delete mode 100644 packages/uniforms-material/src/DateField.tsx delete mode 100644 packages/uniforms-material/src/ErrorField.tsx delete mode 100644 packages/uniforms-material/src/ErrorsField.tsx delete mode 100644 packages/uniforms-material/src/HiddenField.tsx delete mode 100644 packages/uniforms-material/src/ListAddField.tsx delete mode 100644 packages/uniforms-material/src/ListDelField.tsx delete mode 100644 packages/uniforms-material/src/ListField.tsx delete mode 100644 packages/uniforms-material/src/ListItemField.tsx delete mode 100644 packages/uniforms-material/src/LongTextField.tsx delete mode 100644 packages/uniforms-material/src/NestField.tsx delete mode 100644 packages/uniforms-material/src/NumField.tsx delete mode 100644 packages/uniforms-material/src/QuickForm.tsx delete mode 100644 packages/uniforms-material/src/RadioField.tsx delete mode 100644 packages/uniforms-material/src/SelectField.tsx delete mode 100644 packages/uniforms-material/src/SubmitField.tsx delete mode 100644 packages/uniforms-material/src/TextField.tsx delete mode 100644 packages/uniforms-material/src/ValidatedForm.tsx delete mode 100644 packages/uniforms-material/src/ValidatedQuickForm.tsx delete mode 100644 packages/uniforms-material/src/index.ts delete mode 100644 packages/uniforms-material/src/types.ts delete mode 100644 packages/uniforms-material/src/wrapField.tsx delete mode 100644 packages/uniforms-material/tsconfig.cjs.json delete mode 100644 packages/uniforms-material/tsconfig.esm.json diff --git a/.github/labeler.yml b/.github/labeler.yml index 0abe2cf83..21aa9a92f 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -43,7 +43,6 @@ - packages/uniforms-antd/**/* - packages/uniforms-bootstrap4/**/* - packages/uniforms-bootstrap5/**/* - - packages/uniforms-material/**/* - packages/uniforms-mui/**/* - packages/uniforms-semantic/**/* - packages/uniforms-unstyled/**/* @@ -71,10 +70,6 @@ - changed-files: - any-glob-to-any-file: - packages/uniforms-bootstrap5/**/* -'Theme: Material-UI': - - changed-files: - - any-glob-to-any-file: - - packages/uniforms-material/**/* 'Theme: MUI': - changed-files: - any-glob-to-any-file: diff --git a/README.md b/README.md index d91b76155..cd0b05a9b 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,6 @@ - **[AntD](https://ant.design/) theme** - **[Bootstrap4](https://getbootstrap.com/docs/4.6) theme** - **[Bootstrap5](https://getbootstrap.com/) theme** - - **[Material](https://v4.mui.com/) theme** - **[MUI](https://mui.com/) theme** - **[Semantic UI](http://semantic-ui.com/) theme** - **plain HTML theme** diff --git a/docs/installation.mdx b/docs/installation.mdx index 2ed1a9ccf..7fa7b97df 100644 --- a/docs/installation.mdx +++ b/docs/installation.mdx @@ -35,7 +35,6 @@ Now the schema package. group="theme" tabs={[ { name: 'Semantic' }, - { name: 'Material' }, { name: 'MUI' }, { name: 'Bootstrap4' }, { name: 'Bootstrap5' }, diff --git a/package-lock.json b/package-lock.json index 1c76069dc..a8c273b0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,6 @@ "@docusaurus/preset-classic": "2.1.0", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@material-ui/core": "4.11.2", - "@material-ui/icons": "4.11.2", "@mui/material": "5.4.1", "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "12.1.5", @@ -4981,172 +4979,6 @@ "win32" ] }, - "node_modules/@material-ui/core": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.2.tgz", - "integrity": "sha512-/D1+AQQeYX/WhT/FUk78UCRj8ch/RCglsQLYujYTIqPSJlwZHKcvHidNeVhODXeApojeXjkl0tWdk5C9ofwOkQ==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "@material-ui/styles": "^4.11.2", - "@material-ui/system": "^4.11.2", - "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.11.2", - "@types/react-transition-group": "^4.2.0", - "clsx": "^1.0.4", - "hoist-non-react-statics": "^3.3.2", - "popper.js": "1.16.1-lts", - "prop-types": "^15.7.2", - "react-is": "^16.8.0 || ^17.0.0", - "react-transition-group": "^4.4.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/material-ui" - }, - "peerDependencies": { - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@material-ui/icons": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz", - "integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==", - "dependencies": { - "@babel/runtime": "^7.4.4" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "@material-ui/core": "^4.0.0", - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@material-ui/styles": { - "version": "4.11.4", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz", - "integrity": "sha512-KNTIZcnj/zprG5LW0Sao7zw+yG3O35pviHzejMdcSGCdWbiO8qzRgOYL8JAxAsWBKOKYwVZxXtHWaB5T2Kvxew==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "@emotion/hash": "^0.8.0", - "@material-ui/types": "5.1.0", - "@material-ui/utils": "^4.11.2", - "clsx": "^1.0.4", - "csstype": "^2.5.2", - "hoist-non-react-statics": "^3.3.2", - "jss": "^10.5.1", - "jss-plugin-camel-case": "^10.5.1", - "jss-plugin-default-unit": "^10.5.1", - "jss-plugin-global": "^10.5.1", - "jss-plugin-nested": "^10.5.1", - "jss-plugin-props-sort": "^10.5.1", - "jss-plugin-rule-value-function": "^10.5.1", - "jss-plugin-vendor-prefixer": "^10.5.1", - "prop-types": "^15.7.2" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/material-ui" - }, - "peerDependencies": { - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@material-ui/styles/node_modules/csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" - }, - "node_modules/@material-ui/system": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.1.tgz", - "integrity": "sha512-lUdzs4q9kEXZGhbN7BptyiS1rLNHe6kG9o8Y307HCvF4sQxbCgpL2qi+gUk+yI8a2DNk48gISEQxoxpgph0xIw==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "@material-ui/utils": "^4.11.2", - "csstype": "^2.5.2", - "prop-types": "^15.7.2" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/material-ui" - }, - "peerDependencies": { - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@material-ui/system/node_modules/csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" - }, - "node_modules/@material-ui/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", - "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==", - "peerDependencies": { - "@types/react": "*" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@material-ui/utils": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz", - "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "prop-types": "^15.7.2", - "react-is": "^16.8.0 || ^17.0.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" - } - }, "node_modules/@mdx-js/mdx": { "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", @@ -12754,15 +12586,6 @@ "node": ">=0.10.0" } }, - "node_modules/css-vendor": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", - "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", - "dependencies": { - "@babel/runtime": "^7.8.3", - "is-in-browser": "^1.0.2" - } - }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -16393,11 +16216,6 @@ "url": "https://github.com/sponsors/typicode" } }, - "node_modules/hyphenate-style-name": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", - "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -16995,11 +16813,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-in-browser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", - "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" - }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -18355,88 +18168,6 @@ "node": "*" } }, - "node_modules/jss": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.7.1.tgz", - "integrity": "sha512-5QN8JSVZR6cxpZNeGfzIjqPEP+ZJwJJfZbXmeABNdxiExyO+eJJDy6WDtqTf8SDKnbL5kZllEpAP71E/Lt7PXg==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "csstype": "^3.0.2", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/jss" - } - }, - "node_modules/jss-plugin-camel-case": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.7.1.tgz", - "integrity": "sha512-+ioIyWvmAfgDCWXsQcW1NMnLBvRinOVFkSYJUgewQ6TynOcSj5F1bSU23B7z0p1iqK0PPHIU62xY1iNJD33WGA==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "hyphenate-style-name": "^1.0.3", - "jss": "10.7.1" - } - }, - "node_modules/jss-plugin-default-unit": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.7.1.tgz", - "integrity": "sha512-tW+dfYVNARBQb/ONzBwd8uyImigyzMiAEDai+AbH5rcHg5h3TtqhAkxx06iuZiT/dZUiFdSKlbe3q9jZGAPIwA==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1" - } - }, - "node_modules/jss-plugin-global": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.7.1.tgz", - "integrity": "sha512-FbxCnu44IkK/bw8X3CwZKmcAnJqjAb9LujlAc/aP0bMSdVa3/MugKQRyeQSu00uGL44feJJDoeXXiHOakBr/Zw==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1" - } - }, - "node_modules/jss-plugin-nested": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.7.1.tgz", - "integrity": "sha512-RNbICk7FlYKaJyv9tkMl7s6FFfeLA3ubNIFKvPqaWtADK0KUaPsPXVYBkAu4x1ItgsWx67xvReMrkcKA0jSXfA==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1", - "tiny-warning": "^1.0.2" - } - }, - "node_modules/jss-plugin-props-sort": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.7.1.tgz", - "integrity": "sha512-eyd5FhA+J0QrpqXxO7YNF/HMSXXl4pB0EmUdY4vSJI4QG22F59vQ6AHtP6fSwhmBdQ98Qd9gjfO+RMxcE39P1A==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1" - } - }, - "node_modules/jss-plugin-rule-value-function": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.7.1.tgz", - "integrity": "sha512-fGAAImlbaHD3fXAHI3ooX6aRESOl5iBt3LjpVjxs9II5u9tzam7pqFUmgTcrip9VpRqYHn8J3gA7kCtm8xKwHg==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1", - "tiny-warning": "^1.0.2" - } - }, - "node_modules/jss-plugin-vendor-prefixer": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.7.1.tgz", - "integrity": "sha512-1UHFmBn7hZNsHXTkLLOL8abRl8vi+D1EVzWD4WmLFj55vawHZfnH1oEz6TUf5Y61XHv0smdHabdXds6BgOXe3A==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "css-vendor": "^2.0.8", - "jss": "10.7.1" - } - }, "node_modules/jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -21921,11 +21652,6 @@ "node": ">=4" } }, - "node_modules/popper.js": { - "version": "1.16.1-lts", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", - "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==" - }, "node_modules/postcss": { "version": "8.4.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", @@ -32589,97 +32315,6 @@ "integrity": "sha512-BJwkHlSUgtB+Ei52Ai32M1AOMerSlzyIGA/KC4dAGL+GGwVMdwG8HGCOA2TxP3KjhbgDPMYkv7bt/NmOmRIFng==", "optional": true }, - "@material-ui/core": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.2.tgz", - "integrity": "sha512-/D1+AQQeYX/WhT/FUk78UCRj8ch/RCglsQLYujYTIqPSJlwZHKcvHidNeVhODXeApojeXjkl0tWdk5C9ofwOkQ==", - "requires": { - "@babel/runtime": "^7.4.4", - "@material-ui/styles": "^4.11.2", - "@material-ui/system": "^4.11.2", - "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.11.2", - "@types/react-transition-group": "^4.2.0", - "clsx": "^1.0.4", - "hoist-non-react-statics": "^3.3.2", - "popper.js": "1.16.1-lts", - "prop-types": "^15.7.2", - "react-is": "^16.8.0 || ^17.0.0", - "react-transition-group": "^4.4.0" - } - }, - "@material-ui/icons": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz", - "integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==", - "requires": { - "@babel/runtime": "^7.4.4" - } - }, - "@material-ui/styles": { - "version": "4.11.4", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz", - "integrity": "sha512-KNTIZcnj/zprG5LW0Sao7zw+yG3O35pviHzejMdcSGCdWbiO8qzRgOYL8JAxAsWBKOKYwVZxXtHWaB5T2Kvxew==", - "requires": { - "@babel/runtime": "^7.4.4", - "@emotion/hash": "^0.8.0", - "@material-ui/types": "5.1.0", - "@material-ui/utils": "^4.11.2", - "clsx": "^1.0.4", - "csstype": "^2.5.2", - "hoist-non-react-statics": "^3.3.2", - "jss": "^10.5.1", - "jss-plugin-camel-case": "^10.5.1", - "jss-plugin-default-unit": "^10.5.1", - "jss-plugin-global": "^10.5.1", - "jss-plugin-nested": "^10.5.1", - "jss-plugin-props-sort": "^10.5.1", - "jss-plugin-rule-value-function": "^10.5.1", - "jss-plugin-vendor-prefixer": "^10.5.1", - "prop-types": "^15.7.2" - }, - "dependencies": { - "csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" - } - } - }, - "@material-ui/system": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.1.tgz", - "integrity": "sha512-lUdzs4q9kEXZGhbN7BptyiS1rLNHe6kG9o8Y307HCvF4sQxbCgpL2qi+gUk+yI8a2DNk48gISEQxoxpgph0xIw==", - "requires": { - "@babel/runtime": "^7.4.4", - "@material-ui/utils": "^4.11.2", - "csstype": "^2.5.2", - "prop-types": "^15.7.2" - }, - "dependencies": { - "csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" - } - } - }, - "@material-ui/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", - "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==", - "requires": {} - }, - "@material-ui/utils": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz", - "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==", - "requires": { - "@babel/runtime": "^7.4.4", - "prop-types": "^15.7.2", - "react-is": "^16.8.0 || ^17.0.0" - } - }, "@mdx-js/mdx": { "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", @@ -38046,15 +37681,6 @@ } } }, - "css-vendor": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", - "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", - "requires": { - "@babel/runtime": "^7.8.3", - "is-in-browser": "^1.0.2" - } - }, "css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -40790,11 +40416,6 @@ "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==" }, - "hyphenate-style-name": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", - "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -41201,11 +40822,6 @@ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" }, - "is-in-browser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", - "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" - }, "is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -42227,84 +41843,6 @@ "through": ">=2.2.7 <3" } }, - "jss": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.7.1.tgz", - "integrity": "sha512-5QN8JSVZR6cxpZNeGfzIjqPEP+ZJwJJfZbXmeABNdxiExyO+eJJDy6WDtqTf8SDKnbL5kZllEpAP71E/Lt7PXg==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^3.0.2", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - }, - "jss-plugin-camel-case": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.7.1.tgz", - "integrity": "sha512-+ioIyWvmAfgDCWXsQcW1NMnLBvRinOVFkSYJUgewQ6TynOcSj5F1bSU23B7z0p1iqK0PPHIU62xY1iNJD33WGA==", - "requires": { - "@babel/runtime": "^7.3.1", - "hyphenate-style-name": "^1.0.3", - "jss": "10.7.1" - } - }, - "jss-plugin-default-unit": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.7.1.tgz", - "integrity": "sha512-tW+dfYVNARBQb/ONzBwd8uyImigyzMiAEDai+AbH5rcHg5h3TtqhAkxx06iuZiT/dZUiFdSKlbe3q9jZGAPIwA==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1" - } - }, - "jss-plugin-global": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.7.1.tgz", - "integrity": "sha512-FbxCnu44IkK/bw8X3CwZKmcAnJqjAb9LujlAc/aP0bMSdVa3/MugKQRyeQSu00uGL44feJJDoeXXiHOakBr/Zw==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1" - } - }, - "jss-plugin-nested": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.7.1.tgz", - "integrity": "sha512-RNbICk7FlYKaJyv9tkMl7s6FFfeLA3ubNIFKvPqaWtADK0KUaPsPXVYBkAu4x1ItgsWx67xvReMrkcKA0jSXfA==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1", - "tiny-warning": "^1.0.2" - } - }, - "jss-plugin-props-sort": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.7.1.tgz", - "integrity": "sha512-eyd5FhA+J0QrpqXxO7YNF/HMSXXl4pB0EmUdY4vSJI4QG22F59vQ6AHtP6fSwhmBdQ98Qd9gjfO+RMxcE39P1A==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1" - } - }, - "jss-plugin-rule-value-function": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.7.1.tgz", - "integrity": "sha512-fGAAImlbaHD3fXAHI3ooX6aRESOl5iBt3LjpVjxs9II5u9tzam7pqFUmgTcrip9VpRqYHn8J3gA7kCtm8xKwHg==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.7.1", - "tiny-warning": "^1.0.2" - } - }, - "jss-plugin-vendor-prefixer": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.7.1.tgz", - "integrity": "sha512-1UHFmBn7hZNsHXTkLLOL8abRl8vi+D1EVzWD4WmLFj55vawHZfnH1oEz6TUf5Y61XHv0smdHabdXds6BgOXe3A==", - "requires": { - "@babel/runtime": "^7.3.1", - "css-vendor": "^2.0.8", - "jss": "10.7.1" - } - }, "jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -44814,11 +44352,6 @@ "find-up": "^2.1.0" } }, - "popper.js": { - "version": "1.16.1-lts", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", - "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==" - }, "postcss": { "version": "8.4.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", diff --git a/package.json b/package.json index 3e3088231..780610477 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,6 @@ "@docusaurus/preset-classic": "2.1.0", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@material-ui/core": "4.11.2", - "@material-ui/icons": "4.11.2", "@mui/material": "5.4.1", "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "12.1.5", diff --git a/packages/uniforms-material/README.md b/packages/uniforms-material/README.md deleted file mode 100644 index 12f622f0d..000000000 --- a/packages/uniforms-material/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# uniforms-material - -> Material components for `uniforms`. - -## Install - -```sh -$ npm install uniforms-material -``` - -For more in depth documentation see [uniforms.tools](https://uniforms.tools). diff --git a/packages/uniforms-material/__tests__/DateField.tsx b/packages/uniforms-material/__tests__/DateField.tsx deleted file mode 100644 index e9162b0b5..000000000 --- a/packages/uniforms-material/__tests__/DateField.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import FormHelperText from '@material-ui/core/FormHelperText'; -import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import React from 'react'; -import { DateField } from 'uniforms-material'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - DateField tests', () => { - test(' - default props are not passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: false, margin: 'normal' } }, - }); - const { container } = render( - - - , - { x: { type: Date } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - default props are passed when MUI theme props are absent', () => { - const theme = createMuiTheme({}); - const { container } = render( - - - , - { x: { type: Date } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginDense', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - explicit props are passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: true, margin: 'dense' } }, - }); - const explicitProps = { - fullWidth: false, - margin: 'normal' as const, - }; - - const { container } = render( - - - , - { x: { type: Date } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); -}); - -test(' - renders a Input with correct error text (specified)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: Date } })); - - expect(wrapper.find(FormHelperText).text()).toBe('Error'); -}); - -test(' - renders a Input with correct error text (showInlineError=false)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: Date } })); - - expect(wrapper.find(FormHelperText)).toHaveLength(0); -}); diff --git a/packages/uniforms-material/__tests__/ErrorField.tsx b/packages/uniforms-material/__tests__/ErrorField.tsx deleted file mode 100644 index 7f55ab1f6..000000000 --- a/packages/uniforms-material/__tests__/ErrorField.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import React from 'react'; -import { ErrorField } from 'uniforms-material'; -import { renderWithZod } from 'uniforms/__suites__'; -import z from 'zod'; - -describe('@RTL - ErrorField tests', () => { - test(' - default props are not passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { - MuiFormControl: { - fullWidth: false, - margin: 'normal', - variant: 'filled', - }, - }, - }); - - const screen = renderWithZod({ - element: ( - - - - ), - error: z.ZodError.create([ - { code: z.ZodIssueCode.custom, message: '', path: ['x'] }, - ]), - schema: z.object({ x: z.string() }), - }); - - const elements = screen.container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - expect( - screen.container.getElementsByClassName('MuiFormHelperText-contained'), - ).toHaveLength(1); - }); - - test(' - default props are passed when MUI theme props are absent', () => { - const theme = createMuiTheme({}); - const screen = renderWithZod({ - element: ( - - - - ), - error: z.ZodError.create([ - { code: z.ZodIssueCode.custom, message: '', path: ['x'] }, - ]), - schema: z.object({ x: z.string() }), - }); - - const elements = screen.container.getElementsByClassName( - 'MuiFormControl-marginDense', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - expect( - screen.container.getElementsByClassName('MuiFormHelperText-contained'), - ).toHaveLength(0); - }); - - test(' - explicit props are passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { - MuiFormControl: { fullWidth: true, margin: 'dense', variant: 'filled' }, - }, - }); - - const screen = renderWithZod({ - element: ( - - - - ), - error: z.ZodError.create([ - { code: z.ZodIssueCode.custom, message: '', path: ['x'] }, - ]), - schema: z.object({ x: z.string() }), - }); - - const elements = screen.container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - expect( - screen.container.getElementsByClassName('MuiFormHelperText-contained'), - ).toHaveLength(0); - }); -}); diff --git a/packages/uniforms-material/__tests__/ErrorsField.tsx b/packages/uniforms-material/__tests__/ErrorsField.tsx deleted file mode 100644 index 207ec2927..000000000 --- a/packages/uniforms-material/__tests__/ErrorsField.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import React from 'react'; -import { ErrorsField } from 'uniforms-material'; -import { renderWithZod } from 'uniforms/__suites__'; -import z from 'zod'; - -describe('@RTL - ErrorsField tests', () => { - test(' - default props are not passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { - MuiFormControl: { - fullWidth: false, - margin: 'normal', - variant: 'filled', - }, - }, - }); - - const screen = renderWithZod({ - element: ( - - - - ), - error: z.ZodError.create([ - { code: z.ZodIssueCode.custom, message: '', path: ['x'] }, - { code: z.ZodIssueCode.custom, message: '', path: ['y'] }, - { code: z.ZodIssueCode.custom, message: '', path: ['z'] }, - ]), - schema: z.object({ x: z.string() }), - }); - - const elements = screen.container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - expect( - screen.container.getElementsByClassName('MuiFormHelperText-contained'), - ).toHaveLength(3); - }); - - test(' - default props are passed when MUI theme props are absent', () => { - const theme = createMuiTheme({}); - const screen = renderWithZod({ - element: ( - - - - ), - error: z.ZodError.create([ - { code: z.ZodIssueCode.custom, message: '', path: ['x'] }, - { code: z.ZodIssueCode.custom, message: '', path: ['y'] }, - { code: z.ZodIssueCode.custom, message: '', path: ['z'] }, - ]), - schema: z.object({ x: z.string() }), - }); - - const elements = screen.container.getElementsByClassName( - 'MuiFormControl-marginDense', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - expect( - screen.container.getElementsByClassName('MuiFormHelperText-contained'), - ).toHaveLength(0); - }); - - test(' - explicit props are passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { - MuiFormControl: { fullWidth: true, margin: 'dense', variant: 'filled' }, - }, - }); - - const screen = renderWithZod({ - element: ( - - - - ), - error: z.ZodError.create([ - { code: z.ZodIssueCode.custom, message: '', path: ['x'] }, - { code: z.ZodIssueCode.custom, message: '', path: ['y'] }, - { code: z.ZodIssueCode.custom, message: '', path: ['z'] }, - ]), - schema: z.object({ x: z.string() }), - }); - - const elements = screen.container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - expect( - screen.container.getElementsByClassName('MuiFormHelperText-contained'), - ).toHaveLength(0); - }); -}); diff --git a/packages/uniforms-material/__tests__/NestField.tsx b/packages/uniforms-material/__tests__/NestField.tsx deleted file mode 100644 index 468c11de2..000000000 --- a/packages/uniforms-material/__tests__/NestField.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import FormHelperText from '@material-ui/core/FormHelperText'; -import FormLabel from '@material-ui/core/FormLabel'; -import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import React from 'react'; -import { NestField } from 'uniforms-material'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - NestField tests', () => { - test(' - default props are not passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiFormControl: { fullWidth: false, margin: 'normal' } }, - }); - const { container } = render( - - - , - { x: { type: Object }, 'x.a': { type: String } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - default props are passed when MUI theme props are absent', () => { - const theme = createMuiTheme({}); - const { container } = render( - - - , - { x: { type: Object }, 'x.a': { type: String } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginDense', - ); - expect(elements).toHaveLength(2); // Nested TextField is found as well - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - explicit props are passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiFormControl: { fullWidth: true, margin: 'dense' } }, - }); - const explicitProps = { - fullWidth: false, - margin: 'normal' as const, - }; - - const { container } = render( - - - , - { x: { type: Object }, 'x.a': { type: String } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); -}); - -test(' - renders a Subheader', () => { - const element = ; - const wrapper = mount( - element, - createContext({ - x: { type: Object }, - 'x.a': { type: String }, - 'x.b': { type: Number }, - }), - ); - - expect(wrapper.find(FormLabel).at(0).text()).toBe('y *'); -}); - -test(' - renders a helperText', () => { - const element = ; - const wrapper = mount( - element, - createContext({ - x: { type: Object }, - 'x.a': { type: String }, - 'x.b': { type: Number }, - }), - ); - - expect(wrapper.find(FormHelperText)).toHaveLength(1); - expect(wrapper.find(FormHelperText).text()).toBe('Helper'); -}); diff --git a/packages/uniforms-material/__tests__/SelectField.tsx b/packages/uniforms-material/__tests__/SelectField.tsx deleted file mode 100644 index 305d0a365..000000000 --- a/packages/uniforms-material/__tests__/SelectField.tsx +++ /dev/null @@ -1,814 +0,0 @@ -import Checkbox from '@material-ui/core/Checkbox'; -import FormControl from '@material-ui/core/FormControl'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormHelperText from '@material-ui/core/FormHelperText'; -import FormLabel from '@material-ui/core/FormLabel'; -import Radio from '@material-ui/core/Radio'; -import RadioGroup from '@material-ui/core/RadioGroup'; -import Select from '@material-ui/core/Select'; -import Switch from '@material-ui/core/Switch'; -import TextField from '@material-ui/core/TextField'; -import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import React from 'react'; -import { SelectField } from 'uniforms-material'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - SelectField tests', () => { - test(' - default props are not passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: false, margin: 'normal' } }, - }); - const { container } = render( - - - , - { x: { type: String, allowedValues: ['a', 'b'] } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - default props are passed when MUI theme props are absent', () => { - const theme = createMuiTheme({}); - const { container } = render( - - - , - { x: { type: String, allowedValues: ['a', 'b'] } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginDense', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - explicit props are passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: true, margin: 'dense' } }, - }); - const explicitProps = { - fullWidth: false, - margin: 'normal' as const, - }; - - const { container } = render( - - - , - { x: { type: String, allowedValues: ['a', 'b'] } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - MUI theme props are passed', () => { - const theme = createMuiTheme({ - props: { MuiFormControl: { fullWidth: false, margin: 'normal' } }, - }); - const { container } = render( - - - , - { x: { type: String, allowedValues: ['a', 'b'] } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); -}); - -test(' - renders a Select', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); -}); - -test(' - renders a Select with correct disabled state', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(FormControl).prop('disabled')).toBe(true); -}); - -test(' - renders a Select with correct required state', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(TextField).prop('required')).toBe(true); -}); - -test(' - renders a Select with correct id (inherited)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - // FIXME: inputProps is nullable. - expect(wrapper.find(Select).prop('inputProps')!.id).toBeTruthy(); -}); - -test(' - renders a Select with correct id (specified)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - // FIXME: inputProps is nullable. - expect(wrapper.find(Select).prop('inputProps')!.id).toBe('y'); -}); - -test(' - renders a Select with correct name', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - // FIXME: inputProps is nullable. - expect(wrapper.find(Select).prop('inputProps')!.name).toBe('x'); -}); - -test(' - renders a Select with correct options', () => { - const element = ; - const wrapper = mount( - element, - createContext({ - x: { type: String, allowedValues: ['a', 'b'], label: '' }, - }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find('option')).toHaveLength(3); - [ - ['', ''], - ['a', 'a'], - ['b', 'b'], - ].forEach(([value, text], index) => { - const option = wrapper.find('option').at(index); - expect(option.prop('value')).toBe(value); - expect(option.text()).toBe(text); - }); -}); - -test(' - renders a Select with correct options (transform)', () => { - const element = ( - - ); - const wrapper = mount( - element, - createContext({ x: { type: String, label: '' } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find('option')).toHaveLength(3); - [ - ['', ''], - ['a', 'A'], - ['b', 'B'], - ].forEach(([value, text], index) => { - const option = wrapper.find('option').at(index); - expect(option.prop('value')).toBe(value); - expect(option.text()).toBe(text); - }); -}); - -test(' - renders a Select with correct placeholder (implicit)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select).prop('value')).toBe(''); - expect(wrapper.find('option')).toHaveLength(3); - [ - ['', 'y'], - ['a', 'a'], - ['b', 'b'], - ].forEach(([value, text], index) => { - const option = wrapper.find('option').at(index); - expect(option.prop('value')).toBe(value); - expect(option.text()).toBe(text); - }); -}); - -test(' - renders a Select with correct value (default)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(Select).prop('value')).toBe(''); -}); - -test(' - renders a Select with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext( - { x: { type: String, allowedValues: ['a', 'b'] } }, - { model: { x: 'b' } }, - ), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(Select).prop('value')).toBe('b'); -}); - -test(' - renders a Select with correct value (specified)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(Select).prop('value')).toBe('b'); -}); - -test(' - renders a Select which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext( - { x: { type: String, allowedValues: ['a', 'b'] } }, - { onChange }, - ), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - // @ts-expect-error Provide a valid EventTarget. - wrapper.find(TextField).props().onChange!({ target: { value: 'b' } }); - expect(onChange).toHaveBeenLastCalledWith('x', 'b'); -}); - -test(' - renders a Select which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext( - { x: { type: String, allowedValues: ['a', 'b'] } }, - { onChange }, - ), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - // @ts-expect-error Provide a valid EventTarget. - wrapper.find(TextField).props().onChange!({ target: { value: '' } }); - expect(onChange).toHaveBeenLastCalledWith('x', undefined); -}); - -test(' - renders a Select which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext( - { x: { type: String, allowedValues: ['a', 'b'] } }, - { model: { x: 'b' }, onChange }, - ), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - // @ts-expect-error Provide a valid EventTarget. - wrapper.find(TextField).props().onChange!({ target: { value: 'b' } }); - expect(onChange).toHaveBeenLastCalledWith('x', 'b'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(TextField).prop('label')).toBe('y'); -}); - -test(' - renders a SelectField with correct error text (showInlineError=true)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(FormHelperText).text()).toBe('Error'); -}); - -test(' - renders a SelectField with correct error text (showInlineError=false)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(FormHelperText)).toHaveLength(0); -}); - -test(' - works with special characters', () => { - mount( - , - createContext({ x: { type: String, allowedValues: ['ă', 'ș'] } }), - ); -}); - -test(' - disabled items (options) based on predicate', () => { - const allowedValues = ['a', 'b']; - - const element = ( - - ); - const wrapper = mount( - element, - createContext({ - x: { type: Array }, - 'x.$': { type: String, allowedValues }, - }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find('option').at(0).prop('disabled')).toBe(true); - expect(wrapper.find('option').at(1).prop('disabled')).toBe(false); -}); - -test(' - renders with correct classnames', () => { - const wrapper = mount( - , - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - expect(wrapper.find(TextField).props()).toHaveProperty( - 'className', - 'select-class', - ); -}); - -test(' - renders a multiselect with correct value (default)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ - x: { type: Array, allowedValues: ['a', 'b'] }, - 'x.$': { type: String }, - }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(Select).prop('value')).toStrictEqual([]); -}); - -test(' - renders a multiselect with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext( - { - x: { type: Array, allowedValues: ['a', 'b'] }, - 'x.$': { type: String }, - }, - { model: { x: ['b'] } }, - ), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(Select).prop('value')).toStrictEqual(['b']); -}); - -test(' - renders a multiselect with correct value (specified)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ - x: { type: Array, allowedValues: ['a', 'b'] }, - 'x.$': { type: String }, - }), - ); - - expect(wrapper.find(Select)).toHaveLength(1); - expect(wrapper.find(Select).prop('value')).toStrictEqual(['b']); -}); - -test(' - renders a set of Radio buttons', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); -}); - -test(' - renders a set of Radio buttons with correct disabled state', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - expect(wrapper.find(Radio).at(0).prop('disabled')).toBe(true); - expect(wrapper.find(Radio).at(1).prop('disabled')).toBe(true); -}); - -test(' - renders a set of Radio buttons with correct id (inherited)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - expect(wrapper.find(Radio).at(0).prop('id')).toBeTruthy(); - expect(wrapper.find(Radio).at(1).prop('id')).toBeTruthy(); -}); - -test(' - renders a set of Radio buttons with correct id (specified)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - expect(wrapper.find(Radio).at(0).prop('id')).toBe('y-YQ'); - expect(wrapper.find(Radio).at(1).prop('id')).toBe('y-Yg'); -}); - -test(' - renders a set of Radio buttons with correct name', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - expect(wrapper.find(Radio).at(0).find('input').prop('name')).toBe('x'); - expect(wrapper.find(Radio).at(1).find('input').prop('name')).toBe('x'); -}); - -test(' - renders a set of Radio buttons with correct options', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find('label')).toHaveLength(2); - expect(wrapper.find(FormControlLabel).at(0).prop('label')).toBe('a'); - expect(wrapper.find(FormControlLabel).at(1).prop('label')).toBe('b'); -}); - -test(' - renders a set of Radio buttons with correct options (transform)', () => { - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('label')).toHaveLength(2); - expect(wrapper.find(FormControlLabel).at(0).prop('label')).toBe('A'); - expect(wrapper.find(FormControlLabel).at(1).prop('label')).toBe('B'); -}); - -test(' - renders a set of Radio buttons with correct value (default)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - expect(wrapper.find(Radio).at(0).find('input').prop('checked')).toBe(false); - expect(wrapper.find(Radio).at(1).find('input').prop('checked')).toBe(false); -}); - -test(' - renders a set of Radio buttons with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext( - { x: { type: String, allowedValues: ['a', 'b'] } }, - { model: { x: 'b' } }, - ), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - expect(wrapper.find(Radio).at(0).find('input').prop('checked')).toBe(false); - expect(wrapper.find(Radio).at(1).find('input').prop('checked')).toBe(true); -}); - -test(' - renders a set of Radio buttons with correct value (specified)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - expect(wrapper.find(Radio).at(0).find('input').prop('checked')).toBe(false); - expect(wrapper.find(Radio).at(1).find('input').prop('checked')).toBe(true); -}); - -test(' - renders a set of Radio buttons which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext( - { x: { type: String, allowedValues: ['a', 'b'] } }, - { onChange }, - ), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - // @ts-expect-error Provide a valid value. - wrapper.find(RadioGroup).props().onChange!({ target: { value: 'b' } }); - expect(onChange).toHaveBeenLastCalledWith('x', 'b'); -}); - -test(' - renders a set of Checkboxes which correctly reacts on change (array check)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext( - { - x: { type: Array }, - 'x.$': { type: String, allowedValues: ['a', 'b'] }, - }, - { onChange }, - ), - ); - - expect(wrapper.find(Checkbox)).toHaveLength(2); - wrapper.find(Checkbox).at(1).find('input').simulate('change'); - expect(onChange).toHaveBeenLastCalledWith('x', ['b']); -}); - -test(' - renders a set of Checkboxes which correctly reacts on change (array uncheck)', () => { - const onChange = jest.fn(); - const element = ; - const wrapper = mount( - element, - createContext( - { - x: { type: Array }, - 'x.$': { type: String, allowedValues: ['a', 'b'] }, - }, - { onChange }, - ), - ); - - expect(wrapper.find(Checkbox)).toHaveLength(2); - wrapper.find(Checkbox).at(1).find('input').simulate('change'); - expect(onChange).toHaveBeenLastCalledWith('x', []); -}); - -test(' - renders a set of Checkboxes with correct labels', () => { - const onChange = jest.fn(); - const element = ; - const wrapper = mount( - element, - createContext( - { - x: { type: Array }, - 'x.$': { type: String, allowedValues: ['a', 'b'] }, - }, - { onChange }, - ), - ); - - expect(wrapper.find(Checkbox)).toHaveLength(2); - expect(wrapper.find(FormControlLabel).at(0).text()).toBe('a'); - expect(wrapper.find(FormControlLabel).at(1).text()).toBe('b'); -}); - -test(' - renders a set of Checkboxes which correct labels (transform)', () => { - const onChange = jest.fn(); - const element = ( - - ); - const wrapper = mount( - element, - createContext( - { - x: { type: Array }, - 'x.$': { type: String }, - }, - { onChange }, - ), - ); - - expect(wrapper.find(Checkbox)).toHaveLength(2); - expect(wrapper.find(FormControlLabel).at(0).text()).toBe('A'); - expect(wrapper.find(FormControlLabel).at(1).text()).toBe('B'); -}); - -test(' - renders a set of Radio buttons which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext( - { x: { type: String, allowedValues: ['a', 'b'] } }, - { model: { x: 'b' }, onChange }, - ), - ); - - expect(wrapper.find(Radio)).toHaveLength(2); - - // @ts-expect-error Provide a valid value. - wrapper.find(RadioGroup).props().onChange!({ target: { value: 'a' } }); - - expect(onChange).toHaveBeenLastCalledWith('x', 'a'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(FormLabel).text()).toBe('y *'); -}); - -test(' - renders a SelectField with correct error text (showInlineError=true)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(FormHelperText).text()).toBe('Error'); -}); - -test(' - renders a SelectField with correct error text (showInlineError=false)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount( - element, - createContext({ x: { type: String, allowedValues: ['a', 'b'] } }), - ); - - expect(wrapper.find(FormHelperText)).toHaveLength(0); -}); - -test(' - renders Checkbox with appearance=checkbox', () => { - const element = ; - const wrapper = mount( - element, - createContext({ - x: { type: Array }, - 'x.$': { type: String, allowedValues: ['a', 'b'] }, - }), - ); - - expect(wrapper.find(Checkbox)).toHaveLength(2); - expect(wrapper.find(Switch)).toHaveLength(0); -}); - -test(' - renders Switch with appearance=switch', () => { - const element = ; - const wrapper = mount( - element, - createContext({ - x: { type: Array }, - 'x.$': { type: String, allowedValues: ['a', 'b'] }, - }), - ); - - expect(wrapper.find(Checkbox)).toHaveLength(0); - expect(wrapper.find(Switch)).toHaveLength(2); -}); - -test(' - works with special characters', () => { - mount( - , - createContext({ x: { type: String, allowedValues: ['ă', 'ș'] } }), - ); -}); - -test(' - disabled items (checkboxes) based on predicate', () => { - const element = ( - - ); - const wrapper = mount( - element, - createContext({ - x: { type: Array }, - 'x.$': { type: String }, - }), - ); - - expect(wrapper.find(Checkbox)).toHaveLength(2); - expect(wrapper.find(FormControlLabel).at(0).prop('disabled')).toBe(true); - expect(wrapper.find(FormControlLabel).at(1).prop('disabled')).toBe(false); -}); diff --git a/packages/uniforms-material/__tests__/_createContext.ts b/packages/uniforms-material/__tests__/_createContext.ts deleted file mode 100644 index e687bc994..000000000 --- a/packages/uniforms-material/__tests__/_createContext.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { SimpleSchemaDefinition } from 'simpl-schema'; -import { Context, UnknownObject, randomIds, ChangedMap } from 'uniforms'; - -import createSchema from './_createSchema'; - -const randomId = randomIds(); - -export default function createContext( - schema?: SimpleSchemaDefinition, - context?: Partial>, - model = {} as Model, -): { context: Context } { - return { - context: { - changed: false, - changedMap: {} as ChangedMap, - error: null, - model, - name: [], - onChange() {}, - onSubmit() {}, - randomId, - submitted: false, - submitting: false, - validating: false, - ...context, - schema: createSchema(schema), - state: { - disabled: false, - readOnly: false, - showInlineError: false, - ...context?.state, - }, - // @ts-expect-error We don't have a true ref in tests. - formRef: null, - }, - }; -} diff --git a/packages/uniforms-material/__tests__/_createSchema.ts b/packages/uniforms-material/__tests__/_createSchema.ts deleted file mode 100644 index 6ac1ef72b..000000000 --- a/packages/uniforms-material/__tests__/_createSchema.ts +++ /dev/null @@ -1,6 +0,0 @@ -import SimpleSchema, { SimpleSchemaDefinition } from 'simpl-schema'; -import { SimpleSchema2Bridge } from 'uniforms-bridge-simple-schema-2'; - -export default function createSchema(schema: SimpleSchemaDefinition = {}) { - return new SimpleSchema2Bridge({ schema: new SimpleSchema(schema) }); -} diff --git a/packages/uniforms-material/__tests__/_mount.tsx b/packages/uniforms-material/__tests__/_mount.tsx deleted file mode 100644 index d586e42dd..000000000 --- a/packages/uniforms-material/__tests__/_mount.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { mount as enzyme } from 'enzyme'; -import { context } from 'uniforms'; - -function mount(node: any, options: any) { - if (options === undefined) { - return enzyme(node); - } - return enzyme(node, { - wrappingComponent: context.Provider, - wrappingComponentProps: { value: options.context }, - }); -} - -export default mount as typeof enzyme; diff --git a/packages/uniforms-material/__tests__/index.tsx b/packages/uniforms-material/__tests__/index.tsx deleted file mode 100644 index 647461ce5..000000000 --- a/packages/uniforms-material/__tests__/index.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import createMuiTheme, { - ThemeOptions, -} from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import React, { PropsWithChildren } from 'react'; -import * as theme from 'uniforms-material'; -import * as suites from 'uniforms/__suites__'; - -it('exports everything', () => { - expect(theme).toEqual({ - AutoFields: expect.any(Function), - AutoField: expect.any(Function), - AutoForm: expect.any(Function), - BaseForm: expect.any(Function), - BoolField: expect.any(Function), - DateField: expect.any(Function), - ErrorField: expect.any(Function), - ErrorsField: expect.any(Function), - HiddenField: expect.any(Function), - ListAddField: expect.any(Function), - ListDelField: expect.any(Function), - ListField: expect.any(Function), - ListItemField: expect.any(Function), - LongTextField: expect.any(Function), - NestField: expect.any(Function), - NumField: expect.any(Function), - QuickForm: expect.any(Function), - RadioField: expect.any(Function), - SelectField: expect.any(Function), - SubmitField: expect.any(Function), - TextField: expect.any(Function), - ValidatedForm: expect.any(Function), - ValidatedQuickForm: expect.any(Function), - wrapField: expect.any(Function), - }); -}); - -describe('@RTL', () => { - suites.testAutoField(theme.AutoField, { - getDateField: screen => screen.getByLabelText('X *'), - getSelectField: screen => screen.getByRole('button'), - }); - suites.testAutoForm(theme.AutoForm); - suites.testBaseForm(theme.BaseForm); - suites.testBoolField(theme.BoolField, { - testSwitch: true, - testMUIThemeProps: true, - }); - suites.testDateField(theme.DateField); - suites.testErrorField(theme.ErrorField); - suites.testErrorsField(theme.ErrorsField); - suites.testHiddenField(theme.HiddenField); - suites.testListAddField(theme.ListAddField); - suites.testListDelField(theme.ListDelField); - suites.testListField(theme.ListField, { - getListAddField: screen => screen.getByText(/\+/), - testError: false, - }); - suites.testListItemField(theme.ListItemField); - suites.testLongTextField(theme.LongTextField, { - testPassThemeProps: { - ThemeProvider({ - themeOptions, - ...props - }: PropsWithChildren<{ themeOptions: ThemeOptions }>) { - return ( - - {props.children} - - ); - }, - }, - }); - suites.testNestField(theme.NestField, { skipInMuiTests: true }); - suites.testNumField(theme.NumField); - suites.testQuickForm(theme.QuickForm); - suites.testRadioField(theme.RadioField); - // FIXME: MUI select does not work with new RTL test implementation - // suites.testSelectField(theme.SelectField); - suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField, { - testShowInlineError: true, - testPassThemeProps: { - ThemeProvider({ - themeOptions, - ...props - }: PropsWithChildren<{ themeOptions: ThemeOptions }>) { - return ( - - {props.children} - - ); - }, - }, - }); - suites.testValidatedForm(theme.ValidatedForm); - suites.testValidatedQuickForm(theme.ValidatedQuickForm); -}); diff --git a/packages/uniforms-material/package.json b/packages/uniforms-material/package.json deleted file mode 100644 index 9a2845bb5..000000000 --- a/packages/uniforms-material/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "uniforms-material", - "version": "4.0.0-alpha.5", - "license": "MIT", - "main": "./cjs/index.js", - "module": "./esm/index.js", - "sideEffects": false, - "description": "Material-UI components for uniforms.", - "repository": "https://github.com/vazco/uniforms/tree/master/packages/uniforms-material", - "bugs": "https://github.com/vazco/uniforms/issues", - "funding": "https://github.com/vazco/uniforms?sponsor=1", - "keywords": [ - "form", - "forms", - "material design", - "material-ui", - "meteor", - "react", - "react-component", - "schema", - "validation" - ], - "files": [ - "cjs/*.d.ts", - "cjs/*.js", - "esm/*.d.ts", - "esm/*.js", - "src/*.ts", - "src/*.tsx" - ], - "peerDependencies": { - "@material-ui/core": "^4.0.0", - "csstype": "^2.0.0", - "react": "^18.0.0 || ^17.0.0 || ^16.8.0" - }, - "dependencies": { - "invariant": "^2.0.0", - "lodash": "^4.0.0", - "tslib": "^2.2.0", - "uniforms": "^4.0.0-alpha.5" - } -} diff --git a/packages/uniforms-material/src/AutoField.tsx b/packages/uniforms-material/src/AutoField.tsx deleted file mode 100644 index fe7a4693f..000000000 --- a/packages/uniforms-material/src/AutoField.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import invariant from 'invariant'; -export { AutoFieldProps } from 'uniforms'; -import { createAutoField } from 'uniforms'; - -import BoolField from './BoolField'; -import DateField from './DateField'; -import ListField from './ListField'; -import NestField from './NestField'; -import NumField from './NumField'; -import RadioField from './RadioField'; -import SelectField from './SelectField'; -import TextField from './TextField'; - -const AutoField = createAutoField(props => { - if (props.component) { - return props.component; - } - - if (props.options) { - return props.checkboxes && props.fieldType !== Array - ? RadioField - : SelectField; - } - - switch (props.fieldType) { - case Array: - return ListField; - case Boolean: - return BoolField; - case Date: - return DateField; - case Number: - return NumField; - case Object: - return NestField; - case String: - return TextField; - } - - return invariant(false, 'Unsupported field type: %s', props.fieldType); -}); - -export default AutoField; diff --git a/packages/uniforms-material/src/AutoFields.tsx b/packages/uniforms-material/src/AutoFields.tsx deleted file mode 100644 index 1f70b06e0..000000000 --- a/packages/uniforms-material/src/AutoFields.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { ComponentType, Fragment, createElement } from 'react'; -import { useForm } from 'uniforms'; - -import AutoField from './AutoField'; - -export type AutoFieldsProps = { - element?: ComponentType | string; - fields?: string[]; - omitFields?: string[]; - showInlineError?: boolean; -}; - -export default function AutoFields({ - element = Fragment, - fields, - omitFields = [], - showInlineError, - ...props -}: AutoFieldsProps) { - const { schema } = useForm(); - - return createElement( - element, - props, - (fields ?? schema.getSubfields()) - .filter(field => !omitFields.includes(field)) - .map(field => - createElement( - AutoField, - Object.assign( - { key: field, name: field }, - showInlineError === undefined ? null : { showInlineError }, - ), - ), - ), - ); -} diff --git a/packages/uniforms-material/src/AutoForm.tsx b/packages/uniforms-material/src/AutoForm.tsx deleted file mode 100644 index ea8321711..000000000 --- a/packages/uniforms-material/src/AutoForm.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { AutoForm } from 'uniforms'; - -import ValidatedQuickForm from './ValidatedQuickForm'; - -function Auto(parent: any) { - class _ extends AutoForm.Auto(parent) { - static Auto = Auto; - } - - return _ as unknown as AutoForm; -} - -export default Auto(ValidatedQuickForm); diff --git a/packages/uniforms-material/src/BaseForm.tsx b/packages/uniforms-material/src/BaseForm.tsx deleted file mode 100644 index 1fde6e96a..000000000 --- a/packages/uniforms-material/src/BaseForm.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { BaseForm } from 'uniforms'; - -function Material(parent: any) { - class _ extends parent { - static Material = Material; - - static displayName = `Material${parent.displayName}`; - } - - return _ as unknown as typeof BaseForm; -} - -export default Material(BaseForm); diff --git a/packages/uniforms-material/src/BoolField.tsx b/packages/uniforms-material/src/BoolField.tsx deleted file mode 100644 index 2014ce8d3..000000000 --- a/packages/uniforms-material/src/BoolField.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import type { PropTypes } from '@material-ui/core'; -import Checkbox, { CheckboxProps } from '@material-ui/core/Checkbox'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormGroup from '@material-ui/core/FormGroup'; -import FormLabel from '@material-ui/core/FormLabel'; -import Switch, { SwitchProps } from '@material-ui/core/Switch'; -import useTheme from '@material-ui/core/styles/useTheme'; -import omit from 'lodash/omit'; -import React, { Ref } from 'react'; -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -import wrapField from './wrapField'; - -export type BoolFieldProps = FieldProps< - boolean, - CheckboxProps | SwitchProps, - { - appearance?: 'checkbox' | 'switch'; - fullWidth?: boolean; - helperText?: string; - legend?: string; - margin?: PropTypes.Margin; - } ->; - -function Bool(props: BoolFieldProps) { - const { - appearance, - disabled, - inputRef, - label, - legend, - name, - onChange, - readOnly, - value, - } = props; - const theme = useTheme(); - const formControlThemeProps = theme.props?.MuiFormControl; - const SelectionControl = - appearance === 'checkbox' || appearance === undefined ? Checkbox : Switch; - - return wrapField( - { - ...(formControlThemeProps?.fullWidth === undefined && { - fullWidth: true, - }), - ...(formControlThemeProps?.margin === undefined && { margin: 'dense' }), - ...props, - component: 'fieldset', - }, - legend && ( - - {legend} - - ), - - - !disabled && - !readOnly && - onChange && - onChange(event.target.checked) - } - ref={inputRef as Ref} - value={name} - {...omit(filterDOMProps(props), ['helperText', 'fullWidth'])} - /> - } - label={label} - /> - , - ); -} - -export default connectField(Bool, { kind: 'leaf' }); diff --git a/packages/uniforms-material/src/DateField.tsx b/packages/uniforms-material/src/DateField.tsx deleted file mode 100644 index 3eade4db4..000000000 --- a/packages/uniforms-material/src/DateField.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import TextField, { TextFieldProps } from '@material-ui/core/TextField'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React from 'react'; -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -type DateFieldType = 'date' | 'datetime-local'; - -/* istanbul ignore next */ -const DateConstructor = (typeof global === 'object' ? global : window).Date; - -const dateFormat = (value?: Date, type: DateFieldType = 'datetime-local') => - value?.toISOString().slice(0, type === 'datetime-local' ? -8 : -14); - -const dateParse = (timestamp: number, onChange: DateFieldProps['onChange']) => { - const date = new DateConstructor(timestamp); - if (date.getFullYear() < 10000) { - onChange(date); - } else if (isNaN(timestamp)) { - onChange(undefined); - } -}; - -export type DateFieldProps = FieldProps< - Date, - TextFieldProps, - { - labelProps?: object; - max?: Date; - min?: Date; - type?: 'date' | 'datetime-local'; - } ->; - -function Date({ - disabled, - error, - errorMessage, - helperText, - InputLabelProps, - inputRef, - label, - labelProps, - max, - min, - name, - onChange, - placeholder, - readOnly, - showInlineError, - value, - type = 'datetime-local', - ...props -}: DateFieldProps) { - const theme = useTheme(); - const themeProps = theme.props?.MuiTextField; - - return ( - - // FIXME: `valueAsNumber` is not available in `EventTarget`. - disabled || dateParse((event.target as any).valueAsNumber, onChange) - } - placeholder={placeholder} - ref={inputRef} - type={type} - value={dateFormat(value, type) ?? ''} - {...filterDOMProps(props)} - /> - ); -} - -export default connectField(Date, { kind: 'leaf' }); diff --git a/packages/uniforms-material/src/ErrorField.tsx b/packages/uniforms-material/src/ErrorField.tsx deleted file mode 100644 index 93f9aab53..000000000 --- a/packages/uniforms-material/src/ErrorField.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import type { PropTypes } from '@material-ui/core'; -import FormControl from '@material-ui/core/FormControl'; -import FormHelperText, { - FormHelperTextProps, -} from '@material-ui/core/FormHelperText'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React from 'react'; -import { Override, connectField, filterDOMProps } from 'uniforms'; - -export type ErrorFieldProps = Override< - FormHelperTextProps, - { errorMessage?: string; fullWidth?: boolean; margin?: PropTypes.Margin } ->; - -function Error({ - children, - error, - errorMessage, - fullWidth, - margin, - variant, - ...props -}: ErrorFieldProps) { - const theme = useTheme(); - const themeProps = theme.props?.MuiFormControl; - - return !error ? null : ( - - - {children || errorMessage} - - - ); -} - -export default connectField(Error, { - initialValue: false, - kind: 'leaf', -}); diff --git a/packages/uniforms-material/src/ErrorsField.tsx b/packages/uniforms-material/src/ErrorsField.tsx deleted file mode 100644 index 7d1e9a042..000000000 --- a/packages/uniforms-material/src/ErrorsField.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import type { PropTypes } from '@material-ui/core'; -import FormControl from '@material-ui/core/FormControl'; -import FormHelperText, { - FormHelperTextProps, -} from '@material-ui/core/FormHelperText'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React from 'react'; -import { Override, filterDOMProps, useForm } from 'uniforms'; - -export type ErrorsFieldProps = Override< - FormHelperTextProps, - { - fullWidth?: boolean; - margin?: PropTypes.Margin; - variant?: 'standard' | 'outlined' | 'filled'; - } ->; - -function ErrorsField({ - children, - fullWidth, - margin, - variant, - ...props -}: ErrorsFieldProps) { - const theme = useTheme(); - const themeProps = theme.props?.MuiFormControl; - const { error, schema } = useForm(); - - return !error && !children ? null : ( - - {!!children && ( - {children} - )} - {schema.getErrorMessages(error).map((message, index) => ( - - {message} - - ))} - - ); -} - -export default ErrorsField; diff --git a/packages/uniforms-material/src/HiddenField.tsx b/packages/uniforms-material/src/HiddenField.tsx deleted file mode 100644 index 616f87f08..000000000 --- a/packages/uniforms-material/src/HiddenField.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { HTMLProps, Ref, useEffect } from 'react'; -import { Override, filterDOMProps, useField } from 'uniforms'; - -export type HiddenFieldProps = Override< - HTMLProps, - { - inputRef?: Ref; - name: string; - noDOM?: boolean; - value?: unknown; - } ->; - -export default function HiddenField({ value, ...rawProps }: HiddenFieldProps) { - const props = useField(rawProps.name, rawProps, { initialValue: false })[0]; - - useEffect(() => { - if (value !== undefined && value !== props.value) { - props.onChange(value); - } - }); - - return props.noDOM ? null : ( - - ); -} diff --git a/packages/uniforms-material/src/ListAddField.tsx b/packages/uniforms-material/src/ListAddField.tsx deleted file mode 100644 index aa26e33f9..000000000 --- a/packages/uniforms-material/src/ListAddField.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import FormControl, { FormControlProps } from '@material-ui/core/FormControl'; -import IconButton, { IconButtonProps } from '@material-ui/core/IconButton'; -import cloneDeep from 'lodash/cloneDeep'; -import React, { ReactNode } from 'react'; -import { - FieldProps, - connectField, - filterDOMProps, - joinName, - useField, -} from 'uniforms'; - -export type ListAddFieldProps = FieldProps< - unknown, - IconButtonProps, - { - fullWidth?: FormControlProps['fullWidth']; - icon?: ReactNode; - margin?: FormControlProps['margin']; - variant?: FormControlProps['variant']; - } ->; - -function ListAdd({ - disabled, - fullWidth = true, - icon = '+', - margin = 'dense', - name, - readOnly, - value, - variant, - ...props -}: ListAddFieldProps) { - const nameParts = joinName(null, name); - const parentName = joinName(nameParts.slice(0, -1)); - const parent = useField<{ maxCount?: number }, unknown[]>( - parentName, - {}, - { absoluteName: true }, - )[0]; - - const limitNotReached = - !disabled && !(parent.maxCount! <= parent.value!.length); - - return ( - - { - if (!readOnly) { - parent.onChange(parent.value!.concat([cloneDeep(value)])); - } - }} - > - {icon} - - - ); -} - -export default connectField(ListAdd, { - initialValue: false, - kind: 'leaf', -}); diff --git a/packages/uniforms-material/src/ListDelField.tsx b/packages/uniforms-material/src/ListDelField.tsx deleted file mode 100644 index a2ddb3a03..000000000 --- a/packages/uniforms-material/src/ListDelField.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import IconButton, { IconButtonProps } from '@material-ui/core/IconButton'; -import React, { ReactNode } from 'react'; -import { - FieldProps, - connectField, - filterDOMProps, - joinName, - useField, -} from 'uniforms'; - -export type ListDelFieldProps = FieldProps< - unknown, - IconButtonProps, - { icon?: ReactNode } ->; - -function ListDel({ - disabled, - icon = '-', - name, - readOnly, - ...props -}: ListDelFieldProps) { - const nameParts = joinName(null, name); - const nameIndex = +nameParts[nameParts.length - 1]; - const parentName = joinName(nameParts.slice(0, -1)); - const parent = useField<{ minCount?: number }, unknown[]>( - parentName, - {}, - { absoluteName: true }, - )[0]; - - disabled ||= readOnly || parent.minCount! >= parent.value!.length; - - return ( - { - const value = parent.value!.slice(); - value.splice(nameIndex, 1); - parent.onChange(value); - }} - > - {icon} - - ); -} - -export default connectField(ListDel, { - initialValue: false, - kind: 'leaf', -}); diff --git a/packages/uniforms-material/src/ListField.tsx b/packages/uniforms-material/src/ListField.tsx deleted file mode 100644 index f09e5aafb..000000000 --- a/packages/uniforms-material/src/ListField.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import ListMaterial, { ListProps } from '@material-ui/core/List'; -import ListSubheader from '@material-ui/core/ListSubheader'; -import React, { - Children, - ReactNode, - cloneElement, - isValidElement, -} from 'react'; -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -import ListAddField from './ListAddField'; -import ListItemField from './ListItemField'; - -export type ListFieldProps = FieldProps< - unknown[], - ListProps, - { addIcon?: ReactNode; itemProps?: object } ->; - -function List({ - addIcon, - children = , - itemProps, - label, - value, - ...props -}: ListFieldProps) { - return ( - <> - {label} - ) : undefined - } - {...filterDOMProps(props)} - > - {value?.map((item, itemIndex) => - Children.map(children, (child, childIndex) => - isValidElement(child) - ? cloneElement(child, { - key: `${itemIndex}-${childIndex}`, - name: child.props.name?.replace('$', '' + itemIndex), - ...itemProps, - }) - : child, - ), - )} - - - - ); -} - -export default connectField(List); diff --git a/packages/uniforms-material/src/ListItemField.tsx b/packages/uniforms-material/src/ListItemField.tsx deleted file mode 100644 index c844e23a0..000000000 --- a/packages/uniforms-material/src/ListItemField.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import ListItemMaterial, { ListItemProps } from '@material-ui/core/ListItem'; -import React, { ReactNode } from 'react'; -import { connectField } from 'uniforms'; - -import AutoField from './AutoField'; -import ListDelField from './ListDelField'; - -export type ListItemFieldProps = { - children?: ReactNode; - dense?: ListItemProps['dense']; - disableGutters?: ListItemProps['disableGutters']; - divider?: ListItemProps['divider']; - removeIcon?: ReactNode; - value?: unknown; -}; - -function ListItem({ - children = , - dense = true, - disableGutters, - divider, - removeIcon, -}: ListItemFieldProps) { - return ( - - {children} - - - ); -} - -export default connectField(ListItem, { - initialValue: false, -}); diff --git a/packages/uniforms-material/src/LongTextField.tsx b/packages/uniforms-material/src/LongTextField.tsx deleted file mode 100644 index c89cce92c..000000000 --- a/packages/uniforms-material/src/LongTextField.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import TextField, { TextFieldProps } from '@material-ui/core/TextField'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React from 'react'; -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -export type LongTextFieldProps = FieldProps; - -const LongText = ({ - disabled, - error, - errorMessage, - helperText, - inputRef, - label, - name, - onChange, - placeholder, - readOnly, - showInlineError, - type = 'text', - value, - ...props -}: LongTextFieldProps) => { - const theme = useTheme(); - const themeProps = theme.props?.MuiTextField; - - return ( - disabled || onChange(event.target.value)} - placeholder={placeholder} - ref={inputRef} - type={type} - value={value ?? ''} - {...filterDOMProps(props)} - /> - ); -}; - -export default connectField(LongText, { kind: 'leaf' }); diff --git a/packages/uniforms-material/src/NestField.tsx b/packages/uniforms-material/src/NestField.tsx deleted file mode 100644 index 06630daf9..000000000 --- a/packages/uniforms-material/src/NestField.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import FormLabel from '@material-ui/core/FormLabel'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React from 'react'; -import { connectField, HTMLFieldProps } from 'uniforms'; - -import AutoField from './AutoField'; -import wrapField from './wrapField'; - -// FIXME: wrapField is not typed correctly. -export type NestFieldProps = HTMLFieldProps< - object, - HTMLDivElement, - { helperText?: string; itemProps?: object; fullWidth?: boolean; margin?: any } ->; - -function Nest({ - children, - fields, - itemProps, - label, - ...props -}: NestFieldProps) { - const theme = useTheme(); - const formControlThemeProps = theme.props?.MuiFormControl; - return wrapField( - { - fullWidth: formControlThemeProps?.fullWidth ?? true, - margin: formControlThemeProps?.margin ?? 'dense', - ...props, - component: undefined, - }, - label && {label}, - children || - fields.map(field => ( - - )), - ); -} - -export default connectField(Nest); diff --git a/packages/uniforms-material/src/NumField.tsx b/packages/uniforms-material/src/NumField.tsx deleted file mode 100644 index a92e3e6fc..000000000 --- a/packages/uniforms-material/src/NumField.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import TextField, { TextFieldProps } from '@material-ui/core/TextField'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React from 'react'; -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -export type NumFieldProps = FieldProps< - number, - TextFieldProps, - { decimal?: boolean; max?: number; min?: number; step?: number } ->; - -function Num({ - decimal, - disabled, - error, - errorMessage, - helperText, - inputProps, - inputRef, - label, - max, - min, - name, - onChange, - readOnly, - placeholder, - showInlineError, - step = decimal ? 0.01 : 1, - value, - ...props -}: NumFieldProps) { - const theme = useTheme(); - const themeProps = theme.props?.MuiTextField; - - return ( - { - const parse = decimal ? parseFloat : parseInt; - const value = parse(event.target.value); - onChange(isNaN(value) ? undefined : value); - }} - placeholder={placeholder} - ref={inputRef} - type="number" - value={value ?? ''} - {...filterDOMProps(props)} - /> - ); -} - -export default connectField(Num, { kind: 'leaf' }); diff --git a/packages/uniforms-material/src/QuickForm.tsx b/packages/uniforms-material/src/QuickForm.tsx deleted file mode 100644 index 33abbfd3a..000000000 --- a/packages/uniforms-material/src/QuickForm.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { QuickForm } from 'uniforms'; - -import AutoField from './AutoField'; -import BaseForm from './BaseForm'; -import ErrorsField from './ErrorsField'; -import SubmitField from './SubmitField'; - -function Quick(parent: any) { - class _ extends QuickForm.Quick(parent) { - static Quick = Quick; - - getAutoField() { - return AutoField; - } - - getErrorsField() { - return ErrorsField; - } - - getSubmitField() { - return SubmitField; - } - } - - return _ as unknown as QuickForm; -} - -export default Quick(BaseForm); diff --git a/packages/uniforms-material/src/RadioField.tsx b/packages/uniforms-material/src/RadioField.tsx deleted file mode 100644 index 88cd52f54..000000000 --- a/packages/uniforms-material/src/RadioField.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import type { PropTypes } from '@material-ui/core'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormLabel from '@material-ui/core/FormLabel'; -import RadioMaterial, { RadioProps } from '@material-ui/core/Radio'; -import RadioGroup from '@material-ui/core/RadioGroup'; -import useTheme from '@material-ui/core/styles/useTheme'; -import omit from 'lodash/omit'; -import React from 'react'; -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -import type { Option } from './types'; -import wrapField from './wrapField'; - -const base64: (string: string) => string = - typeof btoa === 'undefined' - ? /* istanbul ignore next */ x => Buffer.from(x).toString('base64') - : btoa; -const escape = (x: string) => base64(encodeURIComponent(x)).replace(/=+$/, ''); - -export type RadioFieldProps = FieldProps< - string, - RadioProps, - { - options?: Option[]; - checkboxes?: boolean; - fullWidth?: boolean; - helperText?: string; - margin?: PropTypes.Margin; - row?: boolean; - } ->; - -function Radio({ - options, - disabled, - id, - inputRef, - label, - name, - onChange, - readOnly, - row, - value, - ...props -}: RadioFieldProps) { - const theme = useTheme(); - const formControlThemeProps = theme.props?.MuiFormControl; - return wrapField( - { - fullWidth: formControlThemeProps?.fullWidth ?? true, - margin: formControlThemeProps?.margin ?? 'dense', - ...props, - component: 'fieldset', - disabled, - }, - label && ( - - {label} - - ), - - disabled || readOnly || onChange(event.target.value) - } - ref={inputRef} - row={row} - value={value ?? ''} - > - {options?.map(item => ( - - } - htmlFor={`${id}-${escape(item.value)}`} - key={item.key ?? item.value} - label={item.label ?? item.value} - value={`${item.value}`} - /> - ))} - , - ); -} - -export default connectField(Radio, { kind: 'leaf' }); diff --git a/packages/uniforms-material/src/SelectField.tsx b/packages/uniforms-material/src/SelectField.tsx deleted file mode 100644 index ab1b37181..000000000 --- a/packages/uniforms-material/src/SelectField.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import Checkbox, { CheckboxProps } from '@material-ui/core/Checkbox'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import FormGroup from '@material-ui/core/FormGroup'; -import FormLabel from '@material-ui/core/FormLabel'; -import MenuItem from '@material-ui/core/MenuItem'; -import Radio from '@material-ui/core/Radio'; -import RadioGroup from '@material-ui/core/RadioGroup'; -import { SelectProps as MaterialSelectProps } from '@material-ui/core/Select'; -import Switch, { SwitchProps } from '@material-ui/core/Switch'; -import TextField, { TextFieldProps } from '@material-ui/core/TextField'; -import useTheme from '@material-ui/core/styles/useTheme'; -import omit from 'lodash/omit'; -import xor from 'lodash/xor'; -import React, { Ref } from 'react'; -import { FieldProps, connectField, filterDOMProps, Override } from 'uniforms'; - -import type { Option } from './types'; -import wrapField from './wrapField'; - -type SelectFieldCommonProps = { - appearance?: 'checkbox' | 'switch'; - inputRef?: Ref; - required?: boolean; - variant?: 'standard' | 'outlined' | 'filled'; - options?: Option[]; -}; - -type CheckboxesProps = FieldProps< - string | string[], - CheckboxProps | SwitchProps, - SelectFieldCommonProps & { - checkboxes: true; - legend?: string; - } ->; - -type SelectProps = FieldProps< - string | string[], - Override< - MaterialSelectProps & TextFieldProps, - { margin?: 'normal' | 'dense' | 'none' } - >, - SelectFieldCommonProps & { - checkboxes?: false; - labelProps?: object; - native?: boolean; - textFieldProps?: Omit; - } ->; - -export type SelectFieldProps = CheckboxesProps | SelectProps; - -const base64: (string: string) => string = - typeof btoa === 'undefined' - ? /* istanbul ignore next */ x => Buffer.from(x).toString('base64') - : btoa; -const escape = (x: string) => base64(encodeURIComponent(x)).replace(/=+$/, ''); - -// eslint-disable-next-line complexity -function Select(props: SelectFieldProps) { - const theme = useTheme(); - const formControlThemeProps = theme.props?.MuiFormControl; - const value = props.value ?? ''; - - if (props.checkboxes) { - const { - options, - disabled, - fieldType, - id, - inputRef, - label, - legend, - name, - onChange, - readOnly, - } = props; - - const appearance = props.appearance ?? 'checkbox'; - const SelectionControl = appearance === 'checkbox' ? Checkbox : Switch; - const filteredProps = omit(filterDOMProps(props), [ - 'checkboxes' as never, - 'disableItem' as never, - 'id', - 'inputRef', - ]); - - const children = - fieldType !== Array ? ( - - disabled || readOnly || onChange(event.target.value) - } - ref={inputRef} - value={value ?? ''} - > - {options?.map(option => ( - - } - disabled={option.disabled || disabled} - key={option.key ?? option.value} - label={option.label ?? option.value} - value={option.value} - /> - ))} - - ) : ( - - {options?.map(option => ( - - disabled || readOnly || onChange(xor([option.value], value)) - } - ref={inputRef} - value={name} - {...filteredProps} - /> - } - disabled={option.disabled || disabled} - key={option.key ?? option.value} - label={option.label ?? option.value} - /> - ))} - - ); - - return wrapField( - { ...formControlThemeProps, ...props, component: 'fieldset' }, - (legend || label) && ( - {legend || label} - ), - children, - ); - } - const textFieldThemeProps = theme.props?.MuiTextField; - const { - options, - disabled, - error, - errorMessage, - fieldType, - fullWidth = textFieldThemeProps?.fullWidth ?? true, - helperText, - id, - InputLabelProps, - inputProps, - label, - labelProps, - margin = textFieldThemeProps?.margin ?? 'dense', - name, - native, - onChange, - placeholder, - readOnly, - required, - showInlineError, - variant, - textFieldProps, - } = props; - - const Item = native ? 'option' : MenuItem; - const hasPlaceholder = !!placeholder; - const hasValue = value !== '' && value !== undefined; - - /* - Never was added because these 2 variables cause omit to fall into an unpleasant overload. - So we need to use a trick to reduce the confusion of handling types - */ - const filteredProps = omit(filterDOMProps(props), [ - 'checkboxes' as never, - 'disableItem' as never, - 'fullWidth', - 'helperText', - 'margin', - 'textFieldProps', - 'variant', - ]); - - return ( - - disabled || - readOnly || - onChange(event.target.value !== '' ? event.target.value : undefined) - } - required={required} - select - SelectProps={{ - displayEmpty: hasPlaceholder, - inputProps: { name, id, ...inputProps }, - multiple: fieldType === Array || undefined, - native, - ...filteredProps, - }} - value={native && !value ? '' : value} - variant={variant} - {...textFieldProps} - > - {(hasPlaceholder || !required || !hasValue) && ( - - {placeholder || label} - - )} - - {options?.map(option => ( - - {option.label ?? option.value} - - ))} - - ); -} - -export default connectField(Select, { kind: 'leaf' }); diff --git a/packages/uniforms-material/src/SubmitField.tsx b/packages/uniforms-material/src/SubmitField.tsx deleted file mode 100644 index ab8840b91..000000000 --- a/packages/uniforms-material/src/SubmitField.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import Button, { ButtonProps } from '@material-ui/core/Button'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React, { ReactNode, Ref } from 'react'; -import { Override, filterDOMProps, useForm } from 'uniforms'; - -export type SubmitFieldProps = Override< - ButtonProps, - // FIXME: What kind of `ref` is it? - { inputRef?: Ref; label?: ReactNode } ->; - -function SubmitField({ - children, - disabled, - inputRef, - label = 'Submit', - value, - ...props -}: SubmitFieldProps) { - const { error, state } = useForm(); - const theme = useTheme(); - const themeProps = theme.props?.MuiButton; - - return ( - - ); -} - -export default SubmitField; diff --git a/packages/uniforms-material/src/TextField.tsx b/packages/uniforms-material/src/TextField.tsx deleted file mode 100644 index b7a1e5004..000000000 --- a/packages/uniforms-material/src/TextField.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import TextField, { - TextFieldProps as MUITextFieldProps, -} from '@material-ui/core/TextField'; -import useTheme from '@material-ui/core/styles/useTheme'; -import React from 'react'; -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -export type TextFieldProps = FieldProps; - -function Text({ - disabled, - error, - errorMessage, - helperText, - inputRef, - label, - name, - onChange, - placeholder, - readOnly, - showInlineError, - type = 'text', - value = '', - ...props -}: TextFieldProps) { - const theme = useTheme(); - const themeProps = theme.props?.MuiTextField; - - return ( - disabled || onChange(event.target.value)} - placeholder={placeholder} - ref={inputRef} - type={type} - value={value} - {...filterDOMProps(props)} - /> - ); -} - -export default connectField(Text, { kind: 'leaf' }); diff --git a/packages/uniforms-material/src/ValidatedForm.tsx b/packages/uniforms-material/src/ValidatedForm.tsx deleted file mode 100644 index e843022ad..000000000 --- a/packages/uniforms-material/src/ValidatedForm.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { ValidatedForm } from 'uniforms'; - -import BaseForm from './BaseForm'; - -function Validated(parent: any) { - class _ extends ValidatedForm.Validated(parent) { - static Validated = Validated; - } - - return _ as unknown as ValidatedForm; -} - -export default Validated(BaseForm); diff --git a/packages/uniforms-material/src/ValidatedQuickForm.tsx b/packages/uniforms-material/src/ValidatedQuickForm.tsx deleted file mode 100644 index 554624af2..000000000 --- a/packages/uniforms-material/src/ValidatedQuickForm.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import BaseForm from './BaseForm'; -import QuickForm from './QuickForm'; -import ValidatedForm from './ValidatedForm'; - -export default ValidatedForm.Validated(QuickForm.Quick(BaseForm)); diff --git a/packages/uniforms-material/src/index.ts b/packages/uniforms-material/src/index.ts deleted file mode 100644 index d3c444bdf..000000000 --- a/packages/uniforms-material/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -export { default as AutoField, AutoFieldProps } from './AutoField'; -export { default as AutoFields, AutoFieldsProps } from './AutoFields'; -export { default as AutoForm } from './AutoForm'; -export { default as BaseForm } from './BaseForm'; -export { default as BoolField, BoolFieldProps } from './BoolField'; -export { default as DateField, DateFieldProps } from './DateField'; -export { default as ErrorField, ErrorFieldProps } from './ErrorField'; -export { default as ErrorsField, ErrorsFieldProps } from './ErrorsField'; -export { default as HiddenField, HiddenFieldProps } from './HiddenField'; -export { default as ListAddField, ListAddFieldProps } from './ListAddField'; -export { default as ListDelField, ListDelFieldProps } from './ListDelField'; -export { default as ListField, ListFieldProps } from './ListField'; -export { default as ListItemField, ListItemFieldProps } from './ListItemField'; -export { default as LongTextField, LongTextFieldProps } from './LongTextField'; -export { default as NestField, NestFieldProps } from './NestField'; -export { default as NumField, NumFieldProps } from './NumField'; -export { default as QuickForm } from './QuickForm'; -export { default as RadioField, RadioFieldProps } from './RadioField'; -export { default as SelectField, SelectFieldProps } from './SelectField'; -export { default as SubmitField, SubmitFieldProps } from './SubmitField'; -export { default as TextField, TextFieldProps } from './TextField'; -export { default as ValidatedForm } from './ValidatedForm'; -export { default as ValidatedQuickForm } from './ValidatedQuickForm'; -export { default as wrapField } from './wrapField'; diff --git a/packages/uniforms-material/src/types.ts b/packages/uniforms-material/src/types.ts deleted file mode 100644 index 77ec67be8..000000000 --- a/packages/uniforms-material/src/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** Option type used in SelectField or RadioField */ -export type Option = { - disabled?: boolean; - label?: string; - key?: string; - value: Value; -}; diff --git a/packages/uniforms-material/src/wrapField.tsx b/packages/uniforms-material/src/wrapField.tsx deleted file mode 100644 index 62e4dca82..000000000 --- a/packages/uniforms-material/src/wrapField.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import FormControl from '@material-ui/core/FormControl'; -import FormHelperText from '@material-ui/core/FormHelperText'; -import React, { ReactNode, createElement } from 'react'; - -export default function wrapField( - { - component, - disabled, - error, - errorMessage, - fullWidth, - helperText, - margin, - readOnly, - required, - showInlineError, - variant, - }: any, - ...children: ReactNode[] -) { - const formHelperText = showInlineError && error ? errorMessage : helperText; - const props = { - component, - disabled: !!disabled, - error: !!error, - fullWidth: !!fullWidth, - margin, - readOnly, - required, - variant, - }; - - return createElement( - FormControl, - props, - ...children, - !!formHelperText && {formHelperText}, - ); -} diff --git a/packages/uniforms-material/tsconfig.cjs.json b/packages/uniforms-material/tsconfig.cjs.json deleted file mode 100644 index 17e361e8b..000000000 --- a/packages/uniforms-material/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "baseUrl": "src", - "outDir": "cjs", - "rootDir": "src", - "module": "CommonJS", - "tsBuildInfoFile": "../../node_modules/.cache/uniforms-material.cjs.tsbuildinfo" - }, - "include": ["src"], - "references": [{ "path": "../uniforms/tsconfig.cjs.json" }] -} diff --git a/packages/uniforms-material/tsconfig.esm.json b/packages/uniforms-material/tsconfig.esm.json deleted file mode 100644 index f9293fc59..000000000 --- a/packages/uniforms-material/tsconfig.esm.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "baseUrl": "src", - "outDir": "esm", - "rootDir": "src", - "module": "ES6", - "tsBuildInfoFile": "../../node_modules/.cache/uniforms-material.esm.tsbuildinfo" - }, - "include": ["src"], - "references": [{ "path": "../uniforms/tsconfig.esm.json" }] -} diff --git a/packages/uniforms/__suites__/BoolField.tsx b/packages/uniforms/__suites__/BoolField.tsx index e2594abcc..83cb0894b 100644 --- a/packages/uniforms/__suites__/BoolField.tsx +++ b/packages/uniforms/__suites__/BoolField.tsx @@ -1,4 +1,3 @@ -import { ThemeProvider, createMuiTheme } from '@material-ui/core'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React, { ComponentType } from 'react'; @@ -750,82 +749,4 @@ export function testBoolField( ).toHaveLength(1); }, ); - - skipTestIf(!options?.testMUIThemeProps)( - ' - default props are not passed when MUI theme props are specified', - () => { - const theme = createMuiTheme({ - props: { MuiFormControl: { fullWidth: false, margin: 'normal' } }, - }); - - const screen = renderWithZod({ - element: ( - - - - ), - schema: z.object({ x: z.boolean() }), - }); - - const elements = screen.container.querySelectorAll( - '.MuiFormControl-marginNormal', - ); - - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }, - ); - - skipTestIf(!options?.testMUIThemeProps)( - ' - default props are passed when MUI theme props are absent', - () => { - const theme = createMuiTheme({}); - - const screen = renderWithZod({ - element: ( - - - - ), - schema: z.object({ x: z.boolean() }), - }); - - const elements = screen.container.querySelectorAll( - '.MuiFormControl-marginDense', - ); - - expect(elements).toHaveLength(1); - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - }, - ); - - skipTestIf(!options?.testMUIThemeProps)( - ' - explicit props are passed when MUI theme props are specified', - () => { - const theme = createMuiTheme({ - props: { MuiFormControl: { fullWidth: true, margin: 'dense' } }, - }); - - const explicitProps = { - fullWidth: false, - margin: 'normal' as const, - }; - - const screen = renderWithZod({ - element: ( - - - - ), - schema: z.object({ x: z.boolean() }), - }); - - const elements = screen.container.querySelectorAll( - '.MuiFormControl-marginNormal', - ); - - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }, - ); } diff --git a/reproductions/App.tsx b/reproductions/App.tsx index 1d75fd55c..42c9c34bd 100644 --- a/reproductions/App.tsx +++ b/reproductions/App.tsx @@ -3,7 +3,6 @@ import React from 'react'; // import { AutoForm } from 'uniforms-antd'; // import { AutoForm } from 'uniforms-bootstrap4'; // import { AutoForm } from 'uniforms-bootstrap5'; -// import { AutoForm } from 'uniforms-material'; import { AutoForm } from 'uniforms-mui'; // import { AutoForm } from 'uniforms-semantic'; diff --git a/reproductions/package.json b/reproductions/package.json index b9a5fc587..12b11d3d5 100644 --- a/reproductions/package.json +++ b/reproductions/package.json @@ -9,8 +9,6 @@ "@ant-design/icons": "4.4.0", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@material-ui/core": "4.11.2", - "@material-ui/icons": "4.11.2", "@mui/material": "5.4.1", "@types/react": "17.0.39", "@types/react-dom": "17.0.11", @@ -27,7 +25,6 @@ "uniforms-bootstrap5": "^4.0.0-alpha.0", "uniforms-bridge-json-schema": "^4.0.0-alpha.0", "uniforms-bridge-simple-schema-2": "^4.0.0-alpha.0", - "uniforms-material": "^4.0.0-alpha.0", "uniforms-mui": "^4.0.0-alpha.0", "uniforms-semantic": "^4.0.0-alpha.0", "uniforms-unstyled": "^4.0.0-alpha.0" diff --git a/tsconfig.build.json b/tsconfig.build.json index 46503b469..a5e14e2ae 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -16,8 +16,6 @@ { "path": "packages/uniforms-bridge-simple-schema-2/tsconfig.esm.json" }, { "path": "packages/uniforms-bridge-zod/tsconfig.cjs.json" }, { "path": "packages/uniforms-bridge-zod/tsconfig.esm.json" }, - { "path": "packages/uniforms-material/tsconfig.cjs.json" }, - { "path": "packages/uniforms-material/tsconfig.esm.json" }, { "path": "packages/uniforms-mui/tsconfig.cjs.json" }, { "path": "packages/uniforms-mui/tsconfig.esm.json" }, { "path": "packages/uniforms-semantic/tsconfig.cjs.json" }, diff --git a/tsconfig.global.json b/tsconfig.global.json index 0aae04bc4..1114d33f6 100644 --- a/tsconfig.global.json +++ b/tsconfig.global.json @@ -26,8 +26,6 @@ { "path": "packages/uniforms-bridge-simple-schema-2/tsconfig.cjs.json" }, { "path": "packages/uniforms-bridge-zod/tsconfig.esm.json" }, { "path": "packages/uniforms-bridge-zod/tsconfig.cjs.json" }, - { "path": "packages/uniforms-material/tsconfig.esm.json" }, - { "path": "packages/uniforms-material/tsconfig.cjs.json" }, { "path": "packages/uniforms-mui/tsconfig.esm.json" }, { "path": "packages/uniforms-mui/tsconfig.cjs.json" }, { "path": "packages/uniforms-semantic/tsconfig.esm.json" }, diff --git a/website/components/ExampleCustomizer.tsx b/website/components/ExampleCustomizer.tsx index eb64c5748..1401e5381 100644 --- a/website/components/ExampleCustomizer.tsx +++ b/website/components/ExampleCustomizer.tsx @@ -8,7 +8,6 @@ import { TogglerTabs } from './TogglerTabs'; const tabs = [ { name: 'Semantic', value: 'semantic' as const }, - { name: 'Material', value: 'material' as const }, { name: 'MUI', value: 'mui' as const }, { name: 'Bootstrap4', value: 'bootstrap4' as const }, { name: 'Bootstrap5', value: 'bootstrap5' as const }, diff --git a/website/components/Playground.tsx b/website/components/Playground.tsx index 22763f4d8..7e88adc0e 100644 --- a/website/components/Playground.tsx +++ b/website/components/Playground.tsx @@ -188,7 +188,6 @@ class PlaygroundProps extends Component { const isAntd = theme === 'antd'; const isBootstrap = theme === 'bootstrap4'; - const isMaterial = theme === 'material'; const isSemantic = theme === 'semantic'; // FIXME: theme is undefined during `docusaurus build`. @@ -212,14 +211,11 @@ class PlaygroundProps extends Component { - + @@ -258,7 +254,7 @@ export class PlaygroundWrap extends Component { ); - if (theme === 'material' || theme === 'mui') { + if (theme === 'mui') { // Material-UI injects scoped CSS classes into head. return (
AntD theme
  • Bootstrap4
  • Bootstrap5
  • -
  • Material-UI
  • MUI
  • Semantic UI
  • Plain HTML