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?