diff --git a/packages/dataviews/src/style.scss b/packages/dataviews/src/style.scss
index b85ab247e81a5e..121877e82a8d63 100644
--- a/packages/dataviews/src/style.scss
+++ b/packages/dataviews/src/style.scss
@@ -340,6 +340,7 @@
li {
margin: 0;
+ cursor: pointer;
.dataviews-view-list__item-wrapper {
position: relative;
@@ -355,14 +356,21 @@
background: $gray-100;
height: 1px;
}
- }
- &:not(.is-selected):hover {
- color: var(--wp-admin-theme-color);
+ > * {
+ width: 100%;
+ }
+ }
- .dataviews-view-list__primary-field,
- .dataviews-view-list__fields {
+ &:not(.is-selected) {
+ &:hover,
+ &:focus-within {
color: var(--wp-admin-theme-color);
+
+ .dataviews-view-list__primary-field,
+ .dataviews-view-list__fields {
+ color: var(--wp-admin-theme-color);
+ }
}
}
}
@@ -388,7 +396,8 @@
.dataviews-view-list__item {
padding: $grid-unit-15 0 $grid-unit-15 $grid-unit-30;
width: 100%;
- cursor: pointer;
+ scroll-margin: $grid-unit-10 0;
+
&:focus {
&::before {
position: absolute;
@@ -449,7 +458,9 @@
line-height: $grid-unit-20;
.dataviews-view-list__field {
- &:empty {
+ margin: 0;
+
+ &:has(.dataviews-view-list__field-value:empty) {
display: none;
}
}
diff --git a/packages/dataviews/src/view-list.js b/packages/dataviews/src/view-list.js
index ca6de677b99fd0..677d90c204f812 100644
--- a/packages/dataviews/src/view-list.js
+++ b/packages/dataviews/src/view-list.js
@@ -6,17 +6,135 @@ import classNames from 'classnames';
/**
* WordPress dependencies
*/
-import { useAsyncList } from '@wordpress/compose';
+import { useAsyncList, useInstanceId } from '@wordpress/compose';
import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
+ privateApis as componentsPrivateApis,
Button,
Spinner,
+ VisuallyHidden,
} from '@wordpress/components';
-import { ENTER, SPACE } from '@wordpress/keycodes';
+import { useCallback, useEffect, useRef } from '@wordpress/element';
import { info } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
+/**
+ * Internal dependencies
+ */
+import { unlock } from './lock-unlock';
+
+const {
+ useCompositeStoreV2: useCompositeStore,
+ CompositeV2: Composite,
+ CompositeItemV2: CompositeItem,
+ CompositeRowV2: CompositeRow,
+} = unlock( componentsPrivateApis );
+
+function ListItem( {
+ id,
+ item,
+ isSelected,
+ onSelect,
+ onDetailsChange,
+ mediaField,
+ primaryField,
+ visibleFields,
+} ) {
+ const itemRef = useRef( null );
+ const labelId = `${ id }-label`;
+ const descriptionId = `${ id }-description`;
+
+ useEffect( () => {
+ if ( isSelected ) {
+ itemRef.current?.scrollIntoView( {
+ behavior: 'auto',
+ block: 'nearest',
+ inline: 'nearest',
+ } );
+ }
+ }, [ isSelected ] );
+
+ return (
+
+