mirror of
https://github.com/elastic/kibana.git
synced 2025-04-16 22:21:06 -04:00
Upgrade to Storybook 8 (#195148)
## Summary Depends on #191106 Closes #171591 This PR migrates Storybook from `6.x` to `8.x`. Please see the [migration guide](https://storybook.js.org/docs/migration-guide/from-older-version) for an overview of the changes because there are many breaking changes which effect Kibana. The TODO list below is not inclusive of all the changes. ## Reviewers ### Each commit contains all files changed for a specific codeowner, please find your respective commit to make review easier. A **first step before code review** should be checking the [`Storybooks Preview`](https://ci-artifacts.kibana.dev/storybooks/pr-195148/index.html) from CI for any runtime or style issues which were missed. The preview can be compared to a build from `main` [here](https://ci-artifacts.kibana.dev/storybooks/pr-212585/index.html). It is worth noting that some stories have runtime issues which existed before this migration. Most stories appear to have been migrated properly, but the Operations team does not have prior knowledge into every story. Some of the migration was able to be automated through Storybook provided scripts. It is possible this wasn't entirely correct due to the structure of some stories. Additionally, part of this migration is moving Storybook to Webpack 5 which changed how styles are being loaded. #### TODO - [x] Migrate `stories.mdx` - [x] storyshots - [x] [Migrate packages](https://storybook.js.org/docs/migration-guide/from-older-version#package-structure-changes) which were removed in `8.0` - [x] `react-doc-gen` resolution - [x] [Migrate blocks](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#addon-docs-removed-deprecated-blocksjs-entry) - [x] Migrate deprecated `addon-knobs` to [addon-controls](https://www.npmjs.com/package/@storybook/addon-controls) - [x] React Fast Refresh support - [x] Watch flag callback - [x] `canvas` webpack - [x] Rerun CSF migrations for new stories - [x] Handle ESM import for `addon-docs` - [x] `'@storybook/addon-actions' should be listed in the project's dependencies. Run 'npm i -S @storybook/addon-actions' to add iteslint[import/no-extraneous-dependencies](https://github.com/import-js/eslint-plugin-import/blob/v2.28.0/docs/rules/no-extraneous-dependencies.md)` - [x] `addDecorator` migration - [x] `addParameter` migration - [x] static build - [ ] determine if #176500 is solved or push to followup PR - This will need to be fixed separately - [x] revert `.buildkite/pipelines/pull_request/base.yml` & `.buildkite/scripts/pipelines/pull_request/pipeline.ts` to `main` --------- Co-authored-by: Tiago Costa <tiago.costa@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Jacek Kolezynski <jacek.kolezynski@elastic.co> Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co> Co-authored-by: Clint Andrew Hall <clint@clintandrewhall.com>
This commit is contained in:
parent
eb9e817378
commit
403b5f2363
518 changed files with 12646 additions and 13425 deletions
|
@ -73,4 +73,4 @@ RUN echo "source ${KBN_DIR}/.devcontainer/scripts/env.sh" >> ${HOME}/.bashrc &&
|
|||
echo "source ${KBN_DIR}/.devcontainer/scripts/env.sh" >> ${HOME}/.zshrc
|
||||
|
||||
# This is for documentation. Ports are exposed via devcontainer.json
|
||||
EXPOSE 9200 5601 9229 9230 9231
|
||||
EXPOSE 9200 5601 9229 9230 9231 9001
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
5601,
|
||||
9229,
|
||||
9230,
|
||||
9231
|
||||
9231,
|
||||
9001
|
||||
],
|
||||
"postStartCommand": "${containerWorkspaceFolder}/.devcontainer/scripts/post_start.sh",
|
||||
"remoteUser": "vscode",
|
||||
|
|
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -1616,6 +1616,7 @@ packages/kbn-monaco/src/esql @elastic/kibana-esql
|
|||
/.devcontainer/ @elastic/kibana-operations
|
||||
/.eslintrc.js @elastic/kibana-operations
|
||||
/.eslintignore @elastic/kibana-operations
|
||||
/.ci/.storybook @elastic/kibana-operations
|
||||
|
||||
# QA - Appex QA
|
||||
/x-pack/test/.gitignore @elastic/appex-qa
|
||||
|
|
46
package.json
46
package.json
|
@ -60,7 +60,7 @@
|
|||
"serverless-security": "node scripts/kibana --dev --serverless=security",
|
||||
"spec_to_console": "node scripts/spec_to_console",
|
||||
"start": "node scripts/kibana --dev",
|
||||
"storybook": "node --no-deprecation scripts/storybook",
|
||||
"storybook": "node scripts/storybook",
|
||||
"test:ftr": "node scripts/functional_tests",
|
||||
"test:ftr:runner": "node scripts/functional_test_runner",
|
||||
"test:ftr:server": "node scripts/functional_tests_server",
|
||||
|
@ -77,6 +77,7 @@
|
|||
"yarn": "^1.22.19"
|
||||
},
|
||||
"resolutions": {
|
||||
"**/@babel/parser": "7.24.7",
|
||||
"**/@bazel/typescript/protobufjs": "6.11.4",
|
||||
"**/@hello-pangea/dnd": "16.6.0",
|
||||
"**/@langchain/core": "^0.3.40",
|
||||
|
@ -92,6 +93,7 @@
|
|||
"**/remark-parse/trim": "1.0.1",
|
||||
"**/sharp": "0.32.6",
|
||||
"**/typescript": "5.1.6",
|
||||
"**/util": "^0.11.1",
|
||||
"@aws-sdk/client-bedrock-agent-runtime": "^3.744.0",
|
||||
"@aws-sdk/client-bedrock-runtime": "^3.744.0",
|
||||
"@aws-sdk/client-kendra": "3.744.0",
|
||||
|
@ -1545,28 +1547,26 @@
|
|||
"@octokit/rest": "^21.1.1",
|
||||
"@parcel/watcher": "^2.1.0",
|
||||
"@playwright/test": "1.49.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
|
||||
"@redocly/cli": "^1.33.0",
|
||||
"@statoscope/webpack-plugin": "^5.28.2",
|
||||
"@storybook/addon-a11y": "^6.5.16",
|
||||
"@storybook/addon-actions": "^6.5.16",
|
||||
"@storybook/addon-docs": "^6.5.16",
|
||||
"@storybook/addon-essentials": "^6.5.16",
|
||||
"@storybook/addon-knobs": "^6.4.0",
|
||||
"@storybook/addon-storyshots": "^6.5.16",
|
||||
"@storybook/addons": "^6.5.16",
|
||||
"@storybook/api": "^6.5.16",
|
||||
"@storybook/builder-webpack5": "^6.5.16",
|
||||
"@storybook/client-api": "^6.5.16",
|
||||
"@storybook/components": "^6.5.16",
|
||||
"@storybook/core": "^6.5.16",
|
||||
"@storybook/core-common": "^6.5.16",
|
||||
"@storybook/core-events": "^6.5.16",
|
||||
"@storybook/manager-webpack5": "^6.5.16",
|
||||
"@storybook/node-logger": "^6.5.16",
|
||||
"@storybook/preview-web": "^6.5.16",
|
||||
"@storybook/react": "^6.5.16",
|
||||
"@storybook/testing-react": "^1.3.0",
|
||||
"@storybook/theming": "^6.5.16",
|
||||
"@storybook/addon-a11y": "^8.6.3",
|
||||
"@storybook/addon-actions": "^8.6.3",
|
||||
"@storybook/addon-essentials": "^8.6.3",
|
||||
"@storybook/addon-styling-webpack": "^1.0.1",
|
||||
"@storybook/addon-webpack5-compiler-babel": "^3.0.5",
|
||||
"@storybook/blocks": "^8.6.3",
|
||||
"@storybook/components": "^8.6.3",
|
||||
"@storybook/core-events": "^8.6.3",
|
||||
"@storybook/core-server": "^8.6.3",
|
||||
"@storybook/icons": "^1.3.2",
|
||||
"@storybook/manager-api": "^8.6.3",
|
||||
"@storybook/preview-api": "^8.6.3",
|
||||
"@storybook/react": "^8.6.3",
|
||||
"@storybook/react-webpack5": "^8.6.3",
|
||||
"@storybook/test": "^8.6.3",
|
||||
"@storybook/theming": "^8.6.3",
|
||||
"@storybook/types": "^8.6.3",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.0.1",
|
||||
|
@ -1654,6 +1654,7 @@
|
|||
"@types/picomatch": "^2.3.0",
|
||||
"@types/pixelmatch": "^5.2.4",
|
||||
"@types/pngjs": "^6.0.5",
|
||||
"@types/prettier": "^2.7.3",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/rbush": "^3.0.0",
|
||||
"@types/react": "~18.2.0",
|
||||
|
@ -1769,6 +1770,7 @@
|
|||
"fetch-mock": "^10.1.0",
|
||||
"file-loader": "^4.2.0",
|
||||
"find-cypress-specs": "^1.41.4",
|
||||
"fix-esm": "^1.0.1",
|
||||
"form-data": "^4.0.2",
|
||||
"geckodriver": "^5.0.0",
|
||||
"gulp-brotli": "^3.0.0",
|
||||
|
@ -1835,6 +1837,7 @@
|
|||
"prettier": "^2.8.8",
|
||||
"proxy": "^2.1.1",
|
||||
"react-is": "~18.2.0",
|
||||
"react-refresh": "^0.16.0",
|
||||
"react-test-renderer": "~18.2.0",
|
||||
"recast": "^0.23.9",
|
||||
"regenerate": "^1.4.0",
|
||||
|
@ -1848,6 +1851,7 @@
|
|||
"sinon": "^7.4.2",
|
||||
"sort-package-json": "^1.53.1",
|
||||
"source-map": "^0.7.4",
|
||||
"storybook": "^8.6.3",
|
||||
"string-replace-loader": "^3.1.0",
|
||||
"style-loader": "^4.0.0",
|
||||
"stylelint": "^14.16.1",
|
||||
|
|
|
@ -44,10 +44,25 @@
|
|||
},
|
||||
{
|
||||
"groupName": "webpack",
|
||||
"matchDepNames": ["webpack", "@types/webpack", "webpack-cli", "webpack-dev-server", "webpack-merge"],
|
||||
"reviewers": ["team:kibana-operations"],
|
||||
"matchBaseBranches": ["main"],
|
||||
"labels": ["Team:Operations", "backport:all-open", "release_note:skip", "ci:build-webpack-bundle-analyzer"],
|
||||
"matchDepNames": [
|
||||
"webpack",
|
||||
"@types/webpack",
|
||||
"webpack-cli",
|
||||
"webpack-dev-server",
|
||||
"webpack-merge"
|
||||
],
|
||||
"reviewers": [
|
||||
"team:kibana-operations"
|
||||
],
|
||||
"matchBaseBranches": [
|
||||
"main"
|
||||
],
|
||||
"labels": [
|
||||
"Team:Operations",
|
||||
"backport:all-open",
|
||||
"release_note:skip",
|
||||
"ci:build-webpack-bundle-analyzer"
|
||||
],
|
||||
"minimumReleaseAge": "60 days",
|
||||
"enabled": true
|
||||
},
|
||||
|
@ -1419,7 +1434,8 @@
|
|||
"matchDepNames": [
|
||||
"prettier",
|
||||
"eslint-plugin-prettier",
|
||||
"eslint-config-prettier"
|
||||
"eslint-config-prettier",
|
||||
"@types/prettier"
|
||||
],
|
||||
"reviewers": [
|
||||
"team:kibana-operations"
|
||||
|
@ -3388,28 +3404,7 @@
|
|||
"enabled": true
|
||||
},
|
||||
{
|
||||
"groupName": "@storybook",
|
||||
"reviewers": [
|
||||
"team:kibana-operations"
|
||||
],
|
||||
"matchBaseBranches": [
|
||||
"main"
|
||||
],
|
||||
"matchDepPatterns": [
|
||||
"^@storybook"
|
||||
],
|
||||
"labels": [
|
||||
"Team:Operations",
|
||||
"release_note:skip",
|
||||
"ci:build-storybooks",
|
||||
"backport:skip"
|
||||
],
|
||||
"minimumReleaseAge": "7 days",
|
||||
"allowedVersions": "<7.0",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"groupName": "@storybook/testing-react",
|
||||
"groupName": "storybook",
|
||||
"reviewers": [
|
||||
"team:kibana-operations"
|
||||
],
|
||||
|
@ -3417,16 +3412,20 @@
|
|||
"main"
|
||||
],
|
||||
"matchDepNames": [
|
||||
"@storybook/testing-react"
|
||||
"@pmmmwh/react-refresh-webpack-plugin",
|
||||
"fix-esm",
|
||||
"react-refresh"
|
||||
],
|
||||
"matchDepPatterns": [
|
||||
"storybook"
|
||||
],
|
||||
"labels": [
|
||||
"Team:Operations",
|
||||
"release_note:skip",
|
||||
"ci:build-storybooks",
|
||||
"backport:skip"
|
||||
"backport:prev-minor"
|
||||
],
|
||||
"minimumReleaseAge": "7 days",
|
||||
"allowedVersions": "<2.0",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
|
|
|
@ -71,6 +71,7 @@ export const LICENSE_ALLOWED = [
|
|||
'Python-2.0',
|
||||
'(Apache-2.0 AND MIT)',
|
||||
'BlueOak-1.0.0',
|
||||
'WTFPL OR CC0-1.0',
|
||||
];
|
||||
|
||||
// The following list only applies to licenses that
|
||||
|
|
|
@ -7,23 +7,17 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
// Please also add new aliases to .buildkite/scripts/steps/storybooks/build_and_upload.ts
|
||||
//
|
||||
// If you wish for your Storybook to be built and included in CI, also add your
|
||||
// alias to .buildkite/scripts/steps/storybooks/build_and_upload.ts
|
||||
export const storybookAliases = {
|
||||
ai_assistant: 'x-pack/platform/packages/shared/kbn-ai-assistant/.storybook',
|
||||
apm: 'x-pack/solutions/observability/plugins/apm/.storybook',
|
||||
canvas: 'x-pack/platform/plugins/private/canvas/storybook',
|
||||
cases: 'src/platform/packages/shared/kbn-cases-components/.storybook',
|
||||
cell_actions: 'src/platform/packages/shared/kbn-cell-actions/.storybook',
|
||||
chart_icons: 'src/platform/packages/shared/kbn-chart-icons/.storybook',
|
||||
cloud_security_posture_graph:
|
||||
'x-pack/solutions/security/packages/kbn-cloud-security-posture/graph/.storybook',
|
||||
cloud: 'src/platform/packages/shared/cloud/.storybook',
|
||||
coloring: 'src/platform/packages/shared/kbn-coloring/.storybook',
|
||||
language_documentation_popover:
|
||||
'src/platform/packages/private/kbn-language-documentation/.storybook',
|
||||
chart_icons: 'src/platform/packages/shared/kbn-chart-icons/.storybook',
|
||||
content_management_examples: 'examples/content_management_examples/.storybook',
|
||||
custom_icons: 'src/platform/packages/shared/kbn-custom-icons/.storybook',
|
||||
custom_integrations: 'src/platform/plugins/shared/custom_integrations/storybook',
|
||||
|
@ -31,8 +25,10 @@ export const storybookAliases = {
|
|||
dashboard: 'src/platform/plugins/shared/dashboard/.storybook',
|
||||
data: 'src/platform/plugins/shared/data/.storybook',
|
||||
discover: 'src/platform/plugins/shared/discover/.storybook',
|
||||
esql_ast_inspector: 'examples/esql_ast_inspector/.storybook',
|
||||
es_ui_shared: 'src/platform/plugins/shared/es_ui_shared/.storybook',
|
||||
esql_ast_inspector: 'examples/esql_ast_inspector/.storybook',
|
||||
esql_editor: 'src/platform/packages/private/kbn-esql-editor/.storybook',
|
||||
event_stacktrace: 'x-pack/platform/packages/shared/kbn-event-stacktrace/.storybook',
|
||||
expandable_flyout: 'x-pack/solutions/security/packages/expandable-flyout/.storybook',
|
||||
expression_error: 'src/platform/plugins/shared/expression_error/.storybook',
|
||||
expression_image: 'src/platform/plugins/shared/expression_image/.storybook',
|
||||
|
@ -53,21 +49,22 @@ export const storybookAliases = {
|
|||
inventory: 'x-pack/solutions/observability/plugins/inventory/.storybook',
|
||||
investigate: 'x-pack/solutions/observability/plugins/investigate_app/.storybook',
|
||||
kibana_react: 'src/platform/plugins/shared/kibana_react/.storybook',
|
||||
language_documentation_popover:
|
||||
'src/platform/packages/private/kbn-language-documentation/.storybook',
|
||||
lists: 'x-pack/solutions/security/plugins/lists/.storybook',
|
||||
management: 'src/platform/packages/shared/kbn-management/storybook/config',
|
||||
observability: 'x-pack/solutions/observability/plugins/observability/.storybook',
|
||||
observability_ai_assistant:
|
||||
'x-pack/platform/plugins/shared/observability_ai_assistant/.storybook',
|
||||
observability_ai_assistant_app:
|
||||
'x-pack/solutions/observability/plugins/observability_ai_assistant_app/.storybook',
|
||||
observability_ai_assistant:
|
||||
'x-pack/platform/plugins/shared/observability_ai_assistant/.storybook',
|
||||
observability_inventory: 'x-pack/solutions/observability/plugins/inventory/.storybook',
|
||||
observability_shared: 'x-pack/solutions/observability/plugins/observability_shared/.storybook',
|
||||
observability_slo: 'x-pack/solutions/observability/plugins/slo/.storybook',
|
||||
observability: 'x-pack/solutions/observability/plugins/observability/.storybook',
|
||||
presentation: 'src/platform/plugins/shared/presentation_util/storybook',
|
||||
profiling: 'x-pack/solutions/observability/plugins/profiling/.storybook',
|
||||
random_sampling: 'x-pack/platform/packages/private/kbn-random-sampling/.storybook',
|
||||
esql_editor: 'src/platform/packages/private/kbn-esql-editor/.storybook',
|
||||
// Skipped, please check and fix https://github.com/elastic/kibana/issues/207227
|
||||
// security_solution: 'x-pack/solutions/security/plugins/security_solution/.storybook',
|
||||
security_solution: 'x-pack/solutions/security/plugins/security_solution/.storybook',
|
||||
// security_solution_packages: 'x-pack/solutions/security/packages/storybook/config',
|
||||
serverless: 'src/platform/packages/shared/serverless/storybook/config',
|
||||
shared_ux: 'src/platform/packages/private/shared-ux/storybook/config',
|
||||
|
@ -76,6 +73,4 @@ export const storybookAliases = {
|
|||
ui_actions_enhanced: 'src/platform/plugins/shared/ui_actions_enhanced/.storybook',
|
||||
unified_search: 'src/platform/plugins/shared/unified_search/.storybook',
|
||||
unified_tabs: 'src/platform/packages/shared/kbn-unified-tabs/.storybook',
|
||||
profiling: 'x-pack/solutions/observability/plugins/profiling/.storybook',
|
||||
event_stacktrace: 'x-pack/platform/packages/shared/kbn-event-stacktrace/.storybook',
|
||||
};
|
||||
|
|
|
@ -41,7 +41,6 @@ run(
|
|||
|
||||
log.verbose('Loading Storybook:', configDir);
|
||||
|
||||
// TODO: once storybook is upgraded into a newer version, --no-deprecation flag could be removed when invoking it through the package.json script
|
||||
runStorybookCli({ configDir, name: alias });
|
||||
},
|
||||
{
|
||||
|
|
|
@ -11,7 +11,6 @@ const defaultConfig = require('@kbn/storybook').defaultConfig;
|
|||
|
||||
module.exports = {
|
||||
...defaultConfig,
|
||||
stories: ['../**/*.stories.+(tsx|mdx)'],
|
||||
typescript: {
|
||||
reactDocgen: 'react-docgen-typescript',
|
||||
},
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import { Canvas, Meta, Story, Controls } from '@storybook/blocks';
|
||||
import * as EsqlEditorStories from './esql_editor.stories';
|
||||
|
||||
<Meta of={EsqlEditorStories} />
|
||||
|
||||
# Overview
|
||||
|
||||
The ESQLEditor component is a reusable component and can be used to support text based languages in your application (SQL, ESQL):
|
||||
|
||||
<Canvas of={EsqlEditorStories.ExpandedMode} />
|
||||
|
||||
When there are errors to the query the UI displays the errors to the editor:
|
||||
|
||||
<Canvas of={EsqlEditorStories.WithErrors} />
|
||||
|
||||
## Component props
|
||||
|
||||
The component exposes the following properties:
|
||||
|
||||
<Controls />../esql\_editor
|
|
@ -1,74 +0,0 @@
|
|||
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs/blocks';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { ESQLEditor } from '../esql_editor';
|
||||
|
||||
|
||||
export const Template = (args) =>
|
||||
<I18nProvider>
|
||||
<KibanaContextProvider
|
||||
services={{
|
||||
settings: { client: { get: () => {} } },
|
||||
uiSettings: { get: () => {} },
|
||||
}}
|
||||
>
|
||||
<ESQLEditor {...args} />
|
||||
</KibanaContextProvider>
|
||||
</I18nProvider>;
|
||||
|
||||
<Meta
|
||||
title="Text based languages editor"
|
||||
component={ESQLEditor}
|
||||
/>
|
||||
|
||||
|
||||
# Overview
|
||||
|
||||
The ESQLEditor component is a reusable component and can be used to support text based languages in your application (SQL, ESQL):
|
||||
|
||||
<Canvas>
|
||||
<Story
|
||||
name='expanded mode'
|
||||
args={
|
||||
{
|
||||
query: { esql: 'from dataview | keep field1, field2' },
|
||||
'data-test-subj':'test-id'
|
||||
}
|
||||
}
|
||||
argTypes={
|
||||
{ onTextLangQueryChange: { action: 'changed' }, onTextLangQuerySubmit: { action: 'submitted' }}
|
||||
}
|
||||
>
|
||||
{Template.bind({})}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
When there are errors to the query the UI displays the errors to the editor:
|
||||
|
||||
<Canvas>
|
||||
<Story
|
||||
name='with errors'
|
||||
args={
|
||||
{
|
||||
query: { esql: 'from dataview | keep field1, field2' },
|
||||
'data-test-subj':'test-id',
|
||||
errors: [
|
||||
new Error(
|
||||
'[essql] > Unexpected error from Elasticsearch: verification_exception - Found 1 problem line 1:16: Unknown column [field10]'
|
||||
),
|
||||
]
|
||||
}
|
||||
}
|
||||
argTypes={
|
||||
{ onTextLangQueryChange: { action: 'changed' }, onTextLangQuerySubmit: { action: 'submitted' }}
|
||||
}
|
||||
>
|
||||
{Template.bind({})}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Component props
|
||||
|
||||
The component exposes the following properties:
|
||||
|
||||
<ArgsTable story="expanded mode"/>../esql_editor
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import type { StoryObj } from '@storybook/react';
|
||||
import { ESQLEditor } from '../esql_editor';
|
||||
import type { ESQLEditorProps } from '../types';
|
||||
|
||||
const Template = (args: ESQLEditorProps) => (
|
||||
<KibanaContextProvider
|
||||
services={{
|
||||
settings: { client: { get: () => {} } },
|
||||
uiSettings: { get: () => {} },
|
||||
data: { query: { timefilter: { timefilter: { getTime: () => {} } } } },
|
||||
}}
|
||||
>
|
||||
<ESQLEditor {...args} />
|
||||
</KibanaContextProvider>
|
||||
);
|
||||
|
||||
export default {
|
||||
title: 'Text based languages editor',
|
||||
component: ESQLEditor,
|
||||
};
|
||||
|
||||
export const ExpandedMode: StoryObj<typeof ESQLEditor> = {
|
||||
render: Template,
|
||||
name: 'expanded mode',
|
||||
|
||||
args: {
|
||||
query: {
|
||||
esql: 'from dataview | keep field1, field2',
|
||||
},
|
||||
},
|
||||
|
||||
argTypes: {
|
||||
onTextLangQueryChange: {
|
||||
action: 'changed',
|
||||
},
|
||||
|
||||
onTextLangQuerySubmit: {
|
||||
action: 'submitted',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const WithErrors: StoryObj<typeof ESQLEditor> = {
|
||||
render: Template,
|
||||
name: 'with errors',
|
||||
|
||||
args: {
|
||||
query: {
|
||||
esql: 'from dataview | keep field1, field2',
|
||||
},
|
||||
|
||||
dataTestSubj: 'test-id',
|
||||
|
||||
errors: [
|
||||
new Error(
|
||||
'[essql] > Unexpected error from Elasticsearch: verification_exception - Found 1 problem line 1:16: Unknown column [field10]'
|
||||
),
|
||||
],
|
||||
},
|
||||
|
||||
argTypes: {
|
||||
onTextLangQueryChange: {
|
||||
action: 'changed',
|
||||
},
|
||||
|
||||
onTextLangQuerySubmit: {
|
||||
action: 'submitted',
|
||||
},
|
||||
},
|
||||
};
|
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { LanguageDocumentationPopover } from '../components/as_popover';
|
||||
|
||||
const sections = {
|
||||
|
@ -62,12 +61,20 @@ const sections = {
|
|||
),
|
||||
};
|
||||
|
||||
storiesOf('Language documentation popover', module).add('default', () => (
|
||||
<LanguageDocumentationPopover
|
||||
language="Test"
|
||||
sections={sections}
|
||||
buttonProps={{ color: 'text' }}
|
||||
isHelpMenuOpen={true}
|
||||
onHelpMenuVisibilityChange={() => {}}
|
||||
/>
|
||||
));
|
||||
export default {
|
||||
title: 'Language documentation popover',
|
||||
};
|
||||
|
||||
export const Default = {
|
||||
render: () => (
|
||||
<LanguageDocumentationPopover
|
||||
language="Test"
|
||||
sections={sections}
|
||||
buttonProps={{ color: 'text' }}
|
||||
isHelpMenuOpen={true}
|
||||
onHelpMenuVisibilityChange={() => {}}
|
||||
/>
|
||||
),
|
||||
|
||||
name: 'default',
|
||||
};
|
||||
|
|
|
@ -27,12 +27,14 @@ export default {
|
|||
},
|
||||
};
|
||||
|
||||
export const Analytics = (params: AnalyticsNoDataPageStorybookParams) => {
|
||||
return (
|
||||
<AnalyticsNoDataPageProvider {...mock.getProps(params)} {...mock.getServices(params)}>
|
||||
<Component {...mock.getProps(params)} />
|
||||
</AnalyticsNoDataPageProvider>
|
||||
);
|
||||
};
|
||||
export const Analytics = {
|
||||
render: (params: AnalyticsNoDataPageStorybookParams) => {
|
||||
return (
|
||||
<AnalyticsNoDataPageProvider {...mock.getServices(params)}>
|
||||
<Component {...mock.getProps()} />
|
||||
</AnalyticsNoDataPageProvider>
|
||||
);
|
||||
},
|
||||
|
||||
Analytics.argTypes = mock.getArgumentTypes();
|
||||
argTypes: mock.getArgumentTypes(),
|
||||
};
|
||||
|
|
|
@ -38,18 +38,18 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
propArguments = {
|
||||
// requires hasESData to be toggled to true
|
||||
useCustomOnTryESQL: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
};
|
||||
serviceArguments = {
|
||||
kibanaGuideDocLink: {
|
||||
control: 'text',
|
||||
control: { control: 'text' },
|
||||
defaultValue: 'Kibana guide',
|
||||
},
|
||||
customBranding: {
|
||||
hasCustomBranding$: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
},
|
||||
|
@ -70,10 +70,10 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
};
|
||||
}
|
||||
|
||||
getProps(params: Params) {
|
||||
getProps(params?: Params) {
|
||||
return {
|
||||
onDataViewCreated: action('onDataViewCreated'),
|
||||
onTryESQL: params.useCustomOnTryESQL ? action('onTryESQL-from-props') : undefined,
|
||||
onTryESQL: params?.useCustomOnTryESQL ? action('onTryESQL-from-props') : undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,30 +29,34 @@ export default {
|
|||
|
||||
const mock = new KibanaNoDataPageStorybookMock();
|
||||
|
||||
export const Kibana = (params: KibanaNoDataPageStorybookParams) => {
|
||||
return (
|
||||
<KibanaNoDataPageProvider {...mock.getServices(params)}>
|
||||
<Component {...mock.getProps(params)} />
|
||||
</KibanaNoDataPageProvider>
|
||||
);
|
||||
export const Kibana = {
|
||||
render: (params: KibanaNoDataPageStorybookParams) => {
|
||||
return (
|
||||
<KibanaNoDataPageProvider {...mock.getServices(params)}>
|
||||
<Component {...mock.getProps(params)} />
|
||||
</KibanaNoDataPageProvider>
|
||||
);
|
||||
},
|
||||
|
||||
argTypes: mock.getArgumentTypes(),
|
||||
};
|
||||
|
||||
Kibana.argTypes = mock.getArgumentTypes();
|
||||
export const LoadingState = {
|
||||
render: (params: KibanaNoDataPageStorybookParams) => {
|
||||
// Simulate loading with a Promise that doesn't resolve.
|
||||
const dataCheck = () => new Promise<boolean>((resolve, reject) => {});
|
||||
|
||||
export const LoadingState = (params: KibanaNoDataPageStorybookParams) => {
|
||||
// Simulate loading with a Promise that doesn't resolve.
|
||||
const dataCheck = () => new Promise<boolean>((resolve, reject) => {});
|
||||
const services = {
|
||||
...mock.getServices(params),
|
||||
hasESData: dataCheck,
|
||||
hasUserDataView: dataCheck,
|
||||
hasDataView: dataCheck,
|
||||
};
|
||||
|
||||
const services = {
|
||||
...mock.getServices(params),
|
||||
hasESData: dataCheck,
|
||||
hasUserDataView: dataCheck,
|
||||
hasDataView: dataCheck,
|
||||
};
|
||||
|
||||
return (
|
||||
<KibanaNoDataPageProvider {...services}>
|
||||
<Component {...mock.getProps(params)} />
|
||||
</KibanaNoDataPageProvider>
|
||||
);
|
||||
return (
|
||||
<KibanaNoDataPageProvider {...services}>
|
||||
<Component {...mock.getProps(params)} />
|
||||
</KibanaNoDataPageProvider>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -44,11 +44,11 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
> {
|
||||
propArguments = {
|
||||
solution: {
|
||||
control: 'text',
|
||||
control: { control: 'text' },
|
||||
defaultValue: 'Observability',
|
||||
},
|
||||
logo: {
|
||||
control: { type: 'radio' },
|
||||
control: { control: 'radio' },
|
||||
options: ['logoElastic', 'logoKibana', 'logoCloud', undefined],
|
||||
defaultValue: undefined,
|
||||
},
|
||||
|
@ -56,11 +56,11 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
|
||||
serviceArguments = {
|
||||
hasESData: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
hasUserDataView: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { addons } from '@storybook/addons';
|
||||
import { addons } from '@storybook/manager-api';
|
||||
import { create } from '@storybook/theming';
|
||||
import { PANEL_ID as selectedPanel } from '@storybook/addon-actions';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import type { SampleDataSet } from '@kbn/home-sample-data-types';
|
||||
|
@ -27,24 +27,26 @@ export default {
|
|||
},
|
||||
},
|
||||
decorators: [(Story) => <div style={{ width: '433px', padding: '25px' }}>{Story()}</div>],
|
||||
} as ComponentMeta<typeof Component>;
|
||||
} as Meta<typeof Component>;
|
||||
|
||||
const { description, ...argTypes } = getStoryArgTypes();
|
||||
|
||||
export const CardFooter = (params: Params) => {
|
||||
const { includeAppLinks, status, ...rest } = params;
|
||||
const sampleDataSet: SampleDataSet = {
|
||||
...mockDataSet,
|
||||
...rest,
|
||||
status,
|
||||
appLinks: includeAppLinks ? mockDataSet.appLinks : [],
|
||||
};
|
||||
export const CardFooter = {
|
||||
render: (params: Params) => {
|
||||
const { includeAppLinks, status, ...rest } = params;
|
||||
const sampleDataSet: SampleDataSet = {
|
||||
...mockDataSet,
|
||||
...rest,
|
||||
status,
|
||||
appLinks: includeAppLinks ? mockDataSet.appLinks : [],
|
||||
};
|
||||
|
||||
return (
|
||||
<SampleDataCardProvider {...getStoryServices(params)}>
|
||||
<Component sampleDataSet={sampleDataSet} onAction={action('onAction')} />
|
||||
</SampleDataCardProvider>
|
||||
);
|
||||
return (
|
||||
<SampleDataCardProvider {...getStoryServices(params)}>
|
||||
<Component sampleDataSet={sampleDataSet} onAction={action('onAction')} />
|
||||
</SampleDataCardProvider>
|
||||
);
|
||||
},
|
||||
|
||||
argTypes,
|
||||
};
|
||||
|
||||
CardFooter.argTypes = argTypes;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import type { SampleDataSet } from '@kbn/home-sample-data-types';
|
||||
|
@ -28,23 +28,25 @@ export default {
|
|||
},
|
||||
},
|
||||
decorators: [(Story) => <div style={{ width: '433px', padding: '25px' }}>{Story()}</div>],
|
||||
} as ComponentMeta<typeof SampleDataCard>;
|
||||
} as Meta<typeof SampleDataCard>;
|
||||
|
||||
const argTypes = getStoryArgTypes();
|
||||
|
||||
export const Card = (params: Params) => {
|
||||
const { includeAppLinks, ...rest } = params;
|
||||
const sampleDataSet: SampleDataSet = {
|
||||
...mockDataSet,
|
||||
...rest,
|
||||
appLinks: includeAppLinks ? mockDataSet.appLinks : [],
|
||||
};
|
||||
export const Card = {
|
||||
render: (params: Params) => {
|
||||
const { includeAppLinks, ...rest } = params;
|
||||
const sampleDataSet: SampleDataSet = {
|
||||
...mockDataSet,
|
||||
...rest,
|
||||
appLinks: includeAppLinks ? mockDataSet.appLinks : [],
|
||||
};
|
||||
|
||||
return (
|
||||
<SampleDataCardProvider {...getStoryServices(params)}>
|
||||
<SampleDataCard sampleDataSet={sampleDataSet} onStatusChange={action('onStatusChange')} />
|
||||
</SampleDataCardProvider>
|
||||
);
|
||||
return (
|
||||
<SampleDataCardProvider {...getStoryServices(params)}>
|
||||
<SampleDataCard sampleDataSet={sampleDataSet} onStatusChange={action('onStatusChange')} />
|
||||
</SampleDataCardProvider>
|
||||
);
|
||||
},
|
||||
|
||||
argTypes,
|
||||
};
|
||||
|
||||
Card.argTypes = argTypes;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Meta } from '@storybook/react';
|
||||
|
||||
import { DemoEnvironmentPanel } from './demo_env_panel';
|
||||
|
||||
|
@ -23,6 +23,6 @@ export default {
|
|||
},
|
||||
},
|
||||
decorators: [(Story) => <div style={{ width: 1200 }}>{Story()}</div>],
|
||||
} as ComponentMeta<typeof DemoEnvironmentPanel>;
|
||||
} as Meta<typeof DemoEnvironmentPanel>;
|
||||
|
||||
export const DemoPanel = () => <DemoEnvironmentPanel demoUrl="https://google.com" />;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Meta } from '@storybook/react';
|
||||
|
||||
import { SampleDataTab } from './sample_data_tab';
|
||||
|
||||
|
@ -25,12 +25,14 @@ export default {
|
|||
},
|
||||
},
|
||||
decorators: [(Story) => <div style={{ width: 1200 }}>{Story()}</div>],
|
||||
} as ComponentMeta<typeof SampleDataTab>;
|
||||
} as Meta<typeof SampleDataTab>;
|
||||
|
||||
export const TabContent = (params: Params) => (
|
||||
<SampleDataTabProvider {...getStoryServices(params)}>
|
||||
<SampleDataTab />
|
||||
</SampleDataTabProvider>
|
||||
);
|
||||
export const TabContent = {
|
||||
render: (params: Params) => (
|
||||
<SampleDataTabProvider {...getStoryServices(params)}>
|
||||
<SampleDataTab />
|
||||
</SampleDataTabProvider>
|
||||
),
|
||||
|
||||
TabContent.argTypes = getStoryArgTypes();
|
||||
argTypes: getStoryArgTypes(),
|
||||
};
|
||||
|
|
|
@ -7,9 +7,6 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
// Storybook react doesn't declare this in its typings, but it's there.
|
||||
declare module '@storybook/react/standalone';
|
||||
|
||||
// Storybook uses this module and its types are defined in the source but not in the type output
|
||||
declare module 'file-system-cache' {
|
||||
interface Options {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
import { StoryObj, Meta } from '@storybook/react';
|
||||
|
||||
import { CaseStatuses } from '../status/types';
|
||||
import { Tooltip } from '../tooltip/tooltip';
|
||||
|
@ -59,46 +59,72 @@ const Template = (args: CaseTooltipProps) => (
|
|||
export default {
|
||||
title: 'CaseTooltip',
|
||||
component: Template,
|
||||
} as ComponentMeta<typeof Template>;
|
||||
} as Meta<typeof Template>;
|
||||
|
||||
export const Default: ComponentStory<typeof Template> = Template.bind({});
|
||||
Default.args = { ...tooltipProps };
|
||||
|
||||
export const LoadingState: ComponentStory<typeof Template> = Template.bind({});
|
||||
LoadingState.args = { ...tooltipProps, loading: true };
|
||||
|
||||
export const LongTitle: ComponentStory<typeof Template> = Template.bind({});
|
||||
LongTitle.args = { ...tooltipProps, content: { ...tooltipContent, title: longTitle } };
|
||||
|
||||
export const LongDescription: ComponentStory<typeof Template> = Template.bind({});
|
||||
LongDescription.args = {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, description: longDescription },
|
||||
export const Default: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
args: { ...tooltipProps },
|
||||
};
|
||||
|
||||
export const InProgressStatus: ComponentStory<typeof Template> = Template.bind({});
|
||||
InProgressStatus.args = {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, status: CaseStatuses['in-progress'] },
|
||||
export const LoadingState: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
args: { ...tooltipProps, loading: true },
|
||||
};
|
||||
|
||||
export const ClosedStatus: ComponentStory<typeof Template> = Template.bind({});
|
||||
ClosedStatus.args = {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, status: CaseStatuses.closed },
|
||||
export const LongTitle: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
args: { ...tooltipProps, content: { ...tooltipContent, title: longTitle } },
|
||||
};
|
||||
|
||||
export const NoUserInfo: ComponentStory<typeof Template> = Template.bind({});
|
||||
NoUserInfo.args = { ...tooltipProps, content: { ...tooltipContent, createdBy: {} } };
|
||||
export const LongDescription: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
|
||||
export const FullName: ComponentStory<typeof Template> = Template.bind({});
|
||||
FullName.args = {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, createdBy: { fullName: 'Elastic User' } },
|
||||
args: {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, description: longDescription },
|
||||
},
|
||||
};
|
||||
|
||||
export const LongUserName: ComponentStory<typeof Template> = Template.bind({});
|
||||
LongUserName.args = {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, createdBy: { fullName: 'LoremIpsumElasticUser WithALongSurname' } },
|
||||
export const InProgressStatus: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
|
||||
args: {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, status: CaseStatuses['in-progress'] },
|
||||
},
|
||||
};
|
||||
|
||||
export const ClosedStatus: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
|
||||
args: {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, status: CaseStatuses.closed },
|
||||
},
|
||||
};
|
||||
|
||||
export const NoUserInfo: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
args: { ...tooltipProps, content: { ...tooltipContent, createdBy: {} } },
|
||||
};
|
||||
|
||||
export const FullName: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
|
||||
args: {
|
||||
...tooltipProps,
|
||||
content: { ...tooltipContent, createdBy: { fullName: 'Elastic User' } },
|
||||
},
|
||||
};
|
||||
|
||||
export const LongUserName: StoryObj<typeof Template> = {
|
||||
render: Template,
|
||||
|
||||
args: {
|
||||
...tooltipProps,
|
||||
content: {
|
||||
...tooltipContent,
|
||||
createdBy: { fullName: 'LoremIpsumElasticUser WithALongSurname' },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { ComponentStory } from '@storybook/react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import type { FieldSpec } from '@kbn/data-views-plugin/common';
|
||||
import { CellActionsProvider } from '../context/cell_actions_context';
|
||||
import { makeAction } from '../mocks/helpers';
|
||||
|
@ -50,33 +50,35 @@ export default {
|
|||
],
|
||||
};
|
||||
|
||||
const CellActionsTemplate: ComponentStory<React.FC<CellActionsProps>> = (args) => (
|
||||
const CellActionsTemplate: StoryFn<React.FC<CellActionsProps>> = (args) => (
|
||||
<CellActions {...args}>{'Field value'}</CellActions>
|
||||
);
|
||||
|
||||
export const DefaultWithControls = CellActionsTemplate.bind({});
|
||||
export const DefaultWithControls = {
|
||||
render: CellActionsTemplate,
|
||||
|
||||
DefaultWithControls.argTypes = {
|
||||
mode: {
|
||||
options: [CellActionsMode.HOVER_DOWN, CellActionsMode.INLINE],
|
||||
defaultValue: CellActionsMode.HOVER_DOWN,
|
||||
control: {
|
||||
type: 'radio',
|
||||
argTypes: {
|
||||
mode: {
|
||||
options: [CellActionsMode.HOVER_DOWN, CellActionsMode.INLINE],
|
||||
defaultValue: CellActionsMode.HOVER_DOWN,
|
||||
control: {
|
||||
type: 'radio',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
DefaultWithControls.args = {
|
||||
showActionTooltips: true,
|
||||
mode: CellActionsMode.INLINE,
|
||||
triggerId: TRIGGER_ID,
|
||||
data: [
|
||||
{
|
||||
field: FIELD,
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
visibleCellActions: 3,
|
||||
args: {
|
||||
showActionTooltips: true,
|
||||
mode: CellActionsMode.INLINE,
|
||||
triggerId: TRIGGER_ID,
|
||||
data: [
|
||||
{
|
||||
field: FIELD,
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
visibleCellActions: 3,
|
||||
},
|
||||
};
|
||||
|
||||
export const CellActionInline = () => (
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import React, { FC, ComponentType } from 'react';
|
||||
import { EuiFlexItem, EuiFlexGroup, EuiEmptyPrompt, EuiForm, IconType } from '@elastic/eui';
|
||||
import { ComponentStory } from '@storybook/react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
|
||||
import {
|
||||
IconCircle,
|
||||
|
@ -224,10 +224,12 @@ function RootComponent(props: RootComponentProps) {
|
|||
);
|
||||
}
|
||||
|
||||
const Template: ComponentStory<FC<RootComponentProps>> = (args) => <RootComponent {...args} />;
|
||||
const Template: StoryFn<FC<RootComponentProps>> = (args) => <RootComponent {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
export const Default = {
|
||||
render: Template,
|
||||
|
||||
Default.args = {
|
||||
icons: IconsArray,
|
||||
args: {
|
||||
icons: IconsArray,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
import React, { FC, useState } from 'react';
|
||||
import { getKbnPalettes } from '@kbn/palettes';
|
||||
import { EuiFlyout, EuiForm, EuiPage, isColorDark } from '@elastic/eui';
|
||||
import { ComponentStory } from '@storybook/react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import { css } from '@emotion/react';
|
||||
import { CategoricalColorMapping, ColorMappingProps } from '../categorical_color_mapping';
|
||||
import { DEFAULT_COLOR_MAPPING_CONFIG } from '../config/default_color_mapping';
|
||||
|
@ -25,7 +25,7 @@ export default {
|
|||
decorators: [(story: Function) => story()],
|
||||
};
|
||||
|
||||
const Template: ComponentStory<FC<ColorMappingProps>> = (args) => {
|
||||
const Template: StoryFn<FC<ColorMappingProps>> = (args) => {
|
||||
const [updatedModel, setUpdateModel] = useState<ColorMapping.Config>(
|
||||
DEFAULT_COLOR_MAPPING_CONFIG
|
||||
);
|
||||
|
@ -76,50 +76,53 @@ const Template: ComponentStory<FC<ColorMappingProps>> = (args) => {
|
|||
</EuiPage>
|
||||
);
|
||||
};
|
||||
export const Default = Template.bind({});
|
||||
|
||||
Default.args = {
|
||||
model: {
|
||||
...DEFAULT_COLOR_MAPPING_CONFIG,
|
||||
paletteId: 'eui_amsterdam',
|
||||
export const Default = {
|
||||
render: Template,
|
||||
|
||||
colorMode: {
|
||||
type: 'categorical',
|
||||
},
|
||||
specialAssignments: [
|
||||
{
|
||||
rule: {
|
||||
type: 'other',
|
||||
},
|
||||
color: {
|
||||
type: 'loop',
|
||||
},
|
||||
touched: false,
|
||||
args: {
|
||||
model: {
|
||||
...DEFAULT_COLOR_MAPPING_CONFIG,
|
||||
paletteId: 'eui_amsterdam',
|
||||
|
||||
colorMode: {
|
||||
type: 'categorical',
|
||||
},
|
||||
],
|
||||
assignments: [],
|
||||
},
|
||||
isDarkMode: false,
|
||||
data: {
|
||||
type: 'categories',
|
||||
categories: [
|
||||
'US',
|
||||
'Mexico',
|
||||
'Brasil',
|
||||
'Canada',
|
||||
'Italy',
|
||||
'Germany',
|
||||
'France',
|
||||
'Spain',
|
||||
'UK',
|
||||
'Portugal',
|
||||
'Greece',
|
||||
'Sweden',
|
||||
'Finland',
|
||||
],
|
||||
},
|
||||
specialAssignments: [
|
||||
{
|
||||
rule: {
|
||||
type: 'other',
|
||||
},
|
||||
color: {
|
||||
type: 'loop',
|
||||
},
|
||||
touched: false,
|
||||
},
|
||||
],
|
||||
assignments: [],
|
||||
},
|
||||
isDarkMode: false,
|
||||
data: {
|
||||
type: 'categories',
|
||||
categories: [
|
||||
'US',
|
||||
'Mexico',
|
||||
'Brasil',
|
||||
'Canada',
|
||||
'Italy',
|
||||
'Germany',
|
||||
'France',
|
||||
'Spain',
|
||||
'UK',
|
||||
'Portugal',
|
||||
'Greece',
|
||||
'Sweden',
|
||||
'Finland',
|
||||
],
|
||||
},
|
||||
|
||||
specialTokens: new Map(),
|
||||
// eslint-disable-next-line no-console
|
||||
onModelUpdate: (model) => console.log(model),
|
||||
specialTokens: new Map(),
|
||||
// eslint-disable-next-line no-console
|
||||
onModelUpdate: (model: any) => console.log(model),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import React, { FC, PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import { EuiForm } from '@elastic/eui';
|
||||
import { ComponentStory } from '@storybook/react';
|
||||
import { CustomizablePalette, CustomizablePaletteProps } from '../palette_configuration';
|
||||
import { CustomizablePalette } from '../palette_configuration';
|
||||
import { getPaletteRegistry } from './palettes';
|
||||
|
||||
export default {
|
||||
|
@ -19,29 +18,25 @@ export default {
|
|||
decorators: [(story: Function) => <EuiForm>{story()}</EuiForm>],
|
||||
};
|
||||
|
||||
const Template: ComponentStory<FC<PropsWithChildren<CustomizablePaletteProps>>> = (args) => (
|
||||
<CustomizablePalette {...args} />
|
||||
);
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
Default.args = {
|
||||
palettes: getPaletteRegistry(),
|
||||
activePalette: {
|
||||
type: 'palette',
|
||||
name: 'default',
|
||||
params: {
|
||||
steps: 1,
|
||||
maxSteps: 10,
|
||||
continuity: 'none',
|
||||
export const Default = {
|
||||
args: {
|
||||
palettes: getPaletteRegistry(),
|
||||
activePalette: {
|
||||
type: 'palette',
|
||||
name: 'default',
|
||||
params: {
|
||||
steps: 1,
|
||||
maxSteps: 10,
|
||||
continuity: 'none',
|
||||
},
|
||||
},
|
||||
dataBounds: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
},
|
||||
showExtraActions: true,
|
||||
showRangeTypeSelector: true,
|
||||
disableSwitchingContinuity: false,
|
||||
setPalette: () => {},
|
||||
},
|
||||
dataBounds: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
},
|
||||
showExtraActions: true,
|
||||
showRangeTypeSelector: true,
|
||||
disableSwitchingContinuity: false,
|
||||
setPalette: () => {},
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import { EuiCard, EuiFlexGroup, EuiFlexItem, EuiImage, EuiToolTip } from '@elastic/eui';
|
||||
import type { Story } from '@storybook/react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { AGENT_NAMES } from '@kbn/elastic-agent-utils';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
|
@ -20,7 +20,7 @@ export default {
|
|||
component: AgentIcon,
|
||||
};
|
||||
|
||||
export const List: Story = () => {
|
||||
export const List: StoryFn = () => {
|
||||
return (
|
||||
<EuiThemeProvider darkMode={false}>
|
||||
<EuiFlexGroup gutterSize="l" wrap={true}>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import { EuiCard, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
|
||||
import type { Story } from '@storybook/react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { CloudProviderIcon } from '.';
|
||||
import { CloudProvider } from './get_cloud_provider_icon';
|
||||
|
@ -20,7 +20,7 @@ export default {
|
|||
|
||||
const providers: CloudProvider[] = ['gcp', 'aws', 'azure', 'unknownProvider'];
|
||||
|
||||
export const List: Story = () => {
|
||||
export const List: StoryFn = () => {
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="l" wrap={true}>
|
||||
{providers.map((cloudProvider) => {
|
||||
|
|
|
@ -61,7 +61,7 @@ export const esHitsMockWithSort = esHitsMock.map((hit) => ({
|
|||
}));
|
||||
|
||||
const baseDate = new Date('2024-01-1').getTime();
|
||||
const dateInc = 100_000_000;
|
||||
const dateInc = 100000000;
|
||||
|
||||
const generateFieldValue = (field: DataViewField, index: number) => {
|
||||
switch (field.type) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { Story } from '@storybook/react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import { mockGroupingProps } from './grouping.mock';
|
||||
import { Grouping } from './grouping';
|
||||
import readme from '../../README.mdx';
|
||||
|
@ -24,6 +24,6 @@ export default {
|
|||
},
|
||||
};
|
||||
|
||||
export const Empty: Story<void> = () => {
|
||||
export const Empty: StoryFn = () => {
|
||||
return <Grouping {...mockGroupingProps} />;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { ComponentMeta, Story } from '@storybook/react';
|
||||
import type { StoryFn, Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import { Subscription } from 'rxjs';
|
||||
|
@ -29,7 +29,7 @@ export default {
|
|||
default: 'ghost',
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Component>;
|
||||
} as Meta<typeof Component>;
|
||||
|
||||
/**
|
||||
* Props for a {@link SettinggApplication} Storybook story.
|
||||
|
@ -69,12 +69,12 @@ const getSettingsApplicationStory = ({ hasGlobalSettings }: StoryProps) => (
|
|||
</SettingsApplicationProvider>
|
||||
);
|
||||
|
||||
export const SettingsApplicationWithGlobalSettings: Story = () =>
|
||||
export const SettingsApplicationWithGlobalSettings: StoryFn = () =>
|
||||
getSettingsApplicationStory({
|
||||
hasGlobalSettings: true,
|
||||
});
|
||||
|
||||
export const SettingsApplicationWithoutGlobal: Story = () =>
|
||||
export const SettingsApplicationWithoutGlobal: StoryFn = () =>
|
||||
getSettingsApplicationStory({
|
||||
hasGlobalSettings: false,
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { ComponentMeta, Story } from '@storybook/react';
|
||||
import type { StoryObj, Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { FieldCategories as Component } from '../categories';
|
||||
import { Params, useCategoryStory } from './use_category_story';
|
||||
|
@ -38,9 +38,9 @@ export default {
|
|||
default: 'ghost',
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Component>;
|
||||
} as Meta<typeof Component>;
|
||||
|
||||
export const Categories: Story<Params> = (params) => {
|
||||
const CategoriesComponent = (params: Params) => {
|
||||
const {
|
||||
onClearQuery,
|
||||
isSavingEnabled,
|
||||
|
@ -75,3 +75,7 @@ export const Categories: Story<Params> = (params) => {
|
|||
</FieldCategoryProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const Categories: StoryObj<Params> = {
|
||||
render: (params) => <CategoriesComponent {...params} />,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import { getSettingsMock } from '@kbn/management-settings-utilities/mocks/settings.mock';
|
||||
|
@ -51,11 +51,11 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Component>;
|
||||
} as Meta<typeof Component>;
|
||||
|
||||
type FieldCategoryParams = Pick<ComponentProps, 'category'> & Params;
|
||||
|
||||
export const Category = ({ isFiltered, category, isSavingEnabled }: FieldCategoryParams) => {
|
||||
const CategoryComponent = ({ isFiltered, category, isSavingEnabled }: FieldCategoryParams) => {
|
||||
const { onClearQuery, onFieldChange, unsavedChanges } = useCategoryStory({
|
||||
isFiltered,
|
||||
isSavingEnabled,
|
||||
|
@ -89,3 +89,7 @@ export const Category = ({ isFiltered, category, isSavingEnabled }: FieldCategor
|
|||
</FieldCategoryProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const Category: StoryObj<FieldCategoryParams> = {
|
||||
render: (params) => <CategoryComponent {...params} />,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useArgs } from '@storybook/client-api';
|
||||
import { useArgs } from '@storybook/preview-api';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import { getSettingsMock } from '@kbn/management-settings-utilities/mocks/settings.mock';
|
||||
|
|
|
@ -9,5 +9,7 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('Array Input', 'An input with an array value.');
|
||||
const Story = getStory('Array Input', 'An input with an array value.');
|
||||
export const ArrayInput = getInputStory('array' as const);
|
||||
|
||||
export default { ...Story };
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('Boolean Input', 'An input with a boolean value.');
|
||||
const Story = getStory('Boolean Input', 'An input with a boolean value.');
|
||||
export const BooleanInput = getInputStory('boolean' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('Color Input', 'An input with a color value.');
|
||||
const Story = getStory('Color Input', 'An input with a color value.');
|
||||
export const ColorInput = getInputStory('color' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import { EuiPanel } from '@elastic/eui';
|
||||
|
@ -23,7 +23,7 @@ import {
|
|||
import { getFieldDefinition } from '@kbn/management-settings-field-definition';
|
||||
import { getDefaultValue, getUserValue } from '@kbn/management-settings-utilities/storybook';
|
||||
import { FieldInputProvider } from '../services';
|
||||
import { FieldInput as Component, FieldInput } from '../field_input';
|
||||
import { FieldInput } from '../field_input';
|
||||
import { InputProps } from '../types';
|
||||
|
||||
/**
|
||||
|
@ -92,7 +92,7 @@ export const getStory = (title: string, description: string) =>
|
|||
</FieldInputProvider>
|
||||
),
|
||||
],
|
||||
} as ComponentMeta<typeof Component>);
|
||||
} as Meta<typeof FieldInput>);
|
||||
|
||||
/**
|
||||
* Utility function for returning a {@link FieldInput} Storybook story.
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('Image Input', 'An input with an image value.');
|
||||
const Story = getStory('Image Input', 'An input with an image value.');
|
||||
export const ImageInput = getInputStory('image' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('JSON Input', 'An input with a JSON value.');
|
||||
const Story = getStory('JSON Input', 'An input with a JSON value.');
|
||||
export const JSONInput = getInputStory('json' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('Markdown Input', 'An input with a markdown value.');
|
||||
const Story = getStory('Markdown Input', 'An input with a markdown value.');
|
||||
export const MarkdownInput = getInputStory('markdown' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('Number Input', 'An input with a number value.');
|
||||
const Story = getStory('Number Input', 'An input with a number value.');
|
||||
export const NumberInput = getInputStory('number' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ const settingFields = {
|
|||
options: ['option1', 'option2', 'option3'],
|
||||
};
|
||||
|
||||
export default getStory('Select Input', 'An input with multiple values.');
|
||||
const Story = getStory('Select Input', 'An input with multiple values.');
|
||||
export const SelectInput = getInputStory('select' as const, { argTypes, settingFields });
|
||||
|
||||
SelectInput.args = {
|
||||
|
@ -39,3 +39,7 @@ SelectInput.args = {
|
|||
value: 'option1',
|
||||
userValue: 'option2',
|
||||
};
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getInputStory, getStory } from './common';
|
||||
|
||||
export default getStory('String Input', 'An input with a string value.');
|
||||
const Story = getStory('String Input', 'An input with a string value.');
|
||||
export const StringInput = getInputStory('string' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getFieldRowStory, getStory } from './common';
|
||||
|
||||
export default getStory('Array Row', 'A setting with an array of values.');
|
||||
const Story = getStory('Array Row', 'A setting with an array of values.');
|
||||
export const ArrayRow = getFieldRowStory('array' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getStory, getFieldRowStory } from './common';
|
||||
|
||||
export default getStory('Boolean Row', 'A setting with a boolean value.');
|
||||
const Story = getStory('Boolean Row', 'A setting with a boolean value.');
|
||||
export const BooleanRow = getFieldRowStory('boolean' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getFieldRowStory, getStory } from './common';
|
||||
|
||||
export default getStory('Color Row', 'A setting with an base64 image value.');
|
||||
const Story = getStory('Color Row', 'A setting with an base64 image value.');
|
||||
export const ColorRow = getFieldRowStory('color' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { EuiPanel } from '@elastic/eui';
|
||||
import { SettingType, UnsavedFieldChange } from '@kbn/management-settings-types';
|
||||
|
@ -93,7 +93,7 @@ export const getStory = (
|
|||
</FieldRowProvider>
|
||||
),
|
||||
],
|
||||
} as ComponentMeta<typeof Component>);
|
||||
} as Meta<typeof Component>);
|
||||
|
||||
/**
|
||||
* Default argument values for a {@link FieldInput} Storybook story.
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getFieldRowStory, getStory } from './common';
|
||||
|
||||
export default getStory('Image Row', 'A setting with an base64 image value.');
|
||||
const Story = getStory('Image Row', 'A setting with an base64 image value.');
|
||||
export const ImageRow = getFieldRowStory('image' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getFieldRowStory, getStory } from './common';
|
||||
|
||||
export default getStory('JSON Row', 'A setting with a JSON value.');
|
||||
const Story = getStory('JSON Row', 'A setting with a JSON value.');
|
||||
export const JSONRow = getFieldRowStory('json' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getFieldRowStory, getStory } from './common';
|
||||
|
||||
export default getStory('Markdown Row', 'A setting with a Markdown value.');
|
||||
const Story = getStory('Markdown Row', 'A setting with a Markdown value.');
|
||||
export const MarkdownRow = getFieldRowStory('markdown' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getFieldRowStory, getStory } from './common';
|
||||
|
||||
export default getStory('Number Row', 'A setting with a numeric value.');
|
||||
const Story = getStory('Number Row', 'A setting with a numeric value.');
|
||||
export const NumberRow = getFieldRowStory('number' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -24,5 +24,9 @@ const settingFields = {
|
|||
options: ['option1', 'option2', 'option3'],
|
||||
};
|
||||
|
||||
export default getStory('Select Row', 'A setting with a boolean value.', argTypes);
|
||||
const Story = getStory('Select Row', 'A setting with a boolean value.', argTypes);
|
||||
export const SelectRow = getFieldRowStory('select' as const, settingFields);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,5 +9,9 @@
|
|||
|
||||
import { getFieldRowStory, getStory } from './common';
|
||||
|
||||
export default getStory('String Row', 'A setting with a string value.');
|
||||
const Story = getStory('String Row', 'A setting with a string value.');
|
||||
export const StringRow = getFieldRowStory('string' as const);
|
||||
|
||||
export default {
|
||||
...Story,
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Meta } from '@storybook/react';
|
||||
import { FieldDefinition } from '@kbn/management-settings-types';
|
||||
import { getFieldDefinitions } from '@kbn/management-settings-field-definition';
|
||||
import { getSettingsMock } from '@kbn/management-settings-utilities/mocks/settings.mock';
|
||||
|
@ -20,7 +20,7 @@ import { Form as Component } from '../form';
|
|||
import { FormProvider } from '../services';
|
||||
|
||||
export default {
|
||||
title: `Settings/Form/Form`,
|
||||
title: 'Settings/Form/Form',
|
||||
description: 'A form with field rows',
|
||||
argTypes: {
|
||||
isSavingEnabled: {
|
||||
|
@ -57,7 +57,7 @@ export default {
|
|||
default: 'ghost',
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Component>;
|
||||
} as Meta<typeof Component>;
|
||||
|
||||
interface FormStoryProps {
|
||||
/** True if saving settings is enabled, false otherwise. */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { addons } from '@storybook/addons';
|
||||
import { addons } from '@storybook/manager-api';
|
||||
import { create } from '@storybook/theming';
|
||||
import { PANEL_ID as selectedPanel } from '@storybook/addon-actions';
|
||||
|
||||
|
|
|
@ -7,13 +7,8 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import {
|
||||
defaultConfig,
|
||||
defaultConfigWebFinal,
|
||||
mergeWebpackFinal,
|
||||
StorybookConfig,
|
||||
} from './src/lib/default_config';
|
||||
export { defaultConfig, defaultConfigWebFinal, mergeWebpackFinal };
|
||||
import { defaultConfig, StorybookConfig } from './src/lib/default_config';
|
||||
export { defaultConfig };
|
||||
export type { StorybookConfig };
|
||||
export { runStorybookCli } from './src/lib/run_storybook_cli';
|
||||
export { default as WebpackConfig } from './src/webpack.config';
|
||||
|
|
|
@ -16,7 +16,7 @@ module.exports = {
|
|||
webpackFinal: (config) => {
|
||||
return webpackConfig({ config });
|
||||
},
|
||||
config: (entry) => {
|
||||
return [...entry, require.resolve('./src/lib/decorators')];
|
||||
previewAnnotations: (entry) => {
|
||||
return [...entry, require.resolve('./src/lib/preview')];
|
||||
},
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
import { of, Subject } from 'rxjs';
|
||||
import React, { useEffect } from 'react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import type { DecoratorFn } from '@storybook/react';
|
||||
import type { Decorator } from '@storybook/react';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
import 'core_styles';
|
||||
|
@ -40,7 +40,7 @@ const analytics: AnalyticsServiceStart = {
|
|||
* Storybook decorator using the `KibanaContextProvider`. Uses the value from
|
||||
* `globals` provided by the Storybook theme switcher to set the `colorMode`.
|
||||
*/
|
||||
const KibanaContextDecorator: DecoratorFn = (storyFn, { globals }) => {
|
||||
const KibanaContextDecorator: Decorator = (storyFn, { globals }) => {
|
||||
// TODO: Add a switcher to see components in other locales or pseudo locale
|
||||
i18n.init({ locale: 'en', messages: {} });
|
||||
const { darkMode, name } = getKibanaTheme(globals.euiTheme);
|
||||
|
|
|
@ -9,18 +9,28 @@
|
|||
|
||||
import * as path from 'path';
|
||||
import fs from 'fs';
|
||||
import type { StorybookConfig } from '@storybook/core-common';
|
||||
import webpack, { Configuration } from 'webpack';
|
||||
import { merge as webpackMerge } from 'webpack-merge';
|
||||
import type { StorybookConfig as BaseStorybookConfig } from '@storybook/react-webpack5';
|
||||
import type { TypescriptOptions } from '@storybook/preset-react-webpack';
|
||||
import webpack from 'webpack';
|
||||
import { resolve } from 'path';
|
||||
import UiSharedDepsNpm from '@kbn/ui-shared-deps-npm';
|
||||
import * as UiSharedDepsSrc from '@kbn/ui-shared-deps-src';
|
||||
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
|
||||
import { REPO_ROOT } from './constants';
|
||||
import { default as WebpackConfig } from '../webpack.config';
|
||||
|
||||
const MOCKS_DIRECTORY = '__storybook_mocks__';
|
||||
const EXTENSIONS = ['.ts', '.js'];
|
||||
|
||||
export type { StorybookConfig };
|
||||
/*
|
||||
* false is a valid option for typescript.reactDocgen,
|
||||
* but it is not in the type definition
|
||||
*/
|
||||
interface StorybookConfig extends BaseStorybookConfig {
|
||||
typescript: Partial<TypescriptOptions>;
|
||||
}
|
||||
|
||||
const toPath = (_path: string) => path.join(REPO_ROOT, _path);
|
||||
export type { StorybookConfig };
|
||||
|
||||
// This ignore pattern excludes all of node_modules EXCEPT for `@kbn`. This allows for
|
||||
// changes to packages to cause a refresh in Storybook.
|
||||
|
@ -32,31 +42,101 @@ const IGNORE_GLOBS = [
|
|||
];
|
||||
|
||||
export const defaultConfig: StorybookConfig = {
|
||||
addons: ['@kbn/storybook/preset', '@storybook/addon-a11y', '@storybook/addon-essentials'],
|
||||
core: {
|
||||
builder: 'webpack5',
|
||||
addons: [
|
||||
'@kbn/storybook/preset',
|
||||
'@storybook/addon-a11y',
|
||||
'@storybook/addon-webpack5-compiler-babel',
|
||||
// https://storybook.js.org/docs/essentials
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-jest',
|
||||
{
|
||||
/**
|
||||
* This addon replaces rules in the default SB webpack config
|
||||
* to avoid duplicate rule issues caused by directly using the rules
|
||||
* in the custom webpack config.
|
||||
*/
|
||||
name: '@storybook/addon-styling-webpack',
|
||||
options: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
exclude: /\.module.(s(a|c)ss)$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader', options: { importLoaders: 2 } },
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
config: require.resolve('@kbn/optimizer/postcss.config'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
additionalData(content: string, loaderContext: any) {
|
||||
const req = JSON.stringify(
|
||||
loaderContext.utils.contextify(
|
||||
loaderContext.context || loaderContext.rootContext,
|
||||
resolve(REPO_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss')
|
||||
)
|
||||
);
|
||||
return `@import ${req};\n${content}`;
|
||||
},
|
||||
implementation: require('sass-embedded'),
|
||||
sassOptions: {
|
||||
includePaths: [resolve(REPO_ROOT, 'node_modules')],
|
||||
quietDeps: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
stories: ['../**/*.stories.tsx', '../**/*.mdx'],
|
||||
framework: {
|
||||
name: '@storybook/react-webpack5',
|
||||
options: {},
|
||||
},
|
||||
stories: ['../**/*.stories.tsx', '../**/*.stories.mdx'],
|
||||
typescript: {
|
||||
reactDocgen: false,
|
||||
},
|
||||
features: {
|
||||
postcss: false,
|
||||
core: {
|
||||
disableTelemetry: true,
|
||||
},
|
||||
// @ts-expect-error StorybookConfig type is incomplete
|
||||
// https://storybook.js.org/docs/react/configure/babel#custom-configuration
|
||||
babel: async (options) => {
|
||||
options.presets.push([
|
||||
require.resolve('@emotion/babel-preset-css-prop'),
|
||||
async babel(config: any, options: any) {
|
||||
if (!config?.presets) {
|
||||
config.presets = [];
|
||||
}
|
||||
|
||||
config.presets.push(
|
||||
require.resolve('@kbn/babel-preset/common_preset'),
|
||||
[
|
||||
require.resolve('@emotion/babel-preset-css-prop'),
|
||||
{
|
||||
// There's an issue where emotion classnames may be duplicated,
|
||||
// (e.g. `[hash]-[filename]--[local]_[filename]--[local]`)
|
||||
// https://github.com/emotion-js/emotion/issues/2417
|
||||
autoLabel: 'always',
|
||||
labelFormat: '[filename]--[local]',
|
||||
},
|
||||
],
|
||||
{
|
||||
// There's an issue where emotion classnames may be duplicated,
|
||||
// (e.g. `[hash]-[filename]--[local]_[filename]--[local]`)
|
||||
// https://github.com/emotion-js/emotion/issues/2417
|
||||
autoLabel: 'always',
|
||||
labelFormat: '[filename]--[local]',
|
||||
},
|
||||
]);
|
||||
return options;
|
||||
plugins: [
|
||||
process.env.NODE_ENV !== 'production' && require.resolve('react-refresh/babel'),
|
||||
].filter(Boolean),
|
||||
}
|
||||
);
|
||||
|
||||
return config;
|
||||
},
|
||||
webpackFinal: (config, options) => {
|
||||
if (process.env.CI) {
|
||||
|
@ -64,6 +144,9 @@ export const defaultConfig: StorybookConfig = {
|
|||
config.cache = true;
|
||||
}
|
||||
|
||||
// required for react refresh
|
||||
config.target = 'web';
|
||||
|
||||
// This will go over every component which is imported and check its import statements.
|
||||
// For every import which starts with ./ it will do a check to see if a file with the same name
|
||||
// exists in the __storybook_mocks__ folder. If it does, use that import instead.
|
||||
|
@ -106,6 +189,14 @@ export const defaultConfig: StorybookConfig = {
|
|||
})
|
||||
);
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
config.plugins?.push(
|
||||
new ReactRefreshWebpackPlugin({
|
||||
overlay: false,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
config.resolve = {
|
||||
...config.resolve,
|
||||
fallback: {
|
||||
|
@ -113,43 +204,40 @@ export const defaultConfig: StorybookConfig = {
|
|||
fs: false,
|
||||
},
|
||||
};
|
||||
config.watch = true;
|
||||
|
||||
config.watchOptions = {
|
||||
...config.watchOptions,
|
||||
ignored: IGNORE_GLOBS,
|
||||
};
|
||||
|
||||
// Remove when @storybook has moved to @emotion v11
|
||||
// https://github.com/storybookjs/storybook/issues/13145
|
||||
const emotion11CompatibleConfig = {
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
alias: {
|
||||
...config.resolve?.alias,
|
||||
'@emotion/core': toPath('node_modules/@emotion/react'),
|
||||
'@emotion/styled': toPath('node_modules/@emotion/styled'),
|
||||
'emotion-theming': toPath('node_modules/@emotion/react'),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return emotion11CompatibleConfig;
|
||||
},
|
||||
};
|
||||
|
||||
// defaultConfigWebFinal and mergeWebpackFinal have been moved here because webpackFinal usage in
|
||||
// storybook main.ts somehow is causing issues with newly added dependency of ts-node most likely
|
||||
// an issue with storybook typescript setup see this issue for more details
|
||||
// https://github.com/storybookjs/storybook/issues/9610
|
||||
|
||||
export const defaultConfigWebFinal: StorybookConfig = {
|
||||
...defaultConfig,
|
||||
webpackFinal: (config: Configuration) => {
|
||||
return WebpackConfig({ config });
|
||||
},
|
||||
};
|
||||
previewHead: (head) => `
|
||||
${head}
|
||||
<meta name="eui-global" />
|
||||
<meta name="emotion" />
|
||||
<script>
|
||||
window.__kbnPublicPath__ = { 'kbn-ui-shared-deps-npm': '', 'kbn-ui-shared-deps-src': '' };
|
||||
window.__kbnHardenPrototypes__ = false;
|
||||
</script>
|
||||
<script src="kbn-ui-shared-deps-npm.dll.js"></script>
|
||||
<script src="kbn-ui-shared-deps-src.js"></script>
|
||||
<link href="kbn-ui-shared-deps-src.css" rel="stylesheet" />
|
||||
|
||||
export const mergeWebpackFinal = (extraConfig: Configuration) => {
|
||||
return { webpackFinal: (config: Configuration) => webpackMerge(config, extraConfig) };
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@300..700&family=Roboto+Mono:ital,wght@0,400..700;1,400..700&display=swap"
|
||||
rel="stylesheet">
|
||||
|
||||
<meta name="eui-utilities" />
|
||||
`,
|
||||
staticDirs: [
|
||||
UiSharedDepsNpm.distDir,
|
||||
UiSharedDepsSrc.distDir,
|
||||
{
|
||||
from: `${REPO_ROOT}/src/platform/plugins/shared/kibana_react/public/assets`,
|
||||
to: 'plugins/kibanaReact/assets',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -7,4 +7,17 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
export const STORYBOOK_TITLE = 'Unified Tabs';
|
||||
import type { Preview } from '@storybook/react';
|
||||
import * as jest from 'jest-mock';
|
||||
import { decorators } from './decorators';
|
||||
|
||||
// @ts-expect-error
|
||||
window.jest = jest;
|
||||
|
||||
const preview: Preview = {
|
||||
decorators,
|
||||
initialGlobals: { euiTheme: 'v8.light' },
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default preview;
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { addons } from '@storybook/addons';
|
||||
import { addons } from '@storybook/manager-api';
|
||||
import { create } from '@storybook/theming';
|
||||
import { registerThemeSwitcherAddon } from './register_theme_switcher_addon';
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { addons, types } from '@storybook/addons';
|
||||
import { addons, types } from '@storybook/manager-api';
|
||||
import { ThemeSwitcher } from './theme_switcher';
|
||||
|
||||
export const THEME_SWITCHER_ADDON_ID = 'kibana/eui-theme-switcher';
|
||||
|
@ -16,7 +16,7 @@ export function registerThemeSwitcherAddon() {
|
|||
addons.register(THEME_SWITCHER_ADDON_ID, (api) => {
|
||||
const channel = api.getChannel();
|
||||
|
||||
channel.on('globalsUpdated', ({ globals }) => {
|
||||
channel?.on('globalsUpdated', ({ globals }) => {
|
||||
const previewFrame = document.getElementById(
|
||||
'storybook-preview-iframe'
|
||||
) as HTMLIFrameElement | null;
|
||||
|
|
|
@ -7,17 +7,15 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import { join } from 'path';
|
||||
import { logger } from '@storybook/node-logger';
|
||||
import buildStandalone from '@storybook/react/standalone';
|
||||
import { build } from '@storybook/core-server';
|
||||
import type { CLIOptions, BuilderOptions, LoadOptions } from '@storybook/types';
|
||||
import { Flags, run } from '@kbn/dev-cli-runner';
|
||||
import UiSharedDepsNpm from '@kbn/ui-shared-deps-npm';
|
||||
import * as UiSharedDepsSrc from '@kbn/ui-shared-deps-src';
|
||||
|
||||
// @ts-expect-error internal dep of storybook
|
||||
import interpret from 'interpret'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
import * as constants from './constants';
|
||||
|
||||
type StorybookCliOptions = CLIOptions & BuilderOptions & LoadOptions & { mode: 'dev' | 'static' };
|
||||
|
||||
// Convert the flags to a Storybook loglevel
|
||||
function getLogLevelFromFlags(flags: Flags) {
|
||||
if (flags.debug) {
|
||||
|
@ -40,29 +38,29 @@ export function runStorybookCli({ configDir, name }: { configDir: string; name:
|
|||
async ({ flags, log }) => {
|
||||
log.debug('Global config:\n', constants);
|
||||
|
||||
const staticDir = [
|
||||
UiSharedDepsNpm.distDir,
|
||||
UiSharedDepsSrc.distDir,
|
||||
'src/platform/plugins/shared/kibana_react/public/assets:plugins/kibanaReact/assets',
|
||||
];
|
||||
const config: Record<string, any> = {
|
||||
const config: StorybookCliOptions = {
|
||||
configDir,
|
||||
mode: flags.site ? 'static' : 'dev',
|
||||
port: 9001,
|
||||
staticDir,
|
||||
loglevel: getLogLevelFromFlags(flags),
|
||||
};
|
||||
|
||||
if (flags.site) {
|
||||
config.outputDir = join(constants.ASSET_DIR, name);
|
||||
process.env.NODE_ENV = 'production';
|
||||
} else {
|
||||
// required for react refresh
|
||||
process.env.NODE_ENV = 'development';
|
||||
}
|
||||
|
||||
logger.setLevel(getLogLevelFromFlags(flags));
|
||||
|
||||
// force storybook to use our transpilation rather than ts-node or anything else
|
||||
interpret.extensions['.ts'] = [require.resolve('@kbn/babel-register/install')];
|
||||
interpret.extensions['.tsx'] = [require.resolve('@kbn/babel-register/install')];
|
||||
interpret.extensions['.jsx'] = [require.resolve('@kbn/babel-register/install')];
|
||||
|
||||
await buildStandalone(config);
|
||||
try {
|
||||
// Some transitive deps of addon-docs are ESM and not loading properly
|
||||
// See: https://github.com/storybookjs/storybook/issues/29467
|
||||
require('fix-esm').require('react-docgen');
|
||||
await build(config);
|
||||
} finally {
|
||||
require('fix-esm').unregister();
|
||||
}
|
||||
|
||||
// Line is only reached when building the static version
|
||||
if (flags.site) process.exit();
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { Icons, IconButton, TooltipLinkList, WithTooltip } from '@storybook/components';
|
||||
import { useGlobals } from '@storybook/api';
|
||||
import { IconButton, TooltipLinkList, WithTooltip } from '@storybook/components';
|
||||
import { useGlobals } from '@storybook/manager-api';
|
||||
import { HeartIcon, HeartHollowIcon } from '@storybook/icons';
|
||||
|
||||
import { DEFAULT_THEME, THEMES, THEME_TITLES } from './themes';
|
||||
|
||||
|
@ -37,7 +38,6 @@ export function ThemeSwitcher() {
|
|||
<WithTooltip
|
||||
placement="top"
|
||||
trigger="click"
|
||||
closeOnClick
|
||||
tooltip={({ onHide }) => (
|
||||
<ThemeSwitcherTooltip
|
||||
onHide={onHide}
|
||||
|
@ -46,9 +46,8 @@ export function ThemeSwitcher() {
|
|||
/>
|
||||
)}
|
||||
>
|
||||
{/* @ts-ignore Remove when @storybook has moved to @emotion v11 */}
|
||||
<IconButton key="eui-theme" title="Change the EUI theme">
|
||||
<Icons icon={selectedTheme?.includes('dark') ? 'heart' : 'hearthollow'} />
|
||||
{selectedTheme?.includes('dark') ? <HeartIcon /> : <HeartHollowIcon />}
|
||||
</IconButton>
|
||||
</WithTooltip>
|
||||
);
|
||||
|
@ -78,6 +77,6 @@ const ThemeSwitcherTooltip = React.memo(
|
|||
})
|
||||
);
|
||||
|
||||
return <TooltipLinkList links={links} />;
|
||||
return <TooltipLinkList links={links.flat()} />;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -10,64 +10,13 @@
|
|||
/* eslint-disable import/no-default-export */
|
||||
import { externals } from '@kbn/ui-shared-deps-src';
|
||||
import { resolve } from 'path';
|
||||
import webpack, { Configuration } from 'webpack';
|
||||
import { Configuration } from 'webpack';
|
||||
import { merge as webpackMerge } from 'webpack-merge';
|
||||
import { NodeLibsBrowserPlugin } from '@kbn/node-libs-browser-webpack-plugin';
|
||||
import { REPO_ROOT } from './lib/constants';
|
||||
import { IgnoreNotFoundExportPlugin } from './ignore_not_found_export_plugin';
|
||||
import 'webpack-dev-server'; // Extends webpack configuration with `devServer` property
|
||||
|
||||
type Preset = string | [string, Record<string, unknown>] | Record<string, unknown>;
|
||||
|
||||
function isProgressPlugin(plugin: any) {
|
||||
return 'handler' in plugin && plugin.showActiveModules && plugin.showModules;
|
||||
}
|
||||
|
||||
function isHtmlPlugin(plugin: any): plugin is { options: { template: string } } {
|
||||
return !!(typeof plugin.options?.template === 'string');
|
||||
}
|
||||
|
||||
interface BabelLoaderRule extends webpack.RuleSetRule {
|
||||
use: Array<{
|
||||
loader: 'babel-loader';
|
||||
[key: string]: unknown;
|
||||
}>;
|
||||
}
|
||||
|
||||
function isBabelLoaderRule(rule: webpack.RuleSetRule): rule is BabelLoaderRule {
|
||||
return !!(
|
||||
rule.use &&
|
||||
Array.isArray(rule.use) &&
|
||||
rule.use.some(
|
||||
(l) =>
|
||||
typeof l === 'object' && typeof l?.loader === 'string' && l?.loader.includes('babel-loader')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getPresetPath(preset: Preset) {
|
||||
if (typeof preset === 'string') return preset;
|
||||
if (Array.isArray(preset)) return preset[0];
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getTsPreset(preset: Preset) {
|
||||
if (getPresetPath(preset)?.includes('preset-typescript')) {
|
||||
if (typeof preset === 'string') return [preset, {}];
|
||||
if (Array.isArray(preset)) return preset;
|
||||
|
||||
throw new Error('unsupported preset-typescript format');
|
||||
}
|
||||
}
|
||||
|
||||
function isDesiredPreset(preset: Preset) {
|
||||
return !getPresetPath(preset)?.includes('preset-flow');
|
||||
}
|
||||
|
||||
// Extend the Storybook Webpack config with some customizations
|
||||
/**
|
||||
* @returns {import('webpack').Configuration}
|
||||
*/
|
||||
export default ({ config: storybookConfig }: { config: Configuration }) => {
|
||||
const config: Configuration = {
|
||||
devServer: {
|
||||
|
@ -97,41 +46,6 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
|
|||
loader: require.resolve('@kbn/peggy-loader'),
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
exclude: /\.module.(s(a|c)ss)$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader', options: { importLoaders: 2 } },
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
config: require.resolve('@kbn/optimizer/postcss.config'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
additionalData(content: string, loaderContext: any) {
|
||||
const req = JSON.stringify(
|
||||
loaderContext.utils.contextify(
|
||||
loaderContext.context || loaderContext.rootContext,
|
||||
resolve(REPO_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss')
|
||||
)
|
||||
);
|
||||
return `@import ${req};\n${content}`;
|
||||
},
|
||||
implementation: require('sass-embedded'),
|
||||
sassOptions: {
|
||||
includePaths: [resolve(REPO_ROOT, 'node_modules')],
|
||||
quietDeps: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [new NodeLibsBrowserPlugin(), new IgnoreNotFoundExportPlugin()],
|
||||
|
@ -147,74 +61,5 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
|
|||
stats: 'errors-only',
|
||||
};
|
||||
|
||||
// Override storybookConfig mainFields instead of merging with config
|
||||
delete storybookConfig.resolve?.mainFields;
|
||||
|
||||
const updatedModuleRules: webpack.RuleSetRule[] = [];
|
||||
// clone and modify the module.rules config provided by storybook so that the default babel plugins run after the typescript preset
|
||||
for (const originalRule of storybookConfig.module?.rules ?? []) {
|
||||
const rule = typeof originalRule !== 'string' ? { ...originalRule } : {};
|
||||
updatedModuleRules.push(rule);
|
||||
|
||||
if (isBabelLoaderRule(rule)) {
|
||||
rule.use = [...rule.use];
|
||||
const loader = (rule.use[0] = { ...rule.use[0] });
|
||||
const options = (loader.options = { ...(loader.options as Record<string, any>) });
|
||||
|
||||
// capture the plugins defined at the root level
|
||||
const plugins: string[] = options.plugins ?? [];
|
||||
options.plugins = [];
|
||||
|
||||
// move the plugins to the top of the preset array so they will run after the typescript preset
|
||||
options.presets = [
|
||||
require.resolve('@kbn/babel-preset/common_preset'),
|
||||
{ plugins },
|
||||
...(options.presets as Preset[]).filter(isDesiredPreset).map((preset) => {
|
||||
const tsPreset = getTsPreset(preset);
|
||||
if (!tsPreset) {
|
||||
return preset;
|
||||
}
|
||||
|
||||
return [
|
||||
tsPreset[0],
|
||||
{
|
||||
...tsPreset[1],
|
||||
allowNamespaces: true,
|
||||
allowDeclareFields: true,
|
||||
},
|
||||
];
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// copy and modify the webpack plugins added by storybook
|
||||
const filteredStorybookPlugins = [];
|
||||
for (const plugin of storybookConfig.plugins ?? []) {
|
||||
// Remove the progress plugin
|
||||
if (isProgressPlugin(plugin)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is the hacky part. We find something that looks like the
|
||||
// HtmlWebpackPlugin and mutate its `options.template` to point at our
|
||||
// revised template.
|
||||
if (isHtmlPlugin(plugin)) {
|
||||
plugin.options.template = require.resolve('../templates/index.ejs');
|
||||
}
|
||||
|
||||
filteredStorybookPlugins.push(plugin);
|
||||
}
|
||||
|
||||
return webpackMerge<object>(
|
||||
{
|
||||
...storybookConfig,
|
||||
plugins: filteredStorybookPlugins,
|
||||
module: {
|
||||
...storybookConfig.module,
|
||||
rules: updatedModuleRules,
|
||||
},
|
||||
},
|
||||
config
|
||||
);
|
||||
return webpackMerge(storybookConfig, config);
|
||||
};
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- This is a copy of the
|
||||
[Storybook IFrame template](https://github.com/storybookjs/storybook/blob/337fdcd0fe7436b46bcca65145ff6db2affd780f/lib/core-common/src/templates/index.ejs).
|
||||
We use this one instead because we want to add the @kbn/ui-shared-deps-* tags here.
|
||||
-->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>
|
||||
<%= htmlWebpackPlugin.options.title || 'Storybook' %>
|
||||
</title>
|
||||
|
||||
<% if (htmlWebpackPlugin.files.favicon) { %>
|
||||
<link rel="shortcut icon" href="<%= htmlWebpackPlugin.files.favicon%>" />
|
||||
<% } %>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="eui-global" />
|
||||
<meta name="emotion" />
|
||||
|
||||
<!-- Added for Kibana shared dependencies -->
|
||||
<script>
|
||||
window.__kbnPublicPath__ = { 'kbn-ui-shared-deps-npm': '', 'kbn-ui-shared-deps-src': '' };
|
||||
window.__kbnHardenPrototypes__ = false;
|
||||
</script>
|
||||
<script src="kbn-ui-shared-deps-npm.dll.js"></script>
|
||||
<script src="kbn-ui-shared-deps-src.js"></script>
|
||||
<link href="kbn-ui-shared-deps-src.css" rel="stylesheet" />
|
||||
<!-- -->
|
||||
|
||||
<% if (typeof headHtmlSnippet !=='undefined' ) { %>
|
||||
<%= headHtmlSnippet %>
|
||||
<% } %>
|
||||
<% htmlWebpackPlugin.files.css.forEach(file=> { %>
|
||||
<link href="<%= file %>" rel="stylesheet" />
|
||||
<% }); %>
|
||||
|
||||
<style>
|
||||
#root[hidden],
|
||||
#docs-root[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@300..700&family=Roboto+Mono:ital,wght@0,400..700;1,400..700&display=swap"
|
||||
rel="stylesheet">
|
||||
<meta name="eui-utilities" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<% if (typeof bodyHtmlSnippet !=='undefined' ) { %>
|
||||
<%= bodyHtmlSnippet %>
|
||||
<% } %>
|
||||
|
||||
<div id="root"></div>
|
||||
<div id="docs-root"></div>
|
||||
|
||||
<% if (typeof globals !=='undefined' && Object.keys(globals).length) { %>
|
||||
<script>
|
||||
<% for (var varName in globals) { %>
|
||||
<% if (globals[varName] != undefined) { %>
|
||||
window['<%=varName%>'] = <%= JSON.stringify(globals[varName]) %>;
|
||||
<% } %>
|
||||
<% } %>
|
||||
</script>
|
||||
<% } %>
|
||||
|
||||
<% htmlWebpackPlugin.files.js.forEach(file=> { %>
|
||||
<script src="<%= file %>"></script>
|
||||
<% }); %>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -7,7 +7,6 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { EuiFlexGroup } from '@elastic/eui';
|
||||
import { DataViewField } from '@kbn/data-views-plugin/public';
|
||||
|
@ -36,13 +35,26 @@ const renderFieldName = (fldName: React.ReactNode) => {
|
|||
);
|
||||
};
|
||||
|
||||
storiesOf('components/FieldName/FieldNameStories', module)
|
||||
.add('default', () => renderFieldName(<FieldName fieldName={'Discover test'} />))
|
||||
.add('with field type', () =>
|
||||
renderFieldName(<FieldName fieldName={'Discover test'} fieldType={'number'} />)
|
||||
)
|
||||
.add('with field mapping', () =>
|
||||
export default {
|
||||
title: 'components/FieldName/FieldNameStories',
|
||||
};
|
||||
|
||||
export const Default = {
|
||||
render: () => renderFieldName(<FieldName fieldName={'Discover test'} />),
|
||||
name: 'default',
|
||||
};
|
||||
|
||||
export const WithFieldType = {
|
||||
render: () => renderFieldName(<FieldName fieldName={'Discover test'} fieldType={'number'} />),
|
||||
|
||||
name: 'with field type',
|
||||
};
|
||||
|
||||
export const WithFieldMapping = {
|
||||
render: () =>
|
||||
renderFieldName(
|
||||
<FieldName fieldName={'Discover test'} fieldMapping={field} fieldType={'number'} />
|
||||
)
|
||||
);
|
||||
),
|
||||
|
||||
name: 'with field mapping',
|
||||
};
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { ComponentStory } from '@storybook/react';
|
||||
import type { Meta, StoryFn } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { Tab, type TabProps } from '../tab';
|
||||
import { STORYBOOK_TITLE } from './storybook_constants';
|
||||
import { MAX_TAB_WIDTH, MIN_TAB_WIDTH } from '../../constants';
|
||||
|
||||
const asyncAction =
|
||||
|
@ -21,14 +20,14 @@ const asyncAction =
|
|||
};
|
||||
|
||||
export default {
|
||||
title: `${STORYBOOK_TITLE}/Tab`,
|
||||
title: 'Unified Tabs/Tab',
|
||||
parameters: {
|
||||
backgrounds: {
|
||||
default: 'white',
|
||||
values: [{ name: 'white', value: '#fff' }],
|
||||
},
|
||||
},
|
||||
};
|
||||
} as Meta;
|
||||
|
||||
const tabsSizeConfig = {
|
||||
isScrollable: false,
|
||||
|
@ -36,7 +35,7 @@ const tabsSizeConfig = {
|
|||
regularTabMinWidth: MIN_TAB_WIDTH,
|
||||
};
|
||||
|
||||
const TabTemplate: ComponentStory<React.FC<TabProps>> = (args) => (
|
||||
const TabTemplate: StoryFn<TabProps> = (args) => (
|
||||
<Tab
|
||||
{...args}
|
||||
tabsSizeConfig={tabsSizeConfig}
|
||||
|
|
|
@ -8,23 +8,22 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { ComponentStory } from '@storybook/react';
|
||||
import type { Meta, StoryFn } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { TabbedContent, type TabbedContentProps } from '../tabbed_content';
|
||||
import { useNewTabProps } from '../../hooks/use_new_tab_props';
|
||||
import { STORYBOOK_TITLE } from './storybook_constants';
|
||||
|
||||
export default {
|
||||
title: `${STORYBOOK_TITLE}/Tabs`,
|
||||
title: 'Unified Tabs/Tabs',
|
||||
parameters: {
|
||||
backgrounds: {
|
||||
default: 'white',
|
||||
values: [{ name: 'white', value: '#fff' }],
|
||||
},
|
||||
},
|
||||
};
|
||||
} as Meta;
|
||||
|
||||
const TabbedContentTemplate: ComponentStory<React.FC<TabbedContentProps>> = (args) => {
|
||||
const TabbedContentTemplate: StoryFn<TabbedContentProps> = (args) => {
|
||||
const { getNewTabDefaultProps } = useNewTabProps({
|
||||
numberOfInitialItems: args.initialItems.length,
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ import { I18nProvider } from '@kbn/i18n-react';
|
|||
import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import type { DecoratorFn } from '@storybook/react';
|
||||
import type { Decorator } from '@storybook/react';
|
||||
import type { CoreTheme } from '@kbn/core-theme-browser';
|
||||
import type { I18nStart } from '@kbn/core-i18n-browser';
|
||||
|
||||
|
@ -35,7 +35,7 @@ const i18n: I18nStart = {
|
|||
Context: ({ children }) => <I18nProvider>{children}</I18nProvider>,
|
||||
};
|
||||
|
||||
export const KibanaContextDecorator: DecoratorFn = (storyFn, { globals }) => {
|
||||
export const KibanaContextDecorator: Decorator (storyFn, { globals }) => {
|
||||
const colorMode = globals.euiTheme === 'v8.dark' ? 'dark' : 'light';
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import type { DecoratorFn } from '@storybook/react';
|
||||
import type { Decorator } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import * as styledComponents from 'styled-components';
|
||||
|
@ -52,7 +52,7 @@ const KibanaStyledComponentsThemeProvider = <
|
|||
*
|
||||
* @deprecated All Kibana components need to migrate to Emotion.
|
||||
*/
|
||||
export const KibanaStyledComponentsThemeProviderDecorator: DecoratorFn = (storyFn, { globals }) => {
|
||||
export const KibanaStyledComponentsThemeProviderDecorator: Decorator = (storyFn, { globals }) => {
|
||||
const darkMode = globals.euiTheme === 'v8.dark' || globals.euiTheme === 'v7.dark';
|
||||
|
||||
return (
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { addons } from '@storybook/addons';
|
||||
import { addons } from '@storybook/manager-api';
|
||||
import { create } from '@storybook/theming';
|
||||
import { PANEL_ID as selectedPanel } from '@storybook/addon-actions';
|
||||
|
||||
|
|
|
@ -25,46 +25,50 @@ const argTypes = {
|
|||
|
||||
type KnownSolutionParams = Pick<KnownSolutionProps, 'size' | 'name'>;
|
||||
|
||||
export const SolutionType = (params: KnownSolutionParams) => {
|
||||
return <KibanaSolutionAvatar {...params} />;
|
||||
};
|
||||
|
||||
SolutionType.argTypes = {
|
||||
name: {
|
||||
control: 'select',
|
||||
options: ['Cloud', 'Elastic', 'Kibana', 'Observability', 'Security', 'Enterprise Search'],
|
||||
defaultValue: 'Elastic',
|
||||
export const SolutionType = {
|
||||
render: (params: KnownSolutionParams) => {
|
||||
return <KibanaSolutionAvatar {...params} />;
|
||||
},
|
||||
|
||||
argTypes: {
|
||||
name: {
|
||||
control: 'select',
|
||||
options: ['Cloud', 'Elastic', 'Kibana', 'Observability', 'Security', 'Enterprise Search'],
|
||||
defaultValue: 'Elastic',
|
||||
},
|
||||
...argTypes,
|
||||
},
|
||||
...argTypes,
|
||||
};
|
||||
|
||||
type IconTypeParams = Pick<IconTypeProps, 'size' | 'name' | 'iconType'>;
|
||||
|
||||
export const IconType = (params: IconTypeParams) => {
|
||||
return <KibanaSolutionAvatar {...params} />;
|
||||
};
|
||||
export const IconType = {
|
||||
render: (params: IconTypeParams) => {
|
||||
return <KibanaSolutionAvatar {...params} />;
|
||||
},
|
||||
|
||||
IconType.argTypes = {
|
||||
iconType: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'logoCloud',
|
||||
'logoElastic',
|
||||
'logoElasticsearch',
|
||||
'logoElasticStack',
|
||||
'logoKibana',
|
||||
'logoObservability',
|
||||
'logoSecurity',
|
||||
'logoSiteSearch',
|
||||
'logoWorkplaceSearch',
|
||||
'machineLearningApp',
|
||||
'managementApp',
|
||||
],
|
||||
defaultValue: 'logoElastic',
|
||||
argTypes: {
|
||||
iconType: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'logoCloud',
|
||||
'logoElastic',
|
||||
'logoElasticsearch',
|
||||
'logoElasticStack',
|
||||
'logoKibana',
|
||||
'logoObservability',
|
||||
'logoSecurity',
|
||||
'logoSiteSearch',
|
||||
'logoWorkplaceSearch',
|
||||
'machineLearningApp',
|
||||
'managementApp',
|
||||
],
|
||||
defaultValue: 'logoElastic',
|
||||
},
|
||||
name: {
|
||||
control: 'text',
|
||||
defaultValue: 'Solution Name',
|
||||
},
|
||||
...argTypes,
|
||||
},
|
||||
name: {
|
||||
control: 'text',
|
||||
defaultValue: 'Solution Name',
|
||||
},
|
||||
...argTypes,
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
> {
|
||||
propArguments = {
|
||||
toggleChrome: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: true,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -31,12 +31,14 @@ export default {
|
|||
|
||||
const mock = new ExitFullScreenButtonStorybookMock();
|
||||
|
||||
export const ExitFullScreenButton = (params: ExitFullScreenButtonStorybookParams) => {
|
||||
return (
|
||||
<ExitFullScreenButtonProvider {...mock.getServices()}>
|
||||
<Component {...mock.getProps(params)} />
|
||||
</ExitFullScreenButtonProvider>
|
||||
);
|
||||
};
|
||||
export const ExitFullScreenButton = {
|
||||
render: (params: ExitFullScreenButtonStorybookParams) => {
|
||||
return (
|
||||
<ExitFullScreenButtonProvider {...mock.getServices()}>
|
||||
<Component {...mock.getProps(params)} />
|
||||
</ExitFullScreenButtonProvider>
|
||||
);
|
||||
},
|
||||
|
||||
ExitFullScreenButton.argTypes = mock.getArgumentTypes();
|
||||
argTypes: mock.getArgumentTypes(),
|
||||
};
|
||||
|
|
|
@ -65,8 +65,10 @@ const argTypes = {
|
|||
|
||||
type Params = Record<keyof typeof argTypes, any>;
|
||||
|
||||
export const IconButtonGroup = ({ buttonCount }: Params) => {
|
||||
return <Component legend="Example icon group" buttons={iconButtons.slice(0, buttonCount)} />;
|
||||
};
|
||||
export const IconButtonGroup = {
|
||||
render: ({ buttonCount }: Params) => {
|
||||
return <Component legend="Example icon group" buttons={iconButtons.slice(0, buttonCount)} />;
|
||||
},
|
||||
|
||||
IconButtonGroup.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -47,16 +47,18 @@ const argTypes = {
|
|||
|
||||
type Params = Record<keyof typeof argTypes, any>;
|
||||
|
||||
export const ToolbarButton = ({ buttonStyle, buttonType, iconSide }: Params) => {
|
||||
return (
|
||||
<Component
|
||||
as={buttonStyle}
|
||||
label="Toolbar button"
|
||||
iconType="lensApp"
|
||||
type={buttonType}
|
||||
iconSide={iconSide}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export const ToolbarButton = {
|
||||
render: ({ buttonStyle, buttonType, iconSide }: Params) => {
|
||||
return (
|
||||
<Component
|
||||
as={buttonStyle}
|
||||
label="Toolbar button"
|
||||
iconType="lensApp"
|
||||
type={buttonType}
|
||||
iconSide={iconSide}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
ToolbarButton.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -43,41 +43,43 @@ export default {
|
|||
argTypes,
|
||||
};
|
||||
|
||||
export const Popover = ({ showIcon, buttonType }: Params) => {
|
||||
return (
|
||||
<Component
|
||||
type={buttonType}
|
||||
label="Add element"
|
||||
iconType={showIcon ? 'plusInCircle' : undefined}
|
||||
panelPaddingSize="none"
|
||||
>
|
||||
{() => (
|
||||
<EuiContextMenu
|
||||
initialPanelId={0}
|
||||
panels={[
|
||||
{
|
||||
id: 0,
|
||||
title: 'Open editor',
|
||||
items: [
|
||||
{
|
||||
name: 'Lens',
|
||||
icon: 'lensApp',
|
||||
},
|
||||
{
|
||||
name: 'Maps',
|
||||
icon: 'logoMaps',
|
||||
},
|
||||
{
|
||||
name: 'TSVB',
|
||||
icon: 'visVisualBuilder',
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
export const Popover = {
|
||||
render: ({ showIcon, buttonType }: Params) => {
|
||||
return (
|
||||
<Component
|
||||
type={buttonType}
|
||||
label="Add element"
|
||||
iconType={showIcon ? 'plusInCircle' : undefined}
|
||||
panelPaddingSize="none"
|
||||
>
|
||||
{() => (
|
||||
<EuiContextMenu
|
||||
initialPanelId={0}
|
||||
panels={[
|
||||
{
|
||||
id: 0,
|
||||
title: 'Open editor',
|
||||
items: [
|
||||
{
|
||||
name: 'Lens',
|
||||
icon: 'lensApp',
|
||||
},
|
||||
{
|
||||
name: 'Maps',
|
||||
icon: 'logoMaps',
|
||||
},
|
||||
{
|
||||
name: 'TSVB',
|
||||
icon: 'visVisualBuilder',
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</Component>
|
||||
);
|
||||
},
|
||||
|
||||
Popover.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Story } from '@storybook/react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { EuiContextMenu } from '@elastic/eui';
|
||||
|
||||
|
@ -174,7 +174,7 @@ export default {
|
|||
},
|
||||
};
|
||||
|
||||
const Template: Story<{
|
||||
const Template: StoryFn<{
|
||||
solution: 'Generic' | 'Canvas' | 'Dashboard';
|
||||
iconButtonCount: number;
|
||||
showAddFromLibraryButton: boolean;
|
||||
|
@ -205,20 +205,29 @@ const Template: Story<{
|
|||
);
|
||||
};
|
||||
|
||||
export const Generic = Template.bind({});
|
||||
Generic.args = {
|
||||
...Template.args,
|
||||
solution: 'Generic',
|
||||
export const Generic = {
|
||||
render: Template,
|
||||
|
||||
args: {
|
||||
...Template.args,
|
||||
solution: 'Generic',
|
||||
},
|
||||
};
|
||||
|
||||
export const Canvas = Template.bind({});
|
||||
Canvas.args = {
|
||||
...Template.args,
|
||||
solution: 'Canvas',
|
||||
export const Canvas = {
|
||||
render: Template,
|
||||
|
||||
args: {
|
||||
...Template.args,
|
||||
solution: 'Canvas',
|
||||
},
|
||||
};
|
||||
|
||||
export const Dashboard = Template.bind({});
|
||||
Dashboard.args = {
|
||||
...Template.args,
|
||||
solution: 'Dashboard',
|
||||
export const Dashboard = {
|
||||
render: Template,
|
||||
|
||||
args: {
|
||||
...Template.args,
|
||||
solution: 'Dashboard',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -30,12 +30,14 @@ export default {
|
|||
const mock = new NoDataCardStorybookMock();
|
||||
const argTypes = mock.getArgumentTypes();
|
||||
|
||||
export const Card = (params: NoDataCardStorybookParams) => {
|
||||
return (
|
||||
<NoDataCardProvider {...mock.getServices(params)}>
|
||||
<NoDataCard {...params} />
|
||||
</NoDataCardProvider>
|
||||
);
|
||||
};
|
||||
export const Card = {
|
||||
render: (params: NoDataCardStorybookParams) => {
|
||||
return (
|
||||
<NoDataCardProvider {...mock.getServices(params)}>
|
||||
<NoDataCard {...params} />
|
||||
</NoDataCardProvider>
|
||||
);
|
||||
},
|
||||
|
||||
Card.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -35,25 +35,25 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
propArguments = {
|
||||
category: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: '',
|
||||
},
|
||||
title: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: '',
|
||||
},
|
||||
description: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: '',
|
||||
},
|
||||
button: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: '',
|
||||
},
|
||||
|
@ -61,7 +61,7 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
|
||||
serviceArguments = {
|
||||
canAccessFleet: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: true,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ export class StorybookMock extends AbstractStorybookMock<{}, NavigationServices>
|
|||
|
||||
serviceArguments = {
|
||||
isSideNavCollapsed: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Meta } from '@storybook/react';
|
||||
import React, { EventHandler, FC, MouseEvent, useState, useEffect } from 'react';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
|
@ -530,4 +530,4 @@ export default {
|
|||
},
|
||||
},
|
||||
component: GeneralLayoutStructure,
|
||||
} as ComponentMeta<typeof GeneralLayoutStructure>;
|
||||
} as Meta<typeof GeneralLayoutStructure>;
|
||||
|
|
|
@ -31,19 +31,21 @@ export default {
|
|||
const mock = new CodeEditorStorybookMock();
|
||||
const argTypes = mock.getArgumentTypes();
|
||||
|
||||
export const Basic = (params: CodeEditorStorybookParams) => {
|
||||
return (
|
||||
<CodeEditor
|
||||
{...params}
|
||||
languageId="plainText"
|
||||
onChange={action('on change')}
|
||||
value="Hello!"
|
||||
height={200}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export const Basic = {
|
||||
render: (params: CodeEditorStorybookParams) => {
|
||||
return (
|
||||
<CodeEditor
|
||||
{...params}
|
||||
languageId="plainText"
|
||||
onChange={action('on change')}
|
||||
value="Hello!"
|
||||
height={200}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
Basic.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
||||
// A sample language definition with a few example tokens
|
||||
// Taken from https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
|
||||
|
@ -66,25 +68,27 @@ const logs = `[Sun Mar 7 20:54:27 2004] [notice] [client xx.xx.xx.xx] This is a
|
|||
[Sun Mar 7 21:16:17 2004] [error] [client xx.xx.xx.xx] File does not exist: /home/httpd/twiki/view/Main/WebHome
|
||||
`;
|
||||
|
||||
export const CustomLogLanguage = (params: CodeEditorStorybookParams) => {
|
||||
return (
|
||||
<div>
|
||||
<CodeEditor
|
||||
{...params}
|
||||
languageId="loglang"
|
||||
height={250}
|
||||
value={logs}
|
||||
options={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export const CustomLogLanguage = {
|
||||
render: (params: CodeEditorStorybookParams) => {
|
||||
return (
|
||||
<div>
|
||||
<CodeEditor
|
||||
{...params}
|
||||
languageId="loglang"
|
||||
height={250}
|
||||
value={logs}
|
||||
options={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
CustomLogLanguage.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
||||
export const JSONSupport = () => {
|
||||
return (
|
||||
|
@ -207,24 +211,26 @@ export const HoverProvider = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export const AutomaticResize = (params: CodeEditorStorybookParams) => {
|
||||
return (
|
||||
<div style={{ height: `calc(100vh - 30px)` }}>
|
||||
<CodeEditor
|
||||
{...params}
|
||||
languageId="plainText"
|
||||
onChange={action('on change')}
|
||||
value="Hello!"
|
||||
height={'100%'}
|
||||
options={{ automaticLayout: true }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
export const AutomaticResize = {
|
||||
render: (params: CodeEditorStorybookParams) => {
|
||||
return (
|
||||
<div style={{ height: `calc(100vh - 30px)` }}>
|
||||
<CodeEditor
|
||||
{...params}
|
||||
languageId="plainText"
|
||||
onChange={action('on change')}
|
||||
value="Hello!"
|
||||
height={'100%'}
|
||||
options={{ automaticLayout: true }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
argTypes,
|
||||
};
|
||||
|
||||
AutomaticResize.argTypes = argTypes;
|
||||
|
||||
export const FitToContent = (params: CodeEditorStorybookParams) => {
|
||||
const FitToContentComponent = (params: CodeEditorStorybookParams) => {
|
||||
const [value, setValue] = useState('hello');
|
||||
return (
|
||||
<CodeEditor
|
||||
|
@ -241,4 +247,8 @@ export const FitToContent = (params: CodeEditorStorybookParams) => {
|
|||
);
|
||||
};
|
||||
|
||||
FitToContent.argTypes = argTypes;
|
||||
export const FitToContent = {
|
||||
render: (params: CodeEditorStorybookParams) => <FitToContentComponent {...params} />,
|
||||
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -35,38 +35,38 @@ export class CodeEditorStorybookMock extends AbstractStorybookMock<
|
|||
propArguments = {
|
||||
languageId: {
|
||||
control: {
|
||||
type: 'radio',
|
||||
control: 'radio',
|
||||
},
|
||||
options: ['json', 'loglang', 'plaintext'],
|
||||
defaultValue: 'json',
|
||||
},
|
||||
value: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: '',
|
||||
},
|
||||
'aria-label': {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: 'code editor',
|
||||
},
|
||||
allowFullScreen: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
control: 'boolean',
|
||||
},
|
||||
defaultValue: false,
|
||||
},
|
||||
transparentBackground: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
control: 'boolean',
|
||||
},
|
||||
defaultValue: false,
|
||||
},
|
||||
placeholder: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: 'myplaceholder',
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { Meta, Story } from '@storybook/react';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiFormFieldset } from '@elastic/eui';
|
||||
|
@ -32,7 +32,7 @@ export default {
|
|||
},
|
||||
} as Meta;
|
||||
|
||||
export const ErrorInCallout: Story = () => {
|
||||
export const ErrorInCallout: StoryFn = () => {
|
||||
const services = storybookMock.getServices();
|
||||
|
||||
return (
|
||||
|
@ -46,7 +46,7 @@ export const ErrorInCallout: Story = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export const SectionErrorInCallout: Story = () => {
|
||||
export const SectionErrorInCallout: StoryFn = () => {
|
||||
const services = storybookMock.getServices();
|
||||
|
||||
return (
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { Meta, Story } from '@storybook/react';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiFormFieldset } from '@elastic/eui';
|
||||
|
@ -34,7 +34,7 @@ export default {
|
|||
},
|
||||
} as Meta;
|
||||
|
||||
export const ErrorInCallout: Story = () => {
|
||||
export const ErrorInCallout: StoryFn = () => {
|
||||
const services = storybookMock.getServices();
|
||||
|
||||
return (
|
||||
|
@ -48,7 +48,7 @@ export const ErrorInCallout: Story = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export const SectionErrorInCallout: Story = () => {
|
||||
export const SectionErrorInCallout: StoryFn = () => {
|
||||
const services = storybookMock.getServices();
|
||||
|
||||
return (
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
||||
import { Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { base64dLogo } from '@kbn/shared-ux-file-image-mocks';
|
||||
import type { FileImageMetadata, FileKindBrowser } from '@kbn/shared-ux-file-types';
|
||||
|
@ -17,6 +17,7 @@ import { FilesContext } from '@kbn/shared-ux-file-context';
|
|||
import { FilePicker, Props as FilePickerProps } from './file_picker';
|
||||
|
||||
type ListResponse = ReturnType<FilesClient['list']>;
|
||||
type MetaDecorators = Pick<Meta, 'decorators'>;
|
||||
|
||||
const kind = 'filepicker';
|
||||
const getFileKind = (id: string) =>
|
||||
|
@ -58,11 +59,9 @@ export default {
|
|||
</FilesContext>
|
||||
),
|
||||
],
|
||||
} as ComponentMeta<typeof FilePicker>;
|
||||
} as Meta<typeof FilePicker>;
|
||||
|
||||
const Template: ComponentStory<typeof FilePicker> = (props) => <FilePicker {...props} />;
|
||||
|
||||
export const Empty = Template.bind({});
|
||||
export const Empty = {};
|
||||
|
||||
const d = new Date();
|
||||
let id = 0;
|
||||
|
@ -85,47 +84,17 @@ function createFileJSON(file?: Partial<FileJSON<FileImageMetadata>>): FileJSON<F
|
|||
...file,
|
||||
};
|
||||
}
|
||||
export const BasicOne = Template.bind({});
|
||||
BasicOne.decorators = [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async (): ListResponse => ({
|
||||
files: [createFileJSON()],
|
||||
total: 1,
|
||||
}),
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
];
|
||||
|
||||
export const BasicMany = Template.bind({});
|
||||
BasicMany.decorators = [
|
||||
(Story) => {
|
||||
const files = [
|
||||
createFileJSON({ name: 'abc' }),
|
||||
createFileJSON({ name: 'def' }),
|
||||
createFileJSON({ name: 'efg' }),
|
||||
createFileJSON({ name: 'foo' }),
|
||||
createFileJSON({ name: 'bar' }),
|
||||
createFileJSON(),
|
||||
createFileJSON(),
|
||||
];
|
||||
|
||||
return (
|
||||
export const BasicOne: MetaDecorators = {
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async (): ListResponse => ({
|
||||
files,
|
||||
total: files.length,
|
||||
files: [createFileJSON()],
|
||||
total: 1,
|
||||
}),
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
|
@ -133,73 +102,80 @@ BasicMany.decorators = [
|
|||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
);
|
||||
},
|
||||
];
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const BasicManyMany = Template.bind({});
|
||||
BasicManyMany.decorators = [
|
||||
(Story) => {
|
||||
const array = new Array(102);
|
||||
array.fill(null);
|
||||
return (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async (): ListResponse => ({
|
||||
files: array.map((_, idx) => createFileJSON({ id: String(idx) })),
|
||||
total: array.length,
|
||||
}),
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
);
|
||||
},
|
||||
];
|
||||
export const BasicMany: MetaDecorators = {
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const files = [
|
||||
createFileJSON({ name: 'abc' }),
|
||||
createFileJSON({ name: 'def' }),
|
||||
createFileJSON({ name: 'efg' }),
|
||||
createFileJSON({ name: 'foo' }),
|
||||
createFileJSON({ name: 'bar' }),
|
||||
createFileJSON(),
|
||||
createFileJSON(),
|
||||
];
|
||||
|
||||
export const ErrorLoading = Template.bind({});
|
||||
ErrorLoading.decorators = [
|
||||
(Story) => {
|
||||
const array = new Array(102);
|
||||
array.fill(createFileJSON());
|
||||
return (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async () => {
|
||||
throw new Error('stop');
|
||||
},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
export const TryFilter = Template.bind({});
|
||||
TryFilter.decorators = [
|
||||
(Story) => {
|
||||
const array = { files: [createFileJSON()], total: 1 };
|
||||
return (
|
||||
<>
|
||||
<h2>Try entering a filter!</h2>
|
||||
return (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async ({ name }: { name: string[] }) => {
|
||||
if (name) {
|
||||
return { files: [], total: 0 };
|
||||
}
|
||||
return array;
|
||||
list: async (): ListResponse => ({
|
||||
files,
|
||||
total: files.length,
|
||||
}),
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
);
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const BasicManyMany: MetaDecorators = {
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const array = new Array(102);
|
||||
array.fill(null);
|
||||
return (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async (): ListResponse => ({
|
||||
files: array.map((_, idx) => createFileJSON({ id: String(idx) })),
|
||||
total: array.length,
|
||||
}),
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
);
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const ErrorLoading: MetaDecorators = {
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const array = new Array(102);
|
||||
array.fill(createFileJSON());
|
||||
return (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async () => {
|
||||
throw new Error('stop');
|
||||
},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
|
@ -207,30 +183,61 @@ TryFilter.decorators = [
|
|||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
</>
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
export const SingleSelect = Template.bind({});
|
||||
SingleSelect.decorators = [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async (): ListResponse => ({
|
||||
files: [createFileJSON(), createFileJSON(), createFileJSON()],
|
||||
total: 1,
|
||||
}),
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
];
|
||||
SingleSelect.args = {
|
||||
multiple: undefined,
|
||||
);
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const TryFilter: MetaDecorators = {
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const array = { files: [createFileJSON()], total: 1 };
|
||||
return (
|
||||
<>
|
||||
<h2>Try entering a filter!</h2>
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async ({ name }: { name: string[] }) => {
|
||||
if (name) {
|
||||
return { files: [], total: 0 };
|
||||
}
|
||||
return array;
|
||||
},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
</>
|
||||
);
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const SingleSelect: Partial<Meta> = {
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
getDownloadHref: () => `data:image/png;base64,${base64dLogo}`,
|
||||
list: async (): ListResponse => ({
|
||||
files: [createFileJSON(), createFileJSON(), createFileJSON()],
|
||||
total: 1,
|
||||
}),
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
],
|
||||
|
||||
args: {
|
||||
multiple: undefined,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { FileKindBrowser, BaseFilesClient as FilesClient } from '@kbn/shared-ux-file-types';
|
||||
import { FilesContext } from '@kbn/shared-ux-file-context';
|
||||
|
@ -65,150 +65,162 @@ export default {
|
|||
</FilesContext>
|
||||
),
|
||||
],
|
||||
} as ComponentMeta<typeof FileUpload>;
|
||||
} as Meta<typeof FileUpload>;
|
||||
|
||||
const Template: ComponentStory<typeof FileUpload> = (props: Props) => <FileUpload {...props} />;
|
||||
export const Basic = {};
|
||||
|
||||
export const Basic = Template.bind({});
|
||||
|
||||
export const AllowRepeatedUploads = Template.bind({});
|
||||
AllowRepeatedUploads.args = {
|
||||
allowRepeatedUploads: true,
|
||||
export const AllowRepeatedUploads = {
|
||||
args: {
|
||||
allowRepeatedUploads: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const LongErrorUX = Template.bind({});
|
||||
LongErrorUX.decorators = [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(1000);
|
||||
throw new Error('Something went wrong while uploading! '.repeat(10).trim());
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
];
|
||||
|
||||
export const Abort = Template.bind({});
|
||||
Abort.decorators = [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(60000);
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
];
|
||||
|
||||
export const MaxSize = Template.bind({});
|
||||
MaxSize.args = {
|
||||
kind: miniFile,
|
||||
export const LongErrorUX: StoryObj = {
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(1000);
|
||||
throw new Error('Something went wrong while uploading! '.repeat(10).trim());
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const ZipOnly = Template.bind({});
|
||||
ZipOnly.args = {
|
||||
kind: zipOnly,
|
||||
export const Abort: StoryObj = {
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(60000);
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const AllowClearAfterUpload = Template.bind({});
|
||||
AllowClearAfterUpload.args = {
|
||||
allowClear: true,
|
||||
export const MaxSize = {
|
||||
args: {
|
||||
kind: miniFile,
|
||||
},
|
||||
};
|
||||
|
||||
export const ImmediateUpload = Template.bind({});
|
||||
ImmediateUpload.args = {
|
||||
immediate: true,
|
||||
export const ZipOnly = {
|
||||
args: {
|
||||
kind: zipOnly,
|
||||
},
|
||||
};
|
||||
|
||||
export const ImmediateUploadError = Template.bind({});
|
||||
ImmediateUploadError.args = {
|
||||
immediate: true,
|
||||
};
|
||||
ImmediateUploadError.decorators = [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(1000);
|
||||
throw new Error('Something went wrong while uploading!');
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
];
|
||||
|
||||
export const ImmediateUploadAbort = Template.bind({});
|
||||
ImmediateUploadAbort.decorators = [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(60000);
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
];
|
||||
ImmediateUploadAbort.args = {
|
||||
immediate: true,
|
||||
export const AllowClearAfterUpload = {
|
||||
args: {
|
||||
allowClear: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Compressed = Template.bind({});
|
||||
Compressed.args = {
|
||||
compressed: true,
|
||||
export const ImmediateUpload = {
|
||||
args: {
|
||||
immediate: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const CompressedError = Template.bind({});
|
||||
CompressedError.args = {
|
||||
compressed: true,
|
||||
export const ImmediateUploadError: StoryObj = {
|
||||
args: {
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(1000);
|
||||
throw new Error('Something went wrong while uploading!');
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const ImmediateUploadAbort: StoryObj = {
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(60000);
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
],
|
||||
|
||||
args: {
|
||||
immediate: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Compressed = {
|
||||
args: {
|
||||
compressed: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const CompressedError: StoryObj = {
|
||||
args: {
|
||||
compressed: true,
|
||||
},
|
||||
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(1000);
|
||||
throw new Error('Something went wrong while uploading! '.repeat(10).trim());
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
],
|
||||
};
|
||||
CompressedError.decorators = [
|
||||
(Story) => (
|
||||
<FilesContext
|
||||
client={
|
||||
{
|
||||
create: async () => ({ file: { id: 'test' } }),
|
||||
upload: async () => {
|
||||
await sleep(1000);
|
||||
throw new Error('Something went wrong while uploading! '.repeat(10).trim());
|
||||
},
|
||||
delete: async () => {},
|
||||
getFileKind,
|
||||
} as unknown as FilesClient
|
||||
}
|
||||
>
|
||||
<Story />
|
||||
</FilesContext>
|
||||
),
|
||||
];
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
|
||||
import { getImageMetadata } from '@kbn/shared-ux-file-util';
|
||||
import { getImageData as getBlob, base64dLogo } from '@kbn/shared-ux-file-image-mocks';
|
||||
|
@ -38,47 +38,62 @@ export default {
|
|||
);
|
||||
},
|
||||
],
|
||||
} as ComponentMeta<typeof Image>;
|
||||
} as Meta<typeof Image>;
|
||||
|
||||
const Template: ComponentStory<typeof Image> = (props: Props, { loaded: { meta } }) => (
|
||||
const Template: StoryFn<typeof Image> = (props: Props, { loaded: { meta } }) => (
|
||||
<Image {...props} meta={meta} />
|
||||
);
|
||||
|
||||
export const Basic = Template.bind({});
|
||||
|
||||
export const WithBlurhash = Template.bind({});
|
||||
WithBlurhash.storyName = 'With blurhash';
|
||||
WithBlurhash.loaders = [
|
||||
async () => ({
|
||||
meta: await getImageMetadata(getBlob()),
|
||||
}),
|
||||
];
|
||||
|
||||
export const BrokenSrc = Template.bind({});
|
||||
BrokenSrc.storyName = 'Broken src';
|
||||
BrokenSrc.args = {
|
||||
src: 'foo',
|
||||
export const Basic = {
|
||||
render: Template,
|
||||
};
|
||||
|
||||
export const WithBlurhashAndBrokenSrc = Template.bind({});
|
||||
WithBlurhashAndBrokenSrc.storyName = 'With blurhash and broken src';
|
||||
WithBlurhashAndBrokenSrc.args = {
|
||||
src: 'foo',
|
||||
export const WithBlurhash = {
|
||||
render: Template,
|
||||
name: 'With blurhash',
|
||||
|
||||
loaders: [
|
||||
async () => ({
|
||||
meta: await getImageMetadata(getBlob()),
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
WithBlurhashAndBrokenSrc.loaders = [
|
||||
async () => ({
|
||||
blurhash: await getImageMetadata(getBlob()),
|
||||
}),
|
||||
];
|
||||
export const BrokenSrc = {
|
||||
render: Template,
|
||||
name: 'Broken src',
|
||||
|
||||
export const WithCustomSizing = Template.bind({});
|
||||
WithCustomSizing.storyName = 'With custom sizing';
|
||||
WithCustomSizing.loaders = [
|
||||
async () => ({
|
||||
meta: await getImageMetadata(getBlob()),
|
||||
}),
|
||||
];
|
||||
WithCustomSizing.args = {
|
||||
css: `width: 100px; height: 500px; object-fit: fill`,
|
||||
args: {
|
||||
src: 'foo',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithBlurhashAndBrokenSrc = {
|
||||
render: Template,
|
||||
name: 'With blurhash and broken src',
|
||||
|
||||
args: {
|
||||
src: 'foo',
|
||||
},
|
||||
|
||||
loaders: [
|
||||
async () => ({
|
||||
blurhash: await getImageMetadata(getBlob()),
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
export const WithCustomSizing = {
|
||||
render: Template,
|
||||
name: 'With custom sizing',
|
||||
|
||||
loaders: [
|
||||
async () => ({
|
||||
meta: await getImageMetadata(getBlob()),
|
||||
}),
|
||||
],
|
||||
|
||||
args: {
|
||||
css: `width: 100px; height: 500px; object-fit: fill`,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -28,46 +28,48 @@ export default {
|
|||
|
||||
const mock = new RedirectAppLinksStorybookMock();
|
||||
|
||||
export const RedirectAppLinks = () => {
|
||||
return (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<Component {...mock.getProps()}>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="storybookButton"
|
||||
iconType="plusInCircle"
|
||||
href="/some-test-url"
|
||||
>
|
||||
Button with URL
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="storybookButton"
|
||||
iconType="plusInCircle"
|
||||
onClick={action('onClick')}
|
||||
>
|
||||
Button without URL
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</Component>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiButton
|
||||
data-test-subj="storybookButton"
|
||||
iconType="plusInCircle"
|
||||
href="/?path=/story/redirect-app-links--component"
|
||||
>
|
||||
Button outside RedirectAppLinks
|
||||
</EuiButton>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
export const RedirectAppLinks = {
|
||||
render: () => {
|
||||
return (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<Component {...mock.getProps()}>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="storybookButton"
|
||||
iconType="plusInCircle"
|
||||
href="/some-test-url"
|
||||
>
|
||||
Button with URL
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="storybookButton"
|
||||
iconType="plusInCircle"
|
||||
onClick={action('onClick')}
|
||||
>
|
||||
Button without URL
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</Component>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiButton
|
||||
data-test-subj="storybookButton"
|
||||
iconType="plusInCircle"
|
||||
href="/?path=/story/redirect-app-links--component"
|
||||
>
|
||||
Button outside RedirectAppLinks
|
||||
</EuiButton>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
},
|
||||
|
||||
RedirectAppLinks.argTypes = mock.getArgumentTypes();
|
||||
argTypes: mock.getArgumentTypes(),
|
||||
};
|
||||
|
|
|
@ -28,15 +28,17 @@ export default {
|
|||
const mock = new MarkdownStorybookMock();
|
||||
const argTypes = mock.getArgumentTypes();
|
||||
|
||||
export const MarkdownStoryComponent = (params: MarkdownStorybookParams) => {
|
||||
return (
|
||||
// The markdown component is wrapped in the EuiFlexItem with width set to 50%
|
||||
// Height can be set for the markdown component
|
||||
<EuiFlexItem style={{ width: '400px' }}>
|
||||
{/* readOnly is set to false because the Markdown component editor will error if set to true without markdown content or children */}
|
||||
<Markdown {...params} readOnly={false} />
|
||||
</EuiFlexItem>
|
||||
);
|
||||
};
|
||||
export const MarkdownStoryComponent = {
|
||||
render: (params: MarkdownStorybookParams) => {
|
||||
return (
|
||||
// The markdown component is wrapped in the EuiFlexItem with width set to 50%
|
||||
// Height can be set for the markdown component
|
||||
<EuiFlexItem style={{ width: '400px' }}>
|
||||
{/* readOnly is set to false because the Markdown component editor will error if set to true without markdown content or children */}
|
||||
<Markdown {...params} readOnly={false} />
|
||||
</EuiFlexItem>
|
||||
);
|
||||
},
|
||||
|
||||
MarkdownStoryComponent.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -28,25 +28,27 @@ export default {
|
|||
const mock = new MarkdownStorybookMock();
|
||||
const argTypes = mock.getArgumentTypes();
|
||||
|
||||
export const MarkdownStoryComponent = (params: MarkdownStorybookParams) => {
|
||||
return (
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<Markdown
|
||||
{...params}
|
||||
readOnly={true}
|
||||
markdownContent={'My content in **markdown** format set as the *markdownContent prop*'}
|
||||
/>
|
||||
<Markdown {...params} readOnly={true}>
|
||||
{`My content in **markdown** format passed as *children*
|
||||
\`openLinksInNewTab\` [test link to open in new tab or not](https://www.elastic.co)
|
||||
\`enableTooltipSupport\` !{tooltip[anchor text](Tooltip content)}
|
||||
\`validateLinks\` [link with non-standard scheme](testing-testing-this-is-a-non-standatd-scheme://)
|
||||
`}
|
||||
</Markdown>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
export const MarkdownStoryComponent = {
|
||||
render: (params: MarkdownStorybookParams) => {
|
||||
return (
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<Markdown
|
||||
{...params}
|
||||
readOnly={true}
|
||||
markdownContent={'My content in **markdown** format set as the *markdownContent prop*'}
|
||||
/>
|
||||
<Markdown {...params} readOnly={true}>
|
||||
{`My content in **markdown** format passed as *children*
|
||||
\`openLinksInNewTab\` [test link to open in new tab or not](https://www.elastic.co)
|
||||
\`enableTooltipSupport\` !{tooltip[anchor text](Tooltip content)}
|
||||
\`validateLinks\` [link with non-standard scheme](testing-testing-this-is-a-non-standatd-scheme://)
|
||||
`}
|
||||
</Markdown>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
},
|
||||
|
||||
MarkdownStoryComponent.argTypes = argTypes;
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -35,49 +35,49 @@ export class MarkdownStorybookMock extends AbstractStorybookMock<
|
|||
> {
|
||||
propArguments = {
|
||||
readOnly: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
openLinksInNewTab: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: true,
|
||||
},
|
||||
placeholder: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: '',
|
||||
},
|
||||
markdownContent: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: '',
|
||||
},
|
||||
ariaLabelContent: {
|
||||
control: {
|
||||
type: 'text',
|
||||
control: 'text',
|
||||
},
|
||||
defaultValue: 'markdown component',
|
||||
},
|
||||
height: {
|
||||
control: {
|
||||
type: 'select',
|
||||
control: 'select',
|
||||
defaultValue: 'full',
|
||||
label: 'height',
|
||||
options: [0, 20, 50, 'full'],
|
||||
},
|
||||
},
|
||||
enableTooltipSupport: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
validateLinks: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
enableSoftLineBreaks: {
|
||||
control: 'boolean',
|
||||
control: { control: 'boolean' },
|
||||
defaultValue: false,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -25,47 +25,49 @@ export default {
|
|||
const mock = new TabbedModalStorybookMock();
|
||||
const argTypes = mock.getArgumentTypes();
|
||||
|
||||
export const TrivialExample = (params: TabbedModalStorybookParams) => {
|
||||
return (
|
||||
<TabbedModal
|
||||
{...params}
|
||||
modalTitle="Trivial Example"
|
||||
tabs={[
|
||||
{
|
||||
id: 'hello',
|
||||
name: 'Hello',
|
||||
content: () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiText>
|
||||
<p>Click the button to send a message into the void</p>
|
||||
</EuiText>
|
||||
</Fragment>
|
||||
);
|
||||
},
|
||||
initialState: {
|
||||
message: 'Hello World!!',
|
||||
},
|
||||
modalActionBtn: {
|
||||
id: 'wave',
|
||||
label: 'Say Hi 👋🏾',
|
||||
dataTestSubj: 'wave',
|
||||
handler: ({ state }) => {
|
||||
alert(state.message);
|
||||
export const TrivialExample = {
|
||||
render: (params: TabbedModalStorybookParams) => {
|
||||
return (
|
||||
<TabbedModal
|
||||
{...params}
|
||||
modalTitle="Trivial Example"
|
||||
tabs={[
|
||||
{
|
||||
id: 'hello',
|
||||
name: 'Hello',
|
||||
content: () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiText>
|
||||
<p>Click the button to send a message into the void</p>
|
||||
</EuiText>
|
||||
</Fragment>
|
||||
);
|
||||
},
|
||||
initialState: {
|
||||
message: 'Hello World!!',
|
||||
},
|
||||
modalActionBtn: {
|
||||
id: 'wave',
|
||||
label: 'Say Hi 👋🏾',
|
||||
dataTestSubj: 'wave',
|
||||
handler: ({ state }) => {
|
||||
alert(state.message);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]}
|
||||
defaultSelectedTabId="hello"
|
||||
onClose={() => {}}
|
||||
/>
|
||||
);
|
||||
]}
|
||||
defaultSelectedTabId="hello"
|
||||
onClose={() => {}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
argTypes,
|
||||
};
|
||||
|
||||
TrivialExample.argTypes = argTypes;
|
||||
|
||||
export const NonTrivialExample = (params: TabbedModalStorybookParams) => {
|
||||
const NonTrivialExampleComponent = (params: TabbedModalStorybookParams) => {
|
||||
const checkboxGroupItemId1 = useGeneratedHtmlId({
|
||||
prefix: 'checkboxGroupItem',
|
||||
suffix: 'first',
|
||||
|
@ -177,4 +179,8 @@ export const NonTrivialExample = (params: TabbedModalStorybookParams) => {
|
|||
);
|
||||
};
|
||||
|
||||
NonTrivialExample.argTypes = argTypes;
|
||||
export const NonTrivialExample = {
|
||||
render: (params: TabbedModalStorybookParams) => <NonTrivialExampleComponent {...params} />,
|
||||
|
||||
argTypes,
|
||||
};
|
||||
|
|
|
@ -31,19 +31,19 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
propArguments = {
|
||||
tabs: {
|
||||
control: {
|
||||
type: 'array',
|
||||
control: 'array',
|
||||
},
|
||||
defaultValue: [],
|
||||
},
|
||||
defaultSelectedTabId: {
|
||||
control: {
|
||||
type: 'array',
|
||||
control: 'array',
|
||||
},
|
||||
defaultValue: [],
|
||||
},
|
||||
onClose: {
|
||||
control: {
|
||||
type: 'array',
|
||||
control: 'array',
|
||||
},
|
||||
defaultValue: [],
|
||||
},
|
||||
|
|
|
@ -42,42 +42,50 @@ const solutionNavMock = new SolutionNavStorybookMock();
|
|||
const noDataConfigMock = new NoDataConfigStorybookMock();
|
||||
const innerMock = new InnerPageTemplateStorybookMock();
|
||||
|
||||
export const WithNoDataConfig = (params: NoDataConfigStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...noDataConfigMock.getServices(params)}>
|
||||
<Component {...noDataConfigMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
export const WithNoDataConfig = {
|
||||
render: (params: NoDataConfigStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...noDataConfigMock.getServices(params)}>
|
||||
<Component {...noDataConfigMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
},
|
||||
|
||||
argTypes: noDataConfigMock.getArgumentTypes(),
|
||||
};
|
||||
|
||||
WithNoDataConfig.argTypes = noDataConfigMock.getArgumentTypes();
|
||||
export const WithSolutionNav = {
|
||||
render: (params: SolutionNavStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...solutionNavMock.getServices(params)}>
|
||||
<Component {...solutionNavMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
},
|
||||
|
||||
export const WithSolutionNav = (params: SolutionNavStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...solutionNavMock.getServices(params)}>
|
||||
<Component {...solutionNavMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
argTypes: solutionNavMock.getArgumentTypes(),
|
||||
};
|
||||
|
||||
WithSolutionNav.argTypes = solutionNavMock.getArgumentTypes();
|
||||
export const WithBoth = {
|
||||
render: (params: KibanaPageTemplateStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...templateMock.getServices(params)}>
|
||||
<Component {...templateMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
},
|
||||
|
||||
export const WithBoth = (params: KibanaPageTemplateStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...templateMock.getServices(params)}>
|
||||
<Component {...templateMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
argTypes: templateMock.getArgumentTypes(),
|
||||
};
|
||||
|
||||
WithBoth.argTypes = templateMock.getArgumentTypes();
|
||||
export const WithNeither = {
|
||||
render: (params: InnerPageTemplateStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...innerMock.getServices(params)}>
|
||||
<Component {...innerMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
},
|
||||
|
||||
export const WithNeither = (params: InnerPageTemplateStorybookParams) => {
|
||||
return (
|
||||
<KibanaPageTemplateProvider {...innerMock.getServices(params)}>
|
||||
<Component {...innerMock.getProps(params)} />
|
||||
</KibanaPageTemplateProvider>
|
||||
);
|
||||
argTypes: innerMock.getArgumentTypes(),
|
||||
};
|
||||
|
||||
WithNeither.argTypes = innerMock.getArgumentTypes();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue