sveltejs / svelte

web development for the rest of us
https://svelte.dev
MIT License
80.02k stars 4.26k forks source link

`a11y-label-has-associated-control` error for control inside of component #6469

Open nikmolnar opened 3 years ago

nikmolnar commented 3 years ago

Describe the bug

The a11y-label-has-associated-control linting error is raised whenever a nested control is contained in a child component. For example, if you have a custom component, TextInput, which renders an <input />, then this produces the "no associated control" error.

<label>
    A label
    <TextInput />
</label>

This issue is similar to #5528, where this error is generated if the input is inside a conditional statement.

Reproduction

This REPL demonstrates the issue: https://svelte.dev/repl/8396b0b08a2d460da2d7e781cc0ee4b7?version=3.38.3

Logs

No response

System Info

System:
    OS: macOS 11.1
    CPU: (6) x64 Intel(R) Core(TM) i5-8600 CPU @ 3.10GHz
    Memory: 122.49 MB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 10.22.1 - ~/.nvm/versions/node/v10.22.1/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.6 - ~/.nvm/versions/node/v10.22.1/bin/npm
  Browsers:
    Chrome: 91.0.4472.114
    Firefox: 89.0
    Safari: 14.0.2
  npmPackages:
    svelte: ==3.36.0 => 3.36.0 
    webpack: ^5.37.1 => 5.37.1

Severity

annoyance

Conduitry commented 3 years ago

There's not really a reasonable way to handle this well, because each component is compiled independently. I guess we could not emit a warning whenever there's any component inside the label. That would eliminate these false positives but add false negatives. I'm not sure which is better.

You can also always add a comment to suppress the warning. This isn't an error and isn't stopping the component from being compiled.

nikmolnar commented 3 years ago

@Conduitry thanks for the explanation!

The label-has-associated-control rule from the jsx-a11y package has an optional configuration called controlComponents that allows you to specify names of custom components that should be considered controls. Could something like that work here?

Even though this is only a warning, I think it's important to have some way of satisfying this rule, as "noisy" warnings start to get ignored at some point, which makes them less useful. For now, I'm suppressing the warning as you suggest, but it would be nice to have some other options.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

SamMousa commented 2 years ago

I'm pretty new to Svelte, but from what I understand the warnings are emitted from the Svelte compiler. One thing we could do is have an option tag to mark something as having an input.

<svelte:options isInput={true}/>

This of course requires that (sub)components are compiled before their parents.

Alternatively, a simple but very powerful option is to implement some kind of annotation to silence a warning locally:

<svelte:options ignore-a11y-label-has-associated-control/>
<label>
    A label

    <TextInput />
</label>

This would then allow the compiler to ignore an error on a component level. The benefit of this approach is that it'll always be available as a workaround for false positives, even if we reduce the number of false positives in the future.

Prinzhorn commented 1 year ago

Alternatively, a simple but very powerful option is to implement some kind of annotation to silence a warning locally:

For completeness sake, this exists:

<!-- svelte-ignore a11y-label-has-associated-control -->
<label>
    A label

    <TextInput />
</label>
Lootwig commented 1 year ago

There's not really a reasonable way to handle this well, because each component is compiled independently.

Is that the only possible way to compile?