Question : How to make drawer globally?

Author: galih56Created Feb 11, 2024Updated Jan 12, 2026

Is it possible to make drawer globally and place the content wherever it's needed? Split the form and the drawer. For me, the drawer is not reusable enough. It will be great if I can call the drawer anywhere and place the content dynamically. For now, i can only use the drawer and place it to every single feature i want to make.

As example : In the code below, the FormDrawer must be used along with the form. But i want to create the form for separated from it and use it on other pages, like creatable select or some dialogs. I tried to split them, but i had a hard time syncing the mutation status because the useMutation is called inside parent component and the submit button is called inside the FormDrawer component. Any suggestions?

bash
export const CreateTask = () => {
  const projectOptions = useProjectOptions();
  const tagOptions = useTagOptions();
  const usersOptions = useUserOptions();
  const createTaskMutation = useCreateTask();

  return (
      <FormDrawer
        isDone={createTaskMutation.isSuccess}
        triggerButton={
          <Button variant='primary' size="sm" icon={PlusIcon}>
            Create Task
          </Button>
        }
        title="Create Task"
        submitButton={
          <Button
            form="create-task"
            type="submit"
            size="sm"
            loading={createTaskMutation.isLoading}
          >
            Submit
          </Button>
        }
      >
        <Form<CreateTaskDTO['data'], typeof schema>
          id="create-task"
          onSubmit={async (values) =>  await createTaskMutation.mutateAsync({ data: values })}
          schema={schema}
        >
          {({ register, formState, control }) => (
            <>
              <SelectField
                label='Project'
                options={projectOptions}
                error={formState.errors['projectId']}
                registration={register('projectId')}
                control={control}
              />
              <InputField
                label="Title"
                error={formState.errors['title']}
                registration={register('title')}
              />
              <TextAreaField
                label="Description"
                error={formState.errors['description']}
                registration={register('description')}
              />
              
              <SelectField
                label='Tags'
                options={tagOptions}
                error={formState.errors['tags']}
                registration={register('tags')}
                control={control}
                multiple={true}
              />
              
              <SelectField
                label='Assignees'
                options={usersOptions}
                error={formState.errors['assignees']}
                registration={register('assignees')}
                control={control}
                multiple={true}
              />
            </>
          )}
        </Form>
      </FormDrawer>
  );
};

Source: alan2207/bulletproof-react