microsoft/tslint-microsoft-contrib

react-a11y-no-onchange should allow onChange when onBlur is present

huan086 opened this issue · 0 comments

Bug Report

  • tslint-microsoft-contrib version: 6.0.0
  • TSLint version: 5.12.1
  • TypeScript version: 3.3.3
  • Running TSLint via: webpack fork-ts-checker-webpack-plugin

TypeScript code being linted

export const RouterRowsPerPage = ({ rowsPerPage, history, query }: RowsPerPageProps): JSX.Element => {
    const queryString = stringify(query);
    const [focusState, setFocusState] = useState(false);
    const [selectState, setSelectState] = useState(rowsPerPage);

    const onFocus = useCallback(
        (e: FocusEvent<HTMLSelectElement>) => {
            setFocusState(true);
        },
        []);

    // For accessibility, only change the URL onBlur.
    const onBlur = useCallback(
        (e: FocusEvent<HTMLSelectElement>) => {
            setFocusState(false);

            const newRowsPerPage = parseInt(e.target.value, 10);
            if (rowsPerPage !== newRowsPerPage) {
                history.push(`?${stringify({ ...query, rowsPerPage: newRowsPerPage })}`);
            }
        },
        [queryString, history, rowsPerPage]);

    const onChange = useCallback(
        (e: FocusEvent<HTMLSelectElement>) => {
            const newRowsPerPage = parseInt(e.target.value, 10);
            setSelectState(newRowsPerPage);
        },
        []);

    const selectValue = focusState ? selectState : rowsPerPage;
    return (
        <select onChange={onChange} onFocus={onFocus} onBlur={onBlur} value={selectValue}>
            {options.map(option => (
                <option key={option} role="option" value={option} aria-selected={rowsPerPage === option}>{option}</option>
            ))}
        </select>
    );
};

with tslint.json configuration:

{
  "extends": [ "tslint:latest", "tslint-react", "tslint-microsoft-contrib", "tslint-config-airbnb", "tslint-sonarts" ],
  "linterOptions": {
    "exclude": [ "**/*.json" ]
  },
  "rules": {
    "ter-indent": [ true, 4 ]
  }
}

Actual behavior

react-a11y-no-onchange: onChange event handler should not be used with the <select>. Please use onBlur instead.

Expected behavior

onChange is required for controlled components. See also eslint, which allows onChange as long as onBlur exists