Skip to content

Commit

Permalink
docs: addes jsdoc and storybook autodocs
Browse files Browse the repository at this point in the history
  • Loading branch information
niebag committed Apr 23, 2024
1 parent 99ce46d commit 42a344d
Show file tree
Hide file tree
Showing 30 changed files with 579 additions and 165 deletions.
35 changes: 30 additions & 5 deletions .plop-templates/component/index.stories.tsx.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,37 @@ import type { Meta, StoryObj } from '@storybook/react';

import { {{pascalCase name}} } from '.';

/**
* Meta information for the component.
* This object configures how the component will be displayed in the Storybook interface.
*
* @see https://storybook.js.org/docs/writing-stories#default-export
*/
type {{pascalCase name}}Meta = Meta<typeof {{pascalCase name}}>;

/**
* This meta description below will be visible on the documentation page for the component.
*/
const meta = {
title: '{{pascalCase type}}/{{pascalCase subType}}/{{pascalCase name}}',
component: {{pascalCase name}}
} satisfies Meta<typeof {{pascalCase name}}>;
component: {{pascalCase name}},
tags: ['autodocs'],
title: '{{titleCase type}}/{{titleCase subFolder}}/{{pascalCase name}}',
} satisfies ;
export default meta;

type Story = StoryObj<typeof meta>;
/**
* Type definition for the stories.
* This type defines the expected structure for individual stories.
*
* @see https://storybook.js.org/docs/writing-stories#defining-stories
*/
type {{pascalCase name}}Story = StoryObj<typeof meta>;

/* Stories */

/**
* This story description below will be visible on the documentation page for the component.
*/
export const Default = {} satisfies {{pascalCase name}}Story;

export const Default = {} satisfies Story;
// Write more stories here
27 changes: 21 additions & 6 deletions .plop-templates/component/index.tsx.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import * as React from 'react'; import { cn } from '~/lib/utils'; type Props = { className?: string; }; export function
{{pascalCase name}}({ className, ...props }: Props) { return (
<div data-testid='{{snakeCase name}}' className="{cn(''," className)}>
Hello, world!
</div>
); }
import { cn } from '~/lib/utils';

/**
* Props for the {{pascalCase name}} component.
*/
type {{pascalCase name}}Props = {
/** Optional additional class names for custom styling. */
className?: string;
};

export function {{pascalCase name}}({ className }: {{pascalCase name}}Props) {
// Add more section comments here, e.g. "Constants", "State", "Hooks", "Derived State", "Utils", "Render", etc.

/* JSX */

return (
<div data-testid='{{snakeCase name}}' className={cn('', className)}>
Hello, {{pascalCase name}}!
</div>
);
}
3 changes: 2 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const config: StorybookConfig = {
options: {}
},
docs: {
autodocs: 'tag'
autodocs: 'tag',
defaultName: 'Documentation'
},
staticDirs: ['../public']
};
Expand Down
3 changes: 3 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const preview: Preview = {
date: /Date$/i
}
},
docs: {
toc: true
},
viewport: {
viewports: TAILWIND_VIEWPORTS
}
Expand Down
31 changes: 19 additions & 12 deletions plopfile.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @param {import('plop').NodePlopAPI} plop - Plop provides the API methods for plop actions
* @param {import('plop').NodePlopAPI} plop
*/
export default function (plop) {
plop.setGenerator('component', {
Expand All @@ -18,8 +18,19 @@ export default function (plop) {
},
{
type: 'input',
name: 'subType',
message: `What is your component sub-type? (e.g. 'typography' for atoms, 'cards' for molecules or 'sections' for organisms)`
name: 'subFolder',
message: (answers) => {
switch (answers.type) {
case 'atoms':
return 'Name your subfolder (e.g. interactive, typography, etc.)';
case 'molecules':
return 'Name your subfolder (e.g. forms, cards, etc.)';
case 'organisms':
return 'Name your subfolder (e.g. headers, footers, sections etc.)';
default:
return 'Name your subfolder';
}
}
},
{
type: 'confirm',
Expand All @@ -32,20 +43,16 @@ export default function (plop) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
.replace(/[-_\s]+/g, '');

return `Are you sure you want to create '~/components/${answers.type}/${answers.subType}/${pascalCaseName}'?`;
return `Are you sure you want to create '~/components/${answers.type}/${answers.subFolder}/${pascalCaseName}'?`;
}
}
],
actions: [
{
type: 'add',
path: 'src/components/{{type}}/{{subType}}/{{pascalCase name}}/index.stories.tsx',
templateFile: '.plop-templates/component/index.stories.tsx.hbs'
},
{
type: 'add',
path: 'src/components/{{type}}/{{subType}}/{{pascalCase name}}/index.tsx',
templateFile: '.plop-templates/component/index.tsx.hbs'
type: 'addMany',
destination: 'src/components/{{type}}/{{subFolder}}/{{pascalCase name}}',
base: '.plop-templates/component',
templateFiles: '.plop-templates/component/*.hbs'
}
]
});
Expand Down
38 changes: 32 additions & 6 deletions src/components/atoms/icons/ArrowIcon/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,48 @@ import type { Meta, StoryObj } from '@storybook/react';

import { ArrowIcon } from '.';

/**
* Meta information for the component.
* This object configures how the component will be displayed in the Storybook interface.
*
* @see https://storybook.js.org/docs/writing-stories#default-export
*/
type ArrowIconMeta = Meta<typeof ArrowIcon>;

/**
* Arrow icon that can point to the left or right.
*/
const meta = {
title: 'Atoms/Icons/ArrowIcon',
component: ArrowIcon
} satisfies Meta<typeof ArrowIcon>;
component: ArrowIcon,
tags: ['autodocs'],
title: 'Atoms/Icons/ArrowIcon'
} satisfies ArrowIconMeta;
export default meta;

type Story = StoryObj<typeof meta>;
/**
* Type definition for the stories.
* This type defines the expected structure for individual stories.
*
* @see https://storybook.js.org/docs/writing-stories#defining-stories
*/
type ArrowIconStory = StoryObj<typeof meta>;

/* Stories */

/**
* Arrow icon that points to the left.
*/
export const LeftDirection = {
args: {
direction: 'left'
}
} satisfies Story;
} satisfies ArrowIconStory;

/**
* Arrow icon that points to the right.
*/
export const RightDirection = {
args: {
direction: 'right'
}
} satisfies Story;
} satisfies ArrowIconStory;
15 changes: 11 additions & 4 deletions src/components/atoms/icons/ArrowIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import * as React from 'react';

import { cn } from '~/lib/utils';

type Direction = 'left' | 'right';
type Props = React.HTMLAttributes<HTMLSpanElement> & {

/**
* Props for the ArrowIcon component.
*/
type ArrowIconProps = React.HTMLAttributes<HTMLSpanElement> & {
/** Direction of which the arrow should point to. */
direction: Direction;
};

export function ArrowIcon({ direction, className, ...props }: Props) {
export function ArrowIcon({ direction, className, ...props }: ArrowIconProps) {
/* Constants */

const arrow = direction === 'left' ? '<-' : '->';

/* JSX */

return (
<span data-testid='arrow-icon' className={cn('inline-block', className)} {...props}>
{arrow}
Expand Down
31 changes: 26 additions & 5 deletions src/components/atoms/logos/NextJSLogo/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,38 @@ import type { Meta, StoryObj } from '@storybook/react';

import { NextJSLogo } from '.';

/**
* Meta information for the component.
* This object configures how the component will be displayed in the Storybook interface.
*
* @see https://storybook.js.org/docs/writing-stories#default-export
*/
type NextJSLogoMeta = Meta<typeof NextJSLogo>;

/**
* The Next.js logo
*/
const meta = {
title: 'Atoms/Logos/NextJSLogo',
component: NextJSLogo
} satisfies Meta<typeof NextJSLogo>;
component: NextJSLogo,
tags: ['autodocs'],
title: 'Atoms/Logos/NextJSLogo'
} satisfies NextJSLogoMeta;
export default meta;

type Story = StoryObj<typeof meta>;
/**
* Type definition for the stories.
* This type defines the expected structure for individual stories.
*
* @see https://storybook.js.org/docs/writing-stories#defining-stories
*/
type NextJSLogoStory = StoryObj<typeof meta>;

/**
* The default Next.js logo.
*/
export const Default = {
args: {
width: 180,
height: 37
}
} satisfies Story;
} satisfies NextJSLogoStory;
16 changes: 10 additions & 6 deletions src/components/atoms/logos/NextJSLogo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import Image, { type ImageProps } from 'next/image';

import { cn } from '~/lib/utils';

// We use Omit to create a new type that has all the properties of ImageProps
// except for 'src' and 'alt'. This is because we're setting 'src' and 'alt'
// directly in the NextJSLogo component, so we don't want TypeScript to require
// them when we use the NextJSLogo component.
type Props = Omit<ImageProps, 'src' | 'alt'>;
/**
* Props for the NextJSLogo component.
*
* We use Omit to create a new type that has all the properties of ImageProps
* except for 'src' and 'alt'. This is because we're setting 'src' and 'alt'
* directly in the NextJSLogo component, so we don't want TypeScript to require
* them when we use the NextJSLogo component.
*/
type NextJSLogoProps = Omit<ImageProps, 'src' | 'alt'>;

export function NextJSLogo({ className, ...props }: Props) {
export function NextJSLogo({ className, ...props }: NextJSLogoProps) {
return (
<Image
{...props}
Expand Down
33 changes: 28 additions & 5 deletions src/components/atoms/logos/VercelLogo/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,40 @@ import type { Meta, StoryObj } from '@storybook/react';

import { VercelLogo } from '.';

/**
* Meta information for the component.
* This object configures how the component will be displayed in the Storybook interface.
*
* @see https://storybook.js.org/docs/writing-stories#default-export
*/
type VercelLogoMeta = Meta<typeof VercelLogo>;

/**
* The Vercel logo
*/
const meta = {
title: 'Atoms/Logos/VercelLogo',
component: VercelLogo
} satisfies Meta<typeof VercelLogo>;
component: VercelLogo,
tags: ['autodocs'],
title: 'Atoms/Logos/VercelLogo'
} satisfies VercelLogoMeta;
export default meta;

type Story = StoryObj<typeof meta>;
/**
* Type definition for the stories.
* This type defines the expected structure for individual stories.
*
* @see https://storybook.js.org/docs/writing-stories#defining-stories
*/
type VercelLogoStory = StoryObj<typeof meta>;

/* Stories */

/**
* The default Vercel logo.
*/
export const Default = {
args: {
width: 100,
height: 24
}
} satisfies Story;
} satisfies VercelLogoStory;
18 changes: 12 additions & 6 deletions src/components/atoms/logos/VercelLogo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ import Image, { type ImageProps } from 'next/image';

import { cn } from '~/lib/utils';

// We use Omit to create a new type that has all the properties of ImageProps
// except for 'src' and 'alt'. This is because we're setting 'src' and 'alt'
// directly in the VercelLogo component, so we don't want TypeScript to require
// them when we use the VercelLogo component.
type Props = Omit<ImageProps, 'src' | 'alt'>;
/**
* Props for the VercelLogo component.
*
* We use Omit to create a new type that has all the properties of ImageProps
* except for 'src' and 'alt'. This is because we're setting 'src' and 'alt'
* directly in the VercelLogo component, so we don't want TypeScript to require
* them when we use the VercelLogo component.
*/
type VercelLogoProps = Omit<ImageProps, 'src' | 'alt'>;

export function VercelLogo({ className, ...props }: VercelLogoProps) {
/* JSX */

export function VercelLogo({ className, ...props }: Props) {
return <Image {...props} src='/vercel.svg' alt='Vercel Logo' className={cn('dark:invert', className)} />;
}
Loading

0 comments on commit 42a344d

Please sign in to comment.