Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question]Export FieldProps type #23

Closed
Corsal8 opened this issue Feb 24, 2023 · 4 comments
Closed

[Question]Export FieldProps type #23

Corsal8 opened this issue Feb 24, 2023 · 4 comments
Assignees
Labels
enhancement New feature or request

Comments

@Corsal8
Copy link

Corsal8 commented Feb 24, 2023

Hi! First of all, thanks for your work! I've just started using your library and it seems very promising 馃槂!

I'd like to ask if it can be useful to export the FieldProps type from the Field component. The request comes from the fact that I'm creating my own custom input component. But instead of doing exactly what you have suggested on your doc, I'm also wrapping the Field component. Basically what I'd like to achive (and I'm able to do) is creating an Input component such as this one:

// Input.tsx
import { Field, FieldPath, FieldProps, FieldValues } from "@modular-forms/solid";
import { JSX, splitProps } from "solid-js";

type InputProps<
  TFieldValues extends FieldValues,
  TFieldName extends FieldPath<TFieldValues>
> = JSX.InputHTMLAttributes<HTMLInputElement> & { field: Omit<FieldProps<TFieldValues, TFieldName>, "children"> };

export const Input = <TFieldValues extends FieldValues, TFieldName extends FieldPath<TFieldValues>>(
  props: InputProps<TFieldValues, TFieldName>
) => {
  const [p, other] = splitProps(props, ["class", "field"]);

  return (
    <Field {...p.field}>
      {(field) => {
        const inputClasses = "rounded-xl border border-blue-400 p-2 text-black outline-none";
        const errorClass = () => (field.dirty && field.error ? "bg-red-400" : "");
        const externalClasses = () => p.class;
        const classes = () => `${inputClasses} ${errorClass()} ${externalClasses()}`;

        return <input {...field.props} class={classes()} {...other} />;
      }}
    </Field>
  );
};

In this way, from other components, I can just do the following:

// App.tsx
import { Component } from "solid-js";
import { Input } from "./components/Input";
import { createForm, Form, zodForm } from "@modular-forms/solid";
import { z } from "zod";

const UserSchema = z.object({ name: z.string().trim().min(1).max(20), email: z.string().trim().min(1).max(50) });
type User = z.infer<typeof UserSchema>;

const submit = (user: User) => console.log(user);

export const App: Component = () => {
  const form = createForm<User>({ validate: zodForm(UserSchema), validateOn: "input" });

  return (
    <Form of={form} onSubmit={submit}>
      <div class="flex flex-col gap-2">
        <Input field={{ of: form, name: "name" }} placeholder="Name" />
        <Input field={{ of: form, name: "email" }} placeholder="Email" />
        <button type="submit">Submit</button>
      </div>
    </Form>
  );
};

As you can see the code on App.tsx is very clean since I moved all the Field management on the Input component itself. The only problem was that to preserve type safety and Typescript autocompletion, I needed the FieldProps type. To fix this I just updated the Field.d.ts file to export it, but I wonder if this export can be included on your project. Unless, of course, there is already something better to achieve the same results that I'm not aware of.

Let me know if you need more info and if this request make sense at all! And of course, if needed, I can make a pull request, but maybe it's unnecessary since it's just a single line of code 馃槂!

Thanks!

@apollo79
Copy link

apollo79 commented Feb 25, 2023

I think this would be a good addition. I recently found myself trying to import the FormProps type, which should also be exported I think. My workaround without modifying files was using:

import { Form } from "@modular-forms/solid";
import type { ComponentProps } from "solid-js";

type FormProps<TFieldValues extends FieldValues> = ComponentProps<typeof Form<TFieldValues>>;

but I think it would be much easier if the type would be exported.

@Corsal8 small hint: When using modular-forms with zod, it is better to use z.input<typeof UserSchema> instead of z.infer<typeof UserSchema>, as z.infer gives you the output type of the schema, while you need the input type (this is more important if using zods transform method)

@fabian-hiller
Copy link
Owner

Good idea! I will fix this in the next release.

@fabian-hiller fabian-hiller self-assigned this Feb 25, 2023
@fabian-hiller fabian-hiller added the enhancement New feature or request label Feb 25, 2023
@Corsal8
Copy link
Author

Corsal8 commented Feb 25, 2023

Nice! Thanks a lot for the feedback! Also, thanks a lot @apollo79 for the suggestion! I was't aware of the z.input method, but I'll start using it for sure :)!

@fabian-hiller
Copy link
Owner

The changes are published with v0.11.0. Thank you for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants