vantezzen / autoform

🌟 Automatically render forms for your existing data schema
https://autoform.vantezzen.io
2.97k stars 111 forks source link

migrate from a two-object model to a key-value driven by a "new Map" data structure. #107

Closed leomerida15 closed 1 month ago

leomerida15 commented 1 month ago

First of all, thank you very much for this repository. I really like it. I think it's one of the best I've seen for tackling the problem of generating forms quickly. I'd love to be a contributor. That's why I created this class because I'm the company's technology director and we use multiple component libraries. I'll be publishing this package on npm and I think you might want to add it to this repository so that you can make the library more apprehensive about the component library.

current form

import AutoFormCheckbox from "./fields/checkbox";
import AutoFormDate from "./fields/date";
import AutoFormEnum from "./fields/enum";
import AutoFormFile from "./fields/file";
import AutoFormInput from "./fields/input";
import AutoFormNumber from "./fields/number";
import AutoFormRadioGroup from "./fields/radio-group";
import AutoFormSwitch from "./fields/switch";
import AutoFormTextarea from "./fields/textarea";

export const INPUT_COMPONENTS = {
  checkbox: AutoFormCheckbox,
  date: AutoFormDate,
  select: AutoFormEnum,
  radio: AutoFormRadioGroup,
  switch: AutoFormSwitch,
  textarea: AutoFormTextarea,
  number: AutoFormNumber,
  file: AutoFormFile,
  fallback: AutoFormInput,
};

/**
 * Define handlers for specific Zod types.
 * You can expand this object to support more types.
 */
export const DEFAULT_ZOD_HANDLERS: {
  [key: string]: keyof typeof INPUT_COMPONENTS;
} = {
  ZodBoolean: "checkbox",
  ZodDate: "date",
  ZodEnum: "select",
  ZodNativeEnum: "select",
  ZodNumber: "number",
};

diagram:

graph TD;
    web(react or other web framework vue, svelt)-->Input_Map
    Input_Map-->shadcn/ui;
    Input_Map-->bootstrap;
    Input_Map-->shakraui;

How would the implementation be:

const inputType = INPUT_COMPONENTS.exists(zodBaseType);

const InputComponent =  INPUT_COMPONENTS.get(inputType);
import { InputCompMap } from "../../custom/auto-form/utils";
import AutoFormCheckbox from "./fields/checkbox";
import AutoFormDate from "./fields/date";
import AutoFormEnum from "./fields/enum";
import AutoFormFile from "./fields/file";
import AutoFormInput from "./fields/input";
import AutoFormNumber from "./fields/number";
import AutoFormRadioGroup from "./fields/radio-group";
import AutoFormSwitch from "./fields/switch";
import AutoFormTextarea from "./fields/textarea";
import { AutoFormInputComponentProps } from "./types";

export const INPUT_COMPONENTS = new InputCompMap<
    AutoFormInputComponentProps,
    "gps"
>({
    checkbox: AutoFormCheckbox,
    date: AutoFormDate,
    select: AutoFormEnum,
    radio: AutoFormRadioGroup,
    switch: AutoFormSwitch,
    textarea: AutoFormTextarea,
    number: AutoFormNumber,
    file: AutoFormFile,
    gps: AutoFormInput,
    fallback: AutoFormInput,
}).extends((INPUT_COMPONENT) => ({
    ZodBoolean: INPUT_COMPONENT.get("checkbox")!,
    ZodDate: INPUT_COMPONENT.get("date")!,
    ZodEnum: INPUT_COMPONENT.get("select")!,
    ZodNativeEnum: INPUT_COMPONENT.get("select")!,
    ZodNumber: INPUT_COMPONENT.get("number")!,
}));

This way you can get the list of keys that exist in the component list

export type INPUT_COMPONENTS_KEYS = Parameters<
typeof INPUT_COMPONENTS.get
>["0"];
vantezzen commented 1 month ago

Hey this looks very interesting - I think splitting the general logic from being shadcn-specific sounds good. I don't know if this is the most intuitive method of doing it and integrating with the local shadcn components I'd definitely take a look if you publish the package.