diff --git a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx index 1ab4fd0d017901..276ab7549781ed 100644 --- a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx +++ b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx @@ -2,14 +2,13 @@ * External dependencies */ import clsx from 'clsx'; -import { useStoreState } from '@ariakit/react'; import type { ForwardedRef } from 'react'; /** * WordPress dependencies */ import { useInstanceId } from '@wordpress/compose'; -import { forwardRef, useContext } from '@wordpress/element'; +import { forwardRef, useContext, useEffect } from '@wordpress/element'; import { Icon, check } from '@wordpress/icons'; /** @@ -46,18 +45,21 @@ function UnforwardedOptionAsOption( id: string; className?: string; isSelected?: boolean; - compositeStore: NonNullable< - React.ComponentProps< typeof Composite >[ 'store' ] - >; }, forwardedRef: ForwardedRef< any > ) { - const { id, isSelected, compositeStore, ...additionalProps } = props; - const activeId = useStoreState( compositeStore, 'activeId' ); + const { id, isSelected, ...additionalProps } = props; - if ( isSelected && ! activeId ) { - compositeStore.setActiveId( id ); - } + const { setActiveId, activeId } = useContext( CircularOptionPickerContext ); + + useEffect( () => { + if ( isSelected && ! activeId ) { + // The setTimeout call is necessary to make sure that this update + // doesn't get overridden by `Composite`'s internal logic, which picks + // an initial active item if one is not specifically set. + window.setTimeout( () => setActiveId?.( id ), 0 ); + } + }, [ isSelected, setActiveId, activeId, id ] ); return ( + const isListbox = setActiveId !== undefined; + const optionControl = isListbox ? ( + ) : ( ); diff --git a/packages/components/src/circular-option-picker/circular-option-picker.tsx b/packages/components/src/circular-option-picker/circular-option-picker.tsx index c878000aff84b8..adf2b386e5cbec 100644 --- a/packages/components/src/circular-option-picker/circular-option-picker.tsx +++ b/packages/components/src/circular-option-picker/circular-option-picker.tsx @@ -8,13 +8,13 @@ import clsx from 'clsx'; */ import { useInstanceId } from '@wordpress/compose'; import { isRTL } from '@wordpress/i18n'; +import { useMemo, useState } from '@wordpress/element'; /** * Internal dependencies */ import { CircularOptionPickerContext } from './circular-option-picker-context'; import { Composite } from '../composite'; -import { useCompositeStore } from '../composite/store'; import type { CircularOptionPickerProps, ListboxCircularOptionPickerProps, @@ -86,24 +86,30 @@ function ListboxCircularOptionPicker( ...additionalProps } = props; - const compositeStore = useCompositeStore( { - focusLoop: loop, - rtl: isRTL(), - } ); + const [ activeId, setActiveId ] = useState< string | null | undefined >( + undefined + ); - const compositeContext = { - baseId, - compositeStore, - }; + const contextValue = useMemo( + () => ( { + baseId, + activeId, + setActiveId, + } ), + [ baseId, activeId, setActiveId ] + ); return (
- + { options } @@ -119,9 +125,16 @@ function ButtonsCircularOptionPicker( ) { const { actions, options, children, baseId, ...additionalProps } = props; + const contextValue = useMemo( + () => ( { + baseId, + } ), + [ baseId ] + ); + return (
- + { options } { children } { actions } diff --git a/packages/components/src/circular-option-picker/types.ts b/packages/components/src/circular-option-picker/types.ts index e23ff4165f0580..411782aed575b1 100644 --- a/packages/components/src/circular-option-picker/types.ts +++ b/packages/components/src/circular-option-picker/types.ts @@ -14,7 +14,6 @@ import type { Icon } from '@wordpress/icons'; import type { ButtonAsButtonProps } from '../button/types'; import type { DropdownProps } from '../dropdown/types'; import type { WordPressComponentProps } from '../context'; -import type { Composite } from '../composite'; type CommonCircularOptionPickerProps = { /** @@ -125,5 +124,6 @@ export type OptionProps = Omit< export type CircularOptionPickerContextProps = { baseId?: string; - compositeStore?: React.ComponentProps< typeof Composite >[ 'store' ]; + activeId?: string | null | undefined; + setActiveId?: ( newId: string | null | undefined ) => void; };