feat: add auto form value provider
This commit is contained in:
		
							parent
							
								
									2d033570f4
								
							
						
					
					
						commit
						e3a1d24304
					
				@ -23,6 +23,33 @@ import * as React from "react";
 | 
				
			|||||||
import { useState } from "react";
 | 
					import { useState } from "react";
 | 
				
			||||||
import type { UnknownKeysParam, ZodObject, ZodRawShape, z } from "zod";
 | 
					import type { UnknownKeysParam, ZodObject, ZodRawShape, z } from "zod";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ContextType = [Partial<any>, React.Dispatch<React.SetStateAction<any>>];
 | 
				
			||||||
 | 
					const AutoFormValueContext = React.createContext<ContextType | null>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function AutoFormValueProvider<Z extends ZodObject<any, any>>({
 | 
				
			||||||
 | 
					  children,
 | 
				
			||||||
 | 
					  value,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  children: React.ReactNode;
 | 
				
			||||||
 | 
					  value: ContextType;
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <AutoFormValueContext.Provider value={value}>
 | 
				
			||||||
 | 
					      {children}
 | 
				
			||||||
 | 
					    </AutoFormValueContext.Provider>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function useAutoFormValueContext<Z extends ZodObject<any, any>>() {
 | 
				
			||||||
 | 
					  const context = React.useContext(AutoFormValueContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // if (!context) {
 | 
				
			||||||
 | 
					  //   throw new Error("useInsertModal must be used within a InsertModalProvider");
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return context;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function InsertModal<
 | 
					export function InsertModal<
 | 
				
			||||||
  K extends ZodRawShape,
 | 
					  K extends ZodRawShape,
 | 
				
			||||||
  Y extends UnknownKeysParam,
 | 
					  Y extends UnknownKeysParam,
 | 
				
			||||||
@ -41,65 +68,73 @@ export function InsertModal<
 | 
				
			|||||||
  const [open, setOpen] = React.useState(false);
 | 
					  const [open, setOpen] = React.useState(false);
 | 
				
			||||||
  const [isLoading, setIsLoading] = React.useState(false);
 | 
					  const [isLoading, setIsLoading] = React.useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const a = useState<Partial<z.infer<Z>>>({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Dialog open={open} onOpenChange={setOpen}>
 | 
					    <AutoFormValueProvider value={a}>
 | 
				
			||||||
      {/* <DialogTrigger disabled={props.disabled}> */}
 | 
					      <Dialog open={open} onOpenChange={setOpen}>
 | 
				
			||||||
      {props.tooltip ? (
 | 
					        {/* <DialogTrigger disabled={props.disabled}> */}
 | 
				
			||||||
        <Tooltip>
 | 
					        {props.tooltip ? (
 | 
				
			||||||
          <TooltipTrigger asChild>
 | 
					          <Tooltip>
 | 
				
			||||||
            <Button
 | 
					            <TooltipTrigger asChild>
 | 
				
			||||||
              variant="default"
 | 
					              <Button
 | 
				
			||||||
              className={props.disabled ? "opacity-50" : ""}
 | 
					                variant="default"
 | 
				
			||||||
              onClick={() => {
 | 
					                className={props.disabled ? "opacity-50" : ""}
 | 
				
			||||||
                if (props.disabled) return;
 | 
					                onClick={() => {
 | 
				
			||||||
                setOpen(true);
 | 
					                  if (props.disabled) return;
 | 
				
			||||||
              }}
 | 
					                  setOpen(true);
 | 
				
			||||||
            >
 | 
					                }}
 | 
				
			||||||
              {props.buttonTitle ?? props.title}
 | 
					              >
 | 
				
			||||||
            </Button>
 | 
					                {props.buttonTitle ?? props.title}
 | 
				
			||||||
          </TooltipTrigger>
 | 
					              </Button>
 | 
				
			||||||
          <TooltipContent>
 | 
					            </TooltipTrigger>
 | 
				
			||||||
            <p>{props.tooltip}</p>
 | 
					            <TooltipContent>
 | 
				
			||||||
          </TooltipContent>
 | 
					              <p>{props.tooltip}</p>
 | 
				
			||||||
        </Tooltip>
 | 
					            </TooltipContent>
 | 
				
			||||||
      ) : (
 | 
					          </Tooltip>
 | 
				
			||||||
        <Button
 | 
					        ) : (
 | 
				
			||||||
          variant="default"
 | 
					          <Button
 | 
				
			||||||
          disabled={props.disabled}
 | 
					            variant="default"
 | 
				
			||||||
          onClick={() => {
 | 
					            disabled={props.disabled}
 | 
				
			||||||
            setOpen(true);
 | 
					            onClick={() => {
 | 
				
			||||||
          }}
 | 
					              setOpen(true);
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {props.title}
 | 
				
			||||||
 | 
					          </Button>
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					        {/* </DialogTrigger> */}
 | 
				
			||||||
 | 
					        <DialogContent
 | 
				
			||||||
 | 
					          className={cn("sm:max-w-[425px]", props.dialogClassName)}
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          {props.title}
 | 
					          <DialogHeader>
 | 
				
			||||||
        </Button>
 | 
					            <DialogTitle>{props.title}</DialogTitle>
 | 
				
			||||||
      )}
 | 
					            <DialogDescription>{props.description}</DialogDescription>
 | 
				
			||||||
      {/* </DialogTrigger> */}
 | 
					          </DialogHeader>
 | 
				
			||||||
      <DialogContent className={cn("sm:max-w-[425px]", props.dialogClassName)}>
 | 
					          {/* <ScrollArea> */}
 | 
				
			||||||
        <DialogHeader>
 | 
					          <AutoForm
 | 
				
			||||||
          <DialogTitle>{props.title}</DialogTitle>
 | 
					            values={values}
 | 
				
			||||||
          <DialogDescription>{props.description}</DialogDescription>
 | 
					            onValuesChange={setValues}
 | 
				
			||||||
        </DialogHeader>
 | 
					            fieldConfig={props.fieldConfig}
 | 
				
			||||||
        {/* <ScrollArea> */}
 | 
					            formSchema={props.formSchema}
 | 
				
			||||||
        <AutoForm
 | 
					            onSubmit={async (data) => {
 | 
				
			||||||
          fieldConfig={props.fieldConfig}
 | 
					              setIsLoading(true);
 | 
				
			||||||
          formSchema={props.formSchema}
 | 
					              await callServerPromise(props.serverAction(data));
 | 
				
			||||||
          onSubmit={async (data) => {
 | 
					              setIsLoading(false);
 | 
				
			||||||
            setIsLoading(true);
 | 
					              setOpen(false);
 | 
				
			||||||
            await callServerPromise(props.serverAction(data));
 | 
					            }}
 | 
				
			||||||
            setIsLoading(false);
 | 
					          >
 | 
				
			||||||
            setOpen(false);
 | 
					            <div className="flex justify-end">
 | 
				
			||||||
          }}
 | 
					              <AutoFormSubmit>
 | 
				
			||||||
        >
 | 
					                Save Changes
 | 
				
			||||||
          <div className="flex justify-end">
 | 
					                {isLoading && <LoadingIcon />}
 | 
				
			||||||
            <AutoFormSubmit>
 | 
					              </AutoFormSubmit>
 | 
				
			||||||
              Save Changes
 | 
					            </div>
 | 
				
			||||||
              {isLoading && <LoadingIcon />}
 | 
					          </AutoForm>
 | 
				
			||||||
            </AutoFormSubmit>
 | 
					          {/* </ScrollArea> */}
 | 
				
			||||||
          </div>
 | 
					        </DialogContent>
 | 
				
			||||||
        </AutoForm>
 | 
					      </Dialog>
 | 
				
			||||||
        {/* </ScrollArea> */}
 | 
					    </AutoFormValueProvider>
 | 
				
			||||||
      </DialogContent>
 | 
					 | 
				
			||||||
    </Dialog>
 | 
					 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -138,49 +173,53 @@ export function UpdateModal<
 | 
				
			|||||||
  }, [props.data]);
 | 
					  }, [props.data]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Dialog open={open} onOpenChange={setOpen}>
 | 
					    <AutoFormValueProvider value={[values, setValues]}>
 | 
				
			||||||
      {props.trigger ?? (
 | 
					      <Dialog open={open} onOpenChange={setOpen}>
 | 
				
			||||||
        <DialogTrigger
 | 
					        {props.trigger ?? (
 | 
				
			||||||
          className="appearance-none hover:cursor-pointer"
 | 
					          <DialogTrigger
 | 
				
			||||||
          asChild
 | 
					            className="appearance-none hover:cursor-pointer"
 | 
				
			||||||
          onClick={() => {
 | 
					            asChild
 | 
				
			||||||
            setOpen(true);
 | 
					            onClick={() => {
 | 
				
			||||||
          }}
 | 
					              setOpen(true);
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {props.trigger}
 | 
				
			||||||
 | 
					          </DialogTrigger>
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					        <DialogContent
 | 
				
			||||||
 | 
					          className={cn("sm:max-w-[425px]", props.dialogClassName)}
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          {props.trigger}
 | 
					          <DialogHeader>
 | 
				
			||||||
        </DialogTrigger>
 | 
					            <DialogTitle>{props.title}</DialogTitle>
 | 
				
			||||||
      )}
 | 
					            <DialogDescription>{props.description}</DialogDescription>
 | 
				
			||||||
      <DialogContent className={cn("sm:max-w-[425px]", props.dialogClassName)}>
 | 
					          </DialogHeader>
 | 
				
			||||||
        <DialogHeader>
 | 
					          <AutoForm
 | 
				
			||||||
          <DialogTitle>{props.title}</DialogTitle>
 | 
					            values={values}
 | 
				
			||||||
          <DialogDescription>{props.description}</DialogDescription>
 | 
					            onValuesChange={setValues}
 | 
				
			||||||
        </DialogHeader>
 | 
					            fieldConfig={props.fieldConfig}
 | 
				
			||||||
        <AutoForm
 | 
					            formSchema={props.formSchema}
 | 
				
			||||||
          values={values}
 | 
					            onSubmit={async (data) => {
 | 
				
			||||||
          onValuesChange={setValues}
 | 
					              setIsLoading(true);
 | 
				
			||||||
          fieldConfig={props.fieldConfig}
 | 
					              await callServerPromise(
 | 
				
			||||||
          formSchema={props.formSchema}
 | 
					                props.serverAction({
 | 
				
			||||||
          onSubmit={async (data) => {
 | 
					                  ...data,
 | 
				
			||||||
            setIsLoading(true);
 | 
					                  id: props.data.id,
 | 
				
			||||||
            await callServerPromise(
 | 
					                }),
 | 
				
			||||||
              props.serverAction({
 | 
					              );
 | 
				
			||||||
                ...data,
 | 
					              setIsLoading(false);
 | 
				
			||||||
                id: props.data.id,
 | 
					              setOpen(false);
 | 
				
			||||||
              }),
 | 
					            }}
 | 
				
			||||||
            );
 | 
					          >
 | 
				
			||||||
            setIsLoading(false);
 | 
					            <div className="flex justify-end flex-wrap gap-2">
 | 
				
			||||||
            setOpen(false);
 | 
					              {props.extraButtons}
 | 
				
			||||||
          }}
 | 
					              <AutoFormSubmit>
 | 
				
			||||||
        >
 | 
					                Save Changes
 | 
				
			||||||
          <div className="flex justify-end flex-wrap gap-2">
 | 
					                {isLoading && <LoadingIcon />}
 | 
				
			||||||
            {props.extraButtons}
 | 
					              </AutoFormSubmit>
 | 
				
			||||||
            <AutoFormSubmit>
 | 
					            </div>
 | 
				
			||||||
              Save Changes
 | 
					          </AutoForm>
 | 
				
			||||||
              {isLoading && <LoadingIcon />}
 | 
					        </DialogContent>
 | 
				
			||||||
            </AutoFormSubmit>
 | 
					      </Dialog>
 | 
				
			||||||
          </div>
 | 
					    </AutoFormValueProvider>
 | 
				
			||||||
        </AutoForm>
 | 
					 | 
				
			||||||
      </DialogContent>
 | 
					 | 
				
			||||||
    </Dialog>
 | 
					 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user