Skip to content

linter: False positive for aria-proptypes #17465

Description

@david-crespo

What version of Oxlint are you using?

1.36.0

What command did you run?

oxlint --type-aware

What does your .oxlintrc.json config file look like?

{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "jsPlugins": [
    {
      "name": "playwright",
      "specifier": "eslint-plugin-playwright"
    },
    {
      "name": "react-hook-form",
      "specifier": "eslint-plugin-react-hook-form"
    }
    // eslint-plugin-react-hook-form won't work — all its rules use context.getScope()
  ],
  "plugins": [
    "import",
    "react",
    "jsx-a11y",
    "promise",
    // defaults (see https://oxc.rs/docs/guide/usage/linter/plugins.html#supported-plugins)
    "unicorn",
    "typescript",
    "oxc"
  ],
  "categories": {
    "correctness": "error"
  },
  "rules": {
    // only worry about console.log
    "no-console": ["error", { "allow": ["warn", "error", "info", "table"] }],
    "no-unused-vars": [
      "error",
      {
        "argsIgnorePattern": "^_",
        "varsIgnorePattern": "^_",
        "caughtErrorsIgnorePattern": "^_"
      }
    ],

    "react/button-has-type": "error",
    "react/jsx-boolean-value": "error",

    "react-hooks/exhaustive-deps": "error",
    "react-hooks/rules-of-hooks": "error",
    "import/no-default-export": "error",
    "consistent-type-imports": "error",

    // Missing ESLint core rules
    "eqeqeq": ["error", "always", { "null": "ignore" }],
    "no-param-reassign": "error",
    "no-return-assign": "error",
    "no-restricted-imports": [
      "error",
      {
        // prevent confusion due to auto-imports and barrel files
        "paths": ["."],
        "patterns": [
          // import all CSS except index.css at top level through CSS @import statements
          // to avoid bad ordering situations. See https://github.com/oxidecomputer/console/pull/2035
          "*.css"
        ]
      }
    ],
    "radix": "error",

    // TypeScript rules (currently disabled but available)
    "@typescript-eslint/no-floating-promises": "off",
    "@typescript-eslint/unbound-method": "off",
    "react-hook-form/destructuring-formstate": "error",
    "react-hook-form/no-nested-object-setvalue": "error",
    "react-hook-form/no-access-control": "error"
  },
  "overrides": [
    {
      // default exports are needed in the route modules and the config files,
      // but we want to avoid them anywhere else
      "files": [
        "app/pages/**/*",
        "app/layouts/**/*",
        "app/forms/**/*",
        "*.config.ts",
        "*.config.mjs"
      ],
      "rules": {
        "import/no-default-export": "off"
      }
    },
    {
      // catch unawaited Playwright calls in e2e tests
      "files": ["test/e2e/**/*.ts"],
      "rules": {
        "@typescript-eslint/no-floating-promises": "error",
        "playwright/expect-expect": [
          "warn",
          {
            "assertFunctionNames": [
              "expectVisible",
              "expectRowVisible",
              "expectOptions",
              "expectRowMenuStaysOpen"
            ]
          }
        ],
        "playwright/no-force-option": "off"
      }
    }
  ],
  "ignorePatterns": ["dist/", "node_modules/"]
}

What happened?

I think the string interpolation is throwing the linter off here. As far as I can tell both of these should be accepted by the linter. Ran into this while switching to oxlint in oxidecomputer/console#2998.

  × eslint-plugin-jsx-a11y(aria-proptypes): This is not a valid ARIA state and property value for 'aria-labelledby'.
     ╭─[app/components/form/fields/TextField.tsx:120:9]
 119 │         error={!!error}
 120 │         aria-labelledby={`${id}-label ${id}-help-text`}
     ·         ───────────────────────────────────────────────
 121 │         onChange={(e) => onChange(transform ? transform(e.target.value) : e.target.value)}
     ╰────
  help: The valid value for 'aria-labelledby' is: a space-separated list of element IDs.
        You can find a list of valid ARIA state and property values at https://www.w3.org/TR/wai-aria/#x6-7-definitions-of-states-and-properties-all-aria-attributes

  × eslint-plugin-jsx-a11y(aria-proptypes): This is not a valid ARIA state and property value for 'aria-labelledby'.
    ╭─[app/components/form/fields/RadioField.tsx:83:9]
 82 │         defaultChecked={field.value}
 83 │         aria-labelledby={`${id}-label`}
    ·         ───────────────────────────────
 84 │         onChange={(e) =>
    ╰────
  help: The valid value for 'aria-labelledby' is: a space-separated list of element IDs.
        You can find a list of valid ARIA state and property values at https://www.w3.org/TR/wai-aria/#x6-7-definitions-of-states-and-properties-all-aria-attributes

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions