apply disabled fix when inside a disabled fieldset (#202)

And if we are in a disabled fieldset, double check that we are not in
the first legend. Because in that case we are visually outside of the
fieldset and according to the spec those elements should **not** be
considered disabled.

Fixes: #194
This commit is contained in:
Robin Malfait
2021-01-22 15:41:09 +01:00
committed by GitHub
parent de16c1bd80
commit 5fb605205d
3 changed files with 35 additions and 1 deletions
@@ -12,6 +12,7 @@ import { useId } from '../../hooks/use-id'
import { Keys } from '../keyboard'
import { Focus, calculateActiveIndex } from '../../utils/calculate-active-index'
import { resolvePropValue } from '../../utils/resolve-prop-value'
import { isDisabledReactIssue7711 } from '../../utils/bugs'
enum MenuStates {
Open,
@@ -413,7 +414,8 @@ function Item<TTag extends React.ElementType = typeof DEFAULT_ITEM_TAG>(
}, [bag, id])
const handleClick = React.useCallback(
(event: { preventDefault: Function }) => {
(event: React.MouseEvent) => {
if (isDisabledReactIssue7711(event.currentTarget)) return event.preventDefault()
if (disabled) return event.preventDefault()
dispatch({ type: ActionTypes.CloseMenu })
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
@@ -5,6 +5,7 @@ import { render } from '../../utils/render'
import { useId } from '../../hooks/use-id'
import { Keys } from '../keyboard'
import { resolvePropValue } from '../../utils/resolve-prop-value'
import { isDisabledReactIssue7711 } from '../../utils/bugs'
type StateDefinition = {
switch: HTMLButtonElement | null
@@ -84,6 +85,7 @@ export function Switch<TTag extends React.ElementType = typeof DEFAULT_SWITCH_TA
const toggle = React.useCallback(() => onChange(!checked), [onChange, checked])
const handleClick = React.useCallback(
(event: React.MouseEvent) => {
if (isDisabledReactIssue7711(event.currentTarget)) return event.preventDefault()
event.preventDefault()
toggle()
},
@@ -0,0 +1,30 @@
// See: https://github.com/facebook/react/issues/7711
// See: https://github.com/facebook/react/pull/20612
// See: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-disabled (2.)
export function isDisabledReactIssue7711(element: Element): boolean {
let parent = element.parentElement
let legend = null
while (parent && !(parent instanceof HTMLFieldSetElement)) {
if (parent instanceof HTMLLegendElement) legend = parent
parent = parent.parentElement
}
let isParentDisabled = parent?.getAttribute('disabled') === '' ?? false
if (isParentDisabled && isFirstLegend(legend)) return false
return isParentDisabled
}
function isFirstLegend(element: HTMLLegendElement | null): boolean {
if (!element) return false
let previous = element.previousElementSibling
while (previous !== null) {
if (previous instanceof HTMLLegendElement) return false
previous = previous.previousElementSibling
}
return true
}