Skip to content

Commit

Permalink
CircularOptionPicker: do not use composite store directly
Browse files Browse the repository at this point in the history
  • Loading branch information
ciampo committed Aug 27, 2024
1 parent 956cfbd commit f124cf0
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -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 (
<Composite.Item
Expand All @@ -83,9 +85,7 @@ export function Option( {
tooltipText,
...additionalProps
}: OptionProps ) {
const { baseId, compositeStore } = useContext(
CircularOptionPickerContext
);
const { baseId, setActiveId } = useContext( CircularOptionPickerContext );
const id = useInstanceId(
Option,
baseId || 'components-circular-option-picker__option'
Expand All @@ -97,12 +97,9 @@ export function Option( {
...additionalProps,
};

const optionControl = compositeStore ? (
<OptionAsOption
{ ...commonProps }
compositeStore={ compositeStore }
isSelected={ isSelected }
/>
const isListbox = setActiveId !== undefined;
const optionControl = isListbox ? (
<OptionAsOption { ...commonProps } isSelected={ isSelected } />
) : (
<OptionAsButton { ...commonProps } isPressed={ isSelected } />
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 (
<div className={ className }>
<CircularOptionPickerContext.Provider value={ compositeContext }>
<CircularOptionPickerContext.Provider value={ contextValue }>
<Composite
{ ...additionalProps }
id={ baseId }
store={ compositeStore }
focusLoop={ loop }
rtl={ isRTL() }
role="listbox"
activeId={ activeId }
setActiveId={ setActiveId }
>
{ options }
</Composite>
Expand All @@ -119,9 +125,16 @@ function ButtonsCircularOptionPicker(
) {
const { actions, options, children, baseId, ...additionalProps } = props;

const contextValue = useMemo(
() => ( {
baseId,
} ),
[ baseId ]
);

return (
<div { ...additionalProps } id={ baseId }>
<CircularOptionPickerContext.Provider value={ { baseId } }>
<CircularOptionPickerContext.Provider value={ contextValue }>
{ options }
{ children }
{ actions }
Expand Down
4 changes: 2 additions & 2 deletions packages/components/src/circular-option-picker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
/**
Expand Down Expand Up @@ -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;
};

0 comments on commit f124cf0

Please sign in to comment.