-
Notifications
You must be signed in to change notification settings - Fork 841
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tie field to label without explicit id, and to supporting elements #130
Conversation
…a aria attributes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good, but can we get some test coverage of the aria field getting injected?
Yes, would be good to add. Should have mentioned this isn't intended to be merge-ready just yet. Another issue is that all requisite generation is repeated each render, so depending on rerender frequency there could be a lot of churn. We address this in Cloud's |
FYI I think there's a service around that can do this already. https://github.com/elastic/eui/blob/master/src/services/accessibility/html_id_generator.js @cjcenizal pulled it in a little later on, which is why the docs didn't use it as much. He'll know more about it then me. |
Even better. Is that globally mocked for tests by chance? |
@zinckiwi Not sure what you mean by globally mocked? It's not global, so you'll need to import it into your test to use it. |
But we can't snapshot a randomly generated id -- it will need to return some deterministic value in a test, surely? |
Ah I see. I think the usage of // Instantiate an ID generator with a prefix.
const idGenerator = htmlIdGenerator('loginForm');
// Then you can create "namespaced" IDs by calling the generator with a suffix.
const userNameId = idGenerator('userName');
const passwordId = idGenerator('password');
// "loginForm_userName" and "loginForm_password" respectively.
// You can use the dynamically-created UID feature by omitting the suffix argument.
const emailId = idGenerator();
// "loginForm_${random UID}" I think the whole point behind this service is to allow you to generate unique IDs for repetitive, dynamically-generated forms. Where you'll have several inputs which repeat but which will still need unique IDs. Does this help at all? |
Ah, I understand. I'm getting at something different here. Labels need to be tied to inputs, and inputs need to be tied to related descriptive elements (i.e. help text and errors). That must be done through Given all that, I like to generate statistically almost-certanly-unique |
Makes sense to me. Does the last example in the code snippet address this? const emailId = idGenerator(); |
Oh, and I'm sorry I should also clarify that the IDs in my example are intended to be assigned to labels, form elements, and descriptive text elements, which is what you are trying to do. |
Yep, should do. I mean, they're both probably the same thing perhaps differing by length -- my bigger concern is the churn so if you have thoughts on that I'm all ears! |
Well, now that I've actually read the code in this PR I am able to provide better suggestions... go figure. 🤕 I jumped into the middle of the convo so I missed the overarching context. Is there any reason we shouldn't just make |
hasEmptyLabelSpace, | ||
fullWidth, | ||
className, | ||
...rest | ||
} = this.props; | ||
|
||
const id = rest.id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we make id
required, the consumer can use the generator to create an id
with a unique suffix.
@@ -60,7 +65,7 @@ export class EuiFormRow extends Component { | |||
|
|||
if (helpText) { | |||
optionalHelpText = ( | |||
<EuiFormHelpText className="euiFormRow__text"> | |||
<EuiFormHelpText id={makeId()} className="euiFormRow__text"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could then append the string "help" to the id
that was provided to create this id
.
@@ -71,7 +76,7 @@ export class EuiFormRow extends Component { | |||
if (error) { | |||
const errorTexts = Array.isArray(error) ? error : [error]; | |||
optionalErrors = errorTexts.map(error => ( | |||
<EuiFormErrorText key={error} className="euiFormRow__text"> | |||
<EuiFormErrorText key={error} id={makeId()} className="euiFormRow__text"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do something similar here by appending "error" and index
to create IDs for the errors.
Well, that's what I meant about manually specifying them... in the React world at least I don't think they serve any purpose beyond this one, so offloading that burden truly is that -- and multiplying the burden by however many customers there are. And unless you only ever write forms at a "page" level, you never know if you'll have |
Recapping quick zoom chat with CJ:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great man! I had one minor suggestion.
@@ -0,0 +1,3 @@ | |||
export default function makeId() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a comment for posterity?
// Generate statistically almost-certainly-unique `id`s for associating form inputs with their labels
// and other descriptive text elements.
…e-field-parts # Conflicts: # CHANGELOG.md
id
for the field if necessary, similar to what the docs doaria-describedby
attributes