Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

I want to make a <TextFieldControl> component that passes a <Description> component to its render function.

Rendering a <Description> would automatically add an id to the element, and then add that id to the aria-describedby prop of the associated input.

For example, this component:

const EmailField = ({ error, value, onChange }) =>
  <TextFieldControl
    type="email"
    onChange={onChange}
    error={error}
    value={value}
    render={({ Description, Input, Label }) =>
      <div className='field-wrapper'>
        <Label className='label'>E-mail</Label>
        <Input className='input' />
        <Description className='message'>We'll use this to contact you if anything pops up.</Description>
      </div>
    }
  />

Should render HTML that looks something like this:

<div class='field-wrapper'>
  <label class='label' for='_control_1'>E-mail</label>
  <input class='input' id='_control_1' value='...' aria-describedby='_control_1_description' />
  <span class='message' id='_control_1_description'>
    We'll use this to contact you if anything pops up.
  </span>
</div>

The idea behind this API is that it should be easier to add descriptions, labels, etc. if you don't need to think about ids. This is important in the React world, as the more you use components, the less you want to think about ids.


The problem, is that you only want to add an aria-describedby when a <Description> element has been rendered. However, you don't know if one has been rendered at the time you render <Input>.

It would be possible to use context to add aria-describedby to the <input> element after it is initially rendered, but this would mean that rendering <TextFieldControl> once would result in multiple DOM updates. And I'm wondering if there is a simpler way, or if this is just a terrible idea from the start?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.