Storybook: Fix broken stories (#22975)

* Rewrite to CSF and make it not crash

* Move comments to be in generated docs

* Fix broken ThresholdsEditor story

* Fix breaking Select docs
This commit is contained in:
Tobias Skarhed
2020-03-23 17:54:48 +01:00
committed by GitHub
parent a43e31fbf9
commit aeb88015ab
7 changed files with 101 additions and 76 deletions
@@ -3,9 +3,18 @@ import { FormattedValue } from '../valueFormats';
export type DisplayProcessor = (value: any) => DisplayValue; export type DisplayProcessor = (value: any) => DisplayValue;
export interface DisplayValue extends FormattedValue { export interface DisplayValue extends FormattedValue {
numeric: number; // Use isNaN to check if it is a real number /**
percent?: number; // 0-1 between min & max * Use isNaN to check if it is a real number
color?: string; // color based on configs or Threshold */
numeric: number;
/**
* 0-1 between min & max
*/
percent?: number;
/**
* Color based on configs or Threshold
*/
color?: string;
title?: string; title?: string;
} }
+17 -3
View File
@@ -1,17 +1,31 @@
export interface Threshold { export interface Threshold {
value: number; value: number;
color: string; color: string;
state?: string; // Warning, Error, LowLow, Low, OK, High, HighHigh etc /**
* Warning, Error, LowLow, Low, OK, High, HighHigh etc
*/
state?: string;
} }
/**
* Display mode
*/
export enum ThresholdsMode { export enum ThresholdsMode {
Absolute = 'absolute', Absolute = 'absolute',
Percentage = 'percentage', // between 0 and 1 (based on min/max) /**
* between 0 and 1 (based on min/max)
*/
Percentage = 'percentage',
} }
/**
* Config that is passed to the ThresholdsEditor
*/
export interface ThresholdsConfig { export interface ThresholdsConfig {
mode: ThresholdsMode; mode: ThresholdsMode;
// Must be sorted by 'value', first value is always -Infinity /**
* Must be sorted by 'value', first value is always -Infinity
*/
steps: Threshold[]; steps: Threshold[];
} }
@@ -9,6 +9,7 @@ import { Button } from '../Button';
import { ButtonSelect } from './ButtonSelect'; import { ButtonSelect } from './ButtonSelect';
import { getIconKnob } from '../../../utils/storybook/knobs'; import { getIconKnob } from '../../../utils/storybook/knobs';
import kebabCase from 'lodash/kebabCase'; import kebabCase from 'lodash/kebabCase';
import { generateOptions } from './mockOptions';
export default { export default {
title: 'Forms/Select', title: 'Forms/Select',
@@ -16,36 +17,6 @@ export default {
decorators: [withCenteredStory, withHorizontallyCenteredStory], decorators: [withCenteredStory, withHorizontallyCenteredStory],
}; };
export const generateOptions = () => {
const values = [
'Sharilyn Markowitz',
'Naomi Striplin',
'Beau Bevel',
'Garrett Starkes',
'Hildegarde Pedro',
'Gudrun Seyler',
'Eboni Raines',
'Hye Felix',
'Chau Brito',
'Heidy Zook',
'Karima Husain',
'Virgil Mckinny',
'Kaley Dodrill',
'Sharan Ruf',
'Edgar Loveland',
'Judie Sanger',
'Season Bundrick',
'Ok Vicente',
'Garry Spitz',
'Han Harnish',
];
return values.map<SelectableValue<string>>(name => ({
value: kebabCase(name),
label: name,
}));
};
const loadAsyncOptions = () => { const loadAsyncOptions = () => {
return new Promise<Array<SelectableValue<string>>>(resolve => { return new Promise<Array<SelectableValue<string>>>(resolve => {
setTimeout(() => { setTimeout(() => {
@@ -0,0 +1,32 @@
import { SelectableValue } from '@grafana/data';
import { kebabCase } from 'lodash';
export const generateOptions = () => {
const values = [
'Sharilyn Markowitz',
'Naomi Striplin',
'Beau Bevel',
'Garrett Starkes',
'Hildegarde Pedro',
'Gudrun Seyler',
'Eboni Raines',
'Hye Felix',
'Chau Brito',
'Heidy Zook',
'Karima Husain',
'Virgil Mckinny',
'Kaley Dodrill',
'Sharan Ruf',
'Edgar Loveland',
'Judie Sanger',
'Season Bundrick',
'Ok Vicente',
'Garry Spitz',
'Han Harnish',
];
return values.map<SelectableValue<string>>(name => ({
value: kebabCase(name),
label: name,
}));
};
@@ -1,42 +1,35 @@
import { storiesOf } from '@storybook/react'; import React from 'react';
import { number, text, object } from '@storybook/addon-knobs'; import { number, object, select } from '@storybook/addon-knobs';
import { PieChart, PieChartType } from './PieChart'; import { PieChart, PieChartType } from './PieChart';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
export default {
title: 'Visualizations/PieChart',
decorators: [withCenteredStory],
component: PieChart,
};
const getKnobs = () => { const getKnobs = () => {
return { return {
datapoints: object('datapoints', [ datapoints: object('datapoints', [
{ {
value: 100, numeric: 100,
name: '100', text: '100',
color: '#7EB26D', color: '#7EB26D',
}, },
{ {
value: 200, numeric: 200,
name: '200', text: '200',
color: '#6ED0E0', color: '#6ED0E0',
}, },
]), ]),
pieType: text('pieType', PieChartType.PIE), pieType: select('pieType', [PieChartType.PIE, PieChartType.DONUT], PieChartType.PIE),
strokeWidth: number('strokeWidth', 1), strokeWidth: number('strokeWidth', 1),
unit: text('unit', 'ms'),
}; };
}; };
const PieChartStories = storiesOf('Visualizations/PieChart', module); export const basic = () => {
const { datapoints, pieType, strokeWidth } = getKnobs();
PieChartStories.addDecorator(withCenteredStory); return <PieChart width={200} height={400} values={datapoints} pieType={pieType} strokeWidth={strokeWidth} />;
};
PieChartStories.add('Pie type: pie', () => {
const { datapoints, pieType, strokeWidth, unit } = getKnobs();
return renderComponentWithTheme(PieChart, {
width: 200,
height: 400,
datapoints,
pieType,
strokeWidth,
unit,
});
});
@@ -1,23 +1,29 @@
import React from 'react'; import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import { object } from '@storybook/addon-knobs';
import { ThresholdsEditor } from './ThresholdsEditor'; import { ThresholdsEditor } from './ThresholdsEditor';
import { ThresholdsMode, ThresholdsConfig } from '@grafana/data'; import { ThresholdsMode } from '@grafana/data';
const ThresholdsEditorStories = storiesOf('Panel/ThresholdsEditor', module); export default {
const thresholds: ThresholdsConfig = { title: 'Panel/ThresholdsEditor',
mode: ThresholdsMode.Absolute, component: ThresholdsEditor,
steps: [
{ value: -Infinity, color: 'green' },
{ value: 50, color: 'red' },
],
}; };
ThresholdsEditorStories.add('default', () => { const getKnobs = () => {
return <ThresholdsEditor thresholds={{} as ThresholdsConfig} onChange={action('Thresholds changed')} />; return {
}); initThresholds: object('Initial thresholds', {
mode: ThresholdsMode.Absolute,
steps: [
{ value: -Infinity, color: 'green' },
{ value: 50, color: 'red' },
],
}),
};
};
ThresholdsEditorStories.add('with thresholds', () => { export const basic = () => <ThresholdsEditor onChange={action('Thresholds changed')} />;
return <ThresholdsEditor thresholds={thresholds} onChange={action('Thresholds changed')} />;
}); export const withThresholds = () => (
<ThresholdsEditor thresholds={getKnobs().initThresholds} onChange={action('Thresholds changed')} />
);
@@ -2,7 +2,7 @@ import { text } from '@storybook/addon-knobs';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import { ValuePicker } from './ValuePicker'; import { ValuePicker } from './ValuePicker';
import React from 'react'; import React from 'react';
import { generateOptions } from '../Forms/Select/Select.story'; import { generateOptions } from '../Forms/Select/mockOptions';
export default { export default {
title: 'General/ValuePicker', title: 'General/ValuePicker',