Skip to content

Commit

Permalink
Implement flushSync-based workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
ciampo committed Aug 30, 2024
1 parent 61d121d commit 2b116ee
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
6 changes: 5 additions & 1 deletion packages/components/src/dropdown-menu-v2/checkbox-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,24 @@ import type { WordPressComponentProps } from '../context';
import { DropdownMenuContext } from './context';
import type { DropdownMenuCheckboxItemProps } from './types';
import * as Styled from './styles';
import { useTemporaryFocusVisibleFix } from './use-temporary-focus-visible-fix';

export const DropdownMenuCheckboxItem = forwardRef<
HTMLDivElement,
WordPressComponentProps< DropdownMenuCheckboxItemProps, 'div', false >
>( function DropdownMenuCheckboxItem(
{ suffix, children, hideOnClick = false, ...props },
{ suffix, children, onBlur, hideOnClick = false, ...props },
ref
) {
// TODO: Remove when https://github.com/ariakit/ariakit/issues/4083 is fixed
const focusVisibleFixProps = useTemporaryFocusVisibleFix( { onBlur } );
const dropdownMenuContext = useContext( DropdownMenuContext );

return (
<Styled.DropdownMenuCheckboxItem
ref={ ref }
{ ...props }
{ ...focusVisibleFixProps }
accessibleWhenDisabled
hideOnClick={ hideOnClick }
store={ dropdownMenuContext?.store }
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/dropdown-menu-v2/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,24 @@ import type { WordPressComponentProps } from '../context';
import type { DropdownMenuItemProps } from './types';
import * as Styled from './styles';
import { DropdownMenuContext } from './context';
import { useTemporaryFocusVisibleFix } from './use-temporary-focus-visible-fix';

export const DropdownMenuItem = forwardRef<
HTMLDivElement,
WordPressComponentProps< DropdownMenuItemProps, 'div', false >
>( function DropdownMenuItem(
{ prefix, suffix, children, hideOnClick = true, ...props },
{ prefix, suffix, children, onBlur, hideOnClick = true, ...props },
ref
) {
// TODO: Remove when https://github.com/ariakit/ariakit/issues/4083 is fixed
const focusVisibleFixProps = useTemporaryFocusVisibleFix( { onBlur } );
const dropdownMenuContext = useContext( DropdownMenuContext );

return (
<Styled.DropdownMenuItem
ref={ ref }
{ ...props }
{ ...focusVisibleFixProps }
accessibleWhenDisabled
hideOnClick={ hideOnClick }
store={ dropdownMenuContext?.store }
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/dropdown-menu-v2/radio-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { DropdownMenuContext } from './context';
import type { DropdownMenuRadioItemProps } from './types';
import * as Styled from './styles';
import { SVG, Circle } from '@wordpress/primitives';
import { useTemporaryFocusVisibleFix } from './use-temporary-focus-visible-fix';

const radioCheck = (
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
Expand All @@ -28,15 +29,18 @@ export const DropdownMenuRadioItem = forwardRef<
HTMLDivElement,
WordPressComponentProps< DropdownMenuRadioItemProps, 'div', false >
>( function DropdownMenuRadioItem(
{ suffix, children, hideOnClick = false, ...props },
{ suffix, children, onBlur, hideOnClick = false, ...props },
ref
) {
// TODO: Remove when https://github.com/ariakit/ariakit/issues/4083 is fixed
const focusVisibleFixProps = useTemporaryFocusVisibleFix( { onBlur } );
const dropdownMenuContext = useContext( DropdownMenuContext );

return (
<Styled.DropdownMenuRadioItem
ref={ ref }
{ ...props }
{ ...focusVisibleFixProps }
accessibleWhenDisabled
hideOnClick={ hideOnClick }
store={ dropdownMenuContext?.store }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* WordPress dependencies
*/
import { useState, flushSync } from '@wordpress/element';

export function useTemporaryFocusVisibleFix( {
onBlur: onBlurProp,
}: {
onBlur?: React.FocusEventHandler< HTMLDivElement >;
} ) {
const [ focusVisible, setFocusVisible ] = useState( false );
return {
'data-focus-visible': focusVisible || undefined,
onFocusVisible: () => {
flushSync( () => setFocusVisible( true ) );
},
onBlur: ( ( event ) => {
onBlurProp?.( event );
setFocusVisible( false );
} ) as React.FocusEventHandler< HTMLDivElement >,
};
}

0 comments on commit 2b116ee

Please sign in to comment.