Skip to content

Instantly share code, notes, and snippets.

@shumbo
Last active April 15, 2024 05:07
Show Gist options
  • Save shumbo/3bbb8a2dea5ea0a90ecf0b7c103783e8 to your computer and use it in GitHub Desktop.
Save shumbo/3bbb8a2dea5ea0a90ecf0b7c103783e8 to your computer and use it in GitHub Desktop.
A storybook decorator to use React Hooks Form inside stories
export default {
title: "MyComponent",
component: MyComponent,
decorators: [withRHF(false)], // or true to show submit button on story
} as Meta;
import { action } from "@storybook/addon-actions";
import { StoryFnReactReturnType } from "@storybook/react/dist/client/preview/types";
import { VFC, ReactNode, FC } from "react";
import { FormProvider, useForm } from "react-hook-form";
const StorybookFormProvider: VFC<{ children: ReactNode }> = ({ children }) => {
const methods = useForm();
return (
<FormProvider {...methods}>
<form
onSubmit={methods.handleSubmit(action("[React Hooks Form] Submit"))}
>
{children}
</form>
</FormProvider>
);
};
export const withRHF = (showSubmitButton: boolean) => (
Story: FC
): StoryFnReactReturnType => (
<StorybookFormProvider>
<Story />
{showSubmitButton && <button type="submit">Submit</button>}
</StorybookFormProvider>
);
@natac13
Copy link

natac13 commented Oct 6, 2022

Thank you!

@ignaciolarranaga
Copy link

Hey, code updated for sb7:

import { action } from '@storybook/addon-actions';
import { StoryFn } from '@storybook/react';
import { ReactElement, ReactNode, FC } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

const StorybookFormProvider: FC<{ children: ReactNode }> = ({ children }) => {
  const methods = useForm();
  return (
    <FormProvider {...methods}>
      <form
        onSubmit={methods.handleSubmit(action("[React Hooks Form] Submit"))}
      >
        {children}
      </form>
    </FormProvider>
  );
};

export default (showSubmitButton: boolean) => (
  Story: FC
): ReturnType<StoryFn<ReactElement>> => (
  <StorybookFormProvider>
    <Story />
    {showSubmitButton && <button type="submit">Submit</button>}
  </StorybookFormProvider>
);

@McGern
Copy link

McGern commented May 4, 2023

This is amazing! Thanks you very much @shumbo, and thanks @ignaciolarranaga for the SB7 update. This is much simpler than other solutions out there. I plugged it in and it worked right away (after I fixed the bugs with my components 😛)

I am a total newbie when it comes to storybook and was wondering if there was a simple-ish way to reset the form when certain properties change e.g. input name or default value.

The issue I have, which I am sure is to do with my lack of understanding, is that when a property like "name" changes from the SB playground, RHF registers the new input while keeping the old, which is likely the expected behaviour given that it's (probably) not an actual use case. This doesn't cause an error, but I am outputting the json form values (via watch) underneath the component, and it will show all of the iterations of the input name when it is edited in the playground.

The other issue (again my problem, not with RHF or the code here) is that when switching an input that has single or multiple value options e.g. MUI autocomplete, it bombs out when the property changes from single to multiple even when the values change from array to single element.

I know these are very specific use-cases, but was wondering if there was a way to either reset the form when the values change (maybe via a key change?), or set specific properties as read-only for the playground so the user knows they are there, but can edit them, and have variant examples showing the different properties?

Thanks again for the script.

@quanxenon5525
Copy link

Thank bro so much for helping me find out a easy way to solve my problem

@bogris
Copy link

bogris commented Feb 27, 2024

just what we needed now!

Bravo!

@koorya
Copy link

koorya commented Mar 16, 2024

How do that in sb8 or sb9?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment