[Proposal] <Form>-level `errorClass` & `errorStyle`

Just finished the Form building part of the tutorial, and I found it very repetitive on the error styles part.

I wonder whether Redwood could add the option to have a “global” errorStyle and/or errorClass declared at the <Form> element. It would automatically apply to all nested input elements and their labels for instance, and any errorStyle or errorClass declared at an input/label level would override the Form one (maybe merge styles & override class name).

The tutorial form would then go from this:

<Form onSubmit={onSubmit} validation={{ mode: 'onBlur' }}>
  <Label
    name="name"
    style={{ display: 'block' }}
    errorStyle={{ display: 'block', color: 'red' }}
  >
    Name
  </Label>
  <TextField
    name="name"
    validation={{ required: true }}
    errorStyle={{ display: 'block', borderColor: 'red' }}
  />
  <FieldError name="name" style={{ color: 'red' }} />

  <Label
    name="email"
    style={{ display: 'block' }}
    errorStyle={{ display: 'block', color: 'red' }}
  >
    Email
  </Label>
  <TextField
    name="email"
    validation={{
      required: true,
      pattern: {
        value: /[^@]+@[^\.]+\..+/,
        message: 'Please enter a valid email address',
      },
    }}
    errorStyle={{ display: 'block', borderColor: 'red' }}
  />
  <FieldError name="email" style={{ color: 'red' }} />

  <Label name="message" style={{ display: 'block' }}>
    Message
  </Label>
  <TextAreaField
    name="message"
    validation={{ required: true }}
    errorStyle={{ display: 'block', borderColor: 'red' }}
  />
  <FieldError name="message" style={{ color: 'red' }} />

  <Submit style={{ display: 'block' }}>Send</Submit>
</Form>

to:

<Form
  onSubmit={onSubmit}
  validation={{ mode: 'onBlur' }}
  errorStyle={{ display: 'block', borderColor: 'red', color: 'red' }}
>
  <Label name="name" style={{ display: 'block' }}>
    Name
  </Label>
  <TextField name="name" validation={{ required: true }} />
  <FieldError name="name" style={{ color: 'red' }} />

  <Label name="email" style={{ display: 'block' }}>
    Email
  </Label>
  <TextField
    name="email"
    validation={{
      required: true,
      pattern: {
        value: /[^@]+@[^\.]+\..+/,
        message: 'Please enter a valid email address',
      },
    }}
  />
  <FieldError name="email" style={{ color: 'red' }} />

  <Label name="message" style={{ display: 'block' }}>
    Message
  </Label>
  <TextAreaField name="message" validation={{ required: true }} />
  <FieldError name="message" style={{ color: 'red' }} />

  <Submit style={{ display: 'block' }}>Send</Submit>
</Form>

More realistically, errorClass would more likely be used in that kind of use case, so that different styles for different types of inputs/labels would be covered with a single class.

Not sure that’s the API to go for anyway, but what are your thoughts on the idea?

2 Likes

@rob will be all over this… :wink:

Thanks again, @olance Just so you know, you’re a hero with the team over at Prisma. For realz :muscle:

Hmmm, I feel like this could be mistaken for styling the form—all of the other errorStyle and errorClassName attributes are directly on the elements that they style, so at first blush I would assume these applied to the <Form> if there is an error. I also don’t love that it would apply to both the label and the input. What if I only want the style to apply to one and not the other?

What about some kind of container element that makes it clear you’re stying the children?

<Form ...>
  <ErrorStyle labelErrorStyle={{textColor: "red"}} inputErrorStyle={{borderColor: "red"}}>
    <Label>
    <TextField>
  </ErrorStyle>
</Form>

But maybe that’s inventing a new paradigm for styling, and there already seems to be too many of those in the JS world! And it’s also disconnecting the styling from the place where they’ll apply… hmmm.

ahah :sunglasses:

@rob hmmm… :slight_smile:
I see your point!

I’ve made this proposal in the spirit of DRY (which is dear to any Rails dev ^^) but it shouldn’t break consistency either…

The way I see this, <Form> is some kind of “controller” for the fields and labels it hosts, and as such I am personally not shocked by disconnecting styling from the fields and labels themselves.

Well, maybe it’s not worth complicating things and the solution simply lies into factoring the common styles in two local constants inputErrorStyle and labelErrorStyle (I’d suggest the tutorial could be changed to show that).

I’d like to give it some more thoughts though :slight_smile:

1 Like