From 3000ea5cfa935b7c28d11602dde0322af9e2438f Mon Sep 17 00:00:00 2001 From: Phil Edwards Date: Thu, 4 Jul 2024 12:05:23 -0400 Subject: [PATCH 1/7] Remove legacy React contextTypes This removes some legacy api deprecation notices in the console in React 18. - Replace the last this.context.router in projectSettings.es6 with this.props.router from withRouter HOC. (Tested this, works fine) - Remove these, which are unused: SomeComponent.contextTypes = { router: PropTypes.object }; --- jsapp/js/app.jsx | 3 --- jsapp/js/components/RESTServices/RESTServiceLogs.es6 | 5 ----- jsapp/js/components/drawer.es6 | 9 --------- jsapp/js/components/formEditors.js | 4 ---- jsapp/js/components/formLanding.js | 5 ----- jsapp/js/components/formSubScreens.js | 6 ------ jsapp/js/components/formViewSideTabs.es6 | 5 ----- jsapp/js/components/modalForms/libraryAssetForm.es6 | 2 -- jsapp/js/components/modalForms/libraryNewItemForm.es6 | 5 ----- jsapp/js/components/modalForms/projectSettings.es6 | 11 ++++------- jsapp/js/lists/sidebarForms.es6 | 5 ----- 11 files changed, 4 insertions(+), 56 deletions(-) diff --git a/jsapp/js/app.jsx b/jsapp/js/app.jsx index f68fe3c6a2..a0893685ad 100644 --- a/jsapp/js/app.jsx +++ b/jsapp/js/app.jsx @@ -3,12 +3,10 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; import DocumentTitle from 'react-document-title'; import {Outlet} from 'react-router-dom'; import reactMixin from 'react-mixin'; import Reflux from 'reflux'; -import {stores} from 'js/stores'; import 'js/surveyCompanionStore'; // importing it so it exists import {} from 'js/bemComponents'; // importing it so it exists import bem from 'js/bem'; @@ -147,7 +145,6 @@ class App extends React.Component { } } -App.contextTypes = {router: PropTypes.object}; reactMixin(App.prototype, Reflux.connect(pageState, 'pageState')); reactMixin(App.prototype, mixins.contextRouter); diff --git a/jsapp/js/components/RESTServices/RESTServiceLogs.es6 b/jsapp/js/components/RESTServices/RESTServiceLogs.es6 index de8f6b04f0..3265a9a461 100644 --- a/jsapp/js/components/RESTServices/RESTServiceLogs.es6 +++ b/jsapp/js/components/RESTServices/RESTServiceLogs.es6 @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import autoBind from 'react-autobind'; import reactMixin from 'react-mixin'; import Reflux from 'reflux'; @@ -368,7 +367,3 @@ export default class RESTServiceLogs extends React.Component { reactMixin(RESTServiceLogs.prototype, Reflux.ListenerMixin); reactMixin(RESTServiceLogs.prototype, mixins.contextRouter); - -RESTServiceLogs.contextTypes = { - router: PropTypes.object -}; diff --git a/jsapp/js/components/drawer.es6 b/jsapp/js/components/drawer.es6 index 458584c411..fbefdb6b83 100644 --- a/jsapp/js/components/drawer.es6 +++ b/jsapp/js/components/drawer.es6 @@ -1,5 +1,4 @@ import React, {lazy, Suspense} from 'react'; -import PropTypes from 'prop-types'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import {observer} from 'mobx-react'; @@ -90,10 +89,6 @@ const FormSidebar = observer( } ); -FormSidebar.contextTypes = { - router: PropTypes.object, -}; - reactMixin(FormSidebar.prototype, searches.common); reactMixin(FormSidebar.prototype, mixins.droppable); @@ -217,8 +212,4 @@ reactMixin(Drawer.prototype, searches.common); reactMixin(Drawer.prototype, mixins.droppable); reactMixin(Drawer.prototype, mixins.contextRouter); -Drawer.contextTypes = { - router: PropTypes.object, -}; - export default withRouter(Drawer); diff --git a/jsapp/js/components/formEditors.js b/jsapp/js/components/formEditors.js index cab6b7eaeb..f22968c1b5 100644 --- a/jsapp/js/components/formEditors.js +++ b/jsapp/js/components/formEditors.js @@ -1,12 +1,10 @@ import React from 'react'; -import PropTypes from 'prop-types'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import Reflux from 'reflux'; import editableFormMixin from '../editorMixins/editableForm'; import {update_states} from 'js/constants'; import {ROUTES} from 'js/router/routerConstants'; -import mixins from '../mixins'; import {withRouter} from 'js/router/legacy'; /** @@ -29,7 +27,6 @@ export class FormPage extends React.Component { } reactMixin(FormPage.prototype, Reflux.ListenerMixin); reactMixin(FormPage.prototype, editableFormMixin); -FormPage.contextTypes = {router: PropTypes.object}; class LibraryAssetEditorComponent extends React.Component { constructor(props) { @@ -69,6 +66,5 @@ class LibraryAssetEditorComponent extends React.Component { } reactMixin(LibraryAssetEditorComponent.prototype, Reflux.ListenerMixin); reactMixin(LibraryAssetEditorComponent.prototype, editableFormMixin); -LibraryAssetEditorComponent.contextTypes = {router: PropTypes.object}; export const LibraryAssetEditor = withRouter(LibraryAssetEditorComponent); diff --git a/jsapp/js/components/formLanding.js b/jsapp/js/components/formLanding.js index 9b8cbfc16a..0f52ffae4d 100644 --- a/jsapp/js/components/formLanding.js +++ b/jsapp/js/components/formLanding.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import Reflux from 'reflux'; @@ -804,8 +803,4 @@ class FormLanding extends React.Component { reactMixin(FormLanding.prototype, mixins.dmix); reactMixin(FormLanding.prototype, Reflux.ListenerMixin); -FormLanding.contextTypes = { - router: PropTypes.object, -}; - export default withRouter(FormLanding); diff --git a/jsapp/js/components/formSubScreens.js b/jsapp/js/components/formSubScreens.js index d73cdfe6b0..6a2fa90ff8 100644 --- a/jsapp/js/components/formSubScreens.js +++ b/jsapp/js/components/formSubScreens.js @@ -1,5 +1,4 @@ import React, {Suspense} from 'react'; -import PropTypes from 'prop-types'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import {actions} from '../actions'; @@ -15,7 +14,6 @@ import RESTServices from './RESTServices'; import LoadingSpinner from 'js/components/common/loadingSpinner'; import {ROUTES} from 'js/router/routerConstants'; import {withRouter} from 'js/router/legacy'; -import sessionStore from 'js/stores/session'; import TransferProjects from 'js/components/permissions/transferProjects/transferProjects.component'; const ConnectProjects = React.lazy(() => @@ -166,8 +164,4 @@ export class FormSubScreens extends React.Component { reactMixin(FormSubScreens.prototype, mixins.dmix); reactMixin(FormSubScreens.prototype, mixins.contextRouter); -FormSubScreens.contextTypes = { - router: PropTypes.object, -}; - export default withRouter(FormSubScreens); diff --git a/jsapp/js/components/formViewSideTabs.es6 b/jsapp/js/components/formViewSideTabs.es6 index 3b177aea5b..f5bc578c54 100644 --- a/jsapp/js/components/formViewSideTabs.es6 +++ b/jsapp/js/components/formViewSideTabs.es6 @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import Reflux from 'reflux'; @@ -207,8 +206,4 @@ class FormViewSideTabs extends Reflux.Component { reactMixin(FormViewSideTabs.prototype, Reflux.ListenerMixin); reactMixin(FormViewSideTabs.prototype, mixins.contextRouter); -FormViewSideTabs.contextTypes = { - router: PropTypes.object, -}; - export default withRouter(FormViewSideTabs); diff --git a/jsapp/js/components/modalForms/libraryAssetForm.es6 b/jsapp/js/components/modalForms/libraryAssetForm.es6 index f8b8ae884a..af6fcf126e 100644 --- a/jsapp/js/components/modalForms/libraryAssetForm.es6 +++ b/jsapp/js/components/modalForms/libraryAssetForm.es6 @@ -6,7 +6,6 @@ import Reflux from 'reflux'; import clonedeep from 'lodash.clonedeep'; import KoboTagsInput from 'js/components/common/koboTagsInput'; import WrappedSelect from 'js/components/common/wrappedSelect'; -import PropTypes from 'prop-types'; import TextBox from 'js/components/common/textBox'; import bem from 'js/bem'; import LoadingSpinner from 'js/components/common/loadingSpinner'; @@ -294,5 +293,4 @@ export class LibraryAssetFormComponent extends React.Component { reactMixin(LibraryAssetFormComponent.prototype, Reflux.ListenerMixin); reactMixin(LibraryAssetFormComponent.prototype, mixins.contextRouter); -LibraryAssetFormComponent.contextTypes = {router: PropTypes.object}; export const LibraryAssetForm = withRouter(LibraryAssetFormComponent); diff --git a/jsapp/js/components/modalForms/libraryNewItemForm.es6 b/jsapp/js/components/modalForms/libraryNewItemForm.es6 index 86956887ef..0f1d07774a 100644 --- a/jsapp/js/components/modalForms/libraryNewItemForm.es6 +++ b/jsapp/js/components/modalForms/libraryNewItemForm.es6 @@ -2,7 +2,6 @@ import React from 'react'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import Reflux from 'reflux'; -import PropTypes from 'prop-types'; import bem from 'js/bem'; import LoadingSpinner from 'js/components/common/loadingSpinner'; import sessionStore from 'js/stores/session'; @@ -106,8 +105,4 @@ class LibraryNewItemForm extends React.Component { reactMixin(LibraryNewItemForm.prototype, Reflux.ListenerMixin); reactMixin(LibraryNewItemForm.prototype, mixins.contextRouter); -LibraryNewItemForm.contextTypes = { - router: PropTypes.object -}; - export default withRouter(LibraryNewItemForm); diff --git a/jsapp/js/components/modalForms/projectSettings.es6 b/jsapp/js/components/modalForms/projectSettings.es6 index 8dba44a3d4..fff527f81f 100644 --- a/jsapp/js/components/modalForms/projectSettings.es6 +++ b/jsapp/js/components/modalForms/projectSettings.es6 @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import {when} from 'mobx'; @@ -355,10 +354,10 @@ class ProjectSettings extends React.Component { let targetUid; if (this.state.formAsset) { targetUid = this.state.formAsset.uid; - } else if (this.context.router && this.context.router.params.assetid) { - targetUid = this.context.router.params.assetid; - } else if (this.context.router && this.context.router.params.uid) { - targetUid = this.context.router.params.uid; + } else if (this.props.router.params.assetid) { + targetUid = this.props.router.params.assetid; + } else if (this.props.router.params.uid) { + targetUid = this.props.router.params.uid; } if (!targetUid) { @@ -1131,6 +1130,4 @@ reactMixin(ProjectSettings.prototype, mixins.droppable); // NOTE: dmix mixin is causing a full asset load after component mounts reactMixin(ProjectSettings.prototype, mixins.dmix); -ProjectSettings.contextTypes = {router: PropTypes.object}; - export default withRouter(ProjectSettings); diff --git a/jsapp/js/lists/sidebarForms.es6 b/jsapp/js/lists/sidebarForms.es6 index c413a3c99a..4af91b94ae 100644 --- a/jsapp/js/lists/sidebarForms.es6 +++ b/jsapp/js/lists/sidebarForms.es6 @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import reactMixin from 'react-mixin'; import autoBind from 'react-autobind'; import {Link} from 'react-router-dom'; @@ -149,10 +148,6 @@ class SidebarFormsList extends Reflux.Component { } } -SidebarFormsList.contextTypes = { - router: PropTypes.object, -}; - reactMixin(SidebarFormsList.prototype, searches.common); reactMixin(SidebarFormsList.prototype, Reflux.ListenerMixin); reactMixin(SidebarFormsList.prototype, mixins.contextRouter); From 6dbcacecd38308bbba2a4af8c0ed25a93c4ba344 Mon Sep 17 00:00:00 2001 From: Phil Edwards Date: Thu, 4 Jul 2024 12:06:58 -0400 Subject: [PATCH 2/7] The last user of 'prop-types': reactBemComponents --- jsapp/js/libs/reactBemComponents.es6 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/jsapp/js/libs/reactBemComponents.es6 b/jsapp/js/libs/reactBemComponents.es6 index 4c7cebdb60..54d156b8b1 100644 --- a/jsapp/js/libs/reactBemComponents.es6 +++ b/jsapp/js/libs/reactBemComponents.es6 @@ -38,7 +38,7 @@ */ import React from 'react'; import classNames from 'classnames'; -import PropTypes from 'prop-types'; +// import PropTypes from 'prop-types'; const reactCreateBemElement = function(base, el='div'){ let elUnwrap; @@ -82,11 +82,13 @@ const reactCreateBemElement = function(base, el='div'){ return React.createElement(el, props); } }; - c.propTypes = { - m: PropTypes.any, - className: PropTypes.string, - classNames: PropTypes.any, - }; + + // TODO: replace propTypes with TS and remove the prop-types library + // c.propTypes = { + // m: PropTypes.any, + // className: PropTypes.string, + // classNames: PropTypes.any, + // }; c.displayName = `BEM.${base}`; return c; }; From 17e875937b349a7f354b83ea3d2efd3b37f854e7 Mon Sep 17 00:00:00 2001 From: Phil Edwards Date: Thu, 4 Jul 2024 12:15:44 -0400 Subject: [PATCH 3/7] reactBemComponents .es6 -> .tsx Doing this step in one commit, hoping it will make the diff easier to review online. --- jsapp/js/libs/{reactBemComponents.es6 => reactBemComponents.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jsapp/js/libs/{reactBemComponents.es6 => reactBemComponents.tsx} (100%) diff --git a/jsapp/js/libs/reactBemComponents.es6 b/jsapp/js/libs/reactBemComponents.tsx similarity index 100% rename from jsapp/js/libs/reactBemComponents.es6 rename to jsapp/js/libs/reactBemComponents.tsx From 5b3c6f94724895f6bc07cb3065f5f3a3c6f76bb3 Mon Sep 17 00:00:00 2001 From: Phil Edwards Date: Thu, 4 Jul 2024 12:22:13 -0400 Subject: [PATCH 4/7] TypeScript-ize reactBemComponents --- jsapp/js/libs/reactBemComponents.tsx | 51 ++++++++++++++++++---------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/jsapp/js/libs/reactBemComponents.tsx b/jsapp/js/libs/reactBemComponents.tsx index 54d156b8b1..6d70a0ae51 100644 --- a/jsapp/js/libs/reactBemComponents.tsx +++ b/jsapp/js/libs/reactBemComponents.tsx @@ -37,10 +37,11 @@ */ import React from 'react'; -import classNames from 'classnames'; +import cx from 'classnames'; +import type { Argument as ClassnamesArgument } from 'classnames' // import PropTypes from 'prop-types'; -const reactCreateBemElement = function(base, el='div'){ +const reactCreateBemElement = function(base: string, el='div'){ let elUnwrap; if (el.match) { elUnwrap = el.match(/\<(\w+)\s?\/?\>/); @@ -49,8 +50,15 @@ const reactCreateBemElement = function(base, el='div'){ } } - let reduceModify = function (s, modifier){ - if (Object.prototype.toString.call(modifier) === '[object Object]') { + const reduceModify = function ( + s: {[key: string]: boolean}, + modifier: + {[key: string]: boolean} + | string[] + | string + | undefined + ){ + if (typeof modifier === 'object' && !Array.isArray(modifier)) { Object.keys(modifier).forEach(function(key){ if (modifier[key]) { s[`${base}--${key}`] = true; @@ -62,26 +70,34 @@ const reactCreateBemElement = function(base, el='div'){ return s; }; - class c extends React.Component { - render () { + + class c extends React.Component<{ + m?: string[] | string; + className: string; + classNames: ClassnamesArgument; + }> { + render() { const props = Object.assign({}, this.props); // allows modifiers to be a string, an array, or undefined (ignored) - let modifier = [].concat(props.m) + const modifier = ([] as Array).concat(props.m) .reduce(reduceModify, {}); - delete props.m; // builds the bem classNames, and allows additional classNames // to be specified in an object (props.classNames) or normal string - props.className = classNames(base, - modifier, - props.classNames, - props.className); - delete props.classNames; + const className = cx(base, + modifier, + props.classNames, + props.className); - return React.createElement(el, props); + // Omitting m and classNames from new Props + // via "Tricky Destructuring Assignment" (https://stackoverflow.com/a/33053362) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const {m, classNames, ...newProps} = props; + return React.createElement(el, {...newProps, className, modifier}); } - }; + static displayName = `BEM.${base}`; + } // TODO: replace propTypes with TS and remove the prop-types library // c.propTypes = { @@ -89,13 +105,12 @@ const reactCreateBemElement = function(base, el='div'){ // className: PropTypes.string, // classNames: PropTypes.any, // }; - c.displayName = `BEM.${base}`; return c; }; -export function bemComponents (obj) { +export function bemComponents (obj: {[key: string]: ([string, string?] | string)}) { let keys = Object.keys(obj); - return Object.freeze(keys.reduce(function(hsh, key){ + return Object.freeze(keys.reduce(function(hsh: any, key){ let val = obj[key]; if (val instanceof Array) { hsh[key] = reactCreateBemElement.apply(null, val); From 1995b1a5cbbb6601e34166b63678f6da85bad592 Mon Sep 17 00:00:00 2001 From: Phil Edwards Date: Thu, 4 Jul 2024 12:27:12 -0400 Subject: [PATCH 5/7] Remove 'prop-types' dependency --- jsapp/js/libs/reactBemComponents.tsx | 7 ------- package-lock.json | 1 - package.json | 1 - 3 files changed, 9 deletions(-) diff --git a/jsapp/js/libs/reactBemComponents.tsx b/jsapp/js/libs/reactBemComponents.tsx index 6d70a0ae51..6a730ccbec 100644 --- a/jsapp/js/libs/reactBemComponents.tsx +++ b/jsapp/js/libs/reactBemComponents.tsx @@ -39,7 +39,6 @@ import React from 'react'; import cx from 'classnames'; import type { Argument as ClassnamesArgument } from 'classnames' -// import PropTypes from 'prop-types'; const reactCreateBemElement = function(base: string, el='div'){ let elUnwrap; @@ -99,12 +98,6 @@ const reactCreateBemElement = function(base: string, el='div'){ static displayName = `BEM.${base}`; } - // TODO: replace propTypes with TS and remove the prop-types library - // c.propTypes = { - // m: PropTypes.any, - // className: PropTypes.string, - // classNames: PropTypes.any, - // }; return c; }; diff --git a/package-lock.json b/package-lock.json index e185ff5e0d..d34146bb8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,6 @@ "mobx-react": "^7.6.0", "normalize.css": "^8.0.1", "pretty-bytes": "^6.1.1", - "prop-types": "^15.7.2", "qrcode.react": "^3.1.0", "react": "^18.3.1", "react-autobind": "^1.0.6", diff --git a/package.json b/package.json index b9550022e8..7119283340 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "mobx-react": "^7.6.0", "normalize.css": "^8.0.1", "pretty-bytes": "^6.1.1", - "prop-types": "^15.7.2", "qrcode.react": "^3.1.0", "react": "^18.3.1", "react-autobind": "^1.0.6", From ad794231be71e0f2f0171c34ef9d2bdda443d152 Mon Sep 17 00:00:00 2001 From: Phil Edwards Date: Fri, 5 Jul 2024 12:25:35 -0400 Subject: [PATCH 6/7] =?UTF-8?q?Install=20eslint-plugin-import=20for=20sepa?= =?UTF-8?q?rate=20type=20import=20statements=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e.g., not say 'duplicate import' for this code: import React from 'react' import type { ReactNode } from 'react' …which used to work fine, but typescript-eslint's no-duplicate-imports rule has been removed: - https://github.com/typescript-eslint/typescript-eslint/commit/47eeea9275bd - https://typescript-eslint.io/rules/no-duplicate-imports/ We could do more with this plugin. Only skimmed it, but some of the other features might require some more config. - https://github.com/import-js/eslint-plugin-import/blob/main/README.md#resolvers (Meanwhile, I'll try not to think about how many dev dependencies we bring in just for this cool rule.) --- .eslintrc.js | 19 ++- package-lock.json | 420 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 3 files changed, 439 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 13dee0c4c6..ce20b001b1 100755 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -171,7 +171,11 @@ const tsRules = Object.assign({}, jsRules, { 'comma-dangle': 'off', 'comma-spacing': 'off', 'func-call-spacing': 'off', - 'no-duplicate-imports': [1, {includeExports: true}], + // The 'import' plugin supports separately importing types + // (@typescript-eslint/no-duplicate-imports is deprecated) + 'import/no-duplicates': 1, + // Turn off ESLint's version of this rule when in TypeScript + 'no-duplicate-imports': 'off', 'no-nonoctal-decimal-escape': 'off', // It is recommended that this check is disabled for TS files, see: // https://typescript-eslint.io/docs/linting/troubleshooting/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors @@ -213,7 +217,18 @@ module.exports = { { files: ['**/*.ts', '**/*.tsx'], parser: '@typescript-eslint/parser', - plugins: ['react', '@typescript-eslint'], + plugins: [ + 'react', + '@typescript-eslint', + // For import/no-duplicates + // Could do more with it. + 'import', + ], + settings: { + 'import/resolver': { + typescript: true, + }, + }, extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], parserOptions: { project: ['./tsconfig.json'], diff --git a/package-lock.json b/package-lock.json index d34146bb8b..fcaa48dfe9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -130,6 +130,8 @@ "css-loader": "^6.11.0", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-react": "^7.30.1", "eslint-plugin-storybook": "^0.6.15", "fork-ts-checker-webpack-plugin": "^9.0.2", @@ -7454,6 +7456,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/lodash": { "version": "4.17.6", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", @@ -8836,6 +8844,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -12220,6 +12248,175 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/eslint-plugin-react": { "version": "7.34.3", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", @@ -13862,6 +14059,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/giget": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/giget/-/giget-1.1.3.tgz", @@ -18245,6 +18454,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.hasown": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", @@ -20982,6 +21205,15 @@ "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -30994,6 +31226,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "@types/lodash": { "version": "4.17.6", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", @@ -32144,6 +32382,20 @@ "es-shim-unscopables": "^1.0.2" } }, + "array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + } + }, "array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -34803,6 +35055,148 @@ "dev": true, "requires": {} }, + "eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + } + }, + "eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "requires": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + } + } + }, "eslint-plugin-react": { "version": "7.34.3", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", @@ -35960,6 +36354,15 @@ "get-intrinsic": "^1.2.4" } }, + "get-tsconfig": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "giget": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/giget/-/giget-1.1.3.tgz", @@ -39260,6 +39663,17 @@ "safe-array-concat": "^1.1.2" } }, + "object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + } + }, "object.hasown": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", @@ -41250,6 +41664,12 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", diff --git a/package.json b/package.json index 7119283340..744b07769c 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,8 @@ "css-loader": "^6.11.0", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-react": "^7.30.1", "eslint-plugin-storybook": "^0.6.15", "fork-ts-checker-webpack-plugin": "^9.0.2", From e4056df5870653a37e0793cdea9dd82b24babded Mon Sep 17 00:00:00 2001 From: Phil Edwards Date: Fri, 5 Jul 2024 17:20:19 -0400 Subject: [PATCH 7/7] Refinements after testing KoboMatrix - Remove modifier='[object Object]' in generated bem elements - Use the new React 18 root API in renderInBackbone --- jsapp/js/formbuild/renderInBackbone.es6 | 5 +++-- jsapp/js/libs/reactBemComponents.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/jsapp/js/formbuild/renderInBackbone.es6 b/jsapp/js/formbuild/renderInBackbone.es6 index 85b3cbacaf..3daa304eb7 100644 --- a/jsapp/js/formbuild/renderInBackbone.es6 +++ b/jsapp/js/formbuild/renderInBackbone.es6 @@ -1,5 +1,5 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import {createRoot} from 'react-dom/client'; import KoboMatrix from './containers/KoboMatrix'; import { fromJS } from 'immutable'; @@ -45,5 +45,6 @@ class KoboMatrixRow { export function renderKobomatrix (view, el) { let model = new KoboMatrixRow(view.model); - ReactDOM.render(, el.get(0)); + const root = createRoot(el.get(0)); + root.render(); } diff --git a/jsapp/js/libs/reactBemComponents.tsx b/jsapp/js/libs/reactBemComponents.tsx index 6a730ccbec..e5fe6a7068 100644 --- a/jsapp/js/libs/reactBemComponents.tsx +++ b/jsapp/js/libs/reactBemComponents.tsx @@ -93,7 +93,7 @@ const reactCreateBemElement = function(base: string, el='div'){ // via "Tricky Destructuring Assignment" (https://stackoverflow.com/a/33053362) // eslint-disable-next-line @typescript-eslint/no-unused-vars const {m, classNames, ...newProps} = props; - return React.createElement(el, {...newProps, className, modifier}); + return React.createElement(el, {...newProps, className}); } static displayName = `BEM.${base}`; }