Skip to content
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

control-has-associated-label returns false positive, even wrapped AND with htmlFor #681

Closed
vjwilson opened this issue Apr 26, 2020 · 7 comments · Fixed by #709
Closed

control-has-associated-label returns false positive, even wrapped AND with htmlFor #681

vjwilson opened this issue Apr 26, 2020 · 7 comments · Fixed by #709

Comments

@vjwilson
Copy link

eslint version: 6.8.0
eslint-plugin-jsx-a11y: 6.2.3

The following code block, with a label wrapping an input, AND a htmlFor attribute on the label with the ID of the input, is still being flagged by ESLint, both at the command line and in VSCode integration.

                <label
                    htmlFor="new-policy-name"
                    className="flex flex-col ml-4 block py-2 text-base-600 font-700"
                >
                    <span>New name:</span>
                    <Field name="newName">
                        {({ field, form }) => {
                            const isDisabled = form.values.resolution !== 'rename';
                            return (
                                <input
                                    className={`bg-base-100 ${
                                        isDisabled ? 'bg-base-200' : 'hover:border-base-400'
                                    } border-2 rounded p-2 border-base-300 w-full font-600 text-base-600 leading-normal min-h-10`}
                                    name={field.name}
                                    id="new-policy-name"
                                    type="text"
                                    value={field.value}
                                    disabled={isDisabled}
                                    onChange={changeText(field.onChange, field.name)}
                                />
                            );
                        }}
                    </Field>
                </label>
  • Using Formik <Field> component to render the input (https://jaredpalmer.com/formik/docs/api/field)
  • Not just this input, but 2 other similar ones in the same file.
  • We also tried moving the label INSIDE the return block for the component, but it still shows an error.

The rendered DOM looks accessesible,

<label for="new-policy-name" class="flex flex-col ml-4 block py-2 text-base-600 font-700">
    <span>New name:</span>
    <input class="bg-base-100 hover:border-base-400 border-2 rounded p-2 border-base-300 w-full font-600 text-base-600 leading-normal min-h-10" name="newName" id="new-policy-name" type="text" value="">
</label>

and none of the 3 elements get flagged with the Axe Chrome plugin.

Is this a bug in the jsx-a11y plugin?

@ljharb
Copy link
Member

ljharb commented Apr 26, 2020

I assume this is because it’s inside a render prop instead of being an actual child.

I don’t think it’s safe to assume that a render prop will be rendered, so I’m not sure what the solution would be. I agree that if/since that render prop ends up being rendered as a child of the label, it’s fine.

Is there a reason you couldn’t put the label inside the render prop too?

@vjwilson
Copy link
Author

We tried that, and I just tried again, to make sure I didn't miss anything, but it still shows as wrong in VSCode and when running eslint.

This does not fix the issue:

                <Field name="newName">
                    {({ field, form, meta }) => {
                        const isDisabled = form.values.resolution !== 'rename';
                        return (
                            <label
                                htmlFor="new-policy-name"
                                className="flex flex-col ml-4 block py-2 text-base-600 font-700"
                            >
                                <span className="mb-2">New name:</span>
                                <input
                                    className={`bg-base-100 ${
                                        isDisabled ? 'bg-base-200' : 'hover:border-base-400'
                                    } border-2 rounded p-2 border-base-300 w-full font-600 text-base-600 leading-normal min-h-10`}
                                    name={field.name}
                                    id="new-policy-name"
                                    type="text"
                                    value={field.value}
                                    disabled={isDisabled}
                                    onChange={changeText(field.onChange, field.name)}
                                    onBlur={field.onBlur}
                                />
                                {meta.touched && meta.error && (
                                    <div
                                        className="text-alert-700 mt-1"
                                        data-testid="new-name-error"
                                    >
                                        {meta.error}
                                    </div>
                                )}
                            </label>
                        );
                    }}
                </Field>

@ljharb
Copy link
Member

ljharb commented Apr 27, 2020

That's very strange - in the last example, I can't see any reason why it wouldn't pass.

@herecydev
Copy link

herecydev commented May 28, 2020

Also experiencing this issue. Can be reproduced as simple as:

import React from "react"

export default () => {
  return (
    <label>
      Foo
      <input type="text" />
    </label>
  )
}

@herecydev
Copy link

Forgive me, a framework had turned this to straight warning which was causing a slew of warnings

@ljharb
Copy link
Member

ljharb commented May 28, 2020

@herecydev that one also needs for/ID-linking to be valid with the airbnb config, for example.

@jessebeach
Copy link
Collaborator

The cases noted in the issue are passing in version 6.3.x

jessebeach_jessebeach-mbp____code_evcohen_eslint-plugin-jsx-a11y_and_Preferences

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants