Skip to content

Commit

Permalink
Use tabIndex="-1" for disabled widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
compulim committed Jun 26, 2020
1 parent 29a7284 commit 3a532e1
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 21 deletions.
10 changes: 3 additions & 7 deletions packages/component/src/Utils/AccessibleButton.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import PropTypes from 'prop-types';
import React, { forwardRef, useRef } from 'react';

import useDisableOnBlurEffect from '../hooks/internal/useDisableOnBlurEffect';

const PREVENT_DEFAULT_HANDLER = event => event.preventDefault();

// Differences between <button> and <AccessibleButton>:
// - Disable behavior
// - When the widget is disabled
// - Set "aria-disabled" attribute to "true"
// - Set "readonly" attribute
// - If the focus is on, don't set "disabled" attribute, until it is blurred
// - Otherwise, set "disabled" attribute
// - Set "tabIndex" to -1
// - Remove "onClick" handler
// - Why this is needed
// - Browser compatibility: when the widget is disabled, different browser send focus to different places
Expand All @@ -24,18 +21,17 @@ const PREVENT_DEFAULT_HANDLER = event => event.preventDefault();
// - aria-disabled="true" is the source of truth
// - If the widget is contained by a <form>, the developer need to filter out some `onSubmit` event caused by this widget

const AccessibleButton = forwardRef(({ disabled, onClick, ...props }, forwardedRef) => {
const AccessibleButton = forwardRef(({ disabled, onClick, tabIndex, ...props }, forwardedRef) => {
const targetRef = useRef();

const ref = forwardedRef || targetRef;

useDisableOnBlurEffect(ref, disabled);

return (
<button
aria-disabled={disabled || undefined}
onClick={disabled ? PREVENT_DEFAULT_HANDLER : onClick}
ref={ref}
tabIndex={disabled ? -1 : tabIndex}
{...props}
type="button"
/>
Expand Down
10 changes: 3 additions & 7 deletions packages/component/src/Utils/AccessibleInputText.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import PropTypes from 'prop-types';
import React, { forwardRef, useRef } from 'react';

import useDisableOnBlurEffect from '../hooks/internal/useDisableOnBlurEffect';

// Differences between <input type="text"> and <AccessibleInputText>:
// - Disable behavior
// - When the widget is disabled
// - Set "aria-disabled" attribute to "true"
// - Set "readonly" attribute
// - If the focus is on, don't set "disabled" attribute until it is blurred
// - Otherwise, set "disabled" attribute to `true`
// - Set "tabIndex" to -1
// - Remove "onChange" handler
// - Why this is needed
// - Browser compatibility: when the widget is disabled, different browser send focus to different places
Expand All @@ -22,19 +19,18 @@ import useDisableOnBlurEffect from '../hooks/internal/useDisableOnBlurEffect';
// - aria-disabled="true" is the source of truth
// - If the widget is contained by a <form>, the developer need to filter out some `onSubmit` event caused by this widget

const AccessibleInputText = forwardRef(({ disabled, onChange, ...props }, forwardedRef) => {
const AccessibleInputText = forwardRef(({ disabled, onChange, tabIndex, ...props }, forwardedRef) => {
const targetRef = useRef();

const ref = forwardedRef || targetRef;

useDisableOnBlurEffect(ref, disabled);

return (
<input
aria-disabled={disabled || undefined}
onChange={disabled ? undefined : onChange}
readOnly={disabled}
ref={ref}
tabIndex={disabled ? -1 : tabIndex}
{...props}
type="text"
/>
Expand Down
10 changes: 3 additions & 7 deletions packages/component/src/Utils/AccessibleTextArea.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import PropTypes from 'prop-types';
import React, { forwardRef, useRef } from 'react';

import useDisableOnBlurEffect from '../hooks/internal/useDisableOnBlurEffect';

// Differences between <textarea> and <AccessibleTextArea>:
// - Disable behavior
// - When the widget is disabled
// - Set "aria-disabled" attribute to "true"
// - Set "readonly" attribute
// - If the focus is on, don't set "disabled" attribute until it is blurred
// - Otherwise, set "disabled" attribute to `true`
// - Set "tabIndex" to -1
// - Remove "onChange" handler
// - Why this is needed
// - Browser compatibility: when the widget is disabled, different browser send focus to different places
Expand All @@ -22,19 +19,18 @@ import useDisableOnBlurEffect from '../hooks/internal/useDisableOnBlurEffect';
// - aria-disabled="true" is the source of truth
// - If the widget is contained by a <form>, the developer need to filter out some `onSubmit` event caused by this widget

const AccessibleTextArea = forwardRef(({ disabled, onChange, ...props }, forwardedRef) => {
const AccessibleTextArea = forwardRef(({ disabled, onChange, tabIndex, ...props }, forwardedRef) => {
const targetRef = useRef();

const ref = forwardedRef || targetRef;

useDisableOnBlurEffect(ref, disabled);

return (
<textarea
aria-disabled={disabled || undefined}
onChange={disabled ? undefined : onChange}
readOnly={disabled}
ref={ref}
tabIndex={disabled ? -1 : tabIndex}
{...props}
/>
);
Expand Down

0 comments on commit 3a532e1

Please sign in to comment.