diff --git a/jest.config.base.cjs b/jest.config.base.cjs index cf5744ce0..ff3a78698 100644 --- a/jest.config.base.cjs +++ b/jest.config.base.cjs @@ -1,11 +1,48 @@ const path = require('path'); +// List of node_modules that need to be transformed from ESM to CJS for jest to work +const nodeModulesToTransform = [ + '@deephaven', + 'nanoid', + // monaco + 'monaco-editor', + // plotly.js dependencies + 'd3-interpolate', + 'd3-color', + // react-markdown and its dependencies + 'react-markdown', + 'vfile', + 'vfile-message', + 'unist-util.*', + 'unified', + 'bail', + 'is-plain-obj', + 'trough', + 'remark.*', + 'mdast-util.*', + 'micromark.*', + 'decode-named-character-reference', + 'trim-lines', + 'property-information', + 'hast-util.*', + '.*separated-tokens', + 'ccount', + 'devlop', + 'escape-string-regexp', + 'markdown-table', + 'zwitch', + 'longest-streak', + 'rehype.*', + 'web-namespaces', + 'hastscript', +]; + module.exports = { transform: { '^.+\\.(ts|tsx|js|jsx)$': ['babel-jest', { rootMode: 'upward' }], }, transformIgnorePatterns: [ - '/node_modules/(?!(@deephaven|monaco-editor|d3-interpolate|d3-color|nanoid)/)', + `node_modules/(?!(${nodeModulesToTransform.join('|')})/)`, ], moduleNameMapper: { 'theme-([^/]+?)\\.css(\\?(?:inline|raw))?$': path.join( diff --git a/package-lock.json b/package-lock.json index 322705379..a25f4b08c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12719,6 +12719,11 @@ "node": ">=8" } }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, "node_modules/browserslist": { "version": "4.22.1", "dev": true, @@ -21731,7 +21736,6 @@ }, "node_modules/lodash": { "version": "4.17.21", - "dev": true, "license": "MIT" }, "node_modules/lodash.clamp": { @@ -27405,6 +27409,14 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/require-directory": { "version": "2.1.1", "dev": true, @@ -30160,6 +30172,15 @@ "pbf": "^3.2.1" } }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "license": "MIT", @@ -32185,6 +32206,7 @@ "dependencies": { "@deephaven/chart": "^0.95.0", "@deephaven/components": "^0.95.0", + "@deephaven/console": "^0.95.0", "@deephaven/dashboard": "^0.95.0", "@deephaven/dashboard-core-plugins": "^0.95.0", "@deephaven/golden-layout": "^0.95.0", @@ -32206,7 +32228,10 @@ "classnames": "^2.5.1", "json-rpc-2.0": "^1.6.0", "nanoid": "^5.0.7", - "react-redux": "^7.x" + "react-markdown": "^8.0.7", + "react-redux": "^7.x", + "rehype-mathjax": "^3.1.0", + "remark-math": "^5.1.1" }, "devDependencies": { "@types/react": "^17.0.2", @@ -32290,6 +32315,58 @@ "react-is": ">=16.8.0" } }, + "plugins/ui/src/js/node_modules/@deephaven/console": { + "version": "0.95.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.95.0.tgz", + "integrity": "sha512-JSM6w7iH0Pxbl1AMQyz54vyRch+d3HD2PGDfrhdc+ezvTv5aGqLD7THStGGe1y1byig0OE4SBwR48crlHpNBIA==", + "dependencies": { + "@deephaven/chart": "^0.95.0", + "@deephaven/components": "^0.95.0", + "@deephaven/icons": "^0.95.0", + "@deephaven/jsapi-bootstrap": "^0.95.0", + "@deephaven/jsapi-types": "^1.0.0-dev0.34.0", + "@deephaven/log": "^0.95.0", + "@deephaven/react-hooks": "^0.95.0", + "@deephaven/storage": "^0.95.0", + "@deephaven/utils": "^0.95.0", + "@fortawesome/react-fontawesome": "^0.2.0", + "classnames": "^2.3.1", + "linkifyjs": "^4.1.0", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "memoize-one": "^5.1.1", + "memoizee": "^0.4.15", + "monaco-editor": "^0.41.0", + "nanoid": "^5.0.7", + "papaparse": "5.3.2", + "popper.js": "^1.16.1", + "prop-types": "^15.7.2", + "shell-quote": "^1.7.2" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "plugins/ui/src/js/node_modules/@deephaven/console/node_modules/@deephaven/storage": { + "version": "0.95.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.95.0.tgz", + "integrity": "sha512-Gsc/p9fHrrSdzMtZ/a6/IpSzs2VT3WTOBSspWD0G7P0v682adXl7d25YFdl6uYIQSMq/tBU+JtTgAegMN5zfGg==", + "dependencies": { + "@deephaven/filters": "^0.95.0", + "@deephaven/log": "^0.95.0", + "lodash.throttle": "^4.1.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "plugins/ui/src/js/node_modules/@deephaven/dashboard": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.95.0.tgz", @@ -32367,42 +32444,6 @@ "react-redux": "^7.2.4" } }, - "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/console": { - "version": "0.95.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.95.0.tgz", - "integrity": "sha512-JSM6w7iH0Pxbl1AMQyz54vyRch+d3HD2PGDfrhdc+ezvTv5aGqLD7THStGGe1y1byig0OE4SBwR48crlHpNBIA==", - "dependencies": { - "@deephaven/chart": "^0.95.0", - "@deephaven/components": "^0.95.0", - "@deephaven/icons": "^0.95.0", - "@deephaven/jsapi-bootstrap": "^0.95.0", - "@deephaven/jsapi-types": "^1.0.0-dev0.34.0", - "@deephaven/log": "^0.95.0", - "@deephaven/react-hooks": "^0.95.0", - "@deephaven/storage": "^0.95.0", - "@deephaven/utils": "^0.95.0", - "@fortawesome/react-fontawesome": "^0.2.0", - "classnames": "^2.3.1", - "linkifyjs": "^4.1.0", - "lodash.debounce": "^4.0.8", - "lodash.throttle": "^4.1.1", - "memoize-one": "^5.1.1", - "memoizee": "^0.4.15", - "monaco-editor": "^0.41.0", - "nanoid": "^5.0.7", - "papaparse": "5.3.2", - "popper.js": "^1.16.1", - "prop-types": "^15.7.2", - "shell-quote": "^1.7.2" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/file-explorer": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.95.0.tgz", @@ -32442,6 +32483,25 @@ "react": ">=16.8.0" } }, + "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/rehype-mathjax": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-4.0.3.tgz", + "integrity": "sha512-QIwWH9U+r54nMQklVkT1qluxhKyzdPWz9dFwgel3BrseQsWZafRTDTUj8VR8/14nFuRIV2ChuCMz4zpACPoYvg==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/mathjax": "^0.0.37", + "hast-util-from-dom": "^4.0.0", + "hast-util-to-text": "^3.1.0", + "jsdom": "^20.0.0", + "mathjax-full": "^3.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "plugins/ui/src/js/node_modules/@deephaven/filters": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.95.0.tgz", @@ -32540,42 +32600,6 @@ "react-dom": ">=16.8.0" } }, - "plugins/ui/src/js/node_modules/@deephaven/iris-grid/node_modules/@deephaven/console": { - "version": "0.95.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.95.0.tgz", - "integrity": "sha512-JSM6w7iH0Pxbl1AMQyz54vyRch+d3HD2PGDfrhdc+ezvTv5aGqLD7THStGGe1y1byig0OE4SBwR48crlHpNBIA==", - "dependencies": { - "@deephaven/chart": "^0.95.0", - "@deephaven/components": "^0.95.0", - "@deephaven/icons": "^0.95.0", - "@deephaven/jsapi-bootstrap": "^0.95.0", - "@deephaven/jsapi-types": "^1.0.0-dev0.34.0", - "@deephaven/log": "^0.95.0", - "@deephaven/react-hooks": "^0.95.0", - "@deephaven/storage": "^0.95.0", - "@deephaven/utils": "^0.95.0", - "@fortawesome/react-fontawesome": "^0.2.0", - "classnames": "^2.3.1", - "linkifyjs": "^4.1.0", - "lodash.debounce": "^4.0.8", - "lodash.throttle": "^4.1.1", - "memoize-one": "^5.1.1", - "memoizee": "^0.4.15", - "monaco-editor": "^0.41.0", - "nanoid": "^5.0.7", - "papaparse": "5.3.2", - "popper.js": "^1.16.1", - "prop-types": "^15.7.2", - "shell-quote": "^1.7.2" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "plugins/ui/src/js/node_modules/@deephaven/iris-grid/node_modules/@deephaven/storage": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.95.0.tgz", @@ -32737,6 +32761,42 @@ "node": ">=16" } }, + "plugins/ui/src/js/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, + "plugins/ui/src/js/node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "plugins/ui/src/js/node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "plugins/ui/src/js/node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, "plugins/ui/src/js/node_modules/buffer": { "version": "6.0.3", "funding": [ @@ -32775,6 +32835,53 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "plugins/ui/src/js/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "plugins/ui/src/js/node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "plugins/ui/src/js/node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "plugins/ui/src/js/node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "plugins/ui/src/js/node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, "plugins/ui/src/js/node_modules/event-target-shim": { "version": "6.0.2", "license": "MIT", @@ -32785,6 +32892,233 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "plugins/ui/src/js/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "plugins/ui/src/js/node_modules/hast-util-is-element": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", + "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "plugins/ui/src/js/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "plugins/ui/src/js/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "plugins/ui/src/js/node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "plugins/ui/src/js/node_modules/rehype-mathjax": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-3.1.0.tgz", + "integrity": "sha512-Pmz92Y56lBFmDjFc9nIdrKu1xzKSBYevcwKiKiG7b5JJg74q1E62nRSbPEm37vXaXn7Bn25iRsWcP39bJKkMxg==", + "dependencies": { + "@types/mathjax": "^0.0.36", + "hast-util-from-dom": "^3.0.0", + "hast-util-to-text": "^2.0.0", + "jsdom": "^16.0.0", + "mathjax-full": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/rehype-mathjax/node_modules/@types/mathjax": { + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/@types/mathjax/-/mathjax-0.0.36.tgz", + "integrity": "sha512-TqDJc2GWuTqd/m+G/FbNkN+/TF2OCCHvcawmhIrUaZkdVquMdNZmNiNUkupNg9qctorXXkVLVSogZv1DhmgLmg==" + }, + "plugins/ui/src/js/node_modules/rehype-mathjax/node_modules/hast-util-from-dom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-3.0.0.tgz", + "integrity": "sha512-4vQuGiD5Y/wlD7fZiY4mZML/6oh0GOnH38UNyeDFcSTE4AHF0zjKHZfbd+ekVwPvsZXRl8choc99INHUwSPJlg==", + "dependencies": { + "hastscript": "^6.0.0", + "web-namespaces": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/rehype-mathjax/node_modules/hast-util-to-text": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz", + "integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==", + "dependencies": { + "hast-util-is-element": "^1.0.0", + "repeat-string": "^1.0.0", + "unist-util-find-after": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/rehype-mathjax/node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "plugins/ui/src/js/node_modules/rehype-mathjax/node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "plugins/ui/src/js/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "plugins/ui/src/js/node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, "plugins/ui/src/js/node_modules/typescript": { "version": "4.9.5", "dev": true, @@ -32796,6 +33130,119 @@ "engines": { "node": ">=4.2.0" } + }, + "plugins/ui/src/js/node_modules/unist-util-find-after": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz", + "integrity": "sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ==", + "dependencies": { + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "plugins/ui/src/js/node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "plugins/ui/src/js/node_modules/web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "plugins/ui/src/js/node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "engines": { + "node": ">=10.4" + } + }, + "plugins/ui/src/js/node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "plugins/ui/src/js/node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "plugins/ui/src/js/node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "plugins/ui/src/js/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "plugins/ui/src/js/node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" } }, "dependencies": { @@ -35825,6 +36272,7 @@ "requires": { "@deephaven/chart": "^0.95.0", "@deephaven/components": "^0.95.0", + "@deephaven/console": "^0.95.0", "@deephaven/dashboard": "^0.95.0", "@deephaven/dashboard-core-plugins": "^0.95.0", "@deephaven/golden-layout": "^0.95.0", @@ -35849,7 +36297,10 @@ "nanoid": "^5.0.7", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-markdown": "^8.0.7", "react-redux": "^7.x", + "rehype-mathjax": "^3.1.0", + "remark-math": "^5.1.1", "typescript": "^4.5.4" }, "dependencies": { @@ -35910,6 +36361,47 @@ "react-window": "^1.8.6" } }, + "@deephaven/console": { + "version": "0.95.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.95.0.tgz", + "integrity": "sha512-JSM6w7iH0Pxbl1AMQyz54vyRch+d3HD2PGDfrhdc+ezvTv5aGqLD7THStGGe1y1byig0OE4SBwR48crlHpNBIA==", + "requires": { + "@deephaven/chart": "^0.95.0", + "@deephaven/components": "^0.95.0", + "@deephaven/icons": "^0.95.0", + "@deephaven/jsapi-bootstrap": "^0.95.0", + "@deephaven/jsapi-types": "^1.0.0-dev0.34.0", + "@deephaven/log": "^0.95.0", + "@deephaven/react-hooks": "^0.95.0", + "@deephaven/storage": "^0.95.0", + "@deephaven/utils": "^0.95.0", + "@fortawesome/react-fontawesome": "^0.2.0", + "classnames": "^2.3.1", + "linkifyjs": "^4.1.0", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "memoize-one": "^5.1.1", + "memoizee": "^0.4.15", + "monaco-editor": "^0.41.0", + "nanoid": "^5.0.7", + "papaparse": "5.3.2", + "popper.js": "^1.16.1", + "prop-types": "^15.7.2", + "shell-quote": "^1.7.2" + }, + "dependencies": { + "@deephaven/storage": { + "version": "0.95.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.95.0.tgz", + "integrity": "sha512-Gsc/p9fHrrSdzMtZ/a6/IpSzs2VT3WTOBSspWD0G7P0v682adXl7d25YFdl6uYIQSMq/tBU+JtTgAegMN5zfGg==", + "requires": { + "@deephaven/filters": "^0.95.0", + "@deephaven/log": "^0.95.0", + "lodash.throttle": "^4.1.1" + } + } + } + }, "@deephaven/dashboard": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.95.0.tgz", @@ -35971,35 +36463,6 @@ "remark-math": "^5.1.1" }, "dependencies": { - "@deephaven/console": { - "version": "0.95.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.95.0.tgz", - "integrity": "sha512-JSM6w7iH0Pxbl1AMQyz54vyRch+d3HD2PGDfrhdc+ezvTv5aGqLD7THStGGe1y1byig0OE4SBwR48crlHpNBIA==", - "requires": { - "@deephaven/chart": "^0.95.0", - "@deephaven/components": "^0.95.0", - "@deephaven/icons": "^0.95.0", - "@deephaven/jsapi-bootstrap": "^0.95.0", - "@deephaven/jsapi-types": "^1.0.0-dev0.34.0", - "@deephaven/log": "^0.95.0", - "@deephaven/react-hooks": "^0.95.0", - "@deephaven/storage": "^0.95.0", - "@deephaven/utils": "^0.95.0", - "@fortawesome/react-fontawesome": "^0.2.0", - "classnames": "^2.3.1", - "linkifyjs": "^4.1.0", - "lodash.debounce": "^4.0.8", - "lodash.throttle": "^4.1.1", - "memoize-one": "^5.1.1", - "memoizee": "^0.4.15", - "monaco-editor": "^0.41.0", - "nanoid": "^5.0.7", - "papaparse": "5.3.2", - "popper.js": "^1.16.1", - "prop-types": "^15.7.2", - "shell-quote": "^1.7.2" - } - }, "@deephaven/file-explorer": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.95.0.tgz", @@ -36026,6 +36489,21 @@ "@deephaven/log": "^0.95.0", "lodash.throttle": "^4.1.1" } + }, + "rehype-mathjax": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-4.0.3.tgz", + "integrity": "sha512-QIwWH9U+r54nMQklVkT1qluxhKyzdPWz9dFwgel3BrseQsWZafRTDTUj8VR8/14nFuRIV2ChuCMz4zpACPoYvg==", + "requires": { + "@types/hast": "^2.0.0", + "@types/mathjax": "^0.0.37", + "hast-util-from-dom": "^4.0.0", + "hast-util-to-text": "^3.1.0", + "jsdom": "^20.0.0", + "mathjax-full": "^3.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + } } } }, @@ -36103,35 +36581,6 @@ "react-transition-group": "^4.4.2" }, "dependencies": { - "@deephaven/console": { - "version": "0.95.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.95.0.tgz", - "integrity": "sha512-JSM6w7iH0Pxbl1AMQyz54vyRch+d3HD2PGDfrhdc+ezvTv5aGqLD7THStGGe1y1byig0OE4SBwR48crlHpNBIA==", - "requires": { - "@deephaven/chart": "^0.95.0", - "@deephaven/components": "^0.95.0", - "@deephaven/icons": "^0.95.0", - "@deephaven/jsapi-bootstrap": "^0.95.0", - "@deephaven/jsapi-types": "^1.0.0-dev0.34.0", - "@deephaven/log": "^0.95.0", - "@deephaven/react-hooks": "^0.95.0", - "@deephaven/storage": "^0.95.0", - "@deephaven/utils": "^0.95.0", - "@fortawesome/react-fontawesome": "^0.2.0", - "classnames": "^2.3.1", - "linkifyjs": "^4.1.0", - "lodash.debounce": "^4.0.8", - "lodash.throttle": "^4.1.1", - "memoize-one": "^5.1.1", - "memoizee": "^0.4.15", - "monaco-editor": "^0.41.0", - "nanoid": "^5.0.7", - "papaparse": "5.3.2", - "popper.js": "^1.16.1", - "prop-types": "^15.7.2", - "shell-quote": "^1.7.2" - } - }, "@deephaven/storage": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.95.0.tgz", @@ -36250,6 +36699,32 @@ "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.95.0.tgz", "integrity": "sha512-knAh6xxNl1b2dqsCv6Jv87+3gC2OmGqCW/Ub7FXSsoY+qRWO7r5LG7DkVi9S2kLxVgzNH2tWSqSOA7AUt+wLyQ==" }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + }, "buffer": { "version": "6.0.3", "requires": { @@ -36270,12 +36745,288 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, "event-target-shim": { "version": "6.0.2" }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "hast-util-is-element": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", + "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==" + }, + "hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" + }, + "hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "requires": { + "xtend": "^4.0.0" + } + }, + "rehype-mathjax": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-3.1.0.tgz", + "integrity": "sha512-Pmz92Y56lBFmDjFc9nIdrKu1xzKSBYevcwKiKiG7b5JJg74q1E62nRSbPEm37vXaXn7Bn25iRsWcP39bJKkMxg==", + "requires": { + "@types/mathjax": "^0.0.36", + "hast-util-from-dom": "^3.0.0", + "hast-util-to-text": "^2.0.0", + "jsdom": "^16.0.0", + "mathjax-full": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "@types/mathjax": { + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/@types/mathjax/-/mathjax-0.0.36.tgz", + "integrity": "sha512-TqDJc2GWuTqd/m+G/FbNkN+/TF2OCCHvcawmhIrUaZkdVquMdNZmNiNUkupNg9qctorXXkVLVSogZv1DhmgLmg==" + }, + "hast-util-from-dom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-3.0.0.tgz", + "integrity": "sha512-4vQuGiD5Y/wlD7fZiY4mZML/6oh0GOnH38UNyeDFcSTE4AHF0zjKHZfbd+ekVwPvsZXRl8choc99INHUwSPJlg==", + "requires": { + "hastscript": "^6.0.0", + "web-namespaces": "^1.0.0" + } + }, + "hast-util-to-text": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz", + "integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==", + "requires": { + "hast-util-is-element": "^1.0.0", + "repeat-string": "^1.0.0", + "unist-util-find-after": "^3.0.0" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + } + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + } + } + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "requires": { + "punycode": "^2.1.1" + } + }, "typescript": { "version": "4.9.5", "dev": true + }, + "unist-util-find-after": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz", + "integrity": "sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ==", + "requires": { + "unist-util-is": "^4.0.0" + } + }, + "unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==" + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "requires": {} + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" } } }, @@ -42612,6 +43363,11 @@ "fill-range": "^7.1.1" } }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, "browserslist": { "version": "4.22.1", "dev": true, @@ -48376,8 +49132,7 @@ } }, "lodash": { - "version": "4.17.21", - "dev": true + "version": "4.17.21" }, "lodash.clamp": { "version": "4.0.3" @@ -51910,6 +52665,11 @@ "unified": "^10.0.0" } }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" + }, "require-directory": { "version": "2.1.1", "dev": true @@ -53634,6 +54394,14 @@ "pbf": "^3.2.1" } }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, "w3c-xmlserializer": { "version": "4.0.0", "requires": { diff --git a/plugins/ui/DESIGN.md b/plugins/ui/DESIGN.md index dfa79ec6d..03aadc09f 100644 --- a/plugins/ui/DESIGN.md +++ b/plugins/ui/DESIGN.md @@ -115,6 +115,32 @@ st.write("Result:", res) - Re-running everything can be costly, need to be conscious with caching/memoization - Does not achieve composability +### Markdown Component + +The markdown component should take a string and render it with the CommonMark formatting spec. The component should also support LaTeX with `remark-math` and `rehype-mathjax`. Other plugins and markdown components are not supported. The markdown is wrapped in a `View`, which all props are passed to except for `children`. + +```python +from deephaven import ui + +md_example = ui.markdown( + r""" +# Heading 1 + +## Heading 2 + +Text **bold** + +$$ +\eqalign{ +(a+b)^2 &= (a+b)(a+b) \\ +&= a^2 + ab + ba + b^2 \\ +&= a^2 + 2ab + b^2 +} +$$ + """ +) +``` + ## Proposed Syntaxes ### Interactive Query diff --git a/plugins/ui/docs/components/markdown.md b/plugins/ui/docs/components/markdown.md new file mode 100644 index 000000000..65e44d50d --- /dev/null +++ b/plugins/ui/docs/components/markdown.md @@ -0,0 +1,145 @@ +# Markdown + +The markdown component renders a string in the CommonMark standard. It also supports LaTeX (through MathJax), with `remark-math` and `rehype-mathjax`. Other plugins and markdown components are not supported. The markdown is wrapped in a `View`, which all props are passed to except for `children`. + +For individual lines of text, consider using `ui.text` and `ui.heading` instead. + +## Example + +```python +from deephaven import ui + + +markdown_str = """ +# Heading 1 +## Heading 2 +### Heading 3 + +Regular **bold** *italic* + +- Unordered list 1 +- Unordered list 2 + +1. Ordered list 1 +2. Ordered list 2 + +`inline code` +""" + + +@ui.component +def ui_markdown(): + return ui.markdown(markdown_str) + + +ui_markdown_example = ui_markdown() +``` + +## LaTeX + +When writing LaTeX, be careful how Python handles backslashes with escape characters. To minimize this issue, it is recommended to use raw strings. + +```python +from deephaven import ui + + +raw_md_str = r""" +This is a raw Python string. Notice the "r" before the quotation marks in the code. + +$$ +\eqalign{ +(a+b)^2 &= (a+b)(a+b) \\ +&= a^2 + ab + ba + b^2 \\ +&= a^2 + 2ab + b^2 +} +$$ + +Since raw strings ignore backslashes, all symbols require one backslash. +$$ +\leftarrow \rightarrow \nrightarrow +$$ +""" + +regular_md_str = """ +This is a regular Python string. Notice the extra backslashes necessary in the code. + +$$ +\eqalign{ +(a+b)^2 &= (a+b)(a+b) \\\\ +&= a^2 + ab + ba + b^2 \\\\ +&= a^2 + 2ab + b^2 +} +$$ + +Some backslashes are used to represent escape characters, requiring an extra backslash for LaTeX symbols. +$$ +\leftarrow \\rightarrow \\nrightarrow +$$ +""" + + +@ui.component +def latex_markdown(): + return ui.flex( + ui.markdown(raw_md_str), ui.markdown(regular_md_str), column_gap="30px" + ) + + +latex_example = latex_markdown() +``` + +## Code Blocks + +Code blocks follow Deephaven's formatting. + +````python +from deephaven import ui + + +code_str = """ +### Python + +```python +print("Hello, World!") +``` + +### Java + +```java +public class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} +``` +""" + +@ui.component +def code_markdown(): + return ui.markdown(code_str) + + +code_example = code_markdown() +```` + +## Container Style + +Markdown is automatically wrapped in a `View`, which all props except `children` are passed to. + +```python +from deephaven import ui + + +@ui.component +def style_markdown(): + return ui.markdown("Test", height="150px", width="300px", background_color="red") + + +style_example = style_markdown() +``` + +## API Reference + +```{eval-rst} +.. dhautofunction:: deephaven.ui.markdown +``` diff --git a/plugins/ui/docs/sidebar.json b/plugins/ui/docs/sidebar.json index 970429771..532039c9a 100644 --- a/plugins/ui/docs/sidebar.json +++ b/plugins/ui/docs/sidebar.json @@ -65,6 +65,10 @@ "label": "image", "path": "components/image.md" }, + { + "label": "markdown", + "path": "components/markdown.md" + }, { "label": "picker", "path": "components/picker.md" diff --git a/plugins/ui/src/deephaven/ui/components/__init__.py b/plugins/ui/src/deephaven/ui/components/__init__.py index 049beb11e..482540b66 100644 --- a/plugins/ui/src/deephaven/ui/components/__init__.py +++ b/plugins/ui/src/deephaven/ui/components/__init__.py @@ -31,6 +31,7 @@ from .list_action_menu import list_action_menu from .list_view import list_view from .make_component import make_component as component +from .markdown import markdown from .number_field import number_field from .panel import panel from .picker import picker @@ -93,6 +94,7 @@ "list_action_group", "list_action_menu", "html", + "markdown", "number_field", "panel", "picker", diff --git a/plugins/ui/src/deephaven/ui/components/markdown.py b/plugins/ui/src/deephaven/ui/components/markdown.py new file mode 100644 index 000000000..5e58a51b8 --- /dev/null +++ b/plugins/ui/src/deephaven/ui/components/markdown.py @@ -0,0 +1,245 @@ +from __future__ import annotations +from typing import Any +from .types import ( + ElementTypes, + AlignSelf, + BorderRadius, + BorderSize, + CSSProperties, + DimensionValue, + JustifySelf, + LayoutFlex, + Position, +) +from .basic import component_element +from ..elements import Element +from ..types import Color + + +def markdown( + children: str, + *, + element_type: ElementTypes | None = None, + flex: LayoutFlex | None = None, + flex_grow: float | None = None, + flex_shrink: float | None = None, + flex_basis: DimensionValue | None = None, + align_self: AlignSelf | None = None, + justify_self: JustifySelf | None = None, + order: int | None = None, + grid_area: str | None = None, + grid_row: str | None = None, + grid_row_start: str | None = None, + grid_row_end: str | None = None, + grid_column: str | None = None, + grid_column_start: str | None = None, + grid_column_end: str | None = None, + overflow: str | None = None, + margin: DimensionValue | None = None, + margin_top: DimensionValue | None = None, + margin_bottom: DimensionValue | None = None, + margin_start: DimensionValue | None = None, + margin_end: DimensionValue | None = None, + margin_x: DimensionValue | None = None, + margin_y: DimensionValue | None = None, + padding: DimensionValue | None = None, + padding_top: DimensionValue | None = None, + padding_bottom: DimensionValue | None = None, + padding_start: DimensionValue | None = None, + padding_end: DimensionValue | None = None, + padding_x: DimensionValue | None = None, + padding_y: DimensionValue | None = None, + width: DimensionValue | None = None, + height: DimensionValue | None = None, + min_width: DimensionValue | None = None, + min_height: DimensionValue | None = None, + max_width: DimensionValue | None = None, + max_height: DimensionValue | None = None, + background_color: Color | None = None, + border_width: BorderSize | None = None, + border_start_width: BorderSize | None = None, + border_end_width: BorderSize | None = None, + border_top_width: BorderSize | None = None, + border_bottom_width: BorderSize | None = None, + border_x_width: BorderSize | None = None, + border_y_width: BorderSize | None = None, + border_color: Color | None = None, + border_start_color: Color | None = None, + border_end_color: Color | None = None, + border_top_color: Color | None = None, + border_bottom_color: Color | None = None, + border_x_color: Color | None = None, + border_y_color: Color | None = None, + border_radius: BorderRadius | None = None, + border_top_start_radius: BorderRadius | None = None, + border_top_end_radius: BorderRadius | None = None, + border_bottom_start_radius: BorderRadius | None = None, + border_bottom_end_radius: BorderRadius | None = None, + position: Position | None = None, + top: DimensionValue | None = None, + bottom: DimensionValue | None = None, + start: DimensionValue | None = None, + end: DimensionValue | None = None, + left: DimensionValue | None = None, + right: DimensionValue | None = None, + z_index: int | None = None, + is_hidden: bool | None = None, + id: str | None = None, + UNSAFE_class_name: str | None = None, + UNSAFE_style: CSSProperties | None = None, + key: str | None = None, +) -> Element: + """ + View is a general purpose container with no specific semantics that can be used for custom styling purposes. It supports Spectrum style props to ensure consistency with other Spectrum components. + + Args: + children: The markdown string. + element_type: The type of element to render. + flex: When used in a flex layout, specifies how the element will grow or shrink to fit the space available. + flex_grow: When used in a flex layout, specifies how the element will grow to fit the space available. + flex_shrink: When used in a flex layout, specifies how the element will shrink to fit the space available. + flex_basis: When used in a flex layout, specifies the initial main size of the element. + align_self: Overrides the alignItems property of a flex or grid container. + justify_self: Species how the element is justified inside a flex or grid container. + order: The layout order for the element within a flex or grid container. + grid_area: When used in a grid layout specifies, specifies the named grid area that the element should be placed in within the grid. + grid_row: When used in a grid layout, specifies the row the element should be placed in within the grid. + grid_column: When used in a grid layout, specifies the column the element should be placed in within the grid. + grid_row_start: When used in a grid layout, specifies the starting row to span within the grid. + grid_row_end: When used in a grid layout, specifies the ending row to span within the grid. + grid_column_start: When used in a grid layout, specifies the starting column to span within the grid. + grid_column_end: When used in a grid layout, specifies the ending column to span within the grid. + overflow: Specifies what to do when the elment's content is too long to fit its size. + margin: The margin for all four sides of the element. + margin_top: The margin for the top side of the element. + margin_bottom: The margin for the bottom side of the element. + margin_start: The margin for the logical start side of the element, depending on layout direction. + margin_end: The margin for the logical end side of the element, depending on layout direction. + margin_x: The margin for the left and right sides of the element. + margin_y: The margin for the top and bottom sides of the element. + padding: The padding for all four sides of the element. + padding_top: The padding for the top side of the element. + padding_bottom: The padding for the bottom side of the element. + padding_start: The padding for the logical start side of the element, depending on layout direction. + padding_end: The padding for the logical end side of the element, depending on layout direction. + padding_x: The padding for the left and right sides of the element. + padding_y: The padding for the top and bottom sides of the element. + width: The width of the element. + min_width: The minimum width of the element. + max_width: The maximum width of the element. + height: The height of the element. + min_height: The minimum height of the element. + max_height: The maximum height of the element. + background_color: The background color of the element. + border_width: The width of the border for all four sides of the element. + border_start_width: The width of the border for the start side of the element, depending on layout direction. + border_end_width: The width of the border for the end side of the element, depending on layout direction. + border_top_width: The width of the border for the top side of the element. + border_bottom_width: The width of the border for the bottom side of the element. + border_x_width: The width of the border for the left and right sides of the element. + border_y_width: The width of the border for the top and bottom sides of the element. + + border_color: The color of the border for all four sides of the element. + border_start_color: The color of the border for the start side of the element, depending on layout direction. + border_end_color: The color of the border for the end side of the element, depending on layout direction. + border_top_color: The color of the border for the top side of the element. + border_bottom_color: The color of the border for the bottom side of the element. + border_x_color: The color of the border for the left and right sides of the element. + border_y_color: The color of the border for the top and bottom sides of the element. + + border_radius: The radius of the border for all four corners of the element. + border_top_start_radius: The radius of the border for the top start corner of the element. + border_top_end_radius: The radius of the border for the top end corner of the element. + border_bottom_start_radius: The radius of the border for the bottom start corner of the element. + border_bottom_end_radius: The radius of the border for the bottom end corner of the element. + position: The position of the element. + top: The distance from the top of the containing element. + bottom: The distance from the bottom of the containing element. + left: The distance from the left of the containing element. + right: The distance from the right of the containing element. + start: The distance from the start of the containing element, depending on layout direction. + end: The distance from the end of the containing element, depending on layout direction. + z_index: The stack order of the element. + is_hidden: Whether the element is hidden. + id: The unique identifier of the element. + UNSAFE_class_name: A CSS class to apply to the element. + UNSAFE_style: A CSS style to apply to the element. + key: A unique identifier used by React to render elements in a list. + + Returns: + The rendered view. + """ + + return component_element( + "Markdown", + children=children, + element_type=element_type, + flex=flex, + flex_grow=flex_grow, + flex_shrink=flex_shrink, + flex_basis=flex_basis, + align_self=align_self, + justify_self=justify_self, + order=order, + grid_area=grid_area, + grid_row=grid_row, + grid_row_start=grid_row_start, + grid_row_end=grid_row_end, + grid_column=grid_column, + grid_column_start=grid_column_start, + grid_column_end=grid_column_end, + overflow=overflow, + margin=margin, + margin_top=margin_top, + margin_bottom=margin_bottom, + margin_start=margin_start, + margin_end=margin_end, + margin_x=margin_x, + margin_y=margin_y, + padding=padding, + padding_top=padding_top, + padding_bottom=padding_bottom, + padding_start=padding_start, + padding_end=padding_end, + padding_x=padding_x, + padding_y=padding_y, + width=width, + height=height, + min_width=min_width, + min_height=min_height, + max_width=max_width, + max_height=max_height, + background_color=background_color, + border_width=border_width, + border_start_width=border_start_width, + border_end_width=border_end_width, + border_top_width=border_top_width, + border_bottom_width=border_bottom_width, + border_x_width=border_x_width, + border_y_width=border_y_width, + border_color=border_color, + border_start_color=border_start_color, + border_end_color=border_end_color, + border_top_color=border_top_color, + border_bottom_color=border_bottom_color, + border_x_color=border_x_color, + border_y_color=border_y_color, + border_radius=border_radius, + border_top_start_radius=border_top_start_radius, + border_top_end_radius=border_top_end_radius, + border_bottom_start_radius=border_bottom_start_radius, + border_bottom_end_radius=border_bottom_end_radius, + position=position, + top=top, + bottom=bottom, + start=start, + end=end, + left=left, + right=right, + z_index=z_index, + is_hidden=is_hidden, + id=id, + UNSAFE_class_name=UNSAFE_class_name, + UNSAFE_style=UNSAFE_style, + key=key, + ) diff --git a/plugins/ui/src/js/package.json b/plugins/ui/src/js/package.json index b6983ac88..ae11d76fa 100644 --- a/plugins/ui/src/js/package.json +++ b/plugins/ui/src/js/package.json @@ -41,6 +41,7 @@ "dependencies": { "@deephaven/chart": "^0.95.0", "@deephaven/components": "^0.95.0", + "@deephaven/console": "^0.95.0", "@deephaven/dashboard": "^0.95.0", "@deephaven/dashboard-core-plugins": "^0.95.0", "@deephaven/golden-layout": "^0.95.0", @@ -62,7 +63,10 @@ "classnames": "^2.5.1", "json-rpc-2.0": "^1.6.0", "nanoid": "^5.0.7", - "react-redux": "^7.x" + "react-markdown": "^8.0.7", + "react-redux": "^7.x", + "rehype-mathjax": "^3.1.0", + "remark-math": "^5.1.1" }, "publishConfig": { "access": "public" diff --git a/plugins/ui/src/js/src/elements/Markdown.tsx b/plugins/ui/src/js/src/elements/Markdown.tsx new file mode 100644 index 000000000..e081b24ba --- /dev/null +++ b/plugins/ui/src/js/src/elements/Markdown.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { type CodeComponent } from 'react-markdown/lib/ast-to-react'; +import remarkMath from 'remark-math'; +import rehypeMathjax from 'rehype-mathjax'; +import ReactMarkdown from 'react-markdown'; +import { View, ViewProps } from '@deephaven/components'; +import { Code } from '@deephaven/console'; + +type MarkdownProps = Omit & { + children: string; +}; + +const renderMarkdown: CodeComponent = props => { + const { children, className } = props; + const language = + className !== undefined && className?.startsWith('language-') + ? className.substring(9) + : 'plaintext'; + return ( +
+      
+        
+          {React.Children.map(children, child =>
+            typeof child === 'string' ? child.trim() : child
+          )}
+        
+      
+    
+ ); +}; + +export function Markdown({ children, ...props }: MarkdownProps): JSX.Element { + return ( + // eslint-disable-next-line react/jsx-props-no-spreading + + + {children} + + + ); +} + +Markdown.displayName = 'Markdown'; + +export default Markdown; diff --git a/plugins/ui/src/js/src/elements/index.ts b/plugins/ui/src/js/src/elements/index.ts index e2a3fa596..fab7cd9df 100644 --- a/plugins/ui/src/js/src/elements/index.ts +++ b/plugins/ui/src/js/src/elements/index.ts @@ -16,6 +16,7 @@ export * from './IconElementView'; export * from './IllustratedMessage'; export * from './Image'; export * from './ListView'; +export * from './Markdown'; export * from './model'; export * from './ObjectView'; export * from './Picker'; diff --git a/plugins/ui/src/js/src/elements/model/ElementConstants.ts b/plugins/ui/src/js/src/elements/model/ElementConstants.ts index 0b6f246f0..b58acb112 100644 --- a/plugins/ui/src/js/src/elements/model/ElementConstants.ts +++ b/plugins/ui/src/js/src/elements/model/ElementConstants.ts @@ -48,6 +48,7 @@ export const ELEMENT_NAME = { listActionGroup: uiComponentName('ListActionGroup'), listActionMenu: uiComponentName('ListActionMenu'), listView: uiComponentName('ListView'), + markdown: uiComponentName('Markdown'), numberField: uiComponentName('NumberField'), picker: uiComponentName('Picker'), progressBar: uiComponentName('ProgressBar'), diff --git a/plugins/ui/src/js/src/widget/WidgetUtils.tsx b/plugins/ui/src/js/src/widget/WidgetUtils.tsx index a6c394a50..52e33c096 100644 --- a/plugins/ui/src/js/src/widget/WidgetUtils.tsx +++ b/plugins/ui/src/js/src/widget/WidgetUtils.tsx @@ -60,6 +60,7 @@ import { IllustratedMessage, Image, ListView, + Markdown, Picker, ProgressBar, ProgressCircle, @@ -129,6 +130,7 @@ export const elementComponentMap = { [ELEMENT_NAME.listActionGroup]: ListActionGroup, [ELEMENT_NAME.listActionMenu]: ListActionMenu, [ELEMENT_NAME.listView]: ListView, + [ELEMENT_NAME.markdown]: Markdown, [ELEMENT_NAME.numberField]: NumberField, [ELEMENT_NAME.picker]: Picker, [ELEMENT_NAME.progressBar]: ProgressBar, diff --git a/plugins/ui/src/js/vite.config.ts b/plugins/ui/src/js/vite.config.ts index 9a1abb16f..f8637b5a0 100644 --- a/plugins/ui/src/js/vite.config.ts +++ b/plugins/ui/src/js/vite.config.ts @@ -19,6 +19,7 @@ export default defineConfig(({ mode }) => ({ 'react-redux', '@deephaven/chart', '@deephaven/components', + '@deephaven/console', '@deephaven/dashboard', '@deephaven/icons', '@deephaven/iris-grid',