Skip to content

Commit

Permalink
Dataviews Filter search widget: do not use Composite store (#64985)
Browse files Browse the repository at this point in the history
* Dataviews Filter search widget: do not use Composite store

* Use internal CompositeHover and CompositeTypeahead version

* Better comment

* Refactor generateCompositeItemId arguments

* Export Composite.Typeahead and Composite.Hover as private APIs

* CHANGELOG

---

Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: tyxla <tyxla@git.wordpress.org>
  • Loading branch information
3 people authored Sep 3, 2024
1 parent 9d4f918 commit 7b7196f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@

### Internal

- `DropdownMenu` v2: expose CompositeTypeaheadV2 and CompositeHoverV2 via private APIs ([#64985](https://github.com/WordPress/gutenberg/pull/64985)).
- `DropdownMenu` v2: fix flashing menu item styles when using keyboard ([#64873](https://github.com/WordPress/gutenberg/pull/64873), [#64942](https://github.com/WordPress/gutenberg/pull/64942)).
- `DropdownMenu` v2: refactor to overloaded naming convention ([#64654](https://github.com/WordPress/gutenberg/pull/64654)).
- `DropdownMenu` v2: add `GroupLabel` subcomponent ([#64854](https://github.com/WordPress/gutenberg/pull/64854)).
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/private-apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ lock( privateApis, {
CompositeGroupV2: Composite.Group,
CompositeItemV2: Composite.Item,
CompositeRowV2: Composite.Row,
CompositeTypeaheadV2: Composite.Typeahead,
CompositeHoverV2: Composite.Hover,
useCompositeStoreV2: useCompositeStore,
__experimentalPopoverLegacyPositionToPlacement,
createPrivateSlotFill,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import removeAccents from 'remove-accents';
/**
* WordPress dependencies
*/
import { useInstanceId } from '@wordpress/compose';
import { __, sprintf } from '@wordpress/i18n';
import { useState, useMemo, useDeferredValue } from '@wordpress/element';
import {
Expand All @@ -27,7 +28,8 @@ import type { Filter, NormalizedFilter, View } from '../../types';
const {
CompositeV2: Composite,
CompositeItemV2: CompositeItem,
useCompositeStoreV2: useCompositeStore,
CompositeHoverV2: CompositeHover,
CompositeTypeaheadV2: CompositeTypeahead,
} = unlock( componentsPrivateApis );

interface SearchWidgetProps {
Expand Down Expand Up @@ -84,22 +86,37 @@ const getNewValue = (
return [ value ];
};

function generateFilterElementCompositeItemId(
prefix: string,
filterElementValue: string
) {
return `${ prefix }-${ filterElementValue }`;
}

function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) {
const compositeStore = useCompositeStore( {
virtualFocus: true,
focusLoop: true,
// When we have no or just one operator, we can set the first item as active.
// We do that by passing `undefined` to `defaultActiveId`. Otherwise, we set it to `null`,
// so the first item is not selected, since the focus is on the operators control.
defaultActiveId: filter.operators?.length === 1 ? undefined : null,
} );
const baseId = useInstanceId( ListBox, 'dataviews-filter-list-box' );

const [ activeCompositeId, setActiveCompositeId ] = useState<
string | null | undefined
>(
// When there are one or less operators, the first item is set as active
// (by setting the initial `activeId` to `undefined`).
// With 2 or more operators, the focus is moved on the operators control
// (by setting the initial `activeId` to `null`), meaning that there won't
// be an active item initially. Focus is then managed via the
// `onFocusVisible` callback.
filter.operators?.length === 1 ? undefined : null
);
const currentFilter = view.filters?.find(
( f ) => f.field === filter.field
);
const currentValue = getCurrentValue( filter, currentFilter );
return (
<Composite
store={ compositeStore }
virtualFocus
focusLoop
activeId={ activeCompositeId }
setActiveId={ setActiveCompositeId }
role="listbox"
className="dataviews-filters__search-widget-listbox"
aria-label={ sprintf(
Expand All @@ -108,18 +125,29 @@ function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) {
filter.name
) }
onFocusVisible={ () => {
if ( ! compositeStore.getState().activeId ) {
compositeStore.move( compositeStore.first() );
// `onFocusVisible` needs the `Composite` component to be focusable,
// which is implicitly achieved via the `virtualFocus: true` option
// in the `useCompositeStore` hook.
if ( ! activeCompositeId && filter.elements.length ) {
setActiveCompositeId(
generateFilterElementCompositeItemId(
baseId,
filter.elements[ 0 ].value
)
);
}
} }
render={ <Ariakit.CompositeTypeahead store={ compositeStore } /> }
render={ <CompositeTypeahead /> }
>
{ filter.elements.map( ( element ) => (
<Ariakit.CompositeHover
store={ compositeStore }
<CompositeHover
key={ element.value }
render={
<CompositeItem
id={ generateFilterElementCompositeItemId(
baseId,
element.value
) }
render={
<div
aria-label={ element.label }
Expand Down Expand Up @@ -185,7 +213,7 @@ function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) {
) }
</span>
<span>{ element.label }</span>
</Ariakit.CompositeHover>
</CompositeHover>
) ) }
</Composite>
);
Expand Down

0 comments on commit 7b7196f

Please sign in to comment.