From 151795663bbdc8f52ab046a2dc4aa148b2efba51 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 17 Aug 2022 14:39:44 -0300 Subject: [PATCH] feat: Adds the MetadataBar component (#21090) * feat: Adds the MetadataBar component * Addresses comments --- superset-frontend/.eslintrc.js | 1 + superset-frontend/.storybook/main.js | 4 +- superset-frontend/.storybook/preview.jsx | 1 + superset-frontend/package-lock.json | 2129 ++++++++++++++++- superset-frontend/package.json | 1 + .../components/MetadataBar/ContentConfig.tsx | 143 ++ .../src/components/MetadataBar/ContentType.ts | 91 + .../MetadataBar/MetadataBar.stories.tsx | 109 + .../MetadataBar/MetadataBar.test.tsx | 257 ++ .../MetadataBar/Overview.stories.mdx | 137 ++ .../src/components/MetadataBar/index.tsx | 190 ++ .../components/AddSliceCard/AddSliceCard.tsx | 2 +- superset-frontend/webpack.config.js | 19 + 13 files changed, 3075 insertions(+), 9 deletions(-) create mode 100644 superset-frontend/src/components/MetadataBar/ContentConfig.tsx create mode 100644 superset-frontend/src/components/MetadataBar/ContentType.ts create mode 100644 superset-frontend/src/components/MetadataBar/MetadataBar.stories.tsx create mode 100644 superset-frontend/src/components/MetadataBar/MetadataBar.test.tsx create mode 100644 superset-frontend/src/components/MetadataBar/Overview.stories.mdx create mode 100644 superset-frontend/src/components/MetadataBar/index.tsx diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js index 01ef83996..98a453d8c 100644 --- a/superset-frontend/.eslintrc.js +++ b/superset-frontend/.eslintrc.js @@ -115,6 +115,7 @@ module.exports = { 'jsx-a11y/anchor-is-valid': 1, 'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion 'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion + 'max-classes-per-file': 0, 'new-cap': 0, 'no-bitwise': 0, 'no-continue': 0, diff --git a/superset-frontend/.storybook/main.js b/superset-frontend/.storybook/main.js index caa689835..8a004ba3e 100644 --- a/superset-frontend/.storybook/main.js +++ b/superset-frontend/.storybook/main.js @@ -24,7 +24,7 @@ module.exports = { builder: 'webpack5', }, stories: [ - '../src/@(components|common|filters|explore)/**/*.stories.@(t|j)sx', + '../src/@(components|common|filters|explore)/**/*.stories.@(tsx|jsx|mdx)', ], addons: [ '@storybook/addon-essentials', @@ -47,6 +47,6 @@ module.exports = { plugins: [...config.plugins, ...customConfig.plugins], }), typescript: { - reactDocgen: 'none', + reactDocgen: 'react-docgen-typescript', }, }; diff --git a/superset-frontend/.storybook/preview.jsx b/superset-frontend/.storybook/preview.jsx index 7deb1e608..06cfad0e9 100644 --- a/superset-frontend/.storybook/preview.jsx +++ b/superset-frontend/.storybook/preview.jsx @@ -66,4 +66,5 @@ addParameters({ method: 'alphabetical', }, }, + controls: { expanded: true }, }); diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index aa2eda489..d42cabd78 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -162,6 +162,7 @@ "@hot-loader/react-dom": "^16.13.0", "@istanbuljs/nyc-config-typescript": "^1.0.1", "@storybook/addon-actions": "^6.4.22", + "@storybook/addon-docs": "^6.5.10", "@storybook/addon-essentials": "^6.4.22", "@storybook/addon-knobs": "^6.3.1", "@storybook/addon-links": "^6.4.22", @@ -11368,6 +11369,921 @@ } } }, + "node_modules/@storybook/addon-docs": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-6.5.10.tgz", + "integrity": "sha512-1kgjo3f0vL6GN8fTwLL05M/q/kDdzvuqwhxPY/v5hubFb3aQZGr2yk9pRBaLAbs4bez0yG0ASXcwhYnrEZUppg==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.12.12", + "@babel/preset-env": "^7.12.11", + "@jest/transform": "^26.6.2", + "@mdx-js/react": "^1.6.22", + "@storybook/addons": "6.5.10", + "@storybook/api": "6.5.10", + "@storybook/components": "6.5.10", + "@storybook/core-common": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/docs-tools": "6.5.10", + "@storybook/mdx1-csf": "^0.0.1", + "@storybook/node-logger": "6.5.10", + "@storybook/postinstall": "6.5.10", + "@storybook/preview-web": "6.5.10", + "@storybook/source-loader": "6.5.10", + "@storybook/store": "6.5.10", + "@storybook/theming": "6.5.10", + "babel-loader": "^8.0.0", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "regenerator-runtime": "^0.13.7", + "remark-external-links": "^8.0.0", + "remark-slug": "^6.0.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@storybook/mdx2-csf": "^0.0.3", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@storybook/mdx2-csf": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/addons": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.10.tgz", + "integrity": "sha512-VD4tBCQ23PkSeDoxuHcKy0RfhIs3oMYjBacOZx7d0bvOzK9WjPyvE2ysDAh7r/ceqnwmWHAScIpE+I1RU7gl+g==", + "dev": true, + "dependencies": { + "@storybook/api": "6.5.10", + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/theming": "6.5.10", + "@types/webpack-env": "^1.16.0", + "core-js": "^3.8.2", + "global": "^4.4.0", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/api": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.5.10.tgz", + "integrity": "sha512-AkmgSPNEGdKp4oZA4KQ+RJsacw7GwfvjsVDnCkcXqS9zmSr/RNL0fhpcd60KKkmx/hGKPTDFpK3ZayxDrJ/h4A==", + "dev": true, + "dependencies": { + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.5.10", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "store2": "^2.12.0", + "telejson": "^6.0.8", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/channel-postmessage": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.5.10.tgz", + "integrity": "sha512-t9PTA0UzFvYa3IlOfpBOolfrRMPTjUMIeCQ6FNyM0aj5GqLKSvoQzP8NeoRpIrvyf6ljFKKdaMaZ3fiCvh45ag==", + "dev": true, + "dependencies": { + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "core-js": "^3.8.2", + "global": "^4.4.0", + "qs": "^6.10.0", + "telejson": "^6.0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/channels": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.10.tgz", + "integrity": "sha512-lo26YZ6kWpHXLhuHJF4P/bICY7jD/rXEZqReKtGOSk1Lv99/xvG6pqmcy3hWLf3v3Dy/8otjRPSR7izFVIIZgQ==", + "dev": true, + "dependencies": { + "core-js": "^3.8.2", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/client-logger": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.10.tgz", + "integrity": "sha512-/xA0MHOevXev68hyLMQw8Qo8KczSIdXOxliAgrycMTkDmw5eKeA8TP7B8zP3wGuq/e3MrdD9/8MWhb/IQBNC3w==", + "dev": true, + "dependencies": { + "core-js": "^3.8.2", + "global": "^4.4.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/components": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.5.10.tgz", + "integrity": "sha512-9OhgB8YQfGwOKjo/N96N5mrtJ6qDVVoEM1zuhea32tJUd2eYf0aSWpryA9VnOM0V1q/8DAoCg5rPBMYWMBU5uw==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/theming": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/core-common": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-6.5.10.tgz", + "integrity": "sha512-Bx+VKkfWdrAmD8T51Sjq/mMhRaiapBHcpG4cU5bc3DMbg+LF2/yrgqv/cjVu+m5gHAzYCac5D7gqzBgvG7Myww==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.10", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-decorators": "^7.12.12", + "@babel/plugin-proposal-export-default-from": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-private-property-in-object": "^7.12.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.12", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/preset-env": "^7.12.11", + "@babel/preset-react": "^7.12.10", + "@babel/preset-typescript": "^7.12.7", + "@babel/register": "^7.12.1", + "@storybook/node-logger": "6.5.10", + "@storybook/semver": "^7.3.2", + "@types/node": "^14.0.10 || ^16.0.0", + "@types/pretty-hrtime": "^1.0.0", + "babel-loader": "^8.0.0", + "babel-plugin-macros": "^3.0.1", + "babel-plugin-polyfill-corejs3": "^0.1.0", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "express": "^4.17.1", + "file-system-cache": "^1.0.5", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.0.4", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "handlebars": "^4.7.7", + "interpret": "^2.2.0", + "json5": "^2.1.3", + "lazy-universal-dotenv": "^3.0.1", + "picomatch": "^2.3.0", + "pkg-dir": "^5.0.0", + "pretty-hrtime": "^1.0.3", + "resolve-from": "^5.0.0", + "slash": "^3.0.0", + "telejson": "^6.0.8", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2", + "webpack": "4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/core-events": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.10.tgz", + "integrity": "sha512-EVb1gO1172klVIAABLOoigFMx0V88uctY0K/qVCO8n6v+wd2+0Ccn63kl+gTxsAC3WZ8XhXh9q2w5ImHklVECw==", + "dev": true, + "dependencies": { + "core-js": "^3.8.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/csf": { + "version": "0.0.2--canary.4566f4d.1", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", + "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/node-logger": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.5.10.tgz", + "integrity": "sha512-bYswXIKV7Stru8vYfkjUMNN8UhF7Qg7NRsUvG5Djt5lLIae1XmUIgnH40mU/nW4X4BSfcR9MKxsSsngvn2WmQg==", + "dev": true, + "dependencies": { + "@types/npmlog": "^4.1.2", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "npmlog": "^5.0.1", + "pretty-hrtime": "^1.0.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/postinstall": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-6.5.10.tgz", + "integrity": "sha512-xqUdpnFHYkn8MgtV+QztvIsRWa6jQUk7QT1Mu17Y0S7PbslNGsuskRPHenHhACXBJF+TM86R+4BaAhnVYTmElw==", + "dev": true, + "dependencies": { + "core-js": "^3.8.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/preview-web": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/preview-web/-/preview-web-6.5.10.tgz", + "integrity": "sha512-sTC/o5gkvALOtcNgtApGKGN9EavvSxRHBeBh+5BQjV2qQ8ap+26RsfUizNBECAa2Jrn4osaDYn9HRhJLFL69WA==", + "dev": true, + "dependencies": { + "@storybook/addons": "6.5.10", + "@storybook/channel-postmessage": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/store": "6.5.10", + "ansi-to-html": "^0.6.11", + "core-js": "^3.8.2", + "global": "^4.4.0", + "lodash": "^4.17.21", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "unfetch": "^4.2.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/router": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.10.tgz", + "integrity": "sha512-O+vNW/eEpYFF8eCg5jZjNQ6q2DKQVxqDRPCy9pJdEbvavMDZn6AFYgVK+VJe5F4211WW2yncOu922xObCxXJYg==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/source-loader": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.5.10.tgz", + "integrity": "sha512-1RxxRumpjs8VUUwES9LId+cuNQnixhZAcwCxd6jaKkTZbjiQCtAhXX6DBTjJGV1u/JnCsqEp5b1wB8j/EioNHw==", + "dev": true, + "dependencies": { + "@storybook/addons": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "core-js": "^3.8.2", + "estraverse": "^5.2.0", + "global": "^4.4.0", + "loader-utils": "^2.0.0", + "lodash": "^4.17.21", + "prettier": ">=2.2.1 <=2.3.0", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/source-loader/node_modules/loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/store": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/store/-/store-6.5.10.tgz", + "integrity": "sha512-RswrSYh2IiKkytFPxP9AvP+hekjrvHK2ILvyDk2ZgduCN4n5ivsekOb+N3M2t+dq1eLuW9or5n2T4OWwAwjxxQ==", + "dev": true, + "dependencies": { + "@storybook/addons": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "slash": "^3.0.0", + "stable": "^0.1.8", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/theming": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.10.tgz", + "integrity": "sha512-BvTQBBcSEwKKcsVmF+Ol6v0RIQUr+bxP7gb10wtfBd23mZTEFA0C1N5FnZr/dDeiBKG1pvf1UKvoYA731y0BsA==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/@types/node": { + "version": "16.11.48", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.48.tgz", + "integrity": "sha512-Z9r9UWlNeNkYnxybm+1fc0jxUNjZqRekTAr1pG0qdXe9apT9yCiqk1c4VvKQJsFpnchU4+fLl25MabSLA2wxIw==", + "dev": true + }, + "node_modules/@storybook/addon-docs/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/addon-docs/node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@storybook/addon-docs/node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/@storybook/addon-docs/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@storybook/addon-docs/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@storybook/addon-docs/node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@storybook/addon-docs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/addon-docs/node_modules/isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@storybook/addon-docs/node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/@storybook/addon-docs/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@storybook/addon-docs/node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@storybook/addon-docs/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@storybook/addon-docs/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/addon-docs/node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@storybook/addon-docs/node_modules/prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@storybook/addon-docs/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@storybook/addon-docs/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/addon-docs/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@storybook/addon-docs/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/addon-docs/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/addon-docs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/addon-docs/node_modules/telejson": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-6.0.8.tgz", + "integrity": "sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==", + "dev": true, + "dependencies": { + "@types/is-function": "^1.0.0", + "global": "^4.4.0", + "is-function": "^1.0.2", + "is-regex": "^1.1.2", + "is-symbol": "^1.0.3", + "isobject": "^4.0.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3" + } + }, + "node_modules/@storybook/addon-docs/node_modules/terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/@storybook/addon-docs/node_modules/webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + }, + "webpack-command": { + "optional": true + } + } + }, + "node_modules/@storybook/addon-docs/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, "node_modules/@storybook/addon-essentials": { "version": "6.4.22", "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-6.4.22.tgz", @@ -13934,6 +14850,257 @@ "node": ">=10.13.0" } }, + "node_modules/@storybook/docs-tools": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-6.5.10.tgz", + "integrity": "sha512-/bvYgOO+CxMEcHifkjJg0A60OTGOhcjGxnsB1h0gJuxMrqA/7Qwc108bFmPiX0eiD1BovFkZLJV4O6OY7zP5Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/store": "6.5.10", + "core-js": "^3.8.2", + "doctrine": "^3.0.0", + "lodash": "^4.17.21", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/addons": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.10.tgz", + "integrity": "sha512-VD4tBCQ23PkSeDoxuHcKy0RfhIs3oMYjBacOZx7d0bvOzK9WjPyvE2ysDAh7r/ceqnwmWHAScIpE+I1RU7gl+g==", + "dev": true, + "dependencies": { + "@storybook/api": "6.5.10", + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/theming": "6.5.10", + "@types/webpack-env": "^1.16.0", + "core-js": "^3.8.2", + "global": "^4.4.0", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/api": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.5.10.tgz", + "integrity": "sha512-AkmgSPNEGdKp4oZA4KQ+RJsacw7GwfvjsVDnCkcXqS9zmSr/RNL0fhpcd60KKkmx/hGKPTDFpK3ZayxDrJ/h4A==", + "dev": true, + "dependencies": { + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.5.10", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "store2": "^2.12.0", + "telejson": "^6.0.8", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/channels": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.10.tgz", + "integrity": "sha512-lo26YZ6kWpHXLhuHJF4P/bICY7jD/rXEZqReKtGOSk1Lv99/xvG6pqmcy3hWLf3v3Dy/8otjRPSR7izFVIIZgQ==", + "dev": true, + "dependencies": { + "core-js": "^3.8.2", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/client-logger": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.10.tgz", + "integrity": "sha512-/xA0MHOevXev68hyLMQw8Qo8KczSIdXOxliAgrycMTkDmw5eKeA8TP7B8zP3wGuq/e3MrdD9/8MWhb/IQBNC3w==", + "dev": true, + "dependencies": { + "core-js": "^3.8.2", + "global": "^4.4.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/core-events": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.10.tgz", + "integrity": "sha512-EVb1gO1172klVIAABLOoigFMx0V88uctY0K/qVCO8n6v+wd2+0Ccn63kl+gTxsAC3WZ8XhXh9q2w5ImHklVECw==", + "dev": true, + "dependencies": { + "core-js": "^3.8.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/csf": { + "version": "0.0.2--canary.4566f4d.1", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", + "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/router": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.10.tgz", + "integrity": "sha512-O+vNW/eEpYFF8eCg5jZjNQ6q2DKQVxqDRPCy9pJdEbvavMDZn6AFYgVK+VJe5F4211WW2yncOu922xObCxXJYg==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/store": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/store/-/store-6.5.10.tgz", + "integrity": "sha512-RswrSYh2IiKkytFPxP9AvP+hekjrvHK2ILvyDk2ZgduCN4n5ivsekOb+N3M2t+dq1eLuW9or5n2T4OWwAwjxxQ==", + "dev": true, + "dependencies": { + "@storybook/addons": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "slash": "^3.0.0", + "stable": "^0.1.8", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/docs-tools/node_modules/@storybook/theming": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.10.tgz", + "integrity": "sha512-BvTQBBcSEwKKcsVmF+Ol6v0RIQUr+bxP7gb10wtfBd23mZTEFA0C1N5FnZr/dDeiBKG1pvf1UKvoYA731y0BsA==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@storybook/docs-tools/node_modules/isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@storybook/docs-tools/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@storybook/docs-tools/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/docs-tools/node_modules/telejson": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-6.0.8.tgz", + "integrity": "sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==", + "dev": true, + "dependencies": { + "@types/is-function": "^1.0.0", + "global": "^4.4.0", + "is-function": "^1.0.2", + "is-regex": "^1.1.2", + "is-symbol": "^1.0.3", + "isobject": "^4.0.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3" + } + }, "node_modules/@storybook/manager-webpack4": { "version": "6.4.22", "resolved": "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.4.22.tgz", @@ -14826,6 +15993,63 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "devOptional": true }, + "node_modules/@storybook/mdx1-csf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@storybook/mdx1-csf/-/mdx1-csf-0.0.1.tgz", + "integrity": "sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg==", + "dev": true, + "dependencies": { + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/preset-env": "^7.12.11", + "@babel/types": "^7.12.11", + "@mdx-js/mdx": "^1.6.22", + "@types/lodash": "^4.14.167", + "js-string-escape": "^1.0.1", + "loader-utils": "^2.0.0", + "lodash": "^4.17.21", + "prettier": ">=2.2.1 <=2.3.0", + "ts-dedent": "^2.0.0" + } + }, + "node_modules/@storybook/mdx1-csf/node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@storybook/mdx1-csf/node_modules/loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/@storybook/mdx1-csf/node_modules/prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@storybook/node-logger": { "version": "6.4.22", "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.4.22.tgz", @@ -16891,9 +18115,9 @@ "dev": true }, "node_modules/@types/lodash": { - "version": "4.14.149", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", - "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==" + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" }, "node_modules/@types/lodash.get": { "version": "4.4.6", @@ -64616,6 +65840,670 @@ "ts-dedent": "^2.0.0" } }, + "@storybook/addon-docs": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-6.5.10.tgz", + "integrity": "sha512-1kgjo3f0vL6GN8fTwLL05M/q/kDdzvuqwhxPY/v5hubFb3aQZGr2yk9pRBaLAbs4bez0yG0ASXcwhYnrEZUppg==", + "dev": true, + "requires": { + "@babel/plugin-transform-react-jsx": "^7.12.12", + "@babel/preset-env": "^7.12.11", + "@jest/transform": "^26.6.2", + "@mdx-js/react": "^1.6.22", + "@storybook/addons": "6.5.10", + "@storybook/api": "6.5.10", + "@storybook/components": "6.5.10", + "@storybook/core-common": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/docs-tools": "6.5.10", + "@storybook/mdx1-csf": "^0.0.1", + "@storybook/node-logger": "6.5.10", + "@storybook/postinstall": "6.5.10", + "@storybook/preview-web": "6.5.10", + "@storybook/source-loader": "6.5.10", + "@storybook/store": "6.5.10", + "@storybook/theming": "6.5.10", + "babel-loader": "^8.0.0", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "regenerator-runtime": "^0.13.7", + "remark-external-links": "^8.0.0", + "remark-slug": "^6.0.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "@storybook/addons": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.10.tgz", + "integrity": "sha512-VD4tBCQ23PkSeDoxuHcKy0RfhIs3oMYjBacOZx7d0bvOzK9WjPyvE2ysDAh7r/ceqnwmWHAScIpE+I1RU7gl+g==", + "dev": true, + "requires": { + "@storybook/api": "6.5.10", + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/theming": "6.5.10", + "@types/webpack-env": "^1.16.0", + "core-js": "^3.8.2", + "global": "^4.4.0", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/api": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.5.10.tgz", + "integrity": "sha512-AkmgSPNEGdKp4oZA4KQ+RJsacw7GwfvjsVDnCkcXqS9zmSr/RNL0fhpcd60KKkmx/hGKPTDFpK3ZayxDrJ/h4A==", + "dev": true, + "requires": { + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.5.10", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "store2": "^2.12.0", + "telejson": "^6.0.8", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/channel-postmessage": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.5.10.tgz", + "integrity": "sha512-t9PTA0UzFvYa3IlOfpBOolfrRMPTjUMIeCQ6FNyM0aj5GqLKSvoQzP8NeoRpIrvyf6ljFKKdaMaZ3fiCvh45ag==", + "dev": true, + "requires": { + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "core-js": "^3.8.2", + "global": "^4.4.0", + "qs": "^6.10.0", + "telejson": "^6.0.8" + } + }, + "@storybook/channels": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.10.tgz", + "integrity": "sha512-lo26YZ6kWpHXLhuHJF4P/bICY7jD/rXEZqReKtGOSk1Lv99/xvG6pqmcy3hWLf3v3Dy/8otjRPSR7izFVIIZgQ==", + "dev": true, + "requires": { + "core-js": "^3.8.2", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/client-logger": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.10.tgz", + "integrity": "sha512-/xA0MHOevXev68hyLMQw8Qo8KczSIdXOxliAgrycMTkDmw5eKeA8TP7B8zP3wGuq/e3MrdD9/8MWhb/IQBNC3w==", + "dev": true, + "requires": { + "core-js": "^3.8.2", + "global": "^4.4.0" + } + }, + "@storybook/components": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.5.10.tgz", + "integrity": "sha512-9OhgB8YQfGwOKjo/N96N5mrtJ6qDVVoEM1zuhea32tJUd2eYf0aSWpryA9VnOM0V1q/8DAoCg5rPBMYWMBU5uw==", + "dev": true, + "requires": { + "@storybook/client-logger": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/theming": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/core-common": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-6.5.10.tgz", + "integrity": "sha512-Bx+VKkfWdrAmD8T51Sjq/mMhRaiapBHcpG4cU5bc3DMbg+LF2/yrgqv/cjVu+m5gHAzYCac5D7gqzBgvG7Myww==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-decorators": "^7.12.12", + "@babel/plugin-proposal-export-default-from": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-private-property-in-object": "^7.12.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.12", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/preset-env": "^7.12.11", + "@babel/preset-react": "^7.12.10", + "@babel/preset-typescript": "^7.12.7", + "@babel/register": "^7.12.1", + "@storybook/node-logger": "6.5.10", + "@storybook/semver": "^7.3.2", + "@types/node": "^14.0.10 || ^16.0.0", + "@types/pretty-hrtime": "^1.0.0", + "babel-loader": "^8.0.0", + "babel-plugin-macros": "^3.0.1", + "babel-plugin-polyfill-corejs3": "^0.1.0", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "express": "^4.17.1", + "file-system-cache": "^1.0.5", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.0.4", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "handlebars": "^4.7.7", + "interpret": "^2.2.0", + "json5": "^2.1.3", + "lazy-universal-dotenv": "^3.0.1", + "picomatch": "^2.3.0", + "pkg-dir": "^5.0.0", + "pretty-hrtime": "^1.0.3", + "resolve-from": "^5.0.0", + "slash": "^3.0.0", + "telejson": "^6.0.8", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2", + "webpack": "4" + } + }, + "@storybook/core-events": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.10.tgz", + "integrity": "sha512-EVb1gO1172klVIAABLOoigFMx0V88uctY0K/qVCO8n6v+wd2+0Ccn63kl+gTxsAC3WZ8XhXh9q2w5ImHklVECw==", + "dev": true, + "requires": { + "core-js": "^3.8.2" + } + }, + "@storybook/csf": { + "version": "0.0.2--canary.4566f4d.1", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", + "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "@storybook/node-logger": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.5.10.tgz", + "integrity": "sha512-bYswXIKV7Stru8vYfkjUMNN8UhF7Qg7NRsUvG5Djt5lLIae1XmUIgnH40mU/nW4X4BSfcR9MKxsSsngvn2WmQg==", + "dev": true, + "requires": { + "@types/npmlog": "^4.1.2", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "npmlog": "^5.0.1", + "pretty-hrtime": "^1.0.3" + } + }, + "@storybook/postinstall": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-6.5.10.tgz", + "integrity": "sha512-xqUdpnFHYkn8MgtV+QztvIsRWa6jQUk7QT1Mu17Y0S7PbslNGsuskRPHenHhACXBJF+TM86R+4BaAhnVYTmElw==", + "dev": true, + "requires": { + "core-js": "^3.8.2" + } + }, + "@storybook/preview-web": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/preview-web/-/preview-web-6.5.10.tgz", + "integrity": "sha512-sTC/o5gkvALOtcNgtApGKGN9EavvSxRHBeBh+5BQjV2qQ8ap+26RsfUizNBECAa2Jrn4osaDYn9HRhJLFL69WA==", + "dev": true, + "requires": { + "@storybook/addons": "6.5.10", + "@storybook/channel-postmessage": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/store": "6.5.10", + "ansi-to-html": "^0.6.11", + "core-js": "^3.8.2", + "global": "^4.4.0", + "lodash": "^4.17.21", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "unfetch": "^4.2.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/router": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.10.tgz", + "integrity": "sha512-O+vNW/eEpYFF8eCg5jZjNQ6q2DKQVxqDRPCy9pJdEbvavMDZn6AFYgVK+VJe5F4211WW2yncOu922xObCxXJYg==", + "dev": true, + "requires": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/source-loader": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.5.10.tgz", + "integrity": "sha512-1RxxRumpjs8VUUwES9LId+cuNQnixhZAcwCxd6jaKkTZbjiQCtAhXX6DBTjJGV1u/JnCsqEp5b1wB8j/EioNHw==", + "dev": true, + "requires": { + "@storybook/addons": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "core-js": "^3.8.2", + "estraverse": "^5.2.0", + "global": "^4.4.0", + "loader-utils": "^2.0.0", + "lodash": "^4.17.21", + "prettier": ">=2.2.1 <=2.3.0", + "regenerator-runtime": "^0.13.7" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "@storybook/store": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/store/-/store-6.5.10.tgz", + "integrity": "sha512-RswrSYh2IiKkytFPxP9AvP+hekjrvHK2ILvyDk2ZgduCN4n5ivsekOb+N3M2t+dq1eLuW9or5n2T4OWwAwjxxQ==", + "dev": true, + "requires": { + "@storybook/addons": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "slash": "^3.0.0", + "stable": "^0.1.8", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/theming": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.10.tgz", + "integrity": "sha512-BvTQBBcSEwKKcsVmF+Ol6v0RIQUr+bxP7gb10wtfBd23mZTEFA0C1N5FnZr/dDeiBKG1pvf1UKvoYA731y0BsA==", + "dev": true, + "requires": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7" + } + }, + "@types/node": { + "version": "16.11.48", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.48.tgz", + "integrity": "sha512-Z9r9UWlNeNkYnxybm+1fc0jxUNjZqRekTAr1pG0qdXe9apT9yCiqk1c4VvKQJsFpnchU4+fLl25MabSLA2wxIw==", + "dev": true + }, + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dev": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + }, + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dev": true, + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "requires": { + "find-up": "^5.0.0" + } + }, + "prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "telejson": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-6.0.8.tgz", + "integrity": "sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==", + "dev": true, + "requires": { + "@types/is-function": "^1.0.0", + "global": "^4.4.0", + "is-function": "^1.0.2", + "is-regex": "^1.1.2", + "is-symbol": "^1.0.3", + "isobject": "^4.0.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3" + } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + }, + "webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } + } + }, "@storybook/addon-essentials": { "version": "6.4.22", "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-6.4.22.tgz", @@ -66344,6 +68232,191 @@ } } }, + "@storybook/docs-tools": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-6.5.10.tgz", + "integrity": "sha512-/bvYgOO+CxMEcHifkjJg0A60OTGOhcjGxnsB1h0gJuxMrqA/7Qwc108bFmPiX0eiD1BovFkZLJV4O6OY7zP5Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/store": "6.5.10", + "core-js": "^3.8.2", + "doctrine": "^3.0.0", + "lodash": "^4.17.21", + "regenerator-runtime": "^0.13.7" + }, + "dependencies": { + "@storybook/addons": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.10.tgz", + "integrity": "sha512-VD4tBCQ23PkSeDoxuHcKy0RfhIs3oMYjBacOZx7d0bvOzK9WjPyvE2ysDAh7r/ceqnwmWHAScIpE+I1RU7gl+g==", + "dev": true, + "requires": { + "@storybook/api": "6.5.10", + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/theming": "6.5.10", + "@types/webpack-env": "^1.16.0", + "core-js": "^3.8.2", + "global": "^4.4.0", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/api": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.5.10.tgz", + "integrity": "sha512-AkmgSPNEGdKp4oZA4KQ+RJsacw7GwfvjsVDnCkcXqS9zmSr/RNL0fhpcd60KKkmx/hGKPTDFpK3ZayxDrJ/h4A==", + "dev": true, + "requires": { + "@storybook/channels": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/router": "6.5.10", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.5.10", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "store2": "^2.12.0", + "telejson": "^6.0.8", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/channels": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.10.tgz", + "integrity": "sha512-lo26YZ6kWpHXLhuHJF4P/bICY7jD/rXEZqReKtGOSk1Lv99/xvG6pqmcy3hWLf3v3Dy/8otjRPSR7izFVIIZgQ==", + "dev": true, + "requires": { + "core-js": "^3.8.2", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/client-logger": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.10.tgz", + "integrity": "sha512-/xA0MHOevXev68hyLMQw8Qo8KczSIdXOxliAgrycMTkDmw5eKeA8TP7B8zP3wGuq/e3MrdD9/8MWhb/IQBNC3w==", + "dev": true, + "requires": { + "core-js": "^3.8.2", + "global": "^4.4.0" + } + }, + "@storybook/core-events": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.10.tgz", + "integrity": "sha512-EVb1gO1172klVIAABLOoigFMx0V88uctY0K/qVCO8n6v+wd2+0Ccn63kl+gTxsAC3WZ8XhXh9q2w5ImHklVECw==", + "dev": true, + "requires": { + "core-js": "^3.8.2" + } + }, + "@storybook/csf": { + "version": "0.0.2--canary.4566f4d.1", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", + "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "@storybook/router": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.10.tgz", + "integrity": "sha512-O+vNW/eEpYFF8eCg5jZjNQ6q2DKQVxqDRPCy9pJdEbvavMDZn6AFYgVK+VJe5F4211WW2yncOu922xObCxXJYg==", + "dev": true, + "requires": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/store": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/store/-/store-6.5.10.tgz", + "integrity": "sha512-RswrSYh2IiKkytFPxP9AvP+hekjrvHK2ILvyDk2ZgduCN4n5ivsekOb+N3M2t+dq1eLuW9or5n2T4OWwAwjxxQ==", + "dev": true, + "requires": { + "@storybook/addons": "6.5.10", + "@storybook/client-logger": "6.5.10", + "@storybook/core-events": "6.5.10", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "slash": "^3.0.0", + "stable": "^0.1.8", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/theming": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.10.tgz", + "integrity": "sha512-BvTQBBcSEwKKcsVmF+Ol6v0RIQUr+bxP7gb10wtfBd23mZTEFA0C1N5FnZr/dDeiBKG1pvf1UKvoYA731y0BsA==", + "dev": true, + "requires": { + "@storybook/client-logger": "6.5.10", + "core-js": "^3.8.2", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "telejson": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-6.0.8.tgz", + "integrity": "sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==", + "dev": true, + "requires": { + "@types/is-function": "^1.0.0", + "global": "^4.4.0", + "is-function": "^1.0.2", + "is-regex": "^1.1.2", + "is-symbol": "^1.0.3", + "isobject": "^4.0.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3" + } + } + } + }, "@storybook/manager-webpack4": { "version": "6.4.22", "resolved": "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.4.22.tgz", @@ -66953,6 +69026,50 @@ } } }, + "@storybook/mdx1-csf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@storybook/mdx1-csf/-/mdx1-csf-0.0.1.tgz", + "integrity": "sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg==", + "dev": true, + "requires": { + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/preset-env": "^7.12.11", + "@babel/types": "^7.12.11", + "@mdx-js/mdx": "^1.6.22", + "@types/lodash": "^4.14.167", + "js-string-escape": "^1.0.1", + "loader-utils": "^2.0.0", + "lodash": "^4.17.21", + "prettier": ">=2.2.1 <=2.3.0", + "ts-dedent": "^2.0.0" + }, + "dependencies": { + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true + }, + "loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true + } + } + }, "@storybook/node-logger": { "version": "6.4.22", "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.4.22.tgz", @@ -69357,9 +71474,9 @@ "dev": true }, "@types/lodash": { - "version": "4.14.149", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", - "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==" + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" }, "@types/lodash.get": { "version": "4.4.6", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 36d092c95..ba682a800 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -223,6 +223,7 @@ "@hot-loader/react-dom": "^16.13.0", "@istanbuljs/nyc-config-typescript": "^1.0.1", "@storybook/addon-actions": "^6.4.22", + "@storybook/addon-docs": "^6.5.10", "@storybook/addon-essentials": "^6.4.22", "@storybook/addon-knobs": "^6.3.1", "@storybook/addon-links": "^6.4.22", diff --git a/superset-frontend/src/components/MetadataBar/ContentConfig.tsx b/superset-frontend/src/components/MetadataBar/ContentConfig.tsx new file mode 100644 index 000000000..23d1dec3d --- /dev/null +++ b/superset-frontend/src/components/MetadataBar/ContentConfig.tsx @@ -0,0 +1,143 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import moment from 'moment'; +import { ensureIsArray, styled, t } from '@superset-ui/core'; +import Icons from 'src/components/Icons'; +import { ContentType, MetadataType } from './ContentType'; + +const Header = styled.div` + font-weight: ${({ theme }) => theme.typography.weights.bold}; +`; + +const Info = ({ + text, + header, +}: { + text?: string | string[]; + header?: string; +}) => { + const values = ensureIsArray(text); + return ( + <> + {header &&
{header}
} + {values.map(value => ( +
{value}
+ ))} + + ); +}; + +const config = (contentType: ContentType) => { + const { type } = contentType; + + /** + * Tooltips are very similar. It's pretty much blocks + * of header/text pairs. That's why they are implemented here. + * If more complex tooltips emerge, then we should extract the different + * types of tooltips to their own components and reference them here. + */ + + switch (type) { + case MetadataType.DASHBOARDS: + return { + icon: Icons.FundProjectionScreenOutlined, + title: contentType.title, + tooltip: contentType.description ? ( +
+ +
+ ) : undefined, + }; + + case MetadataType.DESCRIPTION: + return { + icon: Icons.BookOutlined, + title: contentType.value, + }; + + case MetadataType.LAST_MODIFIED: + return { + icon: Icons.EditOutlined, + title: moment.utc(contentType.value).fromNow(), + tooltip: ( +
+ + +
+ ), + }; + + case MetadataType.OWNER: + return { + icon: Icons.UserOutlined, + title: contentType.createdBy, + tooltip: ( +
+ + + +
+ ), + }; + + case MetadataType.ROWS: + return { + icon: Icons.InsertRowBelowOutlined, + title: contentType.title, + tooltip: contentType.title, + }; + + case MetadataType.SQL: + return { + icon: Icons.ConsoleSqlOutlined, + title: contentType.title, + tooltip: contentType.title, + }; + + case MetadataType.TABLE: + return { + icon: Icons.Table, + title: contentType.title, + tooltip: contentType.title, + }; + + case MetadataType.TAGS: + return { + icon: Icons.TagsOutlined, + title: contentType.values.join(', '), + tooltip: ( +
+ +
+ ), + }; + + default: + throw Error(`Invalid type provided: ${type}`); + } +}; + +export { config }; diff --git a/superset-frontend/src/components/MetadataBar/ContentType.ts b/superset-frontend/src/components/MetadataBar/ContentType.ts new file mode 100644 index 000000000..9a4e6082e --- /dev/null +++ b/superset-frontend/src/components/MetadataBar/ContentType.ts @@ -0,0 +1,91 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export enum MetadataType { + DASHBOARDS = 'dashboards', + DESCRIPTION = 'description', + LAST_MODIFIED = 'lastModified', + OWNER = 'owner', + ROWS = 'rows', + SQL = 'sql', + TABLE = 'table', + TAGS = 'tags', +} + +export type Dashboards = { + type: MetadataType.DASHBOARDS; + title: string; + description?: string; + onClick?: (type: string) => void; +}; + +export type Description = { + type: MetadataType.DESCRIPTION; + value: string; + onClick?: (type: string) => void; +}; + +export type LastModified = { + type: MetadataType.LAST_MODIFIED; + value: Date; + modifiedBy: string; + onClick?: (type: string) => void; +}; + +export type Owner = { + type: MetadataType.OWNER; + createdBy: string; + owners: string[]; + createdOn: Date; + onClick?: (type: string) => void; +}; + +export type Rows = { + type: MetadataType.ROWS; + title: string; + onClick?: (type: string) => void; +}; + +export type Sql = { + type: MetadataType.SQL; + title: string; + onClick?: (type: string) => void; +}; + +export type Table = { + type: MetadataType.TABLE; + title: string; + onClick?: (type: string) => void; +}; + +export type Tags = { + type: MetadataType.TAGS; + values: string[]; + onClick?: (type: string) => void; +}; + +export type ContentType = + | Dashboards + | Description + | LastModified + | Owner + | Rows + | Sql + | Table + | Tags; diff --git a/superset-frontend/src/components/MetadataBar/MetadataBar.stories.tsx b/superset-frontend/src/components/MetadataBar/MetadataBar.stories.tsx new file mode 100644 index 000000000..5ad9d9785 --- /dev/null +++ b/superset-frontend/src/components/MetadataBar/MetadataBar.stories.tsx @@ -0,0 +1,109 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { css } from '@superset-ui/core'; +import { useResizeDetector } from 'react-resize-detector'; +import MetadataBar, { MetadataBarProps } from './index'; + +export default { + title: 'MetadataBar', + component: MetadataBar, +}; + +const A_WEEK_AGO = new Date(Date.now() - 7 * 24 * 3600 * 1000); + +export const Component = ({ + items, + onClick, +}: MetadataBarProps & { + onClick: (type: string) => void; +}) => { + const { width, height, ref } = useResizeDetector(); + // eslint-disable-next-line no-param-reassign + items[0].onClick = onClick; + return ( +
+ + {`${width}x${height}`} +
+ ); +}; + +Component.story = { + parameters: { + knobs: { + disable: true, + }, + }, +}; + +Component.args = { + items: [ + { + type: 'sql', + title: 'Click to view query', + }, + { + type: 'owner', + createdBy: 'Jane Smith', + owners: ['John Doe', 'Mary Wilson'], + createdOn: A_WEEK_AGO, + }, + { + type: 'lastModified', + value: A_WEEK_AGO, + modifiedBy: 'Jane Smith', + }, + { + type: 'tags', + values: ['management', 'research', 'poc'], + }, + { + type: 'dashboards', + title: 'Added to 452 dashboards', + description: + 'To preview the list of dashboards go to "More" settings on the right.', + }, + ], +}; + +Component.argTypes = { + onClick: { + action: 'onClick', + table: { + disable: true, + }, + }, +}; diff --git a/superset-frontend/src/components/MetadataBar/MetadataBar.test.tsx b/superset-frontend/src/components/MetadataBar/MetadataBar.test.tsx new file mode 100644 index 000000000..c8a3f9e54 --- /dev/null +++ b/superset-frontend/src/components/MetadataBar/MetadataBar.test.tsx @@ -0,0 +1,257 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, screen, within } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import * as resizeDetector from 'react-resize-detector'; +import moment from 'moment'; +import { supersetTheme } from '@superset-ui/core'; +import { hexToRgb } from 'src/utils/colorUtils'; +import MetadataBar, { MIN_NUMBER_ITEMS, MAX_NUMBER_ITEMS } from '.'; +import { ContentType, MetadataType } from './ContentType'; + +const DASHBOARD_TITLE = 'Added to 452 dashboards'; +const DASHBOARD_DESCRIPTION = + 'To preview the list of dashboards go to "More" settings on the right.'; +const DESCRIPTION_VALUE = 'This is the description'; +const ROWS_TITLE = '500 rows'; +const SQL_TITLE = 'Click to view query'; +const TABLE_TITLE = 'database.schema.table'; +const CREATED_BY = 'Jane Smith'; +const DATE = new Date(Date.parse('2022-01-01')); +const MODIFIED_BY = 'Jane Smith'; +const OWNERS = ['John Doe', 'Mary Wilson']; +const TAGS = ['management', 'research', 'poc']; + +const runWithBarCollapsed = async (func: Function) => { + const spy = jest.spyOn(resizeDetector, 'useResizeDetector'); + spy.mockReturnValue({ width: 80, ref: { current: undefined } }); + await func(); + spy.mockRestore(); +}; + +const ITEMS: ContentType[] = [ + { + type: MetadataType.DASHBOARDS, + title: DASHBOARD_TITLE, + description: DASHBOARD_DESCRIPTION, + }, + { + type: MetadataType.DESCRIPTION, + value: DESCRIPTION_VALUE, + }, + { + type: MetadataType.LAST_MODIFIED, + value: DATE, + modifiedBy: MODIFIED_BY, + }, + { + type: MetadataType.OWNER, + createdBy: CREATED_BY, + owners: OWNERS, + createdOn: DATE, + }, + { + type: MetadataType.ROWS, + title: ROWS_TITLE, + }, + { + type: MetadataType.SQL, + title: SQL_TITLE, + }, + { + type: MetadataType.TABLE, + title: TABLE_TITLE, + }, + { + type: MetadataType.TAGS, + values: TAGS, + }, +]; + +test('renders an array of items', () => { + render(); + expect(screen.getByText(DASHBOARD_TITLE)).toBeInTheDocument(); + expect(screen.getByText(DESCRIPTION_VALUE)).toBeInTheDocument(); +}); + +test('throws errors when out of min/max restrictions', () => { + const spy = jest.spyOn(console, 'error'); + spy.mockImplementation(() => {}); + expect(() => + render(), + ).toThrow( + `The minimum number of items for the metadata bar is ${MIN_NUMBER_ITEMS}.`, + ); + expect(() => + render(), + ).toThrow( + `The maximum number of items for the metadata bar is ${MAX_NUMBER_ITEMS}.`, + ); + spy.mockRestore(); +}); + +test('removes duplicated items when rendering', () => { + render(); + expect(screen.getAllByRole('img').length).toBe(2); +}); + +test('collapses the bar when min width is reached', async () => { + await runWithBarCollapsed(() => { + render(); + expect(screen.queryByText(DASHBOARD_TITLE)).not.toBeInTheDocument(); + expect(screen.queryByText(DESCRIPTION_VALUE)).not.toBeInTheDocument(); + expect(screen.getAllByRole('img').length).toBe(2); + }); +}); + +test('always renders a tooltip when the bar is collapsed', async () => { + await runWithBarCollapsed(async () => { + render(); + userEvent.hover(screen.getAllByRole('img')[0]); + expect(await screen.findByText(DASHBOARD_DESCRIPTION)).toBeInTheDocument(); + userEvent.hover(screen.getAllByRole('img')[1]); + expect(await screen.findByText(DESCRIPTION_VALUE)).toBeInTheDocument(); + }); +}); + +test('renders a tooltip when one is provided even if not collapsed', async () => { + render(); + expect(screen.getByText(DASHBOARD_TITLE)).toBeInTheDocument(); + userEvent.hover(screen.getAllByRole('img')[0]); + expect(await screen.findByText(DASHBOARD_DESCRIPTION)).toBeInTheDocument(); +}); + +test('renders underlined text and emits event when clickable', () => { + const onClick = jest.fn(); + const items = [{ ...ITEMS[0], onClick }, ITEMS[1]]; + render(); + const element = screen.getByText(DASHBOARD_TITLE); + userEvent.click(element); + expect(onClick).toHaveBeenCalled(); + const style = window.getComputedStyle(element); + expect(style.textDecoration).toBe('underline'); +}); + +test('renders clicable items with blue icons when the bar is collapsed', async () => { + await runWithBarCollapsed(async () => { + const onClick = jest.fn(); + const items = [{ ...ITEMS[0], onClick }, ITEMS[1]]; + render(); + const images = screen.getAllByRole('img'); + const clickableColor = window.getComputedStyle(images[0]).color; + const nonClickableColor = window.getComputedStyle(images[1]).color; + expect(clickableColor).toBe(hexToRgb(supersetTheme.colors.primary.base)); + expect(nonClickableColor).toBeFalsy(); + }); +}); + +test('renders the items sorted', () => { + const { container } = render(); + const nodes = container.firstChild?.childNodes as NodeListOf; + expect(within(nodes[0]).getByText(DASHBOARD_TITLE)).toBeInTheDocument(); + expect(within(nodes[1]).getByText(ROWS_TITLE)).toBeInTheDocument(); + expect(within(nodes[2]).getByText(SQL_TITLE)).toBeInTheDocument(); + expect(within(nodes[3]).getByText(DESCRIPTION_VALUE)).toBeInTheDocument(); + expect(within(nodes[4]).getByText(CREATED_BY)).toBeInTheDocument(); +}); + +test('correctly renders the dashboards tooltip', async () => { + render(); + userEvent.hover(screen.getByText(DASHBOARD_TITLE)); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(within(tooltip).getByText(DASHBOARD_TITLE)).toBeInTheDocument(); + expect(within(tooltip).getByText(DASHBOARD_DESCRIPTION)).toBeInTheDocument(); +}); + +test('correctly renders the description tooltip', async () => { + await runWithBarCollapsed(async () => { + render(); + userEvent.hover(screen.getAllByRole('img')[1]); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(within(tooltip).getByText(DESCRIPTION_VALUE)).toBeInTheDocument(); + }); +}); + +test('correctly renders the last modified tooltip', async () => { + const dateText = moment.utc(DATE).fromNow(); + render(); + userEvent.hover(screen.getByText(dateText)); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(within(tooltip).getByText(dateText)).toBeInTheDocument(); + expect(within(tooltip).getByText(MODIFIED_BY)).toBeInTheDocument(); +}); + +test('correctly renders the owner tooltip', async () => { + const dateText = moment.utc(DATE).fromNow(); + render(); + userEvent.hover(screen.getByText(CREATED_BY)); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(within(tooltip).getByText(CREATED_BY)).toBeInTheDocument(); + expect(within(tooltip).getByText(dateText)).toBeInTheDocument(); + OWNERS.forEach(owner => + expect(within(tooltip).getByText(owner)).toBeInTheDocument(), + ); +}); + +test('correctly renders the rows tooltip', async () => { + await runWithBarCollapsed(async () => { + render(); + userEvent.hover(screen.getAllByRole('img')[0]); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(within(tooltip).getByText(ROWS_TITLE)).toBeInTheDocument(); + }); +}); + +test('correctly renders the sql tooltip', async () => { + await runWithBarCollapsed(async () => { + render(); + userEvent.hover(screen.getAllByRole('img')[1]); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(within(tooltip).getByText(SQL_TITLE)).toBeInTheDocument(); + }); +}); + +test('correctly renders the table tooltip', async () => { + await runWithBarCollapsed(async () => { + render(); + userEvent.hover(screen.getAllByRole('img')[2]); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(within(tooltip).getByText(TABLE_TITLE)).toBeInTheDocument(); + }); +}); + +test('correctly renders the tags tooltip', async () => { + await runWithBarCollapsed(async () => { + render(); + userEvent.hover(screen.getAllByRole('img')[3]); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + TAGS.forEach(tag => + expect(within(tooltip).getByText(tag)).toBeInTheDocument(), + ); + }); +}); diff --git a/superset-frontend/src/components/MetadataBar/Overview.stories.mdx b/superset-frontend/src/components/MetadataBar/Overview.stories.mdx new file mode 100644 index 000000000..b9ba919e4 --- /dev/null +++ b/superset-frontend/src/components/MetadataBar/Overview.stories.mdx @@ -0,0 +1,137 @@ +import { Meta, Source } from '@storybook/addon-docs'; + + + +# Usage + +The metadata bar component is used to display additional information about an entity. Some of the common applications in Superset are: + +- Display the chart's metadata in Explore to help the user understand what dashboards this chart is added to and get + to know the details of the chart +- Display the database's metadata in a drill to detail modal to help the user understand what data they are looking + at while accessing the feature in the dashboard + +# Variations + +The metadata bar is by default a static component (besides the links in text). +The variations in this component are related to content and entity type as all of the details are predefined +in the code and should be specific for each metadata object. + +Content types are predefined and consistent across the whole app. This means that +they will be displayed and behave in a consistent manner, keeping the same ordering, +information formatting, and interactions. For example, the Owner content type will always +have the same icon and when hovered it will present who created the entity, its current owners, and when the entity was created. + +To extend the list of content types, a developer needs to request the inclusion of the new type in the design system. +This process is important to make sure the new type is reviewed by the design team, improving Superset consistency. + +To check each content type in detail and its interactions, check the [MetadataBar](/story/metadatabar--component) page. +Below you can find the configurations for each content type: + + + + void; + };`} +/> + + void; + };`} +/> + + void; + };`} +/> + + void; + };`} +/> + + void; + };`} +/> + + void; + };`} +/> + + void; + };`} +/> + + void; + };`} +/> diff --git a/superset-frontend/src/components/MetadataBar/index.tsx b/superset-frontend/src/components/MetadataBar/index.tsx new file mode 100644 index 000000000..c9f57395e --- /dev/null +++ b/superset-frontend/src/components/MetadataBar/index.tsx @@ -0,0 +1,190 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useEffect, useRef, useState } from 'react'; +import { useResizeDetector } from 'react-resize-detector'; +import { uniqWith } from 'lodash'; +import { styled } from '@superset-ui/core'; +import { Tooltip } from 'src/components/Tooltip'; +import { ContentType } from './ContentType'; +import { config } from './ContentConfig'; + +export const MIN_NUMBER_ITEMS = 2; +export const MAX_NUMBER_ITEMS = 6; + +const HORIZONTAL_PADDING = 12; +const VERTICAL_PADDING = 8; +const ICON_PADDING = 8; +const SPACE_BETWEEN_ITEMS = 16; +const ICON_WIDTH = 16; +const TEXT_MIN_WIDTH = 70; +const TEXT_MAX_WIDTH = 150; +const ORDER = { + dashboards: 0, + rows: 1, + sql: 2, + table: 3, + tags: 4, + description: 5, + owner: 6, + lastModified: 7, +}; + +const Bar = styled.div<{ count: number }>` + ${({ theme, count }) => ` + display: flex; + align-items: center; + padding: ${VERTICAL_PADDING}px ${HORIZONTAL_PADDING}px; + background-color: ${theme.colors.grayscale.light4}; + color: ${theme.colors.grayscale.base}; + font-size: ${theme.typography.sizes.s}px; + min-width: ${ + HORIZONTAL_PADDING * 2 + + (ICON_WIDTH + SPACE_BETWEEN_ITEMS) * count - + SPACE_BETWEEN_ITEMS + }px; + `} +`; + +const StyledItem = styled.div<{ + collapsed: boolean; + last: boolean; + onClick?: () => void; +}>` + ${({ theme, collapsed, last, onClick }) => ` + max-width: ${ + ICON_WIDTH + + ICON_PADDING + + TEXT_MAX_WIDTH + + (last ? 0 : SPACE_BETWEEN_ITEMS) + }px; + min-width: ${ICON_WIDTH + (last ? 0 : SPACE_BETWEEN_ITEMS)}px; + overflow: hidden; + text-overflow: ${collapsed ? 'unset' : 'ellipsis'}; + white-space: nowrap; + padding-right: ${last ? 0 : SPACE_BETWEEN_ITEMS}px; + text-decoration: ${onClick ? 'underline' : 'none'}; + cursor: ${onClick ? 'pointer' : 'default'}; + & > span { + color: ${onClick && collapsed ? theme.colors.primary.base : 'undefined'}; + padding-right: ${collapsed ? 0 : ICON_PADDING}px; + } + `} +`; + +// Make sure big tootips are truncated +const TootipContent = styled.div` + display: -webkit-box; + -webkit-line-clamp: 20; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; +`; + +const Item = ({ + barWidth, + contentType, + collapsed, + last = false, +}: { + barWidth: number | undefined; + contentType: ContentType; + collapsed: boolean; + last?: boolean; +}) => { + const { icon, title, tooltip = title } = config(contentType); + const [isTruncated, setIsTruncated] = useState(false); + const ref = useRef(null); + const Icon = icon; + const { type, onClick } = contentType; + + useEffect(() => { + setIsTruncated( + ref.current ? ref.current.scrollWidth > ref.current.clientWidth : false, + ); + }, [barWidth, setIsTruncated, contentType]); + + const content = ( + onClick(type) : undefined} + ref={ref} + > + + {!collapsed && title} + + ); + return isTruncated || collapsed || (tooltip && tooltip !== title) ? ( + {tooltip}}> + {content} + + ) : ( + content + ); +}; + +export interface MetadataBarProps { + /** + * Array of content type configurations. To see the available properties + * for each content type, check {@link ContentType} + */ + items: ContentType[]; +} + +/** + * The metadata bar component is used to display additional information about an entity. + * Content types are predefined and consistent across the whole app. This means that + * they will be displayed and behave in a consistent manner, keeping the same ordering, + * information formatting, and interactions. + * To extend the list of content types, a developer needs to request the inclusion of the new type in the design system. + * This process is important to make sure the new type is reviewed by the design team, improving Superset consistency. + */ +const MetadataBar = ({ items }: MetadataBarProps) => { + const { width, ref } = useResizeDetector(); + const uniqueItems = uniqWith(items, (a, b) => a.type === b.type); + const sortedItems = uniqueItems.sort((a, b) => ORDER[a.type] - ORDER[b.type]); + const count = sortedItems.length; + if (count < MIN_NUMBER_ITEMS) { + throw Error('The minimum number of items for the metadata bar is 2.'); + } + if (count > MAX_NUMBER_ITEMS) { + throw Error('The maximum number of items for the metadata bar is 6.'); + } + // Calculates the breakpoint width to collapse the bar. + // The last item does not have a space, so we subtract SPACE_BETWEEN_ITEMS from the total. + const breakpoint = + (ICON_WIDTH + ICON_PADDING + TEXT_MIN_WIDTH + SPACE_BETWEEN_ITEMS) * count - + SPACE_BETWEEN_ITEMS; + const collapsed = Boolean(width && width < breakpoint); + return ( + + {sortedItems.map((item, index) => ( + + ))} + + ); +}; + +export default MetadataBar; diff --git a/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx b/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx index 8b1866399..caf71c0b9 100644 --- a/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx +++ b/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx @@ -39,7 +39,7 @@ const TruncatedTextWithTooltip: React.FC = ({ children, ...props }) => { const ref = useRef(null); useEffect(() => { setIsTruncated( - ref.current ? ref.current.offsetWidth < ref.current.scrollWidth : false, + ref.current ? ref.current.scrollWidth > ref.current.clientWidth : false, ); }, [children]); diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js index 99d51a7d0..f2919b0d2 100644 --- a/superset-frontend/webpack.config.js +++ b/superset-frontend/webpack.config.js @@ -26,6 +26,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); +const createMdxCompiler = require('@storybook/addon-docs/mdx-compiler-plugin'); const { WebpackManifestPlugin, getCompilerHooks, @@ -442,6 +443,24 @@ const config = { test: /\.geojson$/, type: 'asset/resource', }, + { + test: /\.(stories|story)\.mdx$/, + use: [ + { + loader: 'babel-loader', + // may or may not need this line depending on your app's setup + options: { + plugins: ['@babel/plugin-transform-react-jsx'], + }, + }, + { + loader: '@mdx-js/loader', + options: { + compilers: [createMdxCompiler({})], + }, + }, + ], + }, ], }, externals: {