mirror of
https://github.com/grafana/grafana.git
synced 2024-11-21 16:38:03 -06:00
Chore: Bump storybook to v6 (#28926)
* Wip * feat: get storybook and app building locally * docs: comment webpack react alias * build(grafana-ui): put back ts-loader * build: prefer storybook essentials over actions and docs. bump dark-mode * chore(storybook): migrate to latest config * build: prevent test env throwing Invalid hook call errors * chore: lodash resolves to package dependency rather than project * use decorators as variable instead of function * perf(storybook): reduce bundling time by splitting type check and compilation * refactor(storybook): use sortOrder.order param to sort intro story first * build: use yarn workspace command * refactor(storybook): use previous knobs addon registration * migrate button story to controls * build(storybook): silence warnings in console * build: bump storybook related ts packages * style: remove trailing whitespace * refactor(graphng): export interface for storybook * controls migration guide * fix typo * docs(storybook): default docs to use dark theme as per current implementation * revert(grafana-ui): put back react-is namedExport this was changed for react 17 bump but causes rollup to fail during bundling * chore: bump storybook to 6.1, enable fastRefresh, silence eslint prop-types * docs(grafana-ui): move knobs -> controls migration guide to storybook style-guide * chore(storybook): silence terminal warning about order of docs addon * Update contribute/style-guides/storybook.md Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com> * Apply documentation suggestions Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com> * chore(storybook): bump to 6.1.2 Co-authored-by: Peter Holmberg <peter.hlmbrg@gmail.com> Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>
This commit is contained in:
parent
ce39e12e00
commit
0fc8426bf1
@ -64,13 +64,13 @@ To link a component’s stories with an MDX file you have to do this:
|
||||
```jsx
|
||||
// In TabsBar.story.tsx
|
||||
|
||||
import { TabsBar } from "./TabsBar";
|
||||
import { TabsBar } from './TabsBar';
|
||||
|
||||
// Import the MDX file
|
||||
import mdx from "./TabsBar.mdx";
|
||||
import mdx from './TabsBar.mdx';
|
||||
|
||||
export default {
|
||||
title: "General/Tabs/TabsBar",
|
||||
title: 'General/Tabs/TabsBar',
|
||||
component: TabsBar,
|
||||
parameters: {
|
||||
docs: {
|
||||
@ -93,8 +93,8 @@ There are some things that the MDX file should contain:
|
||||
```jsx
|
||||
// In MyComponent.mdx
|
||||
|
||||
import { Props } from "@storybook/addon-docs/blocks";
|
||||
import { MyComponent } from "./MyComponent";
|
||||
import { Props } from '@storybook/addon-docs/blocks';
|
||||
import { MyComponent } from './MyComponent';
|
||||
|
||||
<Props of={MyComponent} />;
|
||||
```
|
||||
@ -141,39 +141,66 @@ interface MyProps {
|
||||
}
|
||||
```
|
||||
|
||||
### Knobs
|
||||
### Controls
|
||||
|
||||
Knobs is an [addon to Storybook](https://github.com/storybookjs/storybook/tree/master/addons/knobs) which can be used to easily switch values in the UI. A good use case for it is to try different props for the component. Using knobs is easy. Grafana is set up so knobs can be used straight out of the box. Here is an example of how you might use it.
|
||||
The [controls addon](https://storybook.js.org/docs/react/essentials/controls) provides a way to interact with a component's properties dynamically and requires much less code than knobs. We're deprecating knobs in favor of using controls.
|
||||
|
||||
```jsx
|
||||
// In MyComponent.story.tsx
|
||||
#### Migrating a story from Knobs to Controls
|
||||
|
||||
import { number, text } from "@storybook/addon-knobs";
|
||||
As a test, we migrated the [button story](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/src/components/Button/Button.story.tsx). Here's the guide on how to migrate a story to controls.
|
||||
|
||||
export const basicStory = () => (
|
||||
<MyComponent
|
||||
max={number("Max value", 10)}
|
||||
min={number("Min value", -10)}
|
||||
title={text("Title", "Look at the value!")}
|
||||
/>
|
||||
);
|
||||
1. Remove the `@storybook/addon-knobs` dependency.
|
||||
2. Import the Story type from `@storybook/react`
|
||||
|
||||
`import { Story } from @storybook/react`
|
||||
|
||||
3. Import the props interface from the component you're working on (these must be exported in the component).
|
||||
|
||||
`import { Props } from './Component'`
|
||||
|
||||
4. Add the Story type to all stories in the file, then replace the props sent to the component
|
||||
and remove any knobs.
|
||||
|
||||
Before
|
||||
|
||||
```tsx
|
||||
export const Simple = () => {
|
||||
const prop1 = text('Prop1', 'Example text');
|
||||
const prop2 = select('Prop2', ['option1', 'option2'], 'option1');
|
||||
|
||||
return <Component prop1={prop1} prop2={prop2} />;
|
||||
};
|
||||
```
|
||||
|
||||
The general convention is that the first parameter of the knob is its name and the second is the default value. There are some more types:
|
||||
After
|
||||
|
||||
| Knob | Description |
|
||||
| --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `text` | Any text field |
|
||||
| `number` | Any number input. Also [available as range](https://github.com/storybookjs/storybook/tree/master/addons/knobs#number-bound-by-range) |
|
||||
| `boolean` | A switch between true/false |
|
||||
| `color` | Color picker |
|
||||
| `object` | JSON input or array. Good to use if the property requires more complex data structures. |
|
||||
| `array` | Array of strings separated by a comma |
|
||||
| `select` | Select a value from an options object. Good for trying different test cases. |
|
||||
| `options` | Configurable UI for selecting a range of options |
|
||||
| `files` | File selector |
|
||||
| `date` | Select date as stringified Unix timestamp |
|
||||
| `button` | Has a handler which is called when clicked |
|
||||
```tsx
|
||||
export const Simple: Story<Props> = ({ prop1, prop2 }) => {
|
||||
return <Component prop1={prop1} prop2={prop2} />;
|
||||
};
|
||||
```
|
||||
|
||||
5. Add default props (or args in Storybook language).
|
||||
|
||||
```tsx
|
||||
Simple.args = {
|
||||
prop1: 'Example text',
|
||||
prop2: 'option 1',
|
||||
};
|
||||
```
|
||||
|
||||
6. If the component has advanced props type (ie. other than string, number, boolean), you need to
|
||||
specify these in an `argTypes`. This is done in the default export of the story.
|
||||
|
||||
```tsx
|
||||
export default {
|
||||
title: 'Component/Component',
|
||||
component: Component,
|
||||
argTypes: {
|
||||
prop2: { control: { type: 'select', options: ['option1', 'option2'] } },
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
|
@ -20,6 +20,7 @@ module.exports = {
|
||||
'\\.svg': '<rootDir>/public/test/mocks/svg.ts',
|
||||
'\\.css': '<rootDir>/public/test/mocks/style.ts',
|
||||
'monaco-editor/esm/vs/editor/editor.api': '<rootDir>/public/test/mocks/monaco.ts',
|
||||
'^react($|/.+)': '<rootDir>/node_modules/react$1',
|
||||
},
|
||||
watchPathIgnorePatterns: ['<rootDir>/node_modules/'],
|
||||
};
|
||||
|
@ -35,8 +35,8 @@
|
||||
"start:ignoreTheme": "grafana-toolkit core:start --hot",
|
||||
"start:noTsCheck": "grafana-toolkit core:start --noTsCheck",
|
||||
"stats": "webpack --mode production --config scripts/webpack/webpack.prod.js --profile --json > compilation-stats.json",
|
||||
"storybook": "cd packages/grafana-ui && yarn storybook --ci",
|
||||
"storybook:build": "cd packages/grafana-ui && yarn storybook:build",
|
||||
"storybook": "yarn workspace @grafana/ui storybook --ci",
|
||||
"storybook:build": "yarn workspace @grafana/ui storybook:build",
|
||||
"themes:generate": "ts-node --project ./scripts/cli/tsconfig.json ./scripts/cli/generateSassVariableFiles.ts",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"plugins:build-bundled": "grafana-toolkit plugin:bundle-managed",
|
||||
@ -308,7 +308,10 @@
|
||||
],
|
||||
"nohoist": [
|
||||
"**/@types/*",
|
||||
"**/@types/*/**"
|
||||
"**/@types/*/**",
|
||||
"@storybook",
|
||||
"**/@storybook",
|
||||
"**/@storybook/**"
|
||||
]
|
||||
},
|
||||
"_moduleAliases": {
|
||||
|
@ -6,7 +6,8 @@
|
||||
{
|
||||
"files": ["**/*.{test,story}.{ts,tsx}"],
|
||||
"rules": {
|
||||
"no-restricted-imports": "off"
|
||||
"no-restricted-imports": "off",
|
||||
"react/prop-types": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1,3 +1,8 @@
|
||||
const path = require('path');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const FilterWarningsPlugin = require('webpack-filter-warnings-plugin');
|
||||
|
||||
const stories = ['../src/**/*.story.{js,jsx,ts,tsx,mdx}'];
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
@ -7,10 +12,140 @@ if (process.env.NODE_ENV !== 'production') {
|
||||
module.exports = {
|
||||
stories: stories,
|
||||
addons: [
|
||||
'@storybook/addon-docs',
|
||||
'@storybook/addon-controls',
|
||||
'@storybook/addon-knobs',
|
||||
'@storybook/addon-actions',
|
||||
'@storybook/addon-docs',
|
||||
'storybook-dark-mode/register',
|
||||
'@storybook/addon-storysource',
|
||||
],
|
||||
reactOptions: {
|
||||
fastRefresh: true,
|
||||
},
|
||||
typescript: {
|
||||
check: true,
|
||||
reactDocgen: 'react-docgen-typescript',
|
||||
reactDocgenTypescriptOptions: {
|
||||
shouldExtractLiteralValuesFromEnum: true,
|
||||
propFilter: (prop: any) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
|
||||
},
|
||||
},
|
||||
webpackFinal: async (config: any, { configType }: any) => {
|
||||
const isProductionBuild = configType === 'PRODUCTION';
|
||||
config.module.rules = [
|
||||
...(config.module.rules || []),
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('ts-loader'),
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
configFile: path.resolve(__dirname, 'tsconfig.json'),
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve('react-docgen-typescript-loader'),
|
||||
options: {
|
||||
tsconfigPath: path.resolve(__dirname, 'tsconfig.json'),
|
||||
// https://github.com/styleguidist/react-docgen-typescript#parseroptions
|
||||
// @ts-ignore
|
||||
propFilter: prop => {
|
||||
if (prop.parent) {
|
||||
return !prop.parent.fileName.includes('node_modules/@types/react/');
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader',
|
||||
options: { injectType: 'lazyStyleTag' },
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
importLoaders: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: false,
|
||||
config: { path: __dirname + '../../../../scripts/webpack/postcss.config.js' },
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sourceMap: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: require.resolve('jquery'),
|
||||
use: [
|
||||
{
|
||||
loader: 'expose-loader',
|
||||
query: 'jQuery',
|
||||
},
|
||||
{
|
||||
loader: 'expose-loader',
|
||||
query: '$',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
config.optimization = {
|
||||
nodeEnv: 'production',
|
||||
moduleIds: 'hashed',
|
||||
runtimeChunk: 'single',
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
minChunks: 1,
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/].*[jt]sx?$/,
|
||||
chunks: 'initial',
|
||||
priority: -10,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true,
|
||||
},
|
||||
default: {
|
||||
priority: -20,
|
||||
chunks: 'all',
|
||||
test: /.*[jt]sx?$/,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
minimize: isProductionBuild,
|
||||
minimizer: isProductionBuild
|
||||
? [
|
||||
new TerserPlugin({ cache: false, parallel: false, sourceMap: false, exclude: /monaco|bizcharts/ }),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
]
|
||||
: [],
|
||||
};
|
||||
|
||||
config.resolve.alias['@grafana/ui'] = path.resolve(__dirname, '..');
|
||||
|
||||
// Silence "export not found" webpack warnings with transpileOnly
|
||||
// https://github.com/TypeStrong/ts-loader#transpileonly
|
||||
config.plugins.push(
|
||||
new FilterWarningsPlugin({
|
||||
exclude: /export .* was not found in/,
|
||||
})
|
||||
);
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
||||
|
@ -15,8 +15,8 @@ import lightTheme from '../../../public/sass/grafana.light.scss';
|
||||
// @ts-ignore
|
||||
import darkTheme from '../../../public/sass/grafana.dark.scss';
|
||||
import { GrafanaLight, GrafanaDark } from './storybookTheme';
|
||||
import { configure, addDecorator, addParameters } from '@storybook/react';
|
||||
import { withKnobs } from '@storybook/addon-knobs';
|
||||
import { configure } from '@storybook/react';
|
||||
import addons from '@storybook/addons';
|
||||
|
||||
const handleThemeChange = (theme: any) => {
|
||||
if (theme !== 'light') {
|
||||
@ -27,37 +27,36 @@ const handleThemeChange = (theme: any) => {
|
||||
lightTheme.use();
|
||||
}
|
||||
};
|
||||
addDecorator(withTheme(handleThemeChange));
|
||||
addDecorator(withKnobs);
|
||||
addDecorator(withPaddedStory);
|
||||
|
||||
addParameters({
|
||||
addons.setConfig({
|
||||
showRoots: false,
|
||||
theme: GrafanaDark,
|
||||
});
|
||||
|
||||
export const decorators = [withTheme(handleThemeChange), withPaddedStory];
|
||||
|
||||
export const parameters = {
|
||||
info: {},
|
||||
docs: {
|
||||
theme: GrafanaDark,
|
||||
},
|
||||
darkMode: {
|
||||
dark: GrafanaDark,
|
||||
light: GrafanaLight,
|
||||
},
|
||||
options: {
|
||||
theme: GrafanaDark,
|
||||
showPanel: true,
|
||||
showRoots: true,
|
||||
panelPosition: 'right',
|
||||
showNav: true,
|
||||
isFullscreen: false,
|
||||
isToolshown: true,
|
||||
storySort: (a: any, b: any) => {
|
||||
if (a[1].kind.split('/')[0] === 'Docs Overview') {
|
||||
return -1;
|
||||
} else if (b[1].kind.split('/')[0] === 'Docs Overview') {
|
||||
return 1;
|
||||
}
|
||||
return a[1].id.localeCompare(b[1].id);
|
||||
storySort: {
|
||||
method: 'alphabetical',
|
||||
// Order Docs Overview and Docs Overview/Intro story first
|
||||
order: ['Docs Overview', ['Intro']],
|
||||
},
|
||||
},
|
||||
knobs: {
|
||||
escapeHTML: false,
|
||||
},
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
configure(require.context('../src', true, /\.story\.(js|jsx|ts|tsx|mdx)$/), module);
|
||||
};
|
||||
|
@ -1,121 +0,0 @@
|
||||
const path = require('path');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
module.exports = ({ config, mode }) => {
|
||||
const isProductionBuild = mode === 'PRODUCTION';
|
||||
config.module.rules = [
|
||||
...(config.module.rules || []),
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('ts-loader'),
|
||||
options: {
|
||||
// transpileOnly: true,
|
||||
configFile: path.resolve(__dirname, 'tsconfig.json'),
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve('react-docgen-typescript-loader'),
|
||||
options: {
|
||||
tsconfigPath: path.resolve(__dirname, 'tsconfig.json'),
|
||||
// https://github.com/styleguidist/react-docgen-typescript#parseroptions
|
||||
// @ts-ignore
|
||||
propFilter: prop => {
|
||||
if (prop.parent) {
|
||||
return !prop.parent.fileName.includes('node_modules/@types/react/');
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
config.module.rules.push({
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader',
|
||||
options: { injectType: 'lazyStyleTag' },
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
importLoaders: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: false,
|
||||
config: { path: __dirname + '../../../../scripts/webpack/postcss.config.js' },
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sourceMap: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
config.module.rules.push({
|
||||
test: require.resolve('jquery'),
|
||||
use: [
|
||||
{
|
||||
loader: 'expose-loader',
|
||||
query: 'jQuery',
|
||||
},
|
||||
{
|
||||
loader: 'expose-loader',
|
||||
query: '$',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
config.optimization = {
|
||||
nodeEnv: 'production',
|
||||
moduleIds: 'hashed',
|
||||
runtimeChunk: 'single',
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
minChunks: 1,
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/].*[jt]sx?$/,
|
||||
chunks: 'initial',
|
||||
priority: -10,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true,
|
||||
},
|
||||
default: {
|
||||
priority: -20,
|
||||
chunks: 'all',
|
||||
test: /.*[jt]sx?$/,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
minimize: isProductionBuild,
|
||||
minimizer: isProductionBuild
|
||||
? [
|
||||
new TerserPlugin({ cache: false, parallel: false, sourceMap: false, exclude: /monaco|bizcharts/ }),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
]
|
||||
: [],
|
||||
};
|
||||
|
||||
config.resolve.extensions.push('.ts', '.tsx', '.mdx');
|
||||
config.resolve.alias = config.resolve.alias || {};
|
||||
config.resolve.alias['@grafana/ui'] = path.resolve(__dirname, '..');
|
||||
|
||||
config.stats = {
|
||||
warningsFilter: /export .* was not found in/,
|
||||
};
|
||||
|
||||
return config;
|
||||
};
|
@ -17,3 +17,7 @@ See [package source](https://github.com/grafana/grafana/tree/master/packages/gra
|
||||
## Development
|
||||
|
||||
For development purposes we suggest using `yarn link` that will create symlink to @grafana/ui lib. To do so navigate to `packages/grafana-ui` and run `yarn link`. Then, navigate to your project and run `yarn link @grafana/ui` to use the linked version of the lib. To unlink follow the same procedure, but use `yarn unlink` instead.
|
||||
|
||||
### Storybook 6.x migration
|
||||
|
||||
We've upgraded Storybook to version 6 and with that we will convert to using [controls](https://storybook.js.org/docs/react/essentials/controls) instead of knobs for manipulating components. Controls will not require as much coding as knobs do. Please refer to the [storybook style-guide](https://github.com/grafana/grafana/blob/master/contribute/style-guides/storybook.md#contrls) for further information.
|
||||
|
@ -77,13 +77,12 @@
|
||||
"@rollup/plugin-commonjs": "11.0.2",
|
||||
"@rollup/plugin-image": "2.0.4",
|
||||
"@rollup/plugin-node-resolve": "7.1.1",
|
||||
"@storybook/addon-actions": "5.3.21",
|
||||
"@storybook/addon-docs": "5.3.21",
|
||||
"@storybook/addon-info": "5.3.21",
|
||||
"@storybook/addon-knobs": "5.3.21",
|
||||
"@storybook/addon-storysource": "5.3.21",
|
||||
"@storybook/react": "5.3.21",
|
||||
"@storybook/theming": "5.3.21",
|
||||
"@storybook/addon-essentials": "6.1.2",
|
||||
"@storybook/addon-controls": "6.1.2",
|
||||
"@storybook/addon-knobs": "6.1.2",
|
||||
"@storybook/addon-storysource": "6.1.2",
|
||||
"@storybook/react": "6.1.2",
|
||||
"@storybook/theming": "6.1.2",
|
||||
"@types/classnames": "2.2.7",
|
||||
"@types/common-tags": "^1.8.0",
|
||||
"@types/d3": "5.7.2",
|
||||
@ -101,16 +100,18 @@
|
||||
"@types/tinycolor2": "1.4.1",
|
||||
"common-tags": "^1.8.0",
|
||||
"pretty-format": "25.1.0",
|
||||
"react-docgen-typescript-loader": "3.7.1",
|
||||
"react-docgen-typescript-loader": "3.7.2",
|
||||
"react-test-renderer": "16.13.1",
|
||||
"react-is": "16.8.0",
|
||||
"rollup": "2.0.6",
|
||||
"rollup-plugin-sourcemaps": "0.5.0",
|
||||
"rollup-plugin-terser": "5.3.0",
|
||||
"rollup-plugin-typescript2": "0.26.0",
|
||||
"rollup-plugin-visualizer": "3.3.1",
|
||||
"storybook-dark-mode": "0.6.1",
|
||||
"ts-loader": "6.2.1",
|
||||
"typescript": "4.0.2"
|
||||
"storybook-dark-mode": "1.0.3",
|
||||
"ts-loader": "8.0.11",
|
||||
"typescript": "4.0.2",
|
||||
"webpack-filter-warnings-plugin": "1.2.1"
|
||||
},
|
||||
"types": "src/index.ts"
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ const buildCjsPackage = ({ env }) => {
|
||||
// When 'rollup-plugin-commonjs' fails to properly convert the CommonJS modules to ES6 one has to manually name the exports
|
||||
// https://github.com/rollup/rollup-plugin-commonjs#custom-named-exports
|
||||
namedExports: {
|
||||
'../../node_modules/lodash/lodash.js': [
|
||||
'node_modules/lodash/lodash.js': [
|
||||
'flatten',
|
||||
'find',
|
||||
'upperFirst',
|
||||
@ -82,8 +82,7 @@ const buildCjsPackage = ({ env }) => {
|
||||
'useAbsoluteLayout',
|
||||
'useFilters',
|
||||
],
|
||||
'../../node_modules/rc-tooltip/node_modules/react-is/index.js': ['isMemo'],
|
||||
'../../node_modules/rc-motion/node_modules/react-is/index.js': ['isMemo'],
|
||||
'../../node_modules/react-is/index.js': ['isMemo'],
|
||||
},
|
||||
}),
|
||||
resolve(),
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { Meta } from '@storybook/addon-docs/blocks';
|
||||
|
||||
<Meta title="Docs Overview/Intro" parameters={{ options: { isToolshown: false }, id: 1 }} />
|
||||
|
||||
# Grafana design system
|
||||
|
@ -1,15 +1,21 @@
|
||||
import React from 'react';
|
||||
import { select, text, boolean } from '@storybook/addon-knobs';
|
||||
import { Button, ButtonVariant } from '@grafana/ui';
|
||||
import { Story } from '@storybook/react';
|
||||
import { Button, ButtonProps } from './Button';
|
||||
import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
import { getIconKnob } from '../../utils/storybook/knobs';
|
||||
import { iconOptions } from '../../utils/storybook/knobs';
|
||||
import mdx from './Button.mdx';
|
||||
import { ComponentSize } from '../../types/size';
|
||||
|
||||
export default {
|
||||
title: 'Buttons/Button',
|
||||
component: Button,
|
||||
decorators: [withCenteredStory, withHorizontallyCenteredStory],
|
||||
argTypes: {
|
||||
variant: { control: { type: 'select', options: ['primary', 'secondary', 'destructive', 'link'] } },
|
||||
size: { control: { type: 'select', options: ['sm', 'md', 'lg'] } },
|
||||
icon: { control: { type: 'select', options: iconOptions } },
|
||||
css: { control: { disable: true } },
|
||||
className: { control: { disable: true } },
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
page: mdx,
|
||||
@ -17,19 +23,18 @@ export default {
|
||||
},
|
||||
};
|
||||
|
||||
const variants = ['primary', 'secondary', 'destructive', 'link'];
|
||||
|
||||
const sizes = ['sm', 'md', 'lg'];
|
||||
|
||||
export const simple = () => {
|
||||
const variant = select('Variant', variants, 'primary');
|
||||
const size = select('Size', sizes, 'md');
|
||||
const buttonText = text('Text', 'Button');
|
||||
const disabled = boolean('Disabled', false);
|
||||
const icon = getIconKnob();
|
||||
export const Simple: Story<ButtonProps> = ({ disabled, icon, children, size, variant }) => {
|
||||
return (
|
||||
<Button variant={variant as ButtonVariant} size={size as ComponentSize} icon={icon} disabled={disabled}>
|
||||
{buttonText}
|
||||
<Button variant={variant} size={size} icon={icon} disabled={disabled}>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
Simple.args = {
|
||||
variant: 'primary',
|
||||
size: 'md',
|
||||
disabled: false,
|
||||
children: 'Button',
|
||||
icon: undefined,
|
||||
};
|
||||
|
@ -8,7 +8,7 @@ import { LegendPlacement, LegendDisplayMode } from '../Legend/Legend';
|
||||
import { GraphSeriesXY, FieldType, ArrayVector, dateTime, FieldColorModeId } from '@grafana/data';
|
||||
|
||||
export default {
|
||||
title: 'Visualizations/Graph',
|
||||
title: 'Visualizations/Graph/GraphWithLegend',
|
||||
component: GraphWithLegend,
|
||||
decorator: [withCenteredStory],
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ import { useRevision } from '../uPlot/hooks';
|
||||
|
||||
const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1));
|
||||
|
||||
interface GraphNGProps extends Omit<PlotProps, 'data' | 'config'> {
|
||||
export interface GraphNGProps extends Omit<PlotProps, 'data' | 'config'> {
|
||||
data: DataFrame[];
|
||||
legend?: LegendOptions;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { InfoTooltip } from './InfoTooltip';
|
||||
import { Tooltip } from '../Chart/Tooltip';
|
||||
|
||||
export default {
|
||||
title: 'Overlays/Tooltip',
|
||||
title: 'Overlays/TooltipInternal',
|
||||
component: Tooltip,
|
||||
decorators: [withCenteredStory],
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ import { getAvailableIcons } from '../../types';
|
||||
|
||||
const VISUAL_GROUP = 'Visual options';
|
||||
|
||||
const iconOptions = {
|
||||
export const iconOptions = {
|
||||
None: undefined,
|
||||
...getAvailableIcons().reduce<Record<string, string>>((prev, c) => {
|
||||
return {
|
||||
|
@ -45,6 +45,9 @@ module.exports = {
|
||||
// rc-trigger uses babel-runtime which has internal dependency to core-js@2
|
||||
// this alias maps that dependency to core-js@t3
|
||||
'core-js/library/fn': 'core-js/stable',
|
||||
// storybook v6 bump caused the app to bundle multiple versions of react breaking hooks
|
||||
// make sure to resolve only from the project: https://github.com/facebook/react/issues/13991#issuecomment-435587809
|
||||
react: path.resolve(__dirname, '../../node_modules/react'),
|
||||
},
|
||||
modules: [
|
||||
'node_modules',
|
||||
|
Loading…
Reference in New Issue
Block a user