[storybook__addon-info] Update types to match 5.2 (#40270)

* [storybook__addon-info]

 - Use types directly from `Storybook` repo as it is now written in TS
 - Update types to match version 5.2 of the addon and of Storybook (as they have to have the same version)

* [storybook__addon-info] make tests more realistic

Define React simple component and use them to have function call that match the ones done when really using the lib
This commit is contained in:
Gaëtan Maisse 2019-11-18 22:36:05 +01:00 committed by Sheetal Nandi
parent eab1a0860a
commit e6be2d46e4
4 changed files with 172 additions and 114 deletions

View File

@ -1,50 +1,70 @@
// Type definitions for @storybook/addon-info 4.1
// Type definitions for @storybook/addon-info 5.2
// Project: https://github.com/storybookjs/storybook, https://github.com/storybookjs/storybook/tree/master/addons/info
// Definitions by: Mark Kornblum <https://github.com/mkornblum>
// Mattias Wikstrom <https://github.com/fyrkant>
// Kevin Lee <https://github.com/RunningCoderLee>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
// TypeScript Version: 3.1
import * as React from 'react';
import { RenderFunction, StoryDecorator } from '@storybook/react';
import { ComponentType, ReactElement, ReactPortal } from 'react';
import { DecoratorFunction, StoryFn, StoryContext, Parameters, StoryApi } from '@storybook/addons';
export interface WrapStoryProps {
storyFn?: RenderFunction;
context?: object;
options?: object;
storyFn?: StoryFn;
context?: object;
options?: object;
}
export interface TableComponentOptionProps {
propDefinitions: Array<{
property: string;
propType: object | string; // TODO: info about what this object is...
required: boolean;
description: string;
defaultValue: any;
}>;
}
export interface Options {
text?: string;
header?: boolean;
inline?: boolean;
source?: boolean;
propTables?: Array<React.ComponentType<any>> | false;
propTablesExclude?: Array<React.ComponentType<any>>;
styles?: object;
components?: { [key: string]: React.ComponentType<any> };
marksyConf?: object;
maxPropsIntoLine?: number;
maxPropObjectKeys?: number;
maxPropArrayLength?: number;
maxPropStringLength?: number;
TableComponent?: React.ComponentType<{
propDefinitions: Array<{
property: string;
propType: object | string; // TODO: info about what this object is...
required: boolean;
description: string;
defaultValue: any;
}>
}>;
excludedPropTypes?: string[];
text?: string;
header?: boolean;
inline?: boolean;
source?: boolean;
propTables?: Array<ComponentType<any>> | false;
propTablesExclude?: Array<ComponentType<any>>;
styles?: object;
components?: { [key: string]: ComponentType<any> };
/**
* @deprecated "marksyConf" option has been renamed to "components"
*/
marksyConf?: object;
maxPropsIntoLine?: number;
maxPropObjectKeys?: number;
maxPropArrayLength?: number;
maxPropStringLength?: number;
TableComponent?: ComponentType<TableComponentOptionProps>;
excludedPropTypes?: string[];
}
// TODO: it would be better to use type inference for the parameters
// type DecoratorParams = StoryDecorator extends (...a: infer A) => any ? A: never;
export function withInfo(story: RenderFunction, context: { kind: string, story: string }): ReturnType<StoryDecorator>;
// Legacy, but supported
export function withInfo(textOrOptions?: string | Options): (storyFn: RenderFunction) => (context?: object) => React.ReactElement<WrapStoryProps>;
export function withInfo<A = unknown>(story: StoryFn<A>, context: StoryContext): ReturnType<DecoratorFunction<A>>;
// Legacy, but supported
/**
* @deprecated withInfo wrapper is deprecated, use the info parameter globally or on each story
*/
export function withInfo(
textOrOptions?: string | Options,
): (storyFn: StoryFn) => (context?: object) => ReactElement<WrapStoryProps>;
/**
* @deprecated setDefaults is deprecated. Instead, you can pass options into withInfo(options) directly, or use the info parameter.
*/
export function setDefaults(newDefaults: Options): Options;
declare module '@storybook/addons' {
interface ClientStoryApi<StoryFnReturnType = unknown> {
storiesOf(kind: string, module: NodeModule): StoryApi<StoryFnReturnType>;
addParameters(parameter: Parameters & { info: Options }): StoryApi<StoryFnReturnType>;
addDecorator(decorator: DecoratorFunction<StoryFnReturnType>): StoryApi<StoryFnReturnType>;
}
}

View File

@ -0,0 +1,7 @@
{
"private": true,
"dependencies": {
"@storybook/addons": "^5.2.0",
"@storybook/react": "^5.2.0"
}
}

View File

@ -1,77 +1,119 @@
/// <reference types="storybook__react" />
import React, { Component, FunctionComponent, HTMLAttributes } from 'react';
import { addDecorator, addParameters, storiesOf } from '@storybook/react';
import { setDefaults, withInfo, TableComponentOptionProps } from '@storybook/addon-info';
import * as React from 'react';
import { addDecorator, storiesOf } from '@storybook/react';
import { setDefaults, withInfo } from '@storybook/addon-info';
const { Component } = React;
const TableComponent = ({ propDefinitions }: { propDefinitions: Array<{
property: string;
propType: { [key: string]: any} | string;
required: boolean;
description: string;
defaultValue: any;
}> }) => (
const TableComponent: FunctionComponent<TableComponentOptionProps> = ({ propDefinitions }) => (
<table>
<thead>
<tr>
<th>property</th>
<th>propType</th>
<th>required</th>
<th>default</th>
<th>description</th>
</tr>
<tr>
<th>property</th>
<th>propType</th>
<th>required</th>
<th>default</th>
<th>description</th>
</tr>
</thead>
<tbody>
{propDefinitions.map(row => (
<tr key={row.property}>
<td>{row.property}</td>
<td>{row.required ? 'yes' : '-'}</td>
<td>
{row.defaultValue === undefined ? '-' : row.defaultValue}
</td>
<td>{row.description}</td>
</tr>
))}
{propDefinitions.map(row => (
<tr key={row.property}>
<td>{row.property}</td>
<td>{row.required ? 'yes' : '-'}</td>
<td>{row.defaultValue === undefined ? '-' : row.defaultValue}</td>
<td>{row.description}</td>
</tr>
))}
</tbody>
</table>
);
const BaseButton: FunctionComponent<HTMLAttributes<HTMLButtonElement> & { label: string }> = ({ label }) => (
<button type="button">{label}</button>
);
const CustomButton: FunctionComponent<HTMLAttributes<HTMLButtonElement> & { label: string }> = ({ label, style }) => (
<button type="button" style={style}>
{label}
</button>
);
// `withInfo` used as global decorator
addDecorator(withInfo);
// define parameters of info addon as part of global parameters
addParameters({
info: {
text: 'String or React Element with docs about my component',
inline: true,
header: true,
source: true,
propTables: [CustomButton],
propTablesExclude: [BaseButton],
styles: {},
components: {},
marksyConf: {},
maxPropObjectKeys: 1,
maxPropArrayLength: 2,
maxPropsIntoLine: 3,
maxPropStringLength: 4,
TableComponent,
excludedPropTypes: [],
},
});
// `withInfo` used as story decorator
storiesOf('Component', module).addDecorator(withInfo);
// Set parameters for multiple config
storiesOf('Component', module)
.addParameters({
info: {
header: '',
// Your settings
},
})
.add('with some emoji', () => <Component />);
storiesOf('Component', module)
.add(
'with some emoji',
() => <Component emoji />,
{ info: { inline: true, header: false } }, // Make your component render inline with the additional info
)
.add(
'with no emoji',
() => <Component />,
{ info: '☹️ no emojis' }, // Add additional info text directly
);
// Check deprecated option functions
setDefaults({
inline: false,
propTables: false
propTables: false,
});
storiesOf('Component', module)
.add('no info',
withInfo()(() =>
<Component>Click the "?" mark at top-right to view the info.</Component>
)
)
.add('simple info',
withInfo('doc string about my component')(() =>
<Component>Click the "?" mark at top-right to view the info.</Component>
)
)
.add('using an options object',
withInfo({
text: 'String or React Element with docs about my component',
inline: true,
header: true,
source: true,
styles: {},
components: {},
marksyConf: {},
maxPropObjectKeys: 1,
maxPropArrayLength: 2,
maxPropsIntoLine: 3,
maxPropStringLength: 4,
TableComponent,
excludedPropTypes: [],
})(() =>
<Component>Click the "?" mark at top-right to view the info.</Component>
)
);
.add('no info', withInfo()(() => <Component>Click the "?" mark at top-right to view the info.</Component>))
.add(
'simple info',
withInfo('doc string about my component')(() => (
<Component>Click the "?" mark at top-right to view the info.</Component>
)),
)
.add(
'using an options object',
withInfo({
text: 'String or React Element with docs about my component',
inline: true,
header: true,
source: true,
styles: {},
components: {},
marksyConf: {},
maxPropObjectKeys: 1,
maxPropArrayLength: 2,
maxPropsIntoLine: 3,
maxPropStringLength: 4,
TableComponent,
excludedPropTypes: [],
})(() => <Component>Click the "?" mark at top-right to view the info.</Component>),
);

View File

@ -1,32 +1,21 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"lib": ["dom", "es6"],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"jsx": "react",
"typeRoots": [
"../"
],
"typeRoots": ["../"],
"paths": {
"@storybook/addon-info": [
"storybook__addon-info"
],
"@storybook/react": [
"storybook__react"
]
"@storybook/addon-info": ["storybook__addon-info"]
},
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"storybook__addon-info-tests.tsx"
]
}
"files": ["index.d.ts", "storybook__addon-info-tests.tsx"]
}