Dev Diary 2020.03.28 – Storybook - davidhorm/wavelength GitHub Wiki

Dev Diary - React + TypeScript + Storybook + Knobs + Docs

Oh man. It's so much simpler to implement this now than in the before-time since Storybook's CRA preset knows about TypeScript. Just follow the npx step of Storybook Docs Typescript Walkthrough.

npx -p @storybook/cli sb init --story-format=csf-ts
yarn add --dev @storybook/addon-docs @storybook/addon-knobs

Further instructions from Storybook Docs for React so I can document my components, props, and default prop values. And Storybook Addon Knobs so I can interact with it in Storybook.

Update .storybook/main.js with:

module.exports = {
  stories: ['../src/**/*.stories.(ts|tsx|js|jsx)'],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-actions',
    '@storybook/addon-links',
+   '@storybook/addon-docs',
+   '@storybook/addon-knobs/register',
  ],
};

There's some fancier stuff with MDX, but probably not needed for this simple project.

Docs runs off of prop-types, so I'll need that an the corresponding @types/prop-types because of TypeScript.

yarn add --dev prop-types @types/prop-types

Yeah I know, some folks may be asking why both when they're the same thing? Well technically TypeScript helps with build-time, and prop-types helps with runtime. Also prop-types has more rules you can define. Luckily the @types has a way so we only need to define things once with PropTypes.InferProps<typeof T>. Here's a sample component with the comments Docs need.

import PropTypes from 'prop-types';
import React from 'react';
import image from './target.png';

const TargetPropTypes = {
  /** The degree in whole integer numbers to rotate the target with. */
  degree: PropTypes.number,

  /** Visibility. */
  visible: PropTypes.bool,
};

type Props = PropTypes.InferProps<typeof TargetPropTypes>;

/**
 * The Target component displays the scoring target. It can be rotated and hidden.
 *
 * @returns {object} - Target Component
 */
const Target: React.FC<Props> = ({ degree = 0, visible = true }) => {
  return visible ? <img src={image} alt="Target" style={{ transform: `rotate(${degree}deg)` }} /> : <div> </div>;
};

Target.propTypes = TargetPropTypes;

export default Target;

Also I turned off the 'react/require-default-props' ESLint rule because React defaultProps will be deprecated per https://twitter.com/dan_abramov/status/1133878326358171650?s=20.

Oh cool, it looks like React Testing Library is already added by CRA.

⚠️ **GitHub.com Fallback** ⚠️