grafana/ui: Enable storybook docs (#19930)
This commit is contained in:
@@ -1,7 +1,3 @@
|
||||
import { configure, addDecorator } from '@storybook/react';
|
||||
import { withKnobs } from '@storybook/addon-knobs';
|
||||
import { withTheme } from '../src/utils/storybook/withTheme';
|
||||
import { withPaddedStory } from '../src/utils/storybook/withPaddedStory';
|
||||
import 'jquery';
|
||||
import '../../../public/vendor/flot/jquery.flot.js';
|
||||
import '../../../public/vendor/flot/jquery.flot.selection';
|
||||
@@ -13,12 +9,16 @@ import '../../../public/vendor/flot/jquery.flot.fillbelow';
|
||||
import '../../../public/vendor/flot/jquery.flot.crosshair';
|
||||
import '../../../public/vendor/flot/jquery.flot.dashes';
|
||||
import '../../../public/vendor/flot/jquery.flot.gauge';
|
||||
import { withTheme } from '../src/utils/storybook/withTheme';
|
||||
import { withPaddedStory } from '../src/utils/storybook/withPaddedStory';
|
||||
// @ts-ignore
|
||||
import lightTheme from '../../../public/sass/grafana.light.scss';
|
||||
// @ts-ignore
|
||||
import darkTheme from '../../../public/sass/grafana.dark.scss';
|
||||
import { configure, addDecorator, addParameters } from '@storybook/react';
|
||||
import { withKnobs } from '@storybook/addon-knobs';
|
||||
|
||||
const handleThemeChange = (theme: string) => {
|
||||
const handleThemeChange = (theme: any) => {
|
||||
if (theme !== 'light') {
|
||||
lightTheme.unuse();
|
||||
darkTheme.use();
|
||||
@@ -27,15 +27,24 @@ const handleThemeChange = (theme: string) => {
|
||||
lightTheme.use();
|
||||
}
|
||||
};
|
||||
// automatically import all files ending in *.stories.tsx
|
||||
const req = require.context('../src', true, /.story.tsx$/);
|
||||
|
||||
addDecorator(withTheme(handleThemeChange));
|
||||
addDecorator(withKnobs);
|
||||
addDecorator(withPaddedStory);
|
||||
addDecorator(withTheme(handleThemeChange));
|
||||
|
||||
function loadStories() {
|
||||
req.keys().forEach(req);
|
||||
}
|
||||
addParameters({
|
||||
options: {
|
||||
showPanel: true,
|
||||
panelPosition: 'bottom',
|
||||
showNav: true,
|
||||
isFullscreen: false,
|
||||
isToolshown: true,
|
||||
storySort: (a: any, b: any) => a[1].id.localeCompare(b[1].id),
|
||||
},
|
||||
knobs: {
|
||||
escapeHTML: false,
|
||||
},
|
||||
});
|
||||
|
||||
configure(loadStories, module);
|
||||
// @ts-ignore
|
||||
configure(require.context('../src', true, /\.story\.(js|jsx|ts|tsx|mdx)$/), module);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: '@storybook/addon-docs/react/preset',
|
||||
options: { configureJSX: true, babelOptions: {}, sourceLoaderOptions: null },
|
||||
},
|
||||
];
|
||||
@@ -1,15 +1,35 @@
|
||||
const path = require('path');
|
||||
module.exports = ({ config, mode }) => {
|
||||
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/');
|
||||
}
|
||||
|
||||
module.exports = ({config, mode}) => {
|
||||
config.module.rules.push({
|
||||
test: /\.(ts|tsx)$/,
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('ts-loader'),
|
||||
options: {}
|
||||
},
|
||||
],
|
||||
});
|
||||
return true;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
config.module.rules.push({
|
||||
test: /\.scss$/,
|
||||
@@ -54,6 +74,8 @@ module.exports = ({config, mode}) => {
|
||||
});
|
||||
|
||||
config.resolve.extensions.push('.ts', '.tsx');
|
||||
|
||||
config.stats = {
|
||||
warningsFilter: /export .* was not found in/,
|
||||
};
|
||||
return config;
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@storybook/addon-actions": "5.2.4",
|
||||
"@storybook/addon-docs": "^5.2.4",
|
||||
"@storybook/addon-info": "5.2.4",
|
||||
"@storybook/addon-knobs": "5.2.4",
|
||||
"@storybook/react": "5.2.4",
|
||||
@@ -77,8 +78,7 @@
|
||||
"@types/tinycolor2": "1.4.1",
|
||||
"common-tags": "^1.8.0",
|
||||
"pretty-format": "24.9.0",
|
||||
"react-docgen-typescript-loader": "3.0.1",
|
||||
"react-docgen-typescript-webpack-plugin": "1.1.0",
|
||||
"react-docgen-typescript-loader": "3.3.0",
|
||||
"react-test-renderer": "16.8.4",
|
||||
"rollup": "1.6.0",
|
||||
"rollup-plugin-commonjs": "9.2.1",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<Meta title="Intro" parameters={{ options: { isToolshown: false}}}/>
|
||||
|
||||
# @grafana/ui
|
||||
|
||||
Welcome to @grafana/ui
|
||||
@@ -1,5 +1,5 @@
|
||||
// Libraries
|
||||
import React, { FC, useContext } from 'react';
|
||||
import React, { FC, useContext, useEffect } from 'react';
|
||||
// @ts-ignore
|
||||
import Prism from 'prismjs';
|
||||
// Components
|
||||
@@ -17,15 +17,21 @@ interface DataLinksEditorProps {
|
||||
maxLinks?: number;
|
||||
}
|
||||
|
||||
Prism.languages['links'] = {
|
||||
builtInVariable: {
|
||||
pattern: /(\${\S+?})/,
|
||||
},
|
||||
export const enableDatalinksPrismSyntax = () => {
|
||||
Prism.languages['links'] = {
|
||||
builtInVariable: {
|
||||
pattern: /(\${\S+?})/,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const DataLinksEditor: FC<DataLinksEditorProps> = React.memo(({ value, onChange, suggestions, maxLinks }) => {
|
||||
const theme = useContext(ThemeContext);
|
||||
|
||||
useEffect(() => {
|
||||
enableDatalinksPrismSyntax();
|
||||
});
|
||||
|
||||
const onAdd = () => {
|
||||
onChange(value ? [...value, { url: '', title: '' }] : [{ url: '', title: '' }]);
|
||||
};
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { css, cx } from 'emotion';
|
||||
import { FormField, FormLabel, Input, Select, Switch, TagsInput } from '..';
|
||||
import { useTheme } from '../../themes';
|
||||
import { BasicAuthSettings } from './BasicAuthSettings';
|
||||
import { HttpProxySettings } from './HttpProxySettings';
|
||||
import { TLSAuthSettings } from './TLSAuthSettings';
|
||||
import { DataSourceSettings } from '../../types';
|
||||
import { HttpSettingsProps } from './types';
|
||||
import { Select } from '../Select/Select';
|
||||
import { Input } from '../Input/Input';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
import { FormLabel } from '../FormLabel/FormLabel';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { TagsInput } from '../TagsInput/TagsInput';
|
||||
|
||||
const ACCESS_OPTIONS: Array<SelectableValue<string>> = [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { KeyValue } from '@grafana/data';
|
||||
import { css, cx } from 'emotion';
|
||||
import { Tooltip } from '..';
|
||||
import { Tooltip } from '../Tooltip/Tooltip';
|
||||
import { CertificationKey } from './CertificationKey';
|
||||
import { HttpSettingsBaseProps } from './types';
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { Portal } from '../Portal/Portal';
|
||||
import { css, cx } from 'emotion';
|
||||
import { GrafanaTheme, ThemeContext } from '../..';
|
||||
import { GrafanaTheme } from '../../types/theme';
|
||||
import { ThemeContext } from '../../themes/ThemeContext';
|
||||
|
||||
const getStyles = (theme: GrafanaTheme) => ({
|
||||
modal: css`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import omit from 'lodash/omit';
|
||||
import React, { InputHTMLAttributes, FunctionComponent } from 'react';
|
||||
import { FormField } from '..';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
|
||||
interface Props extends InputHTMLAttributes<HTMLInputElement> {
|
||||
// Function to use when reset is clicked. Means you have to reset the input value yourself as this is uncontrolled
|
||||
|
||||
@@ -4,10 +4,11 @@ import { css, cx } from 'emotion';
|
||||
// Ignoring because I couldn't get @types/react-select work wih Torkel's fork
|
||||
// @ts-ignore
|
||||
import { components } from '@torkelo/react-select';
|
||||
import { FadeTransition, Spinner } from '..';
|
||||
import { useDelayedSwitch } from '../../utils/useDelayedSwitch';
|
||||
import { stylesFactory } from '../../themes';
|
||||
import { SlideOutTransition } from '../transitions/SlideOutTransition';
|
||||
import { FadeTransition } from '../transitions/FadeTransition';
|
||||
import { Spinner } from '../Spinner/Spinner';
|
||||
|
||||
const getStyles = stylesFactory(() => {
|
||||
const container = css`
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, { PureComponent } from 'react';
|
||||
import isArray from 'lodash/isArray';
|
||||
import difference from 'lodash/difference';
|
||||
|
||||
import { Select } from '../index';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
import { fieldReducers, SelectableValue } from '@grafana/data';
|
||||
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
// import { storiesOf } from '@storybook/react';
|
||||
// import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
import { Switch } from './Switch';
|
||||
import { text } from '@storybook/addon-knobs';
|
||||
|
||||
const getStory = (title: string, component: any) => ({
|
||||
title,
|
||||
parameters: {
|
||||
component,
|
||||
},
|
||||
});
|
||||
|
||||
export default getStory('UI|Switch', Switch);
|
||||
|
||||
const getKnobs = () => {
|
||||
return {
|
||||
label: text('Label Text', 'Label'),
|
||||
@@ -18,6 +27,4 @@ const SwitchWrapper = () => {
|
||||
return <Switch label={label} checked={checked} onChange={() => setChecked(!checked)} tooltip={tooltip} />;
|
||||
};
|
||||
|
||||
const story = storiesOf('UI/Switch', module);
|
||||
story.addDecorator(withCenteredStory);
|
||||
story.add('switch', () => <SwitchWrapper />);
|
||||
export const basic = () => <SwitchWrapper />;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Table } from './Table';
|
||||
import { getTheme } from '../../themes';
|
||||
|
||||
import { migratedTestTable, migratedTestStyles, simpleTable } from './examples';
|
||||
import { GrafanaThemeType } from '../../types/index';
|
||||
import { GrafanaThemeType } from '../../types/theme';
|
||||
import { DataFrame, FieldType, ArrayVector, ScopedVars } from '@grafana/data';
|
||||
import { withFullSizeStory } from '../../utils/storybook/withFullSizeStory';
|
||||
import { number, boolean } from '@storybook/addon-knobs';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { ChangeEvent, KeyboardEvent, PureComponent } from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
import { stylesFactory } from '../../themes/stylesFactory';
|
||||
import { Button, Input } from '..';
|
||||
import { Button } from '../Button/Button';
|
||||
import { Input } from '../Input/Input';
|
||||
import { TagItem } from './TagItem';
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { FC } from 'react';
|
||||
import { getTimeZoneGroups, SelectableValue } from '@grafana/data';
|
||||
import { Select } from '..';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
interface Props {
|
||||
value: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { Select } from '..';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
import { getValueFormats } from '../../utils';
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import React, { ChangeEvent, PureComponent } from 'react';
|
||||
|
||||
import { FormField, FormLabel, Input, Select } from '..';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
import { FormLabel } from '../FormLabel/FormLabel';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
import { MappingType, ValueMapping } from '@grafana/data';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
|
||||
|
||||
import MappingRow from './MappingRow';
|
||||
import { MappingType, ValueMapping } from '@grafana/data';
|
||||
import { Button } from '../index';
|
||||
import { Button } from '../Button/Button';
|
||||
import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
|
||||
|
||||
export interface Props {
|
||||
|
||||
@@ -5,7 +5,6 @@ const PaddedStory: React.FunctionComponent<{}> = ({ children }) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
minHeight: '100vh',
|
||||
width: '100%',
|
||||
padding: '20px',
|
||||
display: 'flex',
|
||||
|
||||
@@ -3,7 +3,7 @@ import { RenderFunction } from '@storybook/react';
|
||||
import { ThemeContext } from '../../themes/ThemeContext';
|
||||
import { select } from '@storybook/addon-knobs';
|
||||
import { getTheme } from '../../themes/index';
|
||||
import { GrafanaThemeType } from '../../types';
|
||||
import { GrafanaThemeType } from '../../types/theme';
|
||||
|
||||
type SassThemeChangeHandler = (theme: GrafanaThemeType) => void;
|
||||
const ThemableStory: React.FunctionComponent<{ handleSassThemeChange: SassThemeChangeHandler }> = ({
|
||||
|
||||
Reference in New Issue
Block a user