svelte-forms-lib icon indicating copy to clipboard operation
svelte-forms-lib copied to clipboard

Expose context key and FormState so we can create our own components

Open jtlapp opened this issue 4 years ago • 1 comments

Problem to solve

Bootstrap's validation CSS allows for marking the input fields themselves invalid via class is-invalid. Doing so also triggers displaying a following class="invalid-feedback" message.

To implement this, my custom input component needs access to $errors, in order to determine whether an error has been associated with the input element. I see two ways to make $errors available:

  1. Use a Form component declaring let:errors, and include {errors} among the properties I pass to each input element.
  2. Create my own Form element, have it receive a form context property, and save this form context via setContext to make it internally available to my custom input elements.

The first of these makes for extra boilerplate code on every form and input. The second of these ditches the helper components altogether to re-implement the context they already (internally) implement. Neither of these solutions is ideal.

Intended users

People who want to leverage Bootstrap's validation CSS with svelte-forms-lib.

User experience goal

Make it easy to create components that use Bootstrap validation CSS without boilerplate.

Proposal

Under the ideal solution, my custom component would access svelte-form-lib's existing context key. I would also want to properly label its type (in TypeScript). This entails:

  1. Exporting the key given in lib/components/key.js at the package level.
  2. Exporting the type FormState, which is the type of a form context. However, I'd rather have this type renamed to FormContext to be more descriptive and less apparently in conflict with the different type assigned to $state.

Also, as mentioned in #148, to make this type work, occurrences of Record<string, any> will need to change to {[key: string]: any} in the TypeScript declaration.

jtlapp avatar Nov 10 '21 22:11 jtlapp

I blogged a bit on this topic, it may be helpful.

I created my own form element components which access the parent's context, in order render $errors UX as well.

I used a plain <form> but setContext() on that same page, so the child components could access (similar to how svelte-forms-lib <Form /> does it.

Because i used flat $form element names like 'itemlist[1].description', i had to translate to the actual $errors.itemlist[1].description internally.

http://enehana.nohea.com/general/svelte-complex-forms-part-3-components-using-get-setcontext-for-less-passing-props/

nohea avatar Jan 13 '22 22:01 nohea