mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Upgrade react-dnd (#16753)
GitOrigin-RevId: 5a62bed823b716a6e0d6d3aa57ee187d161f3346
This commit is contained in:
parent
34f34c02e3
commit
6dc7ced2df
13 changed files with 311 additions and 277 deletions
147
package-lock.json
generated
147
package-lock.json
generated
|
@ -9813,21 +9813,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-dnd/asap": {
|
"node_modules/@react-dnd/asap": {
|
||||||
"version": "4.0.0",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
|
||||||
"integrity": "sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==",
|
"integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@react-dnd/invariant": {
|
"node_modules/@react-dnd/invariant": {
|
||||||
"version": "2.0.0",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
|
||||||
"integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==",
|
"integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@react-dnd/shallowequal": {
|
"node_modules/@react-dnd/shallowequal": {
|
||||||
"version": "2.0.0",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
|
||||||
"integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==",
|
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@replit/codemirror-emacs": {
|
"node_modules/@replit/codemirror-emacs": {
|
||||||
|
@ -15638,6 +15638,8 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||||
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
|
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/react": "*",
|
"@types/react": "*",
|
||||||
"hoist-non-react-statics": "^3.3.0"
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
|
@ -22091,14 +22093,14 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/dnd-core": {
|
"node_modules/dnd-core": {
|
||||||
"version": "11.1.3",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
|
||||||
"integrity": "sha512-QugF55dNW+h+vzxVJ/LSJeTeUw9MCJ2cllhmVThVPEtF16ooBkxj0WBE5RB+AceFxMFo1rO6bJKXtqKl+JNnyA==",
|
"integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-dnd/asap": "^4.0.0",
|
"@react-dnd/asap": "^5.0.1",
|
||||||
"@react-dnd/invariant": "^2.0.0",
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
"redux": "^4.0.4"
|
"redux": "^4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dns-equal": {
|
"node_modules/dns-equal": {
|
||||||
|
@ -36395,28 +36397,42 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/react-dnd": {
|
"node_modules/react-dnd": {
|
||||||
"version": "11.1.3",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
|
||||||
"integrity": "sha512-8rtzzT8iwHgdSC89VktwhqdKKtfXaAyC4wiqp0SywpHG12TTLvfOoL6xNEIUWXwIEWu+CFfDn4GZJyynCEuHIQ==",
|
"integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-dnd/shallowequal": "^2.0.0",
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
"@types/hoist-non-react-statics": "^3.3.1",
|
"@react-dnd/shallowequal": "^4.0.1",
|
||||||
"dnd-core": "^11.1.3",
|
"dnd-core": "^16.0.1",
|
||||||
"hoist-non-react-statics": "^3.3.0"
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"hoist-non-react-statics": "^3.3.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">= 16.9.0",
|
"@types/hoist-non-react-statics": ">= 3.3.1",
|
||||||
"react-dom": ">= 16.9.0"
|
"@types/node": ">= 12",
|
||||||
|
"@types/react": ">= 16",
|
||||||
|
"react": ">= 16.14"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/hoist-non-react-statics": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dnd-html5-backend": {
|
"node_modules/react-dnd-html5-backend": {
|
||||||
"version": "11.1.3",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
|
||||||
"integrity": "sha512-/1FjNlJbW/ivkUxlxQd7o3trA5DE33QiRZgxent3zKme8DwF4Nbw3OFVhTRFGaYhHFNL1rZt6Rdj1D78BjnNLw==",
|
"integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dnd-core": "^11.1.3"
|
"dnd-core": "^16.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-docgen": {
|
"node_modules/react-docgen": {
|
||||||
|
@ -37086,9 +37102,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/redux": {
|
"node_modules/redux": {
|
||||||
"version": "4.1.2",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||||
"integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
|
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.9.2"
|
"@babel/runtime": "^7.9.2"
|
||||||
|
@ -46316,8 +46332,8 @@
|
||||||
"react-bootstrap": "^0.33.1",
|
"react-bootstrap": "^0.33.1",
|
||||||
"react-chartjs-2": "^5.0.1",
|
"react-chartjs-2": "^5.0.1",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
"react-dnd": "^11.1.3",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^11.1.3",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-error-boundary": "^2.3.1",
|
"react-error-boundary": "^2.3.1",
|
||||||
"react-google-recaptcha": "^3.1.0",
|
"react-google-recaptcha": "^3.1.0",
|
||||||
|
@ -55223,8 +55239,8 @@
|
||||||
"react-bootstrap": "^0.33.1",
|
"react-bootstrap": "^0.33.1",
|
||||||
"react-chartjs-2": "^5.0.1",
|
"react-chartjs-2": "^5.0.1",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
"react-dnd": "^11.1.3",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^11.1.3",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-error-boundary": "^2.3.1",
|
"react-error-boundary": "^2.3.1",
|
||||||
"react-google-recaptcha": "^3.1.0",
|
"react-google-recaptcha": "^3.1.0",
|
||||||
|
@ -56954,21 +56970,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@react-dnd/asap": {
|
"@react-dnd/asap": {
|
||||||
"version": "4.0.0",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
|
||||||
"integrity": "sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==",
|
"integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@react-dnd/invariant": {
|
"@react-dnd/invariant": {
|
||||||
"version": "2.0.0",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
|
||||||
"integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==",
|
"integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@react-dnd/shallowequal": {
|
"@react-dnd/shallowequal": {
|
||||||
"version": "2.0.0",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
|
||||||
"integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==",
|
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@replit/codemirror-emacs": {
|
"@replit/codemirror-emacs": {
|
||||||
|
@ -61339,6 +61355,8 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||||
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
|
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/react": "*",
|
"@types/react": "*",
|
||||||
"hoist-non-react-statics": "^3.3.0"
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
|
@ -66412,14 +66430,14 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"dnd-core": {
|
"dnd-core": {
|
||||||
"version": "11.1.3",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
|
||||||
"integrity": "sha512-QugF55dNW+h+vzxVJ/LSJeTeUw9MCJ2cllhmVThVPEtF16ooBkxj0WBE5RB+AceFxMFo1rO6bJKXtqKl+JNnyA==",
|
"integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@react-dnd/asap": "^4.0.0",
|
"@react-dnd/asap": "^5.0.1",
|
||||||
"@react-dnd/invariant": "^2.0.0",
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
"redux": "^4.0.4"
|
"redux": "^4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dns-equal": {
|
"dns-equal": {
|
||||||
|
@ -78279,24 +78297,25 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"react-dnd": {
|
"react-dnd": {
|
||||||
"version": "11.1.3",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
|
||||||
"integrity": "sha512-8rtzzT8iwHgdSC89VktwhqdKKtfXaAyC4wiqp0SywpHG12TTLvfOoL6xNEIUWXwIEWu+CFfDn4GZJyynCEuHIQ==",
|
"integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@react-dnd/shallowequal": "^2.0.0",
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
"@types/hoist-non-react-statics": "^3.3.1",
|
"@react-dnd/shallowequal": "^4.0.1",
|
||||||
"dnd-core": "^11.1.3",
|
"dnd-core": "^16.0.1",
|
||||||
"hoist-non-react-statics": "^3.3.0"
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"hoist-non-react-statics": "^3.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-dnd-html5-backend": {
|
"react-dnd-html5-backend": {
|
||||||
"version": "11.1.3",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
|
||||||
"integrity": "sha512-/1FjNlJbW/ivkUxlxQd7o3trA5DE33QiRZgxent3zKme8DwF4Nbw3OFVhTRFGaYhHFNL1rZt6Rdj1D78BjnNLw==",
|
"integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"dnd-core": "^11.1.3"
|
"dnd-core": "^16.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-docgen": {
|
"react-docgen": {
|
||||||
|
@ -78807,9 +78826,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redux": {
|
"redux": {
|
||||||
"version": "4.1.2",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||||
"integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
|
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.9.2"
|
"@babel/runtime": "^7.9.2"
|
||||||
|
|
|
@ -15,12 +15,14 @@ const FileTreeContext: FC<{
|
||||||
setRefProviderEnabled: (provider: string, value: boolean) => void
|
setRefProviderEnabled: (provider: string, value: boolean) => void
|
||||||
setStartedFreeTrial: (value: boolean) => void
|
setStartedFreeTrial: (value: boolean) => void
|
||||||
onSelect: () => void
|
onSelect: () => void
|
||||||
|
fileTreeContainer?: HTMLDivElement
|
||||||
}> = ({
|
}> = ({
|
||||||
refProviders,
|
refProviders,
|
||||||
reindexReferences,
|
reindexReferences,
|
||||||
setRefProviderEnabled,
|
setRefProviderEnabled,
|
||||||
setStartedFreeTrial,
|
setStartedFreeTrial,
|
||||||
onSelect,
|
onSelect,
|
||||||
|
fileTreeContainer,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
|
@ -32,7 +34,9 @@ const FileTreeContext: FC<{
|
||||||
>
|
>
|
||||||
<FileTreeSelectableProvider onSelect={onSelect}>
|
<FileTreeSelectableProvider onSelect={onSelect}>
|
||||||
<FileTreeActionableProvider reindexReferences={reindexReferences}>
|
<FileTreeActionableProvider reindexReferences={reindexReferences}>
|
||||||
<FileTreeDraggableProvider>{children}</FileTreeDraggableProvider>
|
<FileTreeDraggableProvider fileTreeContainer={fileTreeContainer}>
|
||||||
|
{children}
|
||||||
|
</FileTreeDraggableProvider>
|
||||||
</FileTreeActionableProvider>
|
</FileTreeActionableProvider>
|
||||||
</FileTreeSelectableProvider>
|
</FileTreeSelectableProvider>
|
||||||
</FileTreeMainProvider>
|
</FileTreeMainProvider>
|
||||||
|
|
|
@ -40,7 +40,7 @@ FileTreeDraggablePreviewLayer.propTypes = {
|
||||||
isOver: PropTypes.bool.isRequired,
|
isOver: PropTypes.bool.isRequired,
|
||||||
isDragging: PropTypes.bool.isRequired,
|
isDragging: PropTypes.bool.isRequired,
|
||||||
item: PropTypes.shape({
|
item: PropTypes.shape({
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string,
|
||||||
}),
|
}),
|
||||||
clientOffset: PropTypes.shape({
|
clientOffset: PropTypes.shape({
|
||||||
x: PropTypes.number,
|
x: PropTypes.number,
|
||||||
|
|
|
@ -22,7 +22,6 @@ function FileTreeFolderList({
|
||||||
className={classNames('list-unstyled', classes.root)}
|
className={classNames('list-unstyled', classes.root)}
|
||||||
role="tree"
|
role="tree"
|
||||||
ref={dropRef}
|
ref={dropRef}
|
||||||
dnd-container="true"
|
|
||||||
data-testid={dataTestId}
|
data-testid={dataTestId}
|
||||||
>
|
>
|
||||||
{folders.sort(compareFunction).map(folder => {
|
{folders.sort(compareFunction).map(folder => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import withErrorBoundary from '../../../infrastructure/error-boundary'
|
import withErrorBoundary from '../../../infrastructure/error-boundary'
|
||||||
import { useProjectContext } from '../../../shared/context/project-context'
|
import { useProjectContext } from '../../../shared/context/project-context'
|
||||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
||||||
|
@ -37,6 +37,8 @@ const FileTreeRoot = React.memo<{
|
||||||
onDelete,
|
onDelete,
|
||||||
isConnected,
|
isConnected,
|
||||||
}) {
|
}) {
|
||||||
|
const [fileTreeContainer, setFileTreeContainer] =
|
||||||
|
useState<HTMLDivElement | null>(null)
|
||||||
const { _id: projectId } = useProjectContext()
|
const { _id: projectId } = useProjectContext()
|
||||||
const { fileTreeData } = useFileTreeData()
|
const { fileTreeData } = useFileTreeData()
|
||||||
const isReady = Boolean(projectId && fileTreeData)
|
const isReady = Boolean(projectId && fileTreeData)
|
||||||
|
@ -47,12 +49,15 @@ const FileTreeRoot = React.memo<{
|
||||||
if (!isReady) return null
|
if (!isReady) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div className="file-tree" ref={setFileTreeContainer}>
|
||||||
|
{fileTreeContainer && (
|
||||||
<FileTreeContext
|
<FileTreeContext
|
||||||
refProviders={refProviders}
|
refProviders={refProviders}
|
||||||
setRefProviderEnabled={setRefProviderEnabled}
|
setRefProviderEnabled={setRefProviderEnabled}
|
||||||
setStartedFreeTrial={setStartedFreeTrial}
|
setStartedFreeTrial={setStartedFreeTrial}
|
||||||
reindexReferences={reindexReferences}
|
reindexReferences={reindexReferences}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
|
fileTreeContainer={fileTreeContainer}
|
||||||
>
|
>
|
||||||
{isConnected ? null : <div className="disconnected-overlay" />}
|
{isConnected ? null : <div className="disconnected-overlay" />}
|
||||||
<FileTreeToolbar />
|
<FileTreeToolbar />
|
||||||
|
@ -65,6 +70,8 @@ const FileTreeRoot = React.memo<{
|
||||||
<FileTreeModalCreateFolder />
|
<FileTreeModalCreateFolder />
|
||||||
<FileTreeModalError />
|
<FileTreeModalError />
|
||||||
</FileTreeContext>
|
</FileTreeContext>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,102 +1,87 @@
|
||||||
import { useRef, useEffect, useState, FC } from 'react'
|
import { useEffect, useState, FC, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import getDroppedFiles from '@uppy/utils/lib/getDroppedFiles'
|
import getDroppedFiles from '@uppy/utils/lib/getDroppedFiles'
|
||||||
import { DndProvider, createDndContext, useDrag, useDrop } from 'react-dnd'
|
import { DndProvider, DragSourceMonitor, useDrag, useDrop } from 'react-dnd'
|
||||||
import {
|
import {
|
||||||
HTML5Backend,
|
HTML5Backend,
|
||||||
getEmptyImage,
|
getEmptyImage,
|
||||||
NativeTypes,
|
NativeTypes,
|
||||||
} from 'react-dnd-html5-backend'
|
} from 'react-dnd-html5-backend'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
findAllInTreeOrThrow,
|
findAllInTreeOrThrow,
|
||||||
findAllFolderIdsInFolders,
|
findAllFolderIdsInFolders,
|
||||||
} from '../util/find-in-tree'
|
} from '../util/find-in-tree'
|
||||||
|
|
||||||
import { useFileTreeActionable } from './file-tree-actionable'
|
import { useFileTreeActionable } from './file-tree-actionable'
|
||||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
|
||||||
import { useFileTreeSelectable } from '../contexts/file-tree-selectable'
|
import { useFileTreeSelectable } from '../contexts/file-tree-selectable'
|
||||||
import { useEditorContext } from '../../../shared/context/editor-context'
|
import { useEditorContext } from '@/shared/context/editor-context'
|
||||||
|
|
||||||
// HACK ALERT
|
|
||||||
// DnD binds drag and drop events on window and stop propagation if the dragged
|
|
||||||
// item is not a DnD element. This break other drag and drop interfaces; in
|
|
||||||
// particular in rich text.
|
|
||||||
// This is a hacky workaround to avoid calling the DnD listeners when the
|
|
||||||
// draggable or droppable element is not within a `dnd-container` element.
|
|
||||||
const ModifiedBackend = (...args: any[]) => {
|
|
||||||
function isDndChild(elt: Element): boolean {
|
|
||||||
if (elt.getAttribute && elt.getAttribute('dnd-container')) return true
|
|
||||||
if (!elt.parentNode) return false
|
|
||||||
return isDndChild(elt.parentNode as Element)
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
const instance = new HTML5Backend(...args)
|
|
||||||
|
|
||||||
const dragDropListeners = [
|
|
||||||
'handleTopDragStart',
|
|
||||||
'handleTopDragStartCapture',
|
|
||||||
'handleTopDragEndCapture',
|
|
||||||
'handleTopDragEnter',
|
|
||||||
'handleTopDragEnterCapture',
|
|
||||||
'handleTopDragLeaveCapture',
|
|
||||||
'handleTopDragOver',
|
|
||||||
'handleTopDragOverCapture',
|
|
||||||
'handleTopDrop',
|
|
||||||
'handleTopDropCapture',
|
|
||||||
]
|
|
||||||
|
|
||||||
dragDropListeners.forEach(dragDropListener => {
|
|
||||||
const originalListener = instance[dragDropListener]
|
|
||||||
instance[dragDropListener] = (ev: Event, ...extraArgs: any[]) => {
|
|
||||||
if (isDndChild(ev.target as Element)) originalListener(ev, ...extraArgs)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return instance
|
|
||||||
}
|
|
||||||
|
|
||||||
const DndContext = createDndContext(ModifiedBackend)
|
|
||||||
|
|
||||||
const DRAGGABLE_TYPE = 'ENTITY'
|
const DRAGGABLE_TYPE = 'ENTITY'
|
||||||
export const FileTreeDraggableProvider: FC = ({ children }) => {
|
export const FileTreeDraggableProvider: FC<{
|
||||||
const DndManager = useRef(DndContext)
|
fileTreeContainer?: HTMLDivElement
|
||||||
|
}> = ({ fileTreeContainer, children }) => {
|
||||||
|
const options = useMemo(
|
||||||
|
() => ({ rootElement: fileTreeContainer }),
|
||||||
|
[fileTreeContainer]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DndProvider manager={DndManager.current.dragDropManager!}>
|
<DndProvider backend={HTML5Backend} options={options}>
|
||||||
{children}
|
{children}
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DragObject = {
|
||||||
|
type: string
|
||||||
|
title: string
|
||||||
|
forbiddenFolderIds: Set<string>
|
||||||
|
draggedEntityIds: Set<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
type DropResult = {
|
||||||
|
targetEntityId: string
|
||||||
|
dropEffect: DataTransfer['dropEffect']
|
||||||
|
}
|
||||||
|
|
||||||
export function useDraggable(draggedEntityId: string) {
|
export function useDraggable(draggedEntityId: string) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const { permissionsLevel } = useEditorContext()
|
const { permissionsLevel } = useEditorContext()
|
||||||
const { fileTreeData } = useFileTreeData()
|
const { fileTreeData } = useFileTreeData()
|
||||||
const { selectedEntityIds, isRootFolderSelected } = useFileTreeSelectable()
|
const { selectedEntityIds, isRootFolderSelected } = useFileTreeSelectable()
|
||||||
|
const { finishMoving } = useFileTreeActionable()
|
||||||
|
|
||||||
const [isDraggable, setIsDraggable] = useState(true)
|
const [isDraggable, setIsDraggable] = useState(true)
|
||||||
|
|
||||||
const item = { type: DRAGGABLE_TYPE }
|
const [, dragRef, preview] = useDrag({
|
||||||
const [{ isDragging, draggedEntityIds }, dragRef, preview] = useDrag({
|
type: DRAGGABLE_TYPE,
|
||||||
item, // required, but overwritten by the return value of `begin`
|
item() {
|
||||||
begin: () => {
|
|
||||||
const draggedEntityIds = getDraggedEntityIds(
|
const draggedEntityIds = getDraggedEntityIds(
|
||||||
isRootFolderSelected ? new Set() : selectedEntityIds,
|
isRootFolderSelected ? new Set() : selectedEntityIds,
|
||||||
draggedEntityId
|
draggedEntityId
|
||||||
)
|
)
|
||||||
|
|
||||||
const draggedItems = findAllInTreeOrThrow(fileTreeData, draggedEntityIds)
|
const draggedItems = findAllInTreeOrThrow(fileTreeData, draggedEntityIds)
|
||||||
const title = getDraggedTitle(draggedItems, t)
|
|
||||||
const forbiddenFolderIds = getForbiddenFolderIds(draggedItems)
|
return {
|
||||||
return { ...item, title, forbiddenFolderIds, draggedEntityIds }
|
type: DRAGGABLE_TYPE,
|
||||||
|
title: getDraggedTitle(draggedItems, t),
|
||||||
|
forbiddenFolderIds: getForbiddenFolderIds(draggedItems),
|
||||||
|
draggedEntityIds,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canDrag() {
|
||||||
|
return permissionsLevel !== 'readOnly' && isDraggable
|
||||||
|
},
|
||||||
|
end(item: DragObject, monitor: DragSourceMonitor<DragObject, DropResult>) {
|
||||||
|
if (monitor.didDrop()) {
|
||||||
|
const result = monitor.getDropResult()
|
||||||
|
if (result) {
|
||||||
|
finishMoving(result.targetEntityId, item.draggedEntityIds) // TODO: use result.dropEffect
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
collect: monitor => ({
|
|
||||||
isDragging: !!monitor.isDragging(),
|
|
||||||
draggedEntityIds: monitor.getItem()?.draggedEntityIds,
|
|
||||||
}),
|
|
||||||
canDrag: () => permissionsLevel !== 'readOnly' && isDraggable,
|
|
||||||
end: () => item,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// remove the automatic preview as we're using a custom preview via
|
// remove the automatic preview as we're using a custom preview via
|
||||||
|
@ -105,51 +90,49 @@ export function useDraggable(draggedEntityId: string) {
|
||||||
preview(getEmptyImage())
|
preview(getEmptyImage())
|
||||||
}, [preview])
|
}, [preview])
|
||||||
|
|
||||||
return {
|
return { dragRef, setIsDraggable }
|
||||||
dragRef,
|
|
||||||
isDragging,
|
|
||||||
setIsDraggable,
|
|
||||||
draggedEntityIds,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useDroppable(droppedEntityId: string) {
|
export function useDroppable(targetEntityId: string) {
|
||||||
const { finishMoving, setDroppedFiles, startUploadingDocOrFile } =
|
const { setDroppedFiles, startUploadingDocOrFile } = useFileTreeActionable()
|
||||||
useFileTreeActionable()
|
|
||||||
|
|
||||||
const [{ isOver }, dropRef] = useDrop<any, any, any>({
|
const [{ isOver }, dropRef] = useDrop({
|
||||||
accept: [DRAGGABLE_TYPE, NativeTypes.FILE],
|
accept: [DRAGGABLE_TYPE, NativeTypes.FILE],
|
||||||
canDrop: (item, monitor) => {
|
canDrop(item: DragObject, monitor) {
|
||||||
const isOver = monitor.isOver({ shallow: true })
|
if (!monitor.isOver({ shallow: true })) {
|
||||||
if (!isOver) return false
|
|
||||||
if (
|
|
||||||
item.type === DRAGGABLE_TYPE &&
|
|
||||||
item.forbiddenFolderIds.has(droppedEntityId)
|
|
||||||
)
|
|
||||||
return false
|
return false
|
||||||
return true
|
}
|
||||||
|
|
||||||
|
return !(
|
||||||
|
item.type === DRAGGABLE_TYPE &&
|
||||||
|
item.forbiddenFolderIds.has(targetEntityId)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
drop: (item, monitor) => {
|
drop(item, monitor) {
|
||||||
const didDropInChild = monitor.didDrop()
|
// monitor.didDrop() returns true if the drop was already handled by a nested child
|
||||||
if (didDropInChild) return
|
if (monitor.didDrop()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// item(s) dragged within the file tree
|
||||||
if (item.type === DRAGGABLE_TYPE) {
|
if (item.type === DRAGGABLE_TYPE) {
|
||||||
finishMoving(droppedEntityId, item.draggedEntityIds)
|
return { targetEntityId }
|
||||||
} else {
|
}
|
||||||
getDroppedFiles(item).then(files => {
|
|
||||||
setDroppedFiles({ files, targetFolderId: droppedEntityId })
|
// native file(s) dragged in from outside
|
||||||
|
getDroppedFiles(item as unknown as DataTransfer).then(files => {
|
||||||
|
setDroppedFiles({ files, targetFolderId: targetEntityId })
|
||||||
startUploadingDocOrFile()
|
startUploadingDocOrFile()
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
collect(monitor) {
|
||||||
|
return {
|
||||||
|
isOver: monitor.canDrop(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
collect: monitor => ({
|
|
||||||
isOver: monitor.canDrop(),
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return { dropRef, isOver }
|
||||||
dropRef,
|
|
||||||
isOver,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the list of dragged entity ids. If the dragged entity is one of the
|
// Get the list of dragged entity ids. If the dragged entity is one of the
|
||||||
|
|
|
@ -31,7 +31,6 @@ export const FileTree = memo(function FileTree() {
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="file-tree">
|
|
||||||
<FileTreeRoot
|
<FileTreeRoot
|
||||||
refProviders={refProviders}
|
refProviders={refProviders}
|
||||||
reindexReferences={reindexReferences}
|
reindexReferences={reindexReferences}
|
||||||
|
@ -42,6 +41,5 @@ export const FileTree = memo(function FileTree() {
|
||||||
onSelect={handleFileTreeSelect}
|
onSelect={handleFileTreeSelect}
|
||||||
onDelete={handleFileTreeDelete}
|
onDelete={handleFileTreeDelete}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -324,8 +324,8 @@
|
||||||
"react-bootstrap": "^0.33.1",
|
"react-bootstrap": "^0.33.1",
|
||||||
"react-chartjs-2": "^5.0.1",
|
"react-chartjs-2": "^5.0.1",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
"react-dnd": "^11.1.3",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^11.1.3",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-error-boundary": "^2.3.1",
|
"react-error-boundary": "^2.3.1",
|
||||||
"react-google-recaptcha": "^3.1.0",
|
"react-google-recaptcha": "^3.1.0",
|
||||||
|
|
|
@ -64,6 +64,7 @@ describe('<FileTreeRoot/>', function () {
|
||||||
]
|
]
|
||||||
|
|
||||||
cy.mount(
|
cy.mount(
|
||||||
|
<div style={{ width: 400 }}>
|
||||||
<EditorProviders
|
<EditorProviders
|
||||||
rootFolder={rootFolder as any}
|
rootFolder={rootFolder as any}
|
||||||
projectId="123abc"
|
projectId="123abc"
|
||||||
|
@ -81,6 +82,7 @@ describe('<FileTreeRoot/>', function () {
|
||||||
isConnected
|
isConnected
|
||||||
/>
|
/>
|
||||||
</EditorProviders>
|
</EditorProviders>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
// as a proxy to check that the invalid entity has not been select we start
|
// as a proxy to check that the invalid entity has not been select we start
|
||||||
|
|
|
@ -26,6 +26,7 @@ describe('FileTree Delete Entity Flow', function () {
|
||||||
]
|
]
|
||||||
|
|
||||||
cy.mount(
|
cy.mount(
|
||||||
|
<div style={{ width: 400 }}>
|
||||||
<EditorProviders
|
<EditorProviders
|
||||||
rootFolder={rootFolder as any}
|
rootFolder={rootFolder as any}
|
||||||
projectId="123abc"
|
projectId="123abc"
|
||||||
|
@ -41,6 +42,7 @@ describe('FileTree Delete Entity Flow', function () {
|
||||||
isConnected
|
isConnected
|
||||||
/>
|
/>
|
||||||
</EditorProviders>
|
</EditorProviders>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
cy.findByRole('treeitem', { name: 'main.tex' }).click()
|
cy.findByRole('treeitem', { name: 'main.tex' }).click()
|
||||||
|
@ -151,6 +153,7 @@ describe('FileTree Delete Entity Flow', function () {
|
||||||
]
|
]
|
||||||
|
|
||||||
cy.mount(
|
cy.mount(
|
||||||
|
<div style={{ width: 400 }}>
|
||||||
<EditorProviders
|
<EditorProviders
|
||||||
rootFolder={rootFolder as any}
|
rootFolder={rootFolder as any}
|
||||||
projectId="123abc"
|
projectId="123abc"
|
||||||
|
@ -166,6 +169,7 @@ describe('FileTree Delete Entity Flow', function () {
|
||||||
isConnected
|
isConnected
|
||||||
/>
|
/>
|
||||||
</EditorProviders>
|
</EditorProviders>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
cy.findByRole('button', { name: 'Expand' }).click()
|
cy.findByRole('button', { name: 'Expand' }).click()
|
||||||
|
@ -212,6 +216,7 @@ describe('FileTree Delete Entity Flow', function () {
|
||||||
]
|
]
|
||||||
|
|
||||||
cy.mount(
|
cy.mount(
|
||||||
|
<div style={{ width: 400 }}>
|
||||||
<EditorProviders
|
<EditorProviders
|
||||||
rootFolder={rootFolder as any}
|
rootFolder={rootFolder as any}
|
||||||
projectId="123abc"
|
projectId="123abc"
|
||||||
|
@ -227,6 +232,7 @@ describe('FileTree Delete Entity Flow', function () {
|
||||||
isConnected
|
isConnected
|
||||||
/>
|
/>
|
||||||
</EditorProviders>
|
</EditorProviders>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
// select two files
|
// select two files
|
||||||
|
|
|
@ -33,6 +33,7 @@ describe('FileTree Rename Entity Flow', function () {
|
||||||
]
|
]
|
||||||
|
|
||||||
cy.mount(
|
cy.mount(
|
||||||
|
<div style={{ width: 400 }}>
|
||||||
<EditorProviders
|
<EditorProviders
|
||||||
rootFolder={rootFolder as any}
|
rootFolder={rootFolder as any}
|
||||||
projectId="123abc"
|
projectId="123abc"
|
||||||
|
@ -48,6 +49,7 @@ describe('FileTree Rename Entity Flow', function () {
|
||||||
isConnected
|
isConnected
|
||||||
/>
|
/>
|
||||||
</EditorProviders>
|
</EditorProviders>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import { ComponentProps, FC, useRef } from 'react'
|
import { ComponentProps, FC, useRef, useState } from 'react'
|
||||||
import FileTreeContext from '@/features/file-tree/components/file-tree-context'
|
import FileTreeContext from '@/features/file-tree/components/file-tree-context'
|
||||||
|
|
||||||
export const FileTreeProvider: FC<{
|
export const FileTreeProvider: FC<{
|
||||||
refProviders?: Record<string, boolean>
|
refProviders?: Record<string, boolean>
|
||||||
}> = ({ children, refProviders = {} }) => {
|
}> = ({ children, refProviders = {} }) => {
|
||||||
|
const [fileTreeContainer, setFileTreeContainer] =
|
||||||
|
useState<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
const propsRef =
|
const propsRef =
|
||||||
useRef<Omit<ComponentProps<typeof FileTreeContext>, 'refProviders'>>()
|
useRef<Omit<ComponentProps<typeof FileTreeContext>, 'refProviders'>>()
|
||||||
|
|
||||||
|
@ -17,8 +20,16 @@ export const FileTreeProvider: FC<{
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FileTreeContext refProviders={refProviders} {...propsRef.current}>
|
<div ref={setFileTreeContainer}>
|
||||||
|
{fileTreeContainer && (
|
||||||
|
<FileTreeContext
|
||||||
|
refProviders={refProviders}
|
||||||
|
fileTreeContainer={fileTreeContainer}
|
||||||
|
{...propsRef.current}
|
||||||
|
>
|
||||||
<>{children}</>
|
<>{children}</>
|
||||||
</FileTreeContext>
|
</FileTreeContext>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,6 +240,9 @@ module.exports = {
|
||||||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs', '.json'],
|
extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs', '.json'],
|
||||||
fallback: {
|
fallback: {
|
||||||
events: require.resolve('events'),
|
events: require.resolve('events'),
|
||||||
|
// for react-dnd + React 17
|
||||||
|
'react/jsx-runtime': 'react/jsx-runtime.js',
|
||||||
|
'react/jsx-dev-runtime': 'react/jsx-dev-runtime.js',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue