From fe0dbc03e60139a794f58104e603eb8739d5ed73 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Sat, 28 Dec 2024 15:36:02 +0100 Subject: [PATCH 1/7] vlist for shell output --- package-lock.json | 1090 ++++++----------- packages/browser-repl/package.json | 2 +- .../src/components/password-prompt.tsx | 86 +- .../src/components/shell-output.tsx | 76 +- .../browser-repl/src/components/shell.tsx | 136 +- 5 files changed, 595 insertions(+), 795 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95c4d87805..f0a13d6bbd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3114,6 +3114,71 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react/node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true, + "license": "MIT" + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "dev": true, + "license": "MIT" + }, "node_modules/@gar/promisify": { "version": "1.1.3", "license": "MIT" @@ -3428,9 +3493,9 @@ } }, "node_modules/@leafygreen-ui/banner": { - "version": "7.0.20", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/banner/-/banner-7.0.20.tgz", - "integrity": "sha512-GCFHQTGXocgjkeSM7uMSLsrV51RAVpMuu5dFy4cK9pbwhd+YNulUkClheVFUKJV6P5xFB/7SNajaGrYbLmVHWA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/banner/-/banner-8.0.1.tgz", + "integrity": "sha512-zKrSG334UW/9nGt4P4QKNM8rnOzsG62cLxfysT4UrrOS8doRNvIlKleeQFSkNd4FmljiqdRI0DjDKO0uGhx8SA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3440,7 +3505,7 @@ "@leafygreen-ui/lib": "^13.3.0", "@leafygreen-ui/palette": "^4.0.9", "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/typography": "^18.3.0" + "@leafygreen-ui/typography": "^19.0.0" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" @@ -3474,16 +3539,16 @@ } }, "node_modules/@leafygreen-ui/card": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/card/-/card-10.0.7.tgz", - "integrity": "sha512-eQFV1IkBuzA4cqT8ozA+13voVDiQD96MGW0JqS8bdZYIjim6HDGLq31PTz1zwuZOvpXa55p/byyBeq94rjSX5w==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/card/-/card-11.0.0.tgz", + "integrity": "sha512-o5rVAkjLHsK5/ACLBeZHOkdNPfHKk+V9xe8KFW5PSjuxxNR1RPL9UOJBsgiMORaqd7obXgdhcF+jDH6klXHH2A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/box": "^3.1.9", "@leafygreen-ui/emotion": "^4.0.8", "@leafygreen-ui/lib": "^13.3.0", - "@leafygreen-ui/palette": "^4.0.9", + "@leafygreen-ui/palette": "^4.1.0", + "@leafygreen-ui/polymorphic": "^2.0.2", "@leafygreen-ui/tokens": "^2.5.2", "polished": "^4.2.2" }, @@ -3492,43 +3557,62 @@ } }, "node_modules/@leafygreen-ui/checkbox": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/checkbox/-/checkbox-12.1.1.tgz", - "integrity": "sha512-9hl2tLeajx4i7MpFyK+Glck76wo+h780MkwkuSGIQZLKNGxithlHXmVJeejDyS72effeLO/umsZJGxylvbEs/A==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/checkbox/-/checkbox-13.1.2.tgz", + "integrity": "sha512-rdn55oDiywyk/t3wKnJKbzDn6CUtCCSm4PQF6t4svZWVaHvNzDgTDjHy5D1s8MYpFQbqhsWbJhf17tpRrzY/Mw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/a11y": "^1.4.11", - "@leafygreen-ui/emotion": "^4.0.7", - "@leafygreen-ui/hooks": "^8.1.2", - "@leafygreen-ui/lib": "^13.0.0", - "@leafygreen-ui/palette": "^4.0.7", - "@leafygreen-ui/tokens": "^2.5.1", - "@leafygreen-ui/typography": "^18.2.2", + "@leafygreen-ui/a11y": "^1.4.13", + "@leafygreen-ui/emotion": "^4.0.8", + "@leafygreen-ui/hooks": "^8.1.4", + "@leafygreen-ui/lib": "^13.4.0", + "@leafygreen-ui/palette": "^4.0.10", + "@leafygreen-ui/tokens": "^2.5.2", + "@leafygreen-ui/typography": "^19.0.0", + "@lg-tools/test-harnesses": "^0.1.2", "react-transition-group": "^4.4.5" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.10" + "@leafygreen-ui/leafygreen-provider": "^3.1.12" + } + }, + "node_modules/@leafygreen-ui/chip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/chip/-/chip-2.0.0.tgz", + "integrity": "sha512-Xblxs3bwibgSqaASg+cn7qIDQajGuiXcMK3/Xfe6gkR6cfQsrcCOcm1BoiIT+9LFYc3qhx0sNP+kwiFTh7E9YA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@leafygreen-ui/emotion": "^4.0.8", + "@leafygreen-ui/icon": "^12.5.4", + "@leafygreen-ui/inline-definition": "^7.0.0", + "@leafygreen-ui/lib": "^13.8.1", + "@leafygreen-ui/palette": "^4.0.9", + "@leafygreen-ui/tokens": "^2.9.0" + }, + "peerDependencies": { + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/code": { - "version": "14.4.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/code/-/code-14.4.0.tgz", - "integrity": "sha512-JIEsohSv0T9zOrB3+mVwxFbmOXAon+Cm7W6mKNQpHhrw+I4NofKjg1XK/ss0k3EdlZ2oXTta5+IhbxUcjlXThA==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/code/-/code-15.0.0.tgz", + "integrity": "sha512-5Kc8xdnHUiXbICssW0IpS4xLNKS45GnXiKKOl6Eh3SssFiA0R2dLZcY92rnLC6vnqorpH8ykbWLbrvKdZvgnVw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/a11y": "^1.4.13", "@leafygreen-ui/button": "^21.1.0", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.4", + "@leafygreen-ui/hooks": "^8.3.0", "@leafygreen-ui/icon": "^12.5.4", "@leafygreen-ui/icon-button": "^15.0.23", - "@leafygreen-ui/lib": "^13.6.0", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/select": "^12.0.0", + "@leafygreen-ui/select": "^13.0.0", "@leafygreen-ui/tokens": "^2.9.0", - "@leafygreen-ui/tooltip": "^11.0.3", + "@leafygreen-ui/tooltip": "^12.0.0", "@types/facepaint": "^1.2.1", "@types/highlight.js": "^10.1.0", "clipboard": "^2.0.6", @@ -3539,92 +3623,37 @@ "polished": "^4.2.2" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, - "node_modules/@leafygreen-ui/code/node_modules/@leafygreen-ui/input-option": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/input-option/-/input-option-2.0.2.tgz", - "integrity": "sha512-GD3TX/5uF6NMdlcOt89jg7NXrN43ZAm+TEg/84NT9Mpdik9pw44Nznhv/BD/jXaWpxPXlDQzq7ReAOi7WtUujg==", + "node_modules/@leafygreen-ui/combobox": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/combobox/-/combobox-10.0.0.tgz", + "integrity": "sha512-FpKj0MGa83Z4mqv70ndohKY56vFtl4N3JZI0DRLNFhG5QI9Eu3+laUx6Qs2e8vTpWogASktzPePmJHD7pCBmXg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/a11y": "^1.5.0", + "@leafygreen-ui/checkbox": "^13.1.2", + "@leafygreen-ui/chip": "^2.0.0", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0", - "@leafygreen-ui/typography": "^19.2.1" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, - "node_modules/@leafygreen-ui/code/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/code/node_modules/@leafygreen-ui/select": { - "version": "12.1.6", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/select/-/select-12.1.6.tgz", - "integrity": "sha512-8hPk1Y2jDMxRbWgEifC4BB6DzPFLDJFNCHrbZoS+svpaG+9b9ubDwJ6doqZzwNnvcBiVSKL5TdNRbq1HRmNPjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/button": "^21.2.0", - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/form-field": "^1.2.4", - "@leafygreen-ui/hooks": "^8.2.1", + "@leafygreen-ui/form-field": "^1.2.5", + "@leafygreen-ui/hooks": "^8.3.0", "@leafygreen-ui/icon": "^12.5.4", - "@leafygreen-ui/input-option": "^2.0.1", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/popover": "^11.4.0", + "@leafygreen-ui/icon-button": "^15.0.23", + "@leafygreen-ui/input-option": "^2.0.2", + "@leafygreen-ui/lib": "^13.8.1", + "@leafygreen-ui/palette": "^4.0.9", + "@leafygreen-ui/popover": "^12.0.0", "@leafygreen-ui/tokens": "^2.9.0", "@leafygreen-ui/typography": "^19.2.1", - "@lg-tools/test-harnesses": "^0.1.2", - "@types/react-is": "^18.0.0", + "chalk": "^4.1.2", "lodash": "^4.17.21", - "polished": "^4.1.3", - "react-is": "^18.0.1" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, - "node_modules/@leafygreen-ui/code/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" + "polished": "^4.2.2" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, - "node_modules/@leafygreen-ui/code/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, "node_modules/@leafygreen-ui/confirmation-modal": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/@leafygreen-ui/confirmation-modal/-/confirmation-modal-5.2.1.tgz", @@ -3646,49 +3675,16 @@ "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/confirmation-modal/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/confirmation-modal/node_modules/@leafygreen-ui/text-input": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/text-input/-/text-input-13.1.1.tgz", - "integrity": "sha512-nJi6poMZEdx5UlYeT7qyZ4Dh7ZWa8MGMObugBvv3H5O3pBddn9RdA2QGh2rUCPKBjNexpIj7ThJNDK6u+u1R4w==", + "node_modules/@leafygreen-ui/descendants": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/descendants/-/descendants-1.0.1.tgz", + "integrity": "sha512-hNCZyduixj3An/MjHufHWzDQXsnK5UzDyUSF5LvulBQy7AOVOJLdKlwepvaWj76rQz95tWPSgIkDrolQcv6RAA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/form-field": "^1.2.4", "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/lib": "^13.4.0", - "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/typography": "^19.0.0", - "@lg-tools/test-harnesses": "^0.1.2" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, - "node_modules/@leafygreen-ui/confirmation-modal/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" + "@leafygreen-ui/lib": "^13.7.0", + "lodash": "^4.17.21" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" @@ -3724,105 +3720,47 @@ "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/form-field/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/form-field/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, "node_modules/@leafygreen-ui/guide-cue": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/guide-cue/-/guide-cue-5.1.0.tgz", - "integrity": "sha512-o+EOUQ0IgS50u5C+8txrQ57js4aFpdK6EPeGSMarAXd5QPY6YsNA5bLBuSSJ6QBoyP2KLjT8c8Zwt7i0q7ywmw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/guide-cue/-/guide-cue-6.0.0.tgz", + "integrity": "sha512-sAqYgy5U5h+OZPWh/ZiF1nYHwfAk4uP3N8frHiR82ZERAWHxjSnuN+/haUYLr2/V1MzNLjrXQ5eDgJQ7BPkBDw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/a11y": "^1.4.13", "@leafygreen-ui/button": "^21.2.0", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", + "@leafygreen-ui/hooks": "^8.3.0", "@leafygreen-ui/icon": "^12.5.0", "@leafygreen-ui/icon-button": "^15.0.21", "@leafygreen-ui/lib": "^13.5.0", "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/popover": "^11.4.0", - "@leafygreen-ui/tooltip": "^11.1.0", + "@leafygreen-ui/popover": "^12.0.0", + "@leafygreen-ui/tooltip": "^12.0.0", "@leafygreen-ui/typography": "^19.0.0", "focus-trap": "6.9.4", "focus-trap-react": "9.0.2", "polished": "^4.2.2" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, - "node_modules/@leafygreen-ui/guide-cue/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/guide-cue/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/hooks": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/hooks/-/hooks-8.2.1.tgz", - "integrity": "sha512-yozp+WfMo1aNzQJG4WOa4eoxEEMK3T7Q7D2AObRWEPR+jPeeocsBKSHoAkUsfJ/8AklQ+LIWM1SvtUm4iuLXtQ==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/hooks/-/hooks-8.3.1.tgz", + "integrity": "sha512-4NRdxL7spdvhDHdTmrEg7HYcSLdD6ILnni3KeT6KycOT6FUDZy8eJkBApWRId+OPEyLhnViMzeUFAw/fwi2MpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/lib": "^13.8.1", "lodash": "^4.17.21" } }, "node_modules/@leafygreen-ui/icon": { - "version": "12.7.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/icon/-/icon-12.7.0.tgz", - "integrity": "sha512-RM+ohvFLF9JCj1WumiqiKUSF7bvYNV4uNWgHCWeXFpydJC+j6wqGXpclIXMHYeP2/bl54aHOgmaY/1FKq7QvRA==", + "version": "12.9.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/icon/-/icon-12.9.0.tgz", + "integrity": "sha512-TX5iObwOwOEZ1xI5YqABuIkzKcfiMN31FApGSDDvorq+uA4MNCo0whoJLnNkg/JkyJ0Wi+MSfstTEE9NYwlVDg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3851,102 +3789,75 @@ } }, "node_modules/@leafygreen-ui/info-sprinkle": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/info-sprinkle/-/info-sprinkle-1.0.5.tgz", - "integrity": "sha512-kwUxXw9rsy2V0xjumHYRcS1SU74HW33yiyQYLZ/+WCKCg7l4ECX62JpvZipFBwmUnUxl/s06/nmoQjXIxOLWxQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/info-sprinkle/-/info-sprinkle-3.0.0.tgz", + "integrity": "sha512-9WbW3IMM1zp0DcwReHLHlKa/FcDPckMV3V9Umerja77EV3A/EDqKO1TvNojrId6LC3eP/WbH8tO/GoIfQyuZoQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.0.1", - "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/icon": "^12.6.0", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.9", "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/tooltip": "^11.0.3" + "@leafygreen-ui/tooltip": "^12.0.0" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/inline-definition": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/inline-definition/-/inline-definition-6.0.15.tgz", - "integrity": "sha512-Lv6j68szWlAol8CU+CI2ip3AcxoOvX/tizsWvNg46atyrkQg4cw0ow/PQMFpO0BwzCCEZK0hGXxbjrQmDWfUvg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/inline-definition/-/inline-definition-7.0.0.tgz", + "integrity": "sha512-JPhU40na9h+GGKfzotbqFO6sqJQiMkRkQy1xJI7kPcYg9zj2/U2k/dwcCI4+RRdHXh67dxXEPlQDAwR8/PAZKw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/tooltip": "^11.0.3" + "@leafygreen-ui/tokens": "^2.11.0", + "@leafygreen-ui/tooltip": "^12.0.0" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/input-option": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/input-option/-/input-option-1.1.4.tgz", - "integrity": "sha512-tti2719MBIId67OwbAnXXm71kqDRGa6Xjiy2cCVWL0au6rYpcm7RXio9J6KZyk4aUvHGu3f6jMNKQgifapvSlw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/a11y": "^1.4.13", - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/lib": "^13.6.0", - "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0", - "@leafygreen-ui/typography": "^19.2.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, - "node_modules/@leafygreen-ui/input-option/node_modules/@leafygreen-ui/polymorphic": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/input-option/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/input-option/-/input-option-2.0.2.tgz", + "integrity": "sha512-GD3TX/5uF6NMdlcOt89jg7NXrN43ZAm+TEg/84NT9Mpdik9pw44Nznhv/BD/jXaWpxPXlDQzq7ReAOi7WtUujg==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@leafygreen-ui/a11y": "^1.5.0", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", + "@leafygreen-ui/palette": "^4.0.9", "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" + "@leafygreen-ui/tokens": "^2.9.0", + "@leafygreen-ui/typography": "^19.2.1" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, "node_modules/@leafygreen-ui/leafygreen-provider": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/leafygreen-provider/-/leafygreen-provider-3.1.12.tgz", - "integrity": "sha512-lV5R30jTZ41FTBj+TSyme/QcplIkQlUnC+WE/YRfWL4XvgGeGUoGXlHl7gu4mMoXy8p/VRBw8fcotxhvBf58gA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/leafygreen-provider/-/leafygreen-provider-3.2.0.tgz", + "integrity": "sha512-tVOnAZXxOLysvGybBbq/e/9S2DN5UcmqurTgagDZbG9z9SXu45h1GWBQLw9eW4f6G39zI9XBAaEibpVgro2DrQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/lib": "^13.3.0" + "@leafygreen-ui/hooks": "^8.3.0", + "@leafygreen-ui/lib": "^13.8.1", + "react-transition-group": "^4.4.5" } }, "node_modules/@leafygreen-ui/lib": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/lib/-/lib-13.7.0.tgz", - "integrity": "sha512-R+2br+QrCABPefv5SD4DOAduIveoVxFtSRqk51frjLyATHLUhg7SwV783KJ0ipofCfsLdae2CZRSzT7MAVbSEA==", + "version": "13.8.2", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/lib/-/lib-13.8.2.tgz", + "integrity": "sha512-UxtZauF0rsB2dT0dsFYadcs9qa22Wk3PJaSXOCoI8BRPxyV8H4H6B+FQuFjCeLpKWFYOGLee9di3Xsqd4ewa8Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3989,62 +3900,37 @@ "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/marketing-modal/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/marketing-modal/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, "node_modules/@leafygreen-ui/menu": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/menu/-/menu-23.0.3.tgz", - "integrity": "sha512-wC5nXKJWAlHWvmMUed7u2ldsyxAl0NjrmAuugov4h4Ng3wSJMfURJRL9F+1240zjxyvURtUnMjZrD/Pc1Q9M8Q==", + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/menu/-/menu-27.0.0.tgz", + "integrity": "sha512-0Oq0K14mpC2wzxe2aBaV7AY+6psxZZHpUX2W96fJnpUBXG96iDuqWmlewxkWO8xb2A/XjX047Khfv67kzbgEkw==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@leafygreen-ui/descendants": "^1.0.1", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/icon": "^12.0.1", - "@leafygreen-ui/icon-button": "^15.0.21", - "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/hooks": "^8.3.0", + "@leafygreen-ui/icon": "^12.5.4", + "@leafygreen-ui/icon-button": "^15.0.23", + "@leafygreen-ui/input-option": "^2.0.2", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/polymorphic": "^1.3.7", - "@leafygreen-ui/popover": "^11.3.1", - "@leafygreen-ui/tokens": "^2.5.2", + "@leafygreen-ui/polymorphic": "^2.0.0", + "@leafygreen-ui/popover": "^12.0.0", + "@leafygreen-ui/tokens": "^2.10.0", + "@leafygreen-ui/typography": "^19.2.1", "lodash": "^4.17.21", + "polished": "^4.3.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/modal": { - "version": "16.0.9", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/modal/-/modal-16.0.9.tgz", - "integrity": "sha512-WWcIkapE8Q4m4dJVXIp5t6RhEEoWGwbGW+nB36UC27JrqQHBtfViGQ9zgZFEfZE0qG8jgLke/PvpEoublNZa4A==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/modal/-/modal-16.1.0.tgz", + "integrity": "sha512-FadLMCC/J3a3w0zF1kngNdQpBAYgKz9fzh1ctbG+E1KA34iQttz+KACKhQWH6oykPLqwJ8Cz1E3WQ9iL1lPXcg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4074,49 +3960,54 @@ "license": "Apache-2.0" }, "node_modules/@leafygreen-ui/pipeline": { - "version": "5.0.20", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/pipeline/-/pipeline-5.0.20.tgz", - "integrity": "sha512-XxANPl3TGWQGNu0OELxAEtLO30bjAAo6NLU4YlUoIF3PGyFjsm0zyGmL646KrMSmOjL+RPaAEhabh10lA6R4MQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/pipeline/-/pipeline-6.0.0.tgz", + "integrity": "sha512-K9YP2KtW8cOKfUCfowZxdNXSPDbLrPx3iEcncNQuH9A8P6fsHx1E2mNd8gl1+hilFy0vXzxipMqLJZMweQXPBg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", + "@leafygreen-ui/hooks": "^8.3.0", "@leafygreen-ui/icon": "^12.0.1", - "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.9", "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/tooltip": "^11.0.3", + "@leafygreen-ui/tooltip": "^12.0.0", "react-intersection-observer": "^8.25.1" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/polymorphic": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-1.3.7.tgz", - "integrity": "sha512-Tr2TmpS0YFJ3hGNbVWQpeseJRo4kTrVumVlZ4aF4hId1JYDzF0TU5JJO40v+brhbgnKsyBu7+Rvz6ExY1NcKew==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", + "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "dependencies": { + "@leafygreen-ui/lib": "^13.6.0", + "lodash": "^4.17.21" + } }, "node_modules/@leafygreen-ui/popover": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/popover/-/popover-11.4.0.tgz", - "integrity": "sha512-hSr3zbbWOCUuhByR5ncFJTkXxFfA7o2QjVjDXKLVPPn9Gh7+sYRLe87mTQWs9m8fbRx9O4Uk7Vq0R9U4A77dxw==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/popover/-/popover-12.0.0.tgz", + "integrity": "sha512-E/2ob3kYAJhmXZLBBxEwGD5/KDlhvZlJ7LIHz7PikwuwqXeWqGiVVVtqniVlvpL1ND8wGsfyM1+L1vZRAVvkng==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@floating-ui/react": "^0.26.28", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/lib": "^13.5.0", + "@leafygreen-ui/hooks": "^8.3.0", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/portal": "^5.1.1", "@leafygreen-ui/tokens": "^2.8.0", "@types/react-transition-group": "^4.4.5", "react-transition-group": "^4.4.5" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/portal": { @@ -4134,181 +4025,124 @@ } }, "node_modules/@leafygreen-ui/radio-box-group": { - "version": "12.0.16", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/radio-box-group/-/radio-box-group-12.0.16.tgz", - "integrity": "sha512-3jTprIrHO87oUsZCGn+FNkK7/clER+yTLV9GKt13rYlpy429hRs1c9EwNHfhT50DPhENhIIc/XYNMpWTDuWyBg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.7", - "@leafygreen-ui/hooks": "^8.0.0", - "@leafygreen-ui/lib": "^13.0.0", - "@leafygreen-ui/palette": "^4.0.7", - "@leafygreen-ui/tokens": "^2.2.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.10" - } - }, - "node_modules/@leafygreen-ui/radio-group": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/radio-group/-/radio-group-10.2.5.tgz", - "integrity": "sha512-QwytVW6RtbxXsiMdDszpdXQeF6jVXElWhiotN4dpW82DCqBpAPNMYr2T24a4I2DTn/2mhfs+nBXBtcN7QYhxTA==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/radio-box-group/-/radio-box-group-13.0.2.tgz", + "integrity": "sha512-1zRW4jeQzwa2i0RdMQ5UPAMTphz0HAy1nQkoNAeMrb+FSlCkfxbTrqWkiqU0f8gkY3ns/cpkNfKhLkYg3eKXWQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/emotion": "^4.0.7", - "@leafygreen-ui/hooks": "^8.1.2", - "@leafygreen-ui/lib": "^13.0.0", - "@leafygreen-ui/palette": "^4.0.7", - "@leafygreen-ui/tokens": "^2.5.1", - "@leafygreen-ui/typography": "^18.2.2" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.10" - } - }, - "node_modules/@leafygreen-ui/ripple": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/ripple/-/ripple-1.1.13.tgz", - "integrity": "sha512-M8JCnV+bYVYnRaO80qFiuf4oZjatFoAeNTw8mUKCr5/hboNmOJe7vGdJ69Um7iQUYMSBa8IXwD8eHHNgUcOAnw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/tokens": "^2.5.2" - } - }, - "node_modules/@leafygreen-ui/search-input": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/search-input/-/search-input-2.1.6.tgz", - "integrity": "sha512-BmxxPXWuAjrOhxUh6a9Dyq4kAYUO7x+PaokH7lUIwyigm1fVY1uinkpk7Gd0/vcFUhLzZjbBl7O6B0OLIJVjcw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/a11y": "^1.4.13", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/icon": "^12.0.1", - "@leafygreen-ui/icon-button": "^15.0.21", - "@leafygreen-ui/input-option": "^1.1.2", + "@leafygreen-ui/hooks": "^8.1.4", "@leafygreen-ui/lib": "^13.3.0", "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/polymorphic": "^1.3.7", - "@leafygreen-ui/popover": "^11.3.1", - "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/typography": "^18.3.0", - "lodash": "^4.17.21", - "polished": "^4.2.2" + "@leafygreen-ui/tokens": "^2.5.2" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/segmented-control": { - "version": "8.2.13", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/segmented-control/-/segmented-control-8.2.13.tgz", - "integrity": "sha512-SqXcAJnOqUslrGYZNfAQuhV7zkftUTHF3AKHbo/FZt5BUtbzhbEr01JhGxoG5mcVTvKIptL+eHLEoCy+2IvyMw==", + "node_modules/@leafygreen-ui/radio-group": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/radio-group/-/radio-group-11.0.3.tgz", + "integrity": "sha512-pXDQ/iRbUQhg8IfFoRlakPHsNjWTvgp5kj7PaKLnighJg8+7hSLFQ5a6n+IZn6nECAfHvRLgxcyM0HJDBLLUYQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/box": "^3.1.9", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/icon": "^12.4.0", + "@leafygreen-ui/hooks": "^8.1.4", "@leafygreen-ui/lib": "^13.3.0", "@leafygreen-ui/palette": "^4.0.9", "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/typography": "^19.0.0", - "lodash": "^4.17.21", - "polished": "^4.2.2" + "@leafygreen-ui/typography": "^19.0.0" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/segmented-control/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", + "node_modules/@leafygreen-ui/ripple": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/ripple/-/ripple-1.1.13.tgz", + "integrity": "sha512-M8JCnV+bYVYnRaO80qFiuf4oZjatFoAeNTw8mUKCr5/hboNmOJe7vGdJ69Um7iQUYMSBa8IXwD8eHHNgUcOAnw==", "dev": true, "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" + "dependencies": { + "@leafygreen-ui/tokens": "^2.5.2" } }, - "node_modules/@leafygreen-ui/segmented-control/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", + "node_modules/@leafygreen-ui/search-input": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/search-input/-/search-input-4.0.0.tgz", + "integrity": "sha512-iiu30IFODxO6zzKwhLdlCUb+TXLuBhyGUwIpvSctmmQwOllDxsOy/Ia5G46SUlG+cwNoKF/XOMBZBWVp3VL8PQ==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@leafygreen-ui/a11y": "^1.5.0", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", + "@leafygreen-ui/hooks": "^8.3.0", + "@leafygreen-ui/icon": "^12.5.4", + "@leafygreen-ui/icon-button": "^15.0.21", + "@leafygreen-ui/input-option": "^2.0.0", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.10", "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" + "@leafygreen-ui/popover": "^12.0.0", + "@leafygreen-ui/tokens": "^2.9.0", + "@leafygreen-ui/typography": "^19.2.1", + "lodash": "^4.17.21", + "polished": "^4.2.2" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, - "node_modules/@leafygreen-ui/select": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/select/-/select-11.3.2.tgz", - "integrity": "sha512-qPAXYibI4UNX+xW7QdspoT+fg9WfkqTwCsD9j27rTyJZ+pR2BOW5oynG5gKnm0AVPWullms5/SdxiLWai1GxNA==", + "node_modules/@leafygreen-ui/segmented-control": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/segmented-control/-/segmented-control-9.0.0.tgz", + "integrity": "sha512-oWcG8/oXobja+KszQzz9I2i7JWb9PNIhOHYgpj6GxJpciYGucX/wg2/nHXLt6u8n4nsjOQmuIxg+BwgVYviJfw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/button": "^21.2.0", + "@leafygreen-ui/box": "^3.1.9", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/icon": "^12.1.0", - "@leafygreen-ui/input-option": "^1.1.3", - "@leafygreen-ui/lib": "^13.4.0", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/popover": "^11.3.1", + "@leafygreen-ui/hooks": "^8.2.1", + "@leafygreen-ui/icon": "^12.4.0", + "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/palette": "^4.0.9", "@leafygreen-ui/tokens": "^2.5.2", "@leafygreen-ui/typography": "^19.0.0", - "@lg-tools/test-harnesses": "^0.1.2", - "@types/react-is": "^18.0.0", "lodash": "^4.17.21", - "polished": "^4.1.3", - "react-is": "^18.0.1" + "polished": "^4.2.2" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/select/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/select/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", + "node_modules/@leafygreen-ui/select": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/select/-/select-13.0.0.tgz", + "integrity": "sha512-8GwMv61pI8CqlzU9BIBeFYM5HbcF9iIfGpemTyMXchE/V9SIync7tvLThhkwaNEpbK7oqyuvdFDsRaCdT3xd9Q==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@leafygreen-ui/button": "^21.3.0", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", + "@leafygreen-ui/form-field": "^1.2.5", + "@leafygreen-ui/hooks": "^8.3.0", + "@leafygreen-ui/icon": "^12.5.4", + "@leafygreen-ui/input-option": "^2.0.1", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" + "@leafygreen-ui/popover": "^12.0.0", + "@leafygreen-ui/tokens": "^2.9.0", + "@leafygreen-ui/typography": "^19.2.1", + "@lg-tools/test-harnesses": "^0.1.2", + "@types/react-is": "^18.0.0", + "lodash": "^4.17.21", + "polished": "^4.1.3", + "react-is": "^18.0.1" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, "node_modules/@leafygreen-ui/select/node_modules/react-is": { @@ -4347,121 +4181,43 @@ "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/table/node_modules/@leafygreen-ui/checkbox": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/checkbox/-/checkbox-13.1.2.tgz", - "integrity": "sha512-rdn55oDiywyk/t3wKnJKbzDn6CUtCCSm4PQF6t4svZWVaHvNzDgTDjHy5D1s8MYpFQbqhsWbJhf17tpRrzY/Mw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/a11y": "^1.4.13", - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.4", - "@leafygreen-ui/lib": "^13.4.0", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/typography": "^19.0.0", - "@lg-tools/test-harnesses": "^0.1.2", - "react-transition-group": "^4.4.5" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, - "node_modules/@leafygreen-ui/table/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/table/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, "node_modules/@leafygreen-ui/tabs": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/tabs/-/tabs-11.2.0.tgz", - "integrity": "sha512-5J1rHPC1Gpn7/F5z8UYr7zUqDN6KcwQYrqHLjnl4RTUdFnT1Agr3itZSXFMpa6/fxo22jR62mjT0Jq0ZPSaGkw==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/tabs/-/tabs-13.1.1.tgz", + "integrity": "sha512-hmUAKNE8EpQDTqEmPaAfLxaOxXXLt1O0fQQJ+pmbpEoj/8JN6Vg4gTk9KZYh7T0M3bRBNgN9szncvepdGUGuJA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@leafygreen-ui/a11y": "^1.4.13", - "@leafygreen-ui/box": "^3.1.9", + "@leafygreen-ui/a11y": "^1.5.0", + "@leafygreen-ui/descendants": "^1.0.0", "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/lib": "^13.3.0", - "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/portal": "^5.1.1", - "@leafygreen-ui/tokens": "^2.7.0", - "@leafygreen-ui/typography": "^19.1.1", + "@leafygreen-ui/hooks": "^8.2.0", + "@leafygreen-ui/lib": "^13.7.0", + "@leafygreen-ui/palette": "^4.1.0", + "@leafygreen-ui/polymorphic": "^2.0.2", + "@leafygreen-ui/tokens": "^2.10.0", + "@leafygreen-ui/typography": "^19.3.0", "@lg-tools/test-harnesses": "0.1.2" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/tabs/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/tabs/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, "node_modules/@leafygreen-ui/text-area": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/text-area/-/text-area-8.2.1.tgz", - "integrity": "sha512-Q1jxuGi5le9bQLbqv9JCHUSwSIL2gD7iNCRpXTgiFjbUkR4k2QuxZaQs8osg0NZw1qojezZtuMe7+hIOU3pCBg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/text-area/-/text-area-9.1.2.tgz", + "integrity": "sha512-xw0hs5VpQiL5fsIvN5m88fiSyr4Pk/4bso/asV0bZRyvoHhaN/efQ9TBq/wXnN1HFnDFbQw2IV8soHImrpgGqQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/emotion": "^4.0.8", + "@leafygreen-ui/form-field": "^1.2.5", "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/icon": "^12.1.0", + "@leafygreen-ui/icon": "^12.4.0", "@leafygreen-ui/lib": "^13.4.0", "@leafygreen-ui/palette": "^4.0.10", "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/typography": "^18.4.0", + "@leafygreen-ui/typography": "^19.0.0", "@lg-tools/test-harnesses": "^0.1.2" }, "peerDependencies": { @@ -4469,27 +4225,28 @@ } }, "node_modules/@leafygreen-ui/text-input": { - "version": "12.1.27", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/text-input/-/text-input-12.1.27.tgz", - "integrity": "sha512-YYF1zTANoP4vp6ioqv8R4iG0vYO+IY+6HMOvuQSrxpOOix9CGUQrr+79N0Yl2hcaLjwGIsJpJAfDlx+DZCMhXA==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/text-input/-/text-input-13.1.2.tgz", + "integrity": "sha512-YoRek1nrD4guXFLmgBMFrh7FB3WFTyeEywAhMRohm3Ih05i2tE3BhM0gdExXOd3vGLiuFgz2tv+cbh7XtI5Rgg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/form-field": "^1.0.1", + "@leafygreen-ui/form-field": "^1.2.5", "@leafygreen-ui/hooks": "^8.1.3", - "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/lib": "^13.4.0", "@leafygreen-ui/tokens": "^2.5.2", - "@leafygreen-ui/typography": "^18.3.0" + "@leafygreen-ui/typography": "^19.0.0", + "@lg-tools/test-harnesses": "^0.1.2" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, "node_modules/@leafygreen-ui/toast": { - "version": "6.1.27", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/toast/-/toast-6.1.27.tgz", - "integrity": "sha512-vV7xDUCvr+UlHnF1aHei3iFcXchAxkxnGZQlC3FjB8M9dSSCXMYlT+PWaO03bEvLhDc8UT9wKNXrLzelUMM+bA==", + "version": "6.1.28", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/toast/-/toast-6.1.28.tgz", + "integrity": "sha512-hqBYOmKSNYGlHW9hwOMU9CJB+gtc0UqV25PoTni8GDwg+WKWKFI6fJP7zo4WNvvxcmTYniX026OI+/6fPxMt5Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4497,7 +4254,7 @@ "@leafygreen-ui/hooks": "^8.1.4", "@leafygreen-ui/icon": "^12.0.1", "@leafygreen-ui/icon-button": "^15.0.23", - "@leafygreen-ui/lib": "^13.3.0", + "@leafygreen-ui/lib": "^13.8.2", "@leafygreen-ui/palette": "^4.1.0", "@leafygreen-ui/portal": "^5.1.1", "@leafygreen-ui/tokens": "^2.5.2", @@ -4510,35 +4267,6 @@ "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/toast/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/toast/node_modules/@leafygreen-ui/typography": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", - "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.6.0", - "@leafygreen-ui/lib": "^13.6.1", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^2.0.0", - "@leafygreen-ui/tokens": "^2.9.0" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, "node_modules/@leafygreen-ui/toggle": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/@leafygreen-ui/toggle/-/toggle-10.1.2.tgz", @@ -4571,39 +4299,28 @@ } }, "node_modules/@leafygreen-ui/tooltip": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/tooltip/-/tooltip-11.1.0.tgz", - "integrity": "sha512-nVIirNqBShuj25u9koOPAVYpqGWKSDe/rsdRyPWZLeL9rLfbtZi9Xn44HeDX7brVo+KBkE29Gsuh1Y3J7LN5ng==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@leafygreen-ui/tooltip/-/tooltip-12.0.0.tgz", + "integrity": "sha512-0iOlrB5PbRX6pp/ARzgH3gSiL277jQa/DXgW5ST/XIXs2nv/zKyk9kjeiYbDcoojxLQU8R64k+Mi8Z1M5AN8Xg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/hooks": "^8.1.3", + "@leafygreen-ui/hooks": "^8.3.0", "@leafygreen-ui/icon": "^12.5.0", - "@leafygreen-ui/lib": "^13.5.0", + "@leafygreen-ui/lib": "^13.8.1", "@leafygreen-ui/palette": "^4.0.9", - "@leafygreen-ui/popover": "^11.4.0", + "@leafygreen-ui/popover": "^12.0.0", "@leafygreen-ui/tokens": "^2.8.0", "@leafygreen-ui/typography": "^19.0.0", "lodash": "^4.17.21", "polished": "^4.2.2" }, "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" + "@leafygreen-ui/leafygreen-provider": "^3.2.0" } }, - "node_modules/@leafygreen-ui/tooltip/node_modules/@leafygreen-ui/polymorphic": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/polymorphic/-/polymorphic-2.0.2.tgz", - "integrity": "sha512-OjP+hPG/cwADShcGa1SZdm51G2wVpbNqpU0B3GonEAvGLcAvG4LDMXa7BWo3GDliNkPtVMS86w0eZzEDmLfKmQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/lib": "^13.6.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@leafygreen-ui/tooltip/node_modules/@leafygreen-ui/typography": { + "node_modules/@leafygreen-ui/typography": { "version": "19.3.0", "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-19.3.0.tgz", "integrity": "sha512-pgTRcc4usW/S9nDDzkf5Ac/JPEybhWtOnDpmrp99mAJHM6tH48Pd1HjRNHWjn6bnh0nXWjwANXX1ZEe+8ggCNg==", @@ -4621,24 +4338,6 @@ "@leafygreen-ui/leafygreen-provider": "^3.1.12" } }, - "node_modules/@leafygreen-ui/typography": { - "version": "18.4.0", - "resolved": "https://registry.npmjs.org/@leafygreen-ui/typography/-/typography-18.4.0.tgz", - "integrity": "sha512-2pfoBv6jEPupMzT/rciyP6oN53Fc2h0Nl/uXubSRuFcIDwUAE6CIb3+IjK3UNyQrnOixGU4lWQhxIPTrnyxCpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@leafygreen-ui/emotion": "^4.0.8", - "@leafygreen-ui/icon": "^12.1.0", - "@leafygreen-ui/lib": "^13.4.0", - "@leafygreen-ui/palette": "^4.0.10", - "@leafygreen-ui/polymorphic": "^1.3.7", - "@leafygreen-ui/tokens": "^2.5.2" - }, - "peerDependencies": { - "@leafygreen-ui/leafygreen-provider": "^3.1.12" - } - }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "dev": true, @@ -5559,66 +5258,64 @@ } }, "node_modules/@mongodb-js/compass-components": { - "version": "1.31.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-components/-/compass-components-1.31.0.tgz", - "integrity": "sha512-yD0YKiCnXWNhGCyo81Ikk5cHj4dGA/tW996KpiCOJcfFsUgoEJNpCcI3ZGUJR5A7B5SV54Jn9BNTvH10fDNxDg==", + "version": "1.32.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-components/-/compass-components-1.32.2.tgz", + "integrity": "sha512-z4hBe5SKH6bkkbloUqM5SBE3xFAoTCDdW/0ncvCl7B6U4svJFUhmA97YeQL+W4qcqG29Vl3MvKOVKRW/cWoSpg==", "dev": true, "license": "SSPL", "dependencies": { "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", - "@leafygreen-ui/badge": "^8.1.1", - "@leafygreen-ui/banner": "^7.0.19", - "@leafygreen-ui/button": "^21.0.12", - "@leafygreen-ui/card": "^10.0.6", - "@leafygreen-ui/checkbox": "^12.1.1", - "@leafygreen-ui/code": "^14.3.1", - "@leafygreen-ui/confirmation-modal": "^5.2.0", - "@leafygreen-ui/emotion": "^4.0.7", - "@leafygreen-ui/guide-cue": "^5.0.6", - "@leafygreen-ui/hooks": "^8.1.2", - "@leafygreen-ui/icon": "^12.0.0", - "@leafygreen-ui/icon-button": "^15.0.20", - "@leafygreen-ui/info-sprinkle": "^1.0.3", - "@leafygreen-ui/inline-definition": "^6.0.14", - "@leafygreen-ui/leafygreen-provider": "^3.1.12", - "@leafygreen-ui/lib": "^13.2.1", - "@leafygreen-ui/logo": "^9.1.1", - "@leafygreen-ui/marketing-modal": "^4.2.1", - "@leafygreen-ui/menu": "^23.0.2", - "@leafygreen-ui/modal": "^16.0.6", - "@leafygreen-ui/palette": "^4.0.8", - "@leafygreen-ui/pipeline": "^5.0.18", - "@leafygreen-ui/polymorphic": "^1.3.6", - "@leafygreen-ui/popover": "^11.3.0", - "@leafygreen-ui/portal": "^5.1.0", - "@leafygreen-ui/radio-box-group": "^12.0.16", - "@leafygreen-ui/radio-group": "^10.2.5", - "@leafygreen-ui/search-input": "^2.1.5", - "@leafygreen-ui/segmented-control": "^8.2.10", - "@leafygreen-ui/select": "^11.2.2", + "@leafygreen-ui/badge": "^8.1.3", + "@leafygreen-ui/banner": "^8.0.1", + "@leafygreen-ui/button": "^21.3.0", + "@leafygreen-ui/card": "^11.0.0", + "@leafygreen-ui/checkbox": "^13.1.2", + "@leafygreen-ui/code": "^15.0.0", + "@leafygreen-ui/combobox": "^10.0.0", + "@leafygreen-ui/confirmation-modal": "^5.2.1", + "@leafygreen-ui/emotion": "^4.0.8", + "@leafygreen-ui/guide-cue": "^6.0.0", + "@leafygreen-ui/hooks": "^8.3.0", + "@leafygreen-ui/icon": "^12.8.0", + "@leafygreen-ui/icon-button": "^15.0.23", + "@leafygreen-ui/info-sprinkle": "^3.0.0", + "@leafygreen-ui/leafygreen-provider": "^3.2.0", + "@leafygreen-ui/logo": "^9.2.0", + "@leafygreen-ui/marketing-modal": "^4.2.3", + "@leafygreen-ui/menu": "^27.0.0", + "@leafygreen-ui/modal": "^16.1.0", + "@leafygreen-ui/palette": "^4.1.1", + "@leafygreen-ui/pipeline": "^6.0.0", + "@leafygreen-ui/polymorphic": "^2.0.2", + "@leafygreen-ui/popover": "^12.0.0", + "@leafygreen-ui/portal": "^5.1.1", + "@leafygreen-ui/radio-box-group": "^13.0.2", + "@leafygreen-ui/radio-group": "^11.0.3", + "@leafygreen-ui/search-input": "^4.0.0", + "@leafygreen-ui/segmented-control": "^9.0.0", + "@leafygreen-ui/select": "^13.0.0", "@leafygreen-ui/table": "^12.7.0", - "@leafygreen-ui/tabs": "^11.1.13", - "@leafygreen-ui/text-area": "^8.1.2", - "@leafygreen-ui/text-input": "^12.1.26", - "@leafygreen-ui/toast": "^6.1.23", - "@leafygreen-ui/toggle": "^10.0.19", - "@leafygreen-ui/tokens": "^2.5.1", - "@leafygreen-ui/tooltip": "^11.1.0", - "@leafygreen-ui/typography": "^18.2.3", + "@leafygreen-ui/tabs": "^13.1.1", + "@leafygreen-ui/text-area": "^9.1.2", + "@leafygreen-ui/text-input": "^13.1.2", + "@leafygreen-ui/toast": "^6.1.28", + "@leafygreen-ui/toggle": "^10.1.2", + "@leafygreen-ui/tokens": "^2.11.0", + "@leafygreen-ui/tooltip": "^12.0.0", + "@leafygreen-ui/typography": "^19.3.0", "@react-aria/interactions": "^3.9.1", "@react-aria/utils": "^3.13.1", "@react-aria/visually-hidden": "^3.3.1", "@tanstack/table-core": "^8.14.0", - "bson": "^6.8.0", + "bson": "^6.10.1", "focus-trap-react": "^9.0.2", - "hadron-document": "^8.6.5", - "hadron-type-checker": "^7.2.3", + "hadron-document": "^8.6.7", + "hadron-type-checker": "^7.2.5", "is-electron-renderer": "^2.0.1", "lodash": "^4.17.21", "polished": "^4.2.2", - "prop-types": "^15.7.2", "react": "^17.0.2", "react-hotkeys-hook": "^4.3.7", "react-intersection-observer": "^8.34.0", @@ -9499,19 +9196,6 @@ "node": ">=12" } }, - "node_modules/@testing-library/react/node_modules/@types/react": { - "version": "17.0.83", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz", - "integrity": "sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "^0.16", - "csstype": "^3.0.2" - } - }, "node_modules/@testing-library/react/node_modules/@types/react-dom": { "version": "17.0.26", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.26.tgz", @@ -9990,12 +9674,14 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "16.14.35", + "version": "17.0.83", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz", + "integrity": "sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==", "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", + "@types/scheduler": "^0.16", "csstype": "^3.0.2" } }, @@ -10008,22 +9694,33 @@ } }, "node_modules/@types/react-is": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.3.0.tgz", - "integrity": "sha512-KZJpHUkAdzyKj/kUHJDc6N7KyidftICufJfOFpiG6haL/BDQNQt5i4n1XDUL/nDZAtGLHDSWRYpLzKTAKSvX6w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-zts4lhQn5ia0cF/y2+3V6Riu0MAfez9/LJYavdM8TvcVl+S91A/7VWxyBT8hbRuWspmuCaiGI0F41OJYGrKhRA==", "dev": true, "license": "MIT", "dependencies": { - "@types/react": "*" + "@types/react": "^18" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", - "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "node_modules/@types/react-is/node_modules/@types/react": { + "version": "18.3.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.17.tgz", + "integrity": "sha512-opAQ5no6LqJNo9TqnxBKsgnkIYHozW9KSTlFVoSUJYh1Fl/sswkEoqIugRSm7tbh6pABtYjGAjW+GOS23j8qbw==", "dev": true, "license": "MIT", "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "dev": true, + "license": "MIT", + "peerDependencies": { "@types/react": "*" } }, @@ -16859,26 +16556,26 @@ } }, "node_modules/hadron-document": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/hadron-document/-/hadron-document-8.6.5.tgz", - "integrity": "sha512-EG2qNKYhrM/FVwksa5YgeO4lROhVGsaYUnQox8KJuNBuCHVTVFogxb5We4Zki08iax8oVDtgvBjdTg/wk3SaMg==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/hadron-document/-/hadron-document-8.6.7.tgz", + "integrity": "sha512-N9MBQGU8mZt3ePflR+14rmImEARvfOjlDEGaFXdlAcstn3BZ92+n+Nxjr1296mRJyRwyr0/1HYDVVV6WCQSzcQ==", "dev": true, "license": "SSPL", "dependencies": { - "bson": "^6.8.0", + "bson": "^6.10.1", "eventemitter3": "^4.0.0", - "hadron-type-checker": "^7.2.3", + "hadron-type-checker": "^7.2.5", "lodash": "^4.17.21" } }, "node_modules/hadron-type-checker": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hadron-type-checker/-/hadron-type-checker-7.2.3.tgz", - "integrity": "sha512-IeqnXS2r3874S8ZByEKwXrQDFdHmYpkEB1G40zIU0toW/UrIrLhD4HokNWVhTWck5GSvlEMEAG924sBQdRlnRQ==", + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/hadron-type-checker/-/hadron-type-checker-7.2.5.tgz", + "integrity": "sha512-VO6Ki78iJJJNf2A3cklTn/KVbGmp0SsbkJpKZ1yH8krS/pLMhFN0g1xSbk2zq9GGWoh9VShJHs0Ge5dass1UgQ==", "dev": true, "license": "SSPL", "dependencies": { - "bson": "^6.8.0", + "bson": "^6.10.1", "lodash": "^4.17.21" } }, @@ -17737,6 +17434,7 @@ }, "node_modules/interruptor": { "version": "1.0.2", + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "bindings": "^1.5.0" @@ -23906,7 +23604,9 @@ } }, "node_modules/polished": { - "version": "4.2.2", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", + "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", "dev": true, "license": "MIT", "dependencies": { @@ -29054,7 +28754,7 @@ "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", "@types/numeral": "^2.0.2", - "@types/react": "^16.9.17", + "@types/react": "^17.0.2", "@types/react-dom": "^18.0.8", "@types/sinon": "^7.5.1", "@types/sinon-chai": "^3.2.4", diff --git a/packages/browser-repl/package.json b/packages/browser-repl/package.json index b4dfeeed01..5cad176022 100644 --- a/packages/browser-repl/package.json +++ b/packages/browser-repl/package.json @@ -81,7 +81,7 @@ "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", "@types/numeral": "^2.0.2", - "@types/react": "^16.9.17", + "@types/react": "^17.0.2", "@types/react-dom": "^18.0.8", "@types/sinon": "^7.5.1", "@types/sinon-chai": "^3.2.4", diff --git a/packages/browser-repl/src/components/password-prompt.tsx b/packages/browser-repl/src/components/password-prompt.tsx index d172428b58..d355a0ac86 100644 --- a/packages/browser-repl/src/components/password-prompt.tsx +++ b/packages/browser-repl/src/components/password-prompt.tsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { useCallback } from 'react'; import { css, fontFamilies, TextInput } from '@mongodb-js/compass-components'; const passwordPrompt = css({ @@ -12,45 +12,51 @@ const passwordPropmtInputStyles = css({ display: 'inline-block', }); -interface PasswordPromptProps { - onFinish: (result: string) => void; +type PasswordPromptProps = { + onChange: (value: string) => void; + onFinish: (value: string) => void; onCancel: () => void; prompt: string; -} + password: string; +}; -export class PasswordPrompt extends Component { - constructor(props: PasswordPromptProps) { - super(props); - } - - onKeyDown = (ev: React.KeyboardEvent): void => { - switch (ev.key) { - case 'Enter': - this.props.onFinish((ev.target as HTMLInputElement).value); - break; - case 'Esc': - case 'Escape': - this.props.onCancel(); - break; - default: - break; - } - }; - - render(): JSX.Element { - return ( - - ); - } -} +export const PasswordPrompt = React.forwardRef< + HTMLInputElement, + PasswordPromptProps +>(function PasswordPrompt( + { prompt, password, onChange, onFinish, onCancel }, + ref +) { + const onKeyDown = useCallback( + (ev: React.KeyboardEvent) => { + switch (ev.key) { + case 'Enter': + onFinish((ev.target as HTMLInputElement).value); + break; + case 'Esc': + case 'Escape': + onCancel(); + break; + default: + break; + } + }, + [onCancel, onFinish] + ); + return ( + + ); +}); diff --git a/packages/browser-repl/src/components/shell-output.tsx b/packages/browser-repl/src/components/shell-output.tsx index e8f331df84..a206d15bcb 100644 --- a/packages/browser-repl/src/components/shell-output.tsx +++ b/packages/browser-repl/src/components/shell-output.tsx @@ -1,28 +1,58 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { ShellOutputLine } from './shell-output-line'; -import type { ShellOutputEntry } from './shell-output-line'; - +import React, { useEffect, useMemo, useRef } from 'react'; +import { + VirtualList, + type VirtualListRef, +} from '@mongodb-js/compass-components'; +import { ShellOutputLine, type ShellOutputEntry } from './shell-output-line'; export type { ShellOutputEntry } from './shell-output-line'; -interface ShellOutputProps { - output: readonly ShellOutputEntry[]; -} +type ShellIOListProps = { + output: ShellOutputEntry[]; + InputPrompt: JSX.Element; + setScrollRef: (ref: HTMLDivElement) => void; +}; + +export const ShellIOList = ({ + output, + InputPrompt, + setScrollRef, +}: ShellIOListProps) => { + const listRef: VirtualListRef = useRef(); -export class ShellOutput extends Component { - static propTypes = { - output: PropTypes.arrayOf(PropTypes.any).isRequired, - }; + useEffect(() => { + if (listRef.current) { + listRef.current.resetAfterIndex(0); + setTimeout(() => { + // After output changes, scroll to the end (which is + // prompt input) + listRef.current.scrollToItem(output.length, 'end'); + }, 100); + } + }, [output, listRef]); - renderLine = (entry: ShellOutputEntry, index: number): JSX.Element => { - return ( - - ); - }; + // Adding prompt to the input list so that its also rendered + // by the virtual list + const items = useMemo(() => [...output, { type: 'inputPrompt' }], [output]); - render(): JSX.Element[] { - return this.props.output - .filter((entry) => entry.value !== undefined) - .map(this.renderLine); - } -} + return ( + { + return ( +
+ {item.type === 'inputPrompt' ? ( + InputPrompt + ) : ( + + )} +
+ ); + }} + estimateItemInitialHeight={() => 24} + /> + ); +}; diff --git a/packages/browser-repl/src/components/shell.tsx b/packages/browser-repl/src/components/shell.tsx index d7a220a65c..b7c6fa2d8f 100644 --- a/packages/browser-repl/src/components/shell.tsx +++ b/packages/browser-repl/src/components/shell.tsx @@ -26,7 +26,7 @@ import type { WorkerRuntime } from '@mongosh/node-runtime-worker-thread'; import { PasswordPrompt } from './password-prompt'; import { ShellInput } from './shell-input'; import type { ShellOutputEntry } from './shell-output'; -import { ShellOutput } from './shell-output'; +import { ShellIOList } from './shell-output'; const shellContainer = css({ fontSize: '13px', @@ -211,6 +211,7 @@ const _Shell: ForwardRefRenderFunction = ( const initialEvaluateRef = useRef(initialEvaluate); const outputRef = useRef(output); const historyRef = useRef(history); + const virtualListScrollRef = useRef(null); useImperativeHandle( ref, @@ -243,6 +244,7 @@ const _Shell: ForwardRefRenderFunction = ( ); const [passwordPrompt, setPasswordPrompt] = useState(''); + const [passwordPromptValue, setPasswordPromptValue] = useState(''); const [shellPrompt, setShellPrompt] = useState('>'); const [onFinishPasswordPrompt, setOnFinishPasswordPrompt] = useState< () => (result: string) => void @@ -250,10 +252,15 @@ const _Shell: ForwardRefRenderFunction = ( const [onCancelPasswordPrompt, setOnCancelPasswordPrompt] = useState< () => () => void >(() => noop); + const passwordInputRef = useRef(null); - const focusEditor = useCallback(() => { - editorRef.current?.focus(); - }, [editorRef]); + const focusInputPrompt = useCallback(() => { + if (passwordPrompt) { + passwordInputRef.current?.focus(); + } else { + editorRef.current?.focus(); + } + }, [editorRef, passwordInputRef, passwordPrompt]); const listener = useMemo(() => { return { @@ -285,7 +292,8 @@ const _Shell: ForwardRefRenderFunction = ( setOnFinishPasswordPrompt(() => noop); setOnCancelPasswordPrompt(() => noop); setPasswordPrompt(''); - setTimeout(focusEditor, 1); + setPasswordPromptValue(''); + setTimeout(focusInputPrompt, 1); }; const ret = new Promise((resolve, reject) => { @@ -308,7 +316,7 @@ const _Shell: ForwardRefRenderFunction = ( onOutputChanged?.([]); }, }; - }, [focusEditor, maxOutputLength, onOutputChanged]); + }, [focusInputPrompt, maxOutputLength, onOutputChanged]); const updateShellPrompt = useCallback(async (): Promise => { let newShellPrompt = '>'; @@ -440,16 +448,35 @@ const _Shell: ForwardRefRenderFunction = ( } shellInputContainerRef.current.scrollIntoView(); - }, [shellInputContainerRef]); + focusInputPrompt(); + }, [shellInputContainerRef, focusInputPrompt]); const onShellClicked = useCallback( (event: React.MouseEvent): void => { - // Focus on input when clicking the shell background (not clicking output). - if (event.currentTarget === event.target) { - focusEditor(); + const path = event.nativeEvent.composedPath(); + const isEditorClicked = path.some( + (el) => el === shellInputContainerRef.current + ); + if (isEditorClicked) { + return focusInputPrompt(); + } + + // If a click originates from the virtualListScrollRef children (except for the last one), + // that means we have to ignore it. Or else, we set isClickedOutside to true. + const listItems: Array = []; + virtualListScrollRef.current?.firstChild?.childNodes.forEach((child) => { + listItems.push(child); + }); + // Remove the last item where we render the input prompt. + listItems.pop(); + const isClickedOutside = !path.some((el) => + listItems.includes(el as Node) + ); + if (isClickedOutside) { + focusInputPrompt(); } }, - [focusEditor] + [focusInputPrompt] ); const onSigInt = useCallback((): Promise => { @@ -481,6 +508,37 @@ const _Shell: ForwardRefRenderFunction = ( }); }); + const setScrollRef = useCallback((ref: HTMLDivElement) => { + virtualListScrollRef.current = ref; + }, []); + + // Password prompt being part of VirtualList, we need to focus it manually + // or else if auto-focussed, it will not let user scroll up and will always + // scroll to the bottom, where its visible. + // As the password prompt is visible, we will focus it automatically. + useEffect(() => { + if (passwordPrompt && passwordInputRef.current) { + passwordInputRef.current.focus(); + } + }, [passwordPrompt]); + + // Focus the password input when it becomes visible + useEffect(() => { + if (!shellInputContainerRef.current) { + return; + } + const observer = new IntersectionObserver(([entry]) => { + if ( + entry.target === shellInputContainerRef.current && + entry.isIntersecting + ) { + passwordInputRef.current?.focus(); + } + }); + observer.observe(shellInputContainerRef.current); + return () => observer.disconnect(); + }, [shellInputContainerRef]); + /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ return ( @@ -493,31 +551,37 @@ const _Shell: ForwardRefRenderFunction = ( )} onClick={onShellClicked} > -
- -
-
- {passwordPrompt ? ( - - ) : ( - - )} -
+ + {passwordPrompt ? ( + + ) : ( + + )} + + } + /> ); /* eslint-enable jsx-a11y/no-static-element-interactions */ From 001771f78253b52c9c9e8ce1a97b93dd3866d63d Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Sun, 12 Jan 2025 13:12:42 +0100 Subject: [PATCH 2/7] clear timeout --- .../src/components/shell-output.tsx | 45 ++++++++++++------- .../browser-repl/src/components/shell.tsx | 8 ++-- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/packages/browser-repl/src/components/shell-output.tsx b/packages/browser-repl/src/components/shell-output.tsx index a206d15bcb..eed19d6274 100644 --- a/packages/browser-repl/src/components/shell-output.tsx +++ b/packages/browser-repl/src/components/shell-output.tsx @@ -8,26 +8,33 @@ export type { ShellOutputEntry } from './shell-output-line'; type ShellIOListProps = { output: ShellOutputEntry[]; - InputPrompt: JSX.Element; + renderInputPrompt: () => JSX.Element; setScrollRef: (ref: HTMLDivElement) => void; + __TEST_OVERSCAN_COUNT?: number; + __TEST_LIST_HEIGHT?: number; }; -export const ShellIOList = ({ +export const ShellOutput = ({ output, - InputPrompt, + renderInputPrompt, setScrollRef, + __TEST_OVERSCAN_COUNT, + __TEST_LIST_HEIGHT, }: ShellIOListProps) => { const listRef: VirtualListRef = useRef(); useEffect(() => { - if (listRef.current) { - listRef.current.resetAfterIndex(0); - setTimeout(() => { - // After output changes, scroll to the end (which is - // prompt input) - listRef.current.scrollToItem(output.length, 'end'); - }, 100); + if (!listRef.current) { + return; } + (window as any).listRef = listRef.current; + listRef.current.resetAfterIndex(0); + const timeout = setTimeout(() => { + // After output changes, scroll to the end (which is + // prompt input) + listRef.current.scrollToItem(output.length, 'end'); + }, 100); + return () => clearTimeout(timeout); }, [output, listRef]); // Adding prompt to the input list so that its also rendered @@ -38,21 +45,25 @@ export const ShellIOList = ({ { + if (item.type === 'inputPrompt') { + return ( +
+ {renderInputPrompt()} +
+ ); + } return ( -
- {item.type === 'inputPrompt' ? ( - InputPrompt - ) : ( - - )} +
+
); }} estimateItemInitialHeight={() => 24} + __TEST_LIST_HEIGHT={__TEST_LIST_HEIGHT} /> ); }; diff --git a/packages/browser-repl/src/components/shell.tsx b/packages/browser-repl/src/components/shell.tsx index b7c6fa2d8f..7dd97fd69a 100644 --- a/packages/browser-repl/src/components/shell.tsx +++ b/packages/browser-repl/src/components/shell.tsx @@ -26,7 +26,7 @@ import type { WorkerRuntime } from '@mongosh/node-runtime-worker-thread'; import { PasswordPrompt } from './password-prompt'; import { ShellInput } from './shell-input'; import type { ShellOutputEntry } from './shell-output'; -import { ShellIOList } from './shell-output'; +import { ShellOutput } from './shell-output'; const shellContainer = css({ fontSize: '13px', @@ -551,10 +551,10 @@ const _Shell: ForwardRefRenderFunction = ( )} onClick={onShellClicked} > - (
{passwordPrompt ? ( = ( /> )}
- } + )} />
); From 11564ce491f33f0fd8d7eed4bb10ddef1e808b53 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Mon, 27 Jan 2025 08:15:26 +0100 Subject: [PATCH 3/7] use input outside list --- .../src/components/password-prompt.tsx | 86 +++++----- .../src/components/shell-output.tsx | 58 ++----- .../browser-repl/src/components/shell.tsx | 162 ++++++++---------- 3 files changed, 131 insertions(+), 175 deletions(-) diff --git a/packages/browser-repl/src/components/password-prompt.tsx b/packages/browser-repl/src/components/password-prompt.tsx index d355a0ac86..d172428b58 100644 --- a/packages/browser-repl/src/components/password-prompt.tsx +++ b/packages/browser-repl/src/components/password-prompt.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React, { Component } from 'react'; import { css, fontFamilies, TextInput } from '@mongodb-js/compass-components'; const passwordPrompt = css({ @@ -12,51 +12,45 @@ const passwordPropmtInputStyles = css({ display: 'inline-block', }); -type PasswordPromptProps = { - onChange: (value: string) => void; - onFinish: (value: string) => void; +interface PasswordPromptProps { + onFinish: (result: string) => void; onCancel: () => void; prompt: string; - password: string; -}; +} -export const PasswordPrompt = React.forwardRef< - HTMLInputElement, - PasswordPromptProps ->(function PasswordPrompt( - { prompt, password, onChange, onFinish, onCancel }, - ref -) { - const onKeyDown = useCallback( - (ev: React.KeyboardEvent) => { - switch (ev.key) { - case 'Enter': - onFinish((ev.target as HTMLInputElement).value); - break; - case 'Esc': - case 'Escape': - onCancel(); - break; - default: - break; - } - }, - [onCancel, onFinish] - ); - return ( - - ); -}); +export class PasswordPrompt extends Component { + constructor(props: PasswordPromptProps) { + super(props); + } + + onKeyDown = (ev: React.KeyboardEvent): void => { + switch (ev.key) { + case 'Enter': + this.props.onFinish((ev.target as HTMLInputElement).value); + break; + case 'Esc': + case 'Escape': + this.props.onCancel(); + break; + default: + break; + } + }; + + render(): JSX.Element { + return ( + + ); + } +} diff --git a/packages/browser-repl/src/components/shell-output.tsx b/packages/browser-repl/src/components/shell-output.tsx index eed19d6274..e6ea3d4ee6 100644 --- a/packages/browser-repl/src/components/shell-output.tsx +++ b/packages/browser-repl/src/components/shell-output.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef } from 'react'; +import React, { useEffect, useRef } from 'react'; import { VirtualList, type VirtualListRef, @@ -8,62 +8,34 @@ export type { ShellOutputEntry } from './shell-output-line'; type ShellIOListProps = { output: ShellOutputEntry[]; - renderInputPrompt: () => JSX.Element; - setScrollRef: (ref: HTMLDivElement) => void; - __TEST_OVERSCAN_COUNT?: number; - __TEST_LIST_HEIGHT?: number; + setInnerContainerRef: (ref: HTMLDivElement) => void; }; export const ShellOutput = ({ output, - renderInputPrompt, - setScrollRef, - __TEST_OVERSCAN_COUNT, - __TEST_LIST_HEIGHT, + setInnerContainerRef, }: ShellIOListProps) => { const listRef: VirtualListRef = useRef(); useEffect(() => { - if (!listRef.current) { - return; - } - (window as any).listRef = listRef.current; - listRef.current.resetAfterIndex(0); - const timeout = setTimeout(() => { - // After output changes, scroll to the end (which is - // prompt input) - listRef.current.scrollToItem(output.length, 'end'); - }, 100); - return () => clearTimeout(timeout); - }, [output, listRef]); - - // Adding prompt to the input list so that its also rendered - // by the virtual list - const items = useMemo(() => [...output, { type: 'inputPrompt' }], [output]); + listRef.current?.resetAfterIndex(0); + listRef.current?.scrollToItem(output.length - 1, 'end'); + }, [output]); return ( { - if (item.type === 'inputPrompt') { - return ( -
- {renderInputPrompt()} -
- ); - } - return ( -
- -
- ); - }} + // TODO: Depends on adding this in compass components + {...{ setInnerContainerRef }} + renderItem={(item, ref) => ( +
+ +
+ )} estimateItemInitialHeight={() => 24} - __TEST_LIST_HEIGHT={__TEST_LIST_HEIGHT} /> ); }; diff --git a/packages/browser-repl/src/components/shell.tsx b/packages/browser-repl/src/components/shell.tsx index 7dd97fd69a..dbdf3089e6 100644 --- a/packages/browser-repl/src/components/shell.tsx +++ b/packages/browser-repl/src/components/shell.tsx @@ -211,7 +211,6 @@ const _Shell: ForwardRefRenderFunction = ( const initialEvaluateRef = useRef(initialEvaluate); const outputRef = useRef(output); const historyRef = useRef(history); - const virtualListScrollRef = useRef(null); useImperativeHandle( ref, @@ -244,7 +243,6 @@ const _Shell: ForwardRefRenderFunction = ( ); const [passwordPrompt, setPasswordPrompt] = useState(''); - const [passwordPromptValue, setPasswordPromptValue] = useState(''); const [shellPrompt, setShellPrompt] = useState('>'); const [onFinishPasswordPrompt, setOnFinishPasswordPrompt] = useState< () => (result: string) => void @@ -252,15 +250,10 @@ const _Shell: ForwardRefRenderFunction = ( const [onCancelPasswordPrompt, setOnCancelPasswordPrompt] = useState< () => () => void >(() => noop); - const passwordInputRef = useRef(null); - const focusInputPrompt = useCallback(() => { - if (passwordPrompt) { - passwordInputRef.current?.focus(); - } else { - editorRef.current?.focus(); - } - }, [editorRef, passwordInputRef, passwordPrompt]); + const focusEditor = useCallback(() => { + editorRef.current?.focus(); + }, [editorRef]); const listener = useMemo(() => { return { @@ -292,8 +285,7 @@ const _Shell: ForwardRefRenderFunction = ( setOnFinishPasswordPrompt(() => noop); setOnCancelPasswordPrompt(() => noop); setPasswordPrompt(''); - setPasswordPromptValue(''); - setTimeout(focusInputPrompt, 1); + setTimeout(focusEditor, 1); }; const ret = new Promise((resolve, reject) => { @@ -316,7 +308,7 @@ const _Shell: ForwardRefRenderFunction = ( onOutputChanged?.([]); }, }; - }, [focusInputPrompt, maxOutputLength, onOutputChanged]); + }, [focusEditor, maxOutputLength, onOutputChanged]); const updateShellPrompt = useCallback(async (): Promise => { let newShellPrompt = '>'; @@ -448,35 +440,16 @@ const _Shell: ForwardRefRenderFunction = ( } shellInputContainerRef.current.scrollIntoView(); - focusInputPrompt(); - }, [shellInputContainerRef, focusInputPrompt]); + }, [shellInputContainerRef]); const onShellClicked = useCallback( (event: React.MouseEvent): void => { - const path = event.nativeEvent.composedPath(); - const isEditorClicked = path.some( - (el) => el === shellInputContainerRef.current - ); - if (isEditorClicked) { - return focusInputPrompt(); - } - - // If a click originates from the virtualListScrollRef children (except for the last one), - // that means we have to ignore it. Or else, we set isClickedOutside to true. - const listItems: Array = []; - virtualListScrollRef.current?.firstChild?.childNodes.forEach((child) => { - listItems.push(child); - }); - // Remove the last item where we render the input prompt. - listItems.pop(); - const isClickedOutside = !path.some((el) => - listItems.includes(el as Node) - ); - if (isClickedOutside) { - focusInputPrompt(); + // Focus on input when clicking the shell background (not clicking output). + if (event.currentTarget === event.target) { + focusEditor(); } }, - [focusInputPrompt] + [focusEditor] ); const onSigInt = useCallback((): Promise => { @@ -508,36 +481,41 @@ const _Shell: ForwardRefRenderFunction = ( }); }); - const setScrollRef = useCallback((ref: HTMLDivElement) => { - virtualListScrollRef.current = ref; + const listInnerContainerRef = useRef(null); + const setInnerContainerRef = useCallback((ref: HTMLDivElement) => { + listInnerContainerRef.current = ref; }, []); - // Password prompt being part of VirtualList, we need to focus it manually - // or else if auto-focussed, it will not let user scroll up and will always - // scroll to the bottom, where its visible. - // As the password prompt is visible, we will focus it automatically. + const [virtualListInnerHeight, setVirtualListInnerHeight] = useState(0); + const [inputEditorHeight, setInputEditorHeight] = useState(0); + useEffect(() => { - if (passwordPrompt && passwordInputRef.current) { - passwordInputRef.current.focus(); + if (!listInnerContainerRef.current) { + return; } - }, [passwordPrompt]); + const observer = new ResizeObserver(([list]) => { + rafraf(() => { + setVirtualListInnerHeight(list.contentRect.height); + }); + }); + observer.observe(listInnerContainerRef.current); + return () => { + observer.disconnect(); + }; + }, [output]); - // Focus the password input when it becomes visible useEffect(() => { if (!shellInputContainerRef.current) { return; } - const observer = new IntersectionObserver(([entry]) => { - if ( - entry.target === shellInputContainerRef.current && - entry.isIntersecting - ) { - passwordInputRef.current?.focus(); - } + const observer = new ResizeObserver(([list]) => { + setInputEditorHeight(list.contentRect.height); }); observer.observe(shellInputContainerRef.current); - return () => observer.disconnect(); - }, [shellInputContainerRef]); + return () => { + observer.disconnect(); + }; + }, []); /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ @@ -551,37 +529,49 @@ const _Shell: ForwardRefRenderFunction = ( )} onClick={onShellClicked} > - ( -
- {passwordPrompt ? ( - - ) : ( - - )} -
+
+ +
+
+ {passwordPrompt ? ( + + ) : ( + )} - /> +
); /* eslint-enable jsx-a11y/no-static-element-interactions */ From 0f368c16ff3e302a983b86fe20276ef31a292742 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Mon, 27 Jan 2025 11:03:57 +0100 Subject: [PATCH 4/7] fix clear --- .../src/components/shell-output.tsx | 8 ++++-- .../browser-repl/src/components/shell.tsx | 25 +++---------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/packages/browser-repl/src/components/shell-output.tsx b/packages/browser-repl/src/components/shell-output.tsx index e6ea3d4ee6..aacebfdccf 100644 --- a/packages/browser-repl/src/components/shell-output.tsx +++ b/packages/browser-repl/src/components/shell-output.tsx @@ -18,8 +18,12 @@ export const ShellOutput = ({ const listRef: VirtualListRef = useRef(); useEffect(() => { - listRef.current?.resetAfterIndex(0); - listRef.current?.scrollToItem(output.length - 1, 'end'); + const lastIndex = output.length - 1; + listRef.current?.resetAfterIndex(lastIndex); + const timeout = setTimeout(() => { + listRef.current?.scrollToItem(lastIndex, 'end'); + }, 100); + return () => clearTimeout(timeout); }, [output]); return ( diff --git a/packages/browser-repl/src/components/shell.tsx b/packages/browser-repl/src/components/shell.tsx index dbdf3089e6..19b7e0efb4 100644 --- a/packages/browser-repl/src/components/shell.tsx +++ b/packages/browser-repl/src/components/shell.tsx @@ -14,7 +14,6 @@ import { fontFamilies, useDarkMode, cx, - rafraf, } from '@mongodb-js/compass-components'; import type { Runtime, @@ -434,14 +433,6 @@ const _Shell: ForwardRefRenderFunction = ( editorRef.current = editor; }, []); - const scrollToBottom = useCallback(() => { - if (!shellInputContainerRef.current) { - return; - } - - shellInputContainerRef.current.scrollIntoView(); - }, [shellInputContainerRef]); - const onShellClicked = useCallback( (event: React.MouseEvent): void => { // Focus on input when clicking the shell background (not clicking output). @@ -473,14 +464,6 @@ const _Shell: ForwardRefRenderFunction = ( } }, [onInput, updateShellPrompt]); - useEffect(() => { - rafraf(() => { - // Scroll to the bottom every time we render so the input/output will be - // in view. - scrollToBottom(); - }); - }); - const listInnerContainerRef = useRef(null); const setInnerContainerRef = useCallback((ref: HTMLDivElement) => { listInnerContainerRef.current = ref; @@ -494,7 +477,7 @@ const _Shell: ForwardRefRenderFunction = ( return; } const observer = new ResizeObserver(([list]) => { - rafraf(() => { + requestAnimationFrame(() => { setVirtualListInnerHeight(list.contentRect.height); }); }); @@ -508,8 +491,8 @@ const _Shell: ForwardRefRenderFunction = ( if (!shellInputContainerRef.current) { return; } - const observer = new ResizeObserver(([list]) => { - setInputEditorHeight(list.contentRect.height); + const observer = new ResizeObserver(([input]) => { + setInputEditorHeight(input.contentRect.height); }); observer.observe(shellInputContainerRef.current); return () => { @@ -540,7 +523,7 @@ const _Shell: ForwardRefRenderFunction = ( // container, we will set it to the height of the container minus // the height of the input editor. height: `min(calc(100% - ${inputEditorHeight}px), ${Math.max( - virtualListInnerHeight, + (output ?? []).length > 0 ? virtualListInnerHeight : 1, 1 )}px)`, }} From 1013caf19e5628162229a4eb92f6dec472783a94 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Mon, 27 Jan 2025 12:34:19 +0100 Subject: [PATCH 5/7] fix tests --- .../src/components/shell-output.spec.tsx | 61 ++++++++++++++----- .../src/components/shell-output.tsx | 3 + .../src/components/shell.spec.tsx | 34 +++++++---- .../browser-repl/src/components/shell.tsx | 2 +- 4 files changed, 71 insertions(+), 29 deletions(-) diff --git a/packages/browser-repl/src/components/shell-output.spec.tsx b/packages/browser-repl/src/components/shell-output.spec.tsx index eb906dc0ae..988f4c2c46 100644 --- a/packages/browser-repl/src/components/shell-output.spec.tsx +++ b/packages/browser-repl/src/components/shell-output.spec.tsx @@ -1,33 +1,62 @@ import React from 'react'; import { expect } from '../../testing/chai'; -import { shallow } from '../../testing/enzyme'; +import { screen, render, waitFor, cleanup } from '@testing-library/react'; import type { ShellOutputEntry } from './shell-output-line'; -import { ShellOutputLine } from './shell-output-line'; import { ShellOutput } from './shell-output'; +function WrappedShellOutput(props: { output: ShellOutputEntry[] }) { + return ( +
+ { + /** */ + }} + /> +
+ ); +} + describe('', function () { + beforeEach(cleanup); + it('renders no output lines if none are passed', function () { - const wrapper = shallow(); - expect(wrapper.find(ShellOutputLine)).to.have.lengthOf(0); + render(); + expect(screen.queryByTestId('shell-output-line')).to.not.exist; }); it('renders an output line if one is passed', function () { - const line1: ShellOutputEntry = { type: 'output', value: 'line 1' }; - const wrapper = shallow(); - expect(wrapper.find(ShellOutputLine)).to.have.lengthOf(1); + const line1: ShellOutputEntry = { + type: 'output', + value: 'line 1', + format: 'output', + }; + render(); + expect(screen.getByText(/line 1/i)).to.exist; + expect(screen.getAllByTestId('shell-output-line')).to.have.lengthOf(1); }); - it('renders no output lines if only one with a value of undefined is passed', function () { - const line1: ShellOutputEntry = { type: 'output', value: undefined }; - const wrapper = shallow(); - expect(wrapper.find(ShellOutputLine)).to.have.lengthOf(0); - }); + it('scrolls to the newly added item', async function () { + const output: ShellOutputEntry[] = Array.from({ length: 100 }, (_, i) => ({ + type: 'output', + value: `line ${i}`, + format: 'output', + })); + + const { rerender } = render(); + + const newLine: ShellOutputEntry = { + type: 'output', + value: 'new line', + format: 'output', + }; - it('pass the entry to the output line as prop', function () { - const line1: ShellOutputEntry = { type: 'output', value: 'line 1' }; - const wrapper = shallow(); + rerender(); - expect(wrapper.find(ShellOutputLine).prop('entry')).to.deep.equal(line1); + await waitFor(() => { + expect(screen.getByText(/new line/i)).to.exist; + }); }); }); diff --git a/packages/browser-repl/src/components/shell-output.tsx b/packages/browser-repl/src/components/shell-output.tsx index aacebfdccf..2ef895ea4a 100644 --- a/packages/browser-repl/src/components/shell-output.tsx +++ b/packages/browser-repl/src/components/shell-output.tsx @@ -9,11 +9,13 @@ export type { ShellOutputEntry } from './shell-output-line'; type ShellIOListProps = { output: ShellOutputEntry[]; setInnerContainerRef: (ref: HTMLDivElement) => void; + __TEST_LIST_HEIGHT?: number; }; export const ShellOutput = ({ output, setInnerContainerRef, + __TEST_LIST_HEIGHT, }: ShellIOListProps) => { const listRef: VirtualListRef = useRef(); @@ -40,6 +42,7 @@ export const ShellOutput = ({ )} estimateItemInitialHeight={() => 24} + __TEST_LIST_HEIGHT={__TEST_LIST_HEIGHT} /> ); }; diff --git a/packages/browser-repl/src/components/shell.spec.tsx b/packages/browser-repl/src/components/shell.spec.tsx index dfe4804ca6..61281f7b72 100644 --- a/packages/browser-repl/src/components/shell.spec.tsx +++ b/packages/browser-repl/src/components/shell.spec.tsx @@ -28,7 +28,11 @@ function ShellWrapper({ ...props }: React.ComponentProps) { const initialEvaluate = useInitialEval(_initialEvaluate); - return ; + return ( +
+ +
+ ); } function filterEvaluateCalls(calls: any) { @@ -89,8 +93,18 @@ describe('shell', function () { }); it('calls onOutputChanged', async function () { - let output = []; - const onOutputChanged = (newOutput) => { + const shellEntries: ShellOutputEntry[] = Array.from( + { length: 10 }, + (_, i) => ({ + format: 'input', + type: 'input', + value: `item ${i}`, + }) + ); + + let output = shellEntries; + // this callback contains the new output (current merged with the new one) + const onOutputChanged = (newOutput: ShellOutputEntry[]) => { output = newOutput; }; @@ -100,12 +114,13 @@ describe('shell', function () { runtime={fakeRuntime} initialEvaluate={initialEvaluate} onOutputChanged={onOutputChanged} - output={output} + output={output as any} /> ); await waitFor(() => { expect(output).to.deep.equal([ + ...shellEntries, { format: 'input', value: 'my command', @@ -120,22 +135,17 @@ describe('shell', function () { expect(filterEvaluateCalls(fakeRuntime.evaluate.args)).to.have.length(1); - // scrolls to the bottom initially and every time it outputs - await waitFor(() => { - expect(Element.prototype.scrollIntoView).to.have.been.calledTwice; - }); - - // make sure we scroll to the bottom every time output changes rerender( ); + // Make sure that it scrolls to the last added item await waitFor(() => { - expect(Element.prototype.scrollIntoView).to.have.been.calledThrice; + expect(screen.getByText('some result')).to.exist; }); }); diff --git a/packages/browser-repl/src/components/shell.tsx b/packages/browser-repl/src/components/shell.tsx index 19b7e0efb4..31edef5072 100644 --- a/packages/browser-repl/src/components/shell.tsx +++ b/packages/browser-repl/src/components/shell.tsx @@ -485,7 +485,7 @@ const _Shell: ForwardRefRenderFunction = ( return () => { observer.disconnect(); }; - }, [output]); + }, [listInnerContainerRef.current]); useEffect(() => { if (!shellInputContainerRef.current) { From 94452fb4fd197f281b3a33a84c02e850bf3dbdbc Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Mon, 27 Jan 2025 12:35:34 +0100 Subject: [PATCH 6/7] remove any --- packages/browser-repl/src/components/shell.spec.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/browser-repl/src/components/shell.spec.tsx b/packages/browser-repl/src/components/shell.spec.tsx index 61281f7b72..dc7deb84b4 100644 --- a/packages/browser-repl/src/components/shell.spec.tsx +++ b/packages/browser-repl/src/components/shell.spec.tsx @@ -114,7 +114,7 @@ describe('shell', function () { runtime={fakeRuntime} initialEvaluate={initialEvaluate} onOutputChanged={onOutputChanged} - output={output as any} + output={output} /> ); @@ -140,7 +140,7 @@ describe('shell', function () { runtime={fakeRuntime} initialEvaluate={initialEvaluate} onOutputChanged={onOutputChanged} - output={output as any} + output={output} /> ); // Make sure that it scrolls to the last added item From 99743a01bb7dcd2ca0766148c9d3e21f423d3d13 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Thu, 30 Jan 2025 10:06:39 +0100 Subject: [PATCH 7/7] input editor at bottom --- ...output.spec.tsx => shell-content.spec.tsx} | 20 ++-- .../src/components/shell-content.tsx | 65 +++++++++++ .../src/components/shell-output.tsx | 48 -------- .../browser-repl/src/components/shell.tsx | 109 +++++------------- 4 files changed, 104 insertions(+), 138 deletions(-) rename packages/browser-repl/src/components/{shell-output.spec.tsx => shell-content.spec.tsx} (76%) create mode 100644 packages/browser-repl/src/components/shell-content.tsx delete mode 100644 packages/browser-repl/src/components/shell-output.tsx diff --git a/packages/browser-repl/src/components/shell-output.spec.tsx b/packages/browser-repl/src/components/shell-content.spec.tsx similarity index 76% rename from packages/browser-repl/src/components/shell-output.spec.tsx rename to packages/browser-repl/src/components/shell-content.spec.tsx index 988f4c2c46..882d191a03 100644 --- a/packages/browser-repl/src/components/shell-output.spec.tsx +++ b/packages/browser-repl/src/components/shell-content.spec.tsx @@ -3,23 +3,22 @@ import { expect } from '../../testing/chai'; import { screen, render, waitFor, cleanup } from '@testing-library/react'; import type { ShellOutputEntry } from './shell-output-line'; -import { ShellOutput } from './shell-output'; +import { ShellContent } from './shell-content'; -function WrappedShellOutput(props: { output: ShellOutputEntry[] }) { +function WrappedShellOutput(props: Partial>) { return (
- } __TEST_LIST_HEIGHT={200} - setInnerContainerRef={() => { - /** */ - }} + {...props} />
); } -describe('', function () { +describe('', function () { beforeEach(cleanup); it('renders no output lines if none are passed', function () { @@ -59,4 +58,9 @@ describe('', function () { expect(screen.getByText(/new line/i)).to.exist; }); }); + + it('renders input prompt', function () { + render(Enter here

} />); + expect(screen.getByText(/enter here/i)).to.exist; + }); }); diff --git a/packages/browser-repl/src/components/shell-content.tsx b/packages/browser-repl/src/components/shell-content.tsx new file mode 100644 index 0000000000..484bd3901d --- /dev/null +++ b/packages/browser-repl/src/components/shell-content.tsx @@ -0,0 +1,65 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { ShellOutputLine, type ShellOutputEntry } from './shell-output-line'; +import { + rafraf, + VirtualList, + type VirtualListRef, +} from '@mongodb-js/compass-components'; + +export const ShellContent = ({ + output, + InputPrompt, + __TEST_LIST_HEIGHT, +}: { + output: ShellOutputEntry[]; + InputPrompt: JSX.Element; + __TEST_LIST_HEIGHT?: number; +}) => { + const [inputEditorHeight, setInputEditorHeight] = useState(24); + const shellInputContainerRef = useRef(null); + + const listRef: VirtualListRef = useRef(); + + useEffect(() => { + const lastIndex = output.length - 1; + listRef.current?.resetAfterIndex(lastIndex); + const abortFn = rafraf(() => { + listRef.current?.scrollToItem(lastIndex, 'end'); + }); + return abortFn; + }, [output.length]); + + useEffect(() => { + if (!shellInputContainerRef.current) { + return; + } + const observer = new ResizeObserver(([input]) => { + setInputEditorHeight(input.contentRect.height); + }); + observer.observe(shellInputContainerRef.current); + return () => { + observer.disconnect(); + }; + }, []); + + return ( + <> +
+ ( +
+ +
+ )} + estimateItemInitialHeight={() => 0} + __TEST_LIST_HEIGHT={__TEST_LIST_HEIGHT} + /> +
+
{InputPrompt}
+ + ); +}; diff --git a/packages/browser-repl/src/components/shell-output.tsx b/packages/browser-repl/src/components/shell-output.tsx deleted file mode 100644 index 2ef895ea4a..0000000000 --- a/packages/browser-repl/src/components/shell-output.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { useEffect, useRef } from 'react'; -import { - VirtualList, - type VirtualListRef, -} from '@mongodb-js/compass-components'; -import { ShellOutputLine, type ShellOutputEntry } from './shell-output-line'; -export type { ShellOutputEntry } from './shell-output-line'; - -type ShellIOListProps = { - output: ShellOutputEntry[]; - setInnerContainerRef: (ref: HTMLDivElement) => void; - __TEST_LIST_HEIGHT?: number; -}; - -export const ShellOutput = ({ - output, - setInnerContainerRef, - __TEST_LIST_HEIGHT, -}: ShellIOListProps) => { - const listRef: VirtualListRef = useRef(); - - useEffect(() => { - const lastIndex = output.length - 1; - listRef.current?.resetAfterIndex(lastIndex); - const timeout = setTimeout(() => { - listRef.current?.scrollToItem(lastIndex, 'end'); - }, 100); - return () => clearTimeout(timeout); - }, [output]); - - return ( - ( -
- -
- )} - estimateItemInitialHeight={() => 24} - __TEST_LIST_HEIGHT={__TEST_LIST_HEIGHT} - /> - ); -}; diff --git a/packages/browser-repl/src/components/shell.tsx b/packages/browser-repl/src/components/shell.tsx index 31edef5072..8f487aa2a1 100644 --- a/packages/browser-repl/src/components/shell.tsx +++ b/packages/browser-repl/src/components/shell.tsx @@ -24,8 +24,8 @@ import { changeHistory } from '@mongosh/history'; import type { WorkerRuntime } from '@mongosh/node-runtime-worker-thread'; import { PasswordPrompt } from './password-prompt'; import { ShellInput } from './shell-input'; -import type { ShellOutputEntry } from './shell-output'; -import { ShellOutput } from './shell-output'; +import { ShellContent } from './shell-content'; +import type { ShellOutputEntry } from './shell-output-line'; const shellContainer = css({ fontSize: '13px', @@ -206,7 +206,6 @@ const _Shell: ForwardRefRenderFunction = ( const darkMode = useDarkMode(); const editorRef = useRef(null); - const shellInputContainerRef = useRef(null); const initialEvaluateRef = useRef(initialEvaluate); const outputRef = useRef(output); const historyRef = useRef(history); @@ -464,42 +463,6 @@ const _Shell: ForwardRefRenderFunction = ( } }, [onInput, updateShellPrompt]); - const listInnerContainerRef = useRef(null); - const setInnerContainerRef = useCallback((ref: HTMLDivElement) => { - listInnerContainerRef.current = ref; - }, []); - - const [virtualListInnerHeight, setVirtualListInnerHeight] = useState(0); - const [inputEditorHeight, setInputEditorHeight] = useState(0); - - useEffect(() => { - if (!listInnerContainerRef.current) { - return; - } - const observer = new ResizeObserver(([list]) => { - requestAnimationFrame(() => { - setVirtualListInnerHeight(list.contentRect.height); - }); - }); - observer.observe(listInnerContainerRef.current); - return () => { - observer.disconnect(); - }; - }, [listInnerContainerRef.current]); - - useEffect(() => { - if (!shellInputContainerRef.current) { - return; - } - const observer = new ResizeObserver(([input]) => { - setInputEditorHeight(input.contentRect.height); - }); - observer.observe(shellInputContainerRef.current); - return () => { - observer.disconnect(); - }; - }, []); - /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ return ( @@ -512,49 +475,31 @@ const _Shell: ForwardRefRenderFunction = ( )} onClick={onShellClicked} > -
0 ? virtualListInnerHeight : 1, - 1 - )}px)`, - }} - > - -
-
- {passwordPrompt ? ( - - ) : ( - - )} -
+ + ) : ( + + ) + } + /> ); /* eslint-enable jsx-a11y/no-static-element-interactions */