@wordpress/dataviews 4.6.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +596 -89
  3. package/build/components/dataform-combined-edit/index.js +12 -6
  4. package/build/components/dataform-combined-edit/index.js.map +1 -1
  5. package/build/components/dataviews/index.js +8 -1
  6. package/build/components/dataviews/index.js.map +1 -1
  7. package/build/components/dataviews-bulk-actions/index.js +6 -6
  8. package/build/components/dataviews-bulk-actions/index.js.map +1 -1
  9. package/build/components/dataviews-context/index.js +2 -0
  10. package/build/components/dataviews-context/index.js.map +1 -1
  11. package/build/components/dataviews-filters/add-filter.js +7 -7
  12. package/build/components/dataviews-filters/add-filter.js.map +1 -1
  13. package/build/components/dataviews-filters/index.js +2 -2
  14. package/build/components/dataviews-filters/index.js.map +1 -1
  15. package/build/components/dataviews-item-actions/index.js +11 -11
  16. package/build/components/dataviews-item-actions/index.js.map +1 -1
  17. package/build/components/dataviews-layout/index.js +5 -1
  18. package/build/components/dataviews-layout/index.js.map +1 -1
  19. package/build/components/dataviews-selection-checkbox/index.js +1 -2
  20. package/build/components/dataviews-selection-checkbox/index.js.map +1 -1
  21. package/build/components/dataviews-view-config/index.js +6 -6
  22. package/build/components/dataviews-view-config/index.js.map +1 -1
  23. package/build/components/form-field-visibility/index.js +32 -0
  24. package/build/components/form-field-visibility/index.js.map +1 -0
  25. package/build/dataforms-layouts/panel/index.js +9 -3
  26. package/build/dataforms-layouts/panel/index.js.map +1 -1
  27. package/build/dataforms-layouts/regular/index.js +8 -2
  28. package/build/dataforms-layouts/regular/index.js.map +1 -1
  29. package/build/dataviews-layouts/grid/index.js +14 -3
  30. package/build/dataviews-layouts/grid/index.js.map +1 -1
  31. package/build/dataviews-layouts/list/index.js +10 -12
  32. package/build/dataviews-layouts/list/index.js.map +1 -1
  33. package/build/dataviews-layouts/table/column-header-menu.js +18 -18
  34. package/build/dataviews-layouts/table/column-header-menu.js.map +1 -1
  35. package/build/dataviews-layouts/table/index.js +22 -5
  36. package/build/dataviews-layouts/table/index.js.map +1 -1
  37. package/build/dataviews-layouts/utils/get-clickable-item-props.js +25 -0
  38. package/build/dataviews-layouts/utils/get-clickable-item-props.js.map +1 -0
  39. package/build/normalize-fields.js +16 -3
  40. package/build/normalize-fields.js.map +1 -1
  41. package/build/types.js.map +1 -1
  42. package/build/validation.js +9 -0
  43. package/build/validation.js.map +1 -1
  44. package/build-module/components/dataform-combined-edit/index.js +12 -6
  45. package/build-module/components/dataform-combined-edit/index.js.map +1 -1
  46. package/build-module/components/dataviews/index.js +8 -1
  47. package/build-module/components/dataviews/index.js.map +1 -1
  48. package/build-module/components/dataviews-bulk-actions/index.js +6 -6
  49. package/build-module/components/dataviews-bulk-actions/index.js.map +1 -1
  50. package/build-module/components/dataviews-context/index.js +2 -0
  51. package/build-module/components/dataviews-context/index.js.map +1 -1
  52. package/build-module/components/dataviews-filters/add-filter.js +6 -6
  53. package/build-module/components/dataviews-filters/add-filter.js.map +1 -1
  54. package/build-module/components/dataviews-filters/index.js +4 -4
  55. package/build-module/components/dataviews-filters/index.js.map +1 -1
  56. package/build-module/components/dataviews-item-actions/index.js +10 -10
  57. package/build-module/components/dataviews-item-actions/index.js.map +1 -1
  58. package/build-module/components/dataviews-layout/index.js +5 -1
  59. package/build-module/components/dataviews-layout/index.js.map +1 -1
  60. package/build-module/components/dataviews-selection-checkbox/index.js +1 -2
  61. package/build-module/components/dataviews-selection-checkbox/index.js.map +1 -1
  62. package/build-module/components/dataviews-view-config/index.js +6 -6
  63. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  64. package/build-module/components/form-field-visibility/index.js +26 -0
  65. package/build-module/components/form-field-visibility/index.js.map +1 -0
  66. package/build-module/dataforms-layouts/panel/index.js +9 -4
  67. package/build-module/dataforms-layouts/panel/index.js.map +1 -1
  68. package/build-module/dataforms-layouts/regular/index.js +7 -2
  69. package/build-module/dataforms-layouts/regular/index.js.map +1 -1
  70. package/build-module/dataviews-layouts/grid/index.js +14 -3
  71. package/build-module/dataviews-layouts/grid/index.js.map +1 -1
  72. package/build-module/dataviews-layouts/list/index.js +11 -13
  73. package/build-module/dataviews-layouts/list/index.js.map +1 -1
  74. package/build-module/dataviews-layouts/table/column-header-menu.js +18 -18
  75. package/build-module/dataviews-layouts/table/column-header-menu.js.map +1 -1
  76. package/build-module/dataviews-layouts/table/index.js +22 -5
  77. package/build-module/dataviews-layouts/table/index.js.map +1 -1
  78. package/build-module/dataviews-layouts/utils/get-clickable-item-props.js +19 -0
  79. package/build-module/dataviews-layouts/utils/get-clickable-item-props.js.map +1 -0
  80. package/build-module/normalize-fields.js +15 -3
  81. package/build-module/normalize-fields.js.map +1 -1
  82. package/build-module/types.js.map +1 -1
  83. package/build-module/validation.js +9 -0
  84. package/build-module/validation.js.map +1 -1
  85. package/build-style/style-rtl.css +15 -6
  86. package/build-style/style.css +15 -6
  87. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  88. package/build-types/components/dataform-combined-edit/index.d.ts.map +1 -1
  89. package/build-types/components/dataviews/index.d.ts +3 -1
  90. package/build-types/components/dataviews/index.d.ts.map +1 -1
  91. package/build-types/components/dataviews-context/index.d.ts +2 -0
  92. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  93. package/build-types/components/dataviews-filters/add-filter.d.ts +1 -1
  94. package/build-types/components/dataviews-filters/add-filter.d.ts.map +1 -1
  95. package/build-types/components/dataviews-item-actions/index.d.ts +2 -2
  96. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  97. package/build-types/components/dataviews-layout/index.d.ts.map +1 -1
  98. package/build-types/components/dataviews-selection-checkbox/index.d.ts.map +1 -1
  99. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  100. package/build-types/components/form-field-visibility/index.d.ts +11 -0
  101. package/build-types/components/form-field-visibility/index.d.ts.map +1 -0
  102. package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
  103. package/build-types/dataforms-layouts/regular/index.d.ts.map +1 -1
  104. package/build-types/dataviews-layouts/grid/index.d.ts +1 -1
  105. package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -1
  106. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
  107. package/build-types/dataviews-layouts/table/column-header-menu.d.ts.map +1 -1
  108. package/build-types/dataviews-layouts/table/index.d.ts +1 -1
  109. package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
  110. package/build-types/dataviews-layouts/utils/get-clickable-item-props.d.ts +14 -0
  111. package/build-types/dataviews-layouts/utils/get-clickable-item-props.d.ts.map +1 -0
  112. package/build-types/lock-unlock.d.ts +1 -1
  113. package/build-types/lock-unlock.d.ts.map +1 -1
  114. package/build-types/normalize-fields.d.ts.map +1 -1
  115. package/build-types/types.d.ts +11 -6
  116. package/build-types/types.d.ts.map +1 -1
  117. package/build-types/validation.d.ts +9 -0
  118. package/build-types/validation.d.ts.map +1 -1
  119. package/package.json +12 -11
  120. package/src/components/dataform/stories/index.story.tsx +19 -3
  121. package/src/components/dataform-combined-edit/index.tsx +10 -7
  122. package/src/components/dataform-combined-edit/style.scss +4 -0
  123. package/src/components/dataviews/index.tsx +10 -1
  124. package/src/components/dataviews/style.scss +9 -3
  125. package/src/components/dataviews-bulk-actions/index.tsx +6 -6
  126. package/src/components/dataviews-context/index.ts +4 -0
  127. package/src/components/dataviews-filters/add-filter.tsx +8 -10
  128. package/src/components/dataviews-filters/index.tsx +4 -4
  129. package/src/components/dataviews-item-actions/index.tsx +15 -15
  130. package/src/components/dataviews-layout/index.tsx +4 -0
  131. package/src/components/dataviews-selection-checkbox/index.tsx +3 -2
  132. package/src/components/dataviews-view-config/index.tsx +8 -10
  133. package/src/components/form-field-visibility/index.tsx +32 -0
  134. package/src/dataforms-layouts/panel/index.tsx +11 -5
  135. package/src/dataforms-layouts/regular/index.tsx +9 -3
  136. package/src/dataviews-layouts/grid/index.tsx +29 -5
  137. package/src/dataviews-layouts/grid/style.scss +5 -0
  138. package/src/dataviews-layouts/list/index.tsx +10 -12
  139. package/src/dataviews-layouts/list/style.scss +1 -7
  140. package/src/dataviews-layouts/table/column-header-menu.tsx +31 -35
  141. package/src/dataviews-layouts/table/index.tsx +34 -3
  142. package/src/dataviews-layouts/utils/get-clickable-item-props.ts +22 -0
  143. package/src/normalize-fields.ts +17 -2
  144. package/src/test/normalize-fields.ts +45 -0
  145. package/src/types.ts +13 -2
  146. package/src/validation.ts +9 -0
  147. package/tsconfig.tsbuildinfo +1 -1
@@ -10,13 +10,13 @@ import {
10
10
  } from '@wordpress/element';
11
11
  import { __experimentalHStack as HStack, Button } from '@wordpress/components';
12
12
  import { funnel } from '@wordpress/icons';
13
- import { __ } from '@wordpress/i18n';
13
+ import { __, _x } from '@wordpress/i18n';
14
14
 
15
15
  /**
16
16
  * Internal dependencies
17
17
  */
18
18
  import FilterSummary from './filter-summary';
19
- import { default as AddFilter, AddFilterDropdownMenu } from './add-filter';
19
+ import { default as AddFilter, AddFilterMenu } from './add-filter';
20
20
  import ResetFilters from './reset-filters';
21
21
  import DataViewsContext from '../dataviews-context';
22
22
  import { sanitizeOperators } from '../../utils';
@@ -100,7 +100,7 @@ export function FilterVisibilityToggle( {
100
100
  }
101
101
  if ( ! hasVisibleFilters ) {
102
102
  return (
103
- <AddFilterDropdownMenu
103
+ <AddFilterMenu
104
104
  filters={ filters }
105
105
  view={ view }
106
106
  onChangeView={ onChangeViewWithFilterVisibility }
@@ -124,7 +124,7 @@ export function FilterVisibilityToggle( {
124
124
  className="dataviews-filters__visibility-toggle"
125
125
  size="compact"
126
126
  icon={ funnel }
127
- label={ __( 'Toggle filter display' ) }
127
+ label={ _x( 'Filter', 'verb' ) }
128
128
  onClick={ () => {
129
129
  if ( ! isShowingFilter ) {
130
130
  setOpenedFilter( null );
@@ -23,7 +23,7 @@ import { useRegistry } from '@wordpress/data';
23
23
  import { unlock } from '../../lock-unlock';
24
24
  import type { Action, ActionModal as ActionModalType } from '../../types';
25
25
 
26
- const { DropdownMenuV2, kebabCase } = unlock( componentsPrivateApis );
26
+ const { Menu, kebabCase } = unlock( componentsPrivateApis );
27
27
 
28
28
  export interface ActionTriggerProps< Item > {
29
29
  action: Action< Item >;
@@ -43,7 +43,7 @@ interface ActionWithModalProps< Item > extends ActionModalProps< Item > {
43
43
  isBusy?: boolean;
44
44
  }
45
45
 
46
- interface ActionsDropdownMenuGroupProps< Item > {
46
+ interface ActionsMenuGroupProps< Item > {
47
47
  actions: Action< Item >[];
48
48
  item: Item;
49
49
  }
@@ -77,7 +77,7 @@ function ButtonTrigger< Item >( {
77
77
  );
78
78
  }
79
79
 
80
- function DropdownMenuItemTrigger< Item >( {
80
+ function MenuItemTrigger< Item >( {
81
81
  action,
82
82
  onClick,
83
83
  items,
@@ -85,12 +85,12 @@ function DropdownMenuItemTrigger< Item >( {
85
85
  const label =
86
86
  typeof action.label === 'string' ? action.label : action.label( items );
87
87
  return (
88
- <DropdownMenuV2.Item
88
+ <Menu.Item
89
89
  onClick={ onClick }
90
90
  hideOnClick={ ! ( 'RenderModal' in action ) }
91
91
  >
92
- <DropdownMenuV2.ItemLabel>{ label }</DropdownMenuV2.ItemLabel>
93
- </DropdownMenuV2.Item>
92
+ <Menu.ItemLabel>{ label }</Menu.ItemLabel>
93
+ </Menu.Item>
94
94
  );
95
95
  }
96
96
 
@@ -146,13 +146,13 @@ export function ActionWithModal< Item >( {
146
146
  );
147
147
  }
148
148
 
149
- export function ActionsDropdownMenuGroup< Item >( {
149
+ export function ActionsMenuGroup< Item >( {
150
150
  actions,
151
151
  item,
152
- }: ActionsDropdownMenuGroupProps< Item > ) {
152
+ }: ActionsMenuGroupProps< Item > ) {
153
153
  const registry = useRegistry();
154
154
  return (
155
- <DropdownMenuV2.Group>
155
+ <Menu.Group>
156
156
  { actions.map( ( action ) => {
157
157
  if ( 'RenderModal' in action ) {
158
158
  return (
@@ -160,12 +160,12 @@ export function ActionsDropdownMenuGroup< Item >( {
160
160
  key={ action.id }
161
161
  action={ action }
162
162
  items={ [ item ] }
163
- ActionTrigger={ DropdownMenuItemTrigger }
163
+ ActionTrigger={ MenuItemTrigger }
164
164
  />
165
165
  );
166
166
  }
167
167
  return (
168
- <DropdownMenuItemTrigger
168
+ <MenuItemTrigger
169
169
  key={ action.id }
170
170
  action={ action }
171
171
  onClick={ () => {
@@ -175,7 +175,7 @@ export function ActionsDropdownMenuGroup< Item >( {
175
175
  />
176
176
  );
177
177
  } ) }
178
- </DropdownMenuV2.Group>
178
+ </Menu.Group>
179
179
  );
180
180
  }
181
181
 
@@ -245,7 +245,7 @@ function CompactItemActions< Item >( {
245
245
  actions,
246
246
  }: CompactItemActionsProps< Item > ) {
247
247
  return (
248
- <DropdownMenuV2
248
+ <Menu
249
249
  trigger={
250
250
  <Button
251
251
  size="compact"
@@ -258,7 +258,7 @@ function CompactItemActions< Item >( {
258
258
  }
259
259
  placement="bottom-end"
260
260
  >
261
- <ActionsDropdownMenuGroup actions={ actions } item={ item } />
262
- </DropdownMenuV2>
261
+ <ActionsMenuGroup actions={ actions } item={ item } />
262
+ </Menu>
263
263
  );
264
264
  }
@@ -28,6 +28,8 @@ export default function DataViewsLayout() {
28
28
  onChangeSelection,
29
29
  setOpenedFilter,
30
30
  density,
31
+ onClickItem,
32
+ isItemClickable,
31
33
  } = useContext( DataViewsContext );
32
34
 
33
35
  const ViewComponent = VIEW_LAYOUTS.find( ( v ) => v.type === view.type )
@@ -44,6 +46,8 @@ export default function DataViewsLayout() {
44
46
  onChangeSelection={ onChangeSelection }
45
47
  selection={ selection }
46
48
  setOpenedFilter={ setOpenedFilter }
49
+ onClickItem={ onClickItem }
50
+ isItemClickable={ isItemClickable }
47
51
  view={ view }
48
52
  density={ density }
49
53
  />
@@ -33,8 +33,9 @@ export default function DataViewsSelectionCheckbox< Item >( {
33
33
  if ( primaryField?.getValue && item ) {
34
34
  // eslint-disable-next-line @wordpress/valid-sprintf
35
35
  selectionLabel = sprintf(
36
- /* translators: %s: item title. */
37
- checked ? __( 'Deselect item: %s' ) : __( 'Select item: %s' ),
36
+ checked
37
+ ? /* translators: %s: item title. */ __( 'Deselect item: %s' )
38
+ : /* translators: %s: item title. */ __( 'Select item: %s' ),
38
39
  primaryField.getValue( { item } )
39
40
  );
40
41
  } else {
@@ -51,7 +51,7 @@ import DataViewsContext from '../dataviews-context';
51
51
  import { unlock } from '../../lock-unlock';
52
52
  import DensityPicker from '../../dataviews-layouts/grid/density-picker';
53
53
 
54
- const { DropdownMenuV2 } = unlock( componentsPrivateApis );
54
+ const { Menu } = unlock( componentsPrivateApis );
55
55
 
56
56
  interface ViewTypeMenuProps {
57
57
  defaultLayouts?: SupportedLayouts;
@@ -69,7 +69,7 @@ function ViewTypeMenu( {
69
69
  }
70
70
  const activeView = VIEW_LAYOUTS.find( ( v ) => view.type === v.type );
71
71
  return (
72
- <DropdownMenuV2
72
+ <Menu
73
73
  trigger={
74
74
  <Button
75
75
  size="compact"
@@ -84,7 +84,7 @@ function ViewTypeMenu( {
84
84
  return null;
85
85
  }
86
86
  return (
87
- <DropdownMenuV2.RadioItem
87
+ <Menu.RadioItem
88
88
  key={ layout }
89
89
  value={ layout }
90
90
  name="view-actions-available-view"
@@ -104,13 +104,11 @@ function ViewTypeMenu( {
104
104
  warning( 'Invalid dataview' );
105
105
  } }
106
106
  >
107
- <DropdownMenuV2.ItemLabel>
108
- { config.label }
109
- </DropdownMenuV2.ItemLabel>
110
- </DropdownMenuV2.RadioItem>
107
+ <Menu.ItemLabel>{ config.label }</Menu.ItemLabel>
108
+ </Menu.RadioItem>
111
109
  );
112
110
  } ) }
113
- </DropdownMenuV2>
111
+ </Menu>
114
112
  );
115
113
  }
116
114
 
@@ -363,12 +361,12 @@ function FieldItem( {
363
361
  isVisible
364
362
  ? sprintf(
365
363
  /* translators: %s: field label */
366
- __( 'Hide %s' ),
364
+ _x( 'Hide %s', 'field' ),
367
365
  label
368
366
  )
369
367
  : sprintf(
370
368
  /* translators: %s: field label */
371
- __( 'Show %s' ),
369
+ _x( 'Show %s', 'field' ),
372
370
  label
373
371
  )
374
372
  }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMemo } from '@wordpress/element';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import type { NormalizedField } from '../../types';
10
+
11
+ type FormFieldVisibilityProps< Item > = React.PropsWithChildren< {
12
+ field: NormalizedField< Item >;
13
+ data: Item;
14
+ } >;
15
+
16
+ export default function FormFieldVisibility< Item >( {
17
+ data,
18
+ field,
19
+ children,
20
+ }: FormFieldVisibilityProps< Item > ) {
21
+ const isVisible = useMemo( () => {
22
+ if ( field.isVisible ) {
23
+ return field.isVisible( data );
24
+ }
25
+ return true;
26
+ }, [ field.isVisible, data ] );
27
+
28
+ if ( ! isVisible ) {
29
+ return null;
30
+ }
31
+ return children;
32
+ }
@@ -10,7 +10,7 @@ import {
10
10
  Button,
11
11
  } from '@wordpress/components';
12
12
  import { useState, useMemo } from '@wordpress/element';
13
- import { sprintf, __ } from '@wordpress/i18n';
13
+ import { sprintf, __, _x } from '@wordpress/i18n';
14
14
  import { closeSmall } from '@wordpress/icons';
15
15
 
16
16
  /**
@@ -19,6 +19,7 @@ import { closeSmall } from '@wordpress/icons';
19
19
  import { normalizeFields } from '../../normalize-fields';
20
20
  import { getVisibleFields } from '../get-visible-fields';
21
21
  import type { DataFormProps, NormalizedField } from '../../types';
22
+ import FormFieldVisibility from '../../components/form-field-visibility';
22
23
 
23
24
  interface FormFieldProps< Item > {
24
25
  data: Item;
@@ -105,7 +106,7 @@ function FormField< Item >( {
105
106
  aria-expanded={ isOpen }
106
107
  aria-label={ sprintf(
107
108
  // translators: %s: Field name.
108
- __( 'Edit %s' ),
109
+ _x( 'Edit %s', 'field' ),
109
110
  field.label
110
111
  ) }
111
112
  onClick={ onToggle }
@@ -156,12 +157,17 @@ export default function FormPanel< Item >( {
156
157
  <VStack spacing={ 2 }>
157
158
  { visibleFields.map( ( field ) => {
158
159
  return (
159
- <FormField
160
+ <FormFieldVisibility
160
161
  key={ field.id }
161
162
  data={ data }
162
163
  field={ field }
163
- onChange={ onChange }
164
- />
164
+ >
165
+ <FormField
166
+ data={ data }
167
+ field={ field }
168
+ onChange={ onChange }
169
+ />
170
+ </FormFieldVisibility>
165
171
  );
166
172
  } ) }
167
173
  </VStack>
@@ -10,6 +10,7 @@ import { useMemo } from '@wordpress/element';
10
10
  import { normalizeFields } from '../../normalize-fields';
11
11
  import { getVisibleFields } from '../get-visible-fields';
12
12
  import type { DataFormProps } from '../../types';
13
+ import FormFieldVisibility from '../../components/form-field-visibility';
13
14
 
14
15
  export default function FormRegular< Item >( {
15
16
  data,
@@ -33,12 +34,17 @@ export default function FormRegular< Item >( {
33
34
  <VStack spacing={ 4 }>
34
35
  { visibleFields.map( ( field ) => {
35
36
  return (
36
- <field.Edit
37
+ <FormFieldVisibility
37
38
  key={ field.id }
38
39
  data={ data }
39
40
  field={ field }
40
- onChange={ onChange }
41
- />
41
+ >
42
+ <field.Edit
43
+ data={ data }
44
+ field={ field }
45
+ onChange={ onChange }
46
+ />
47
+ </FormFieldVisibility>
42
48
  );
43
49
  } ) }
44
50
  </VStack>
@@ -24,11 +24,14 @@ import SingleSelectionCheckbox from '../../components/dataviews-selection-checkb
24
24
  import { useHasAPossibleBulkAction } from '../../components/dataviews-bulk-actions';
25
25
  import type { Action, NormalizedField, ViewGridProps } from '../../types';
26
26
  import type { SetSelection } from '../../private-types';
27
+ import getClickableItemProps from '../utils/get-clickable-item-props';
27
28
 
28
29
  interface GridItemProps< Item > {
29
30
  selection: string[];
30
31
  onChangeSelection: SetSelection;
31
32
  getItemId: ( item: Item ) => string;
33
+ onClickItem: ( item: Item ) => void;
34
+ isItemClickable: ( item: Item ) => boolean;
32
35
  item: Item;
33
36
  actions: Action< Item >[];
34
37
  mediaField?: NormalizedField< Item >;
@@ -41,6 +44,8 @@ interface GridItemProps< Item > {
41
44
  function GridItem< Item >( {
42
45
  selection,
43
46
  onChangeSelection,
47
+ onClickItem,
48
+ isItemClickable,
44
49
  getItemId,
45
50
  item,
46
51
  actions,
@@ -59,6 +64,21 @@ function GridItem< Item >( {
59
64
  const renderedPrimaryField = primaryField?.render ? (
60
65
  <primaryField.render item={ item } />
61
66
  ) : null;
67
+
68
+ const clickableMediaItemProps = getClickableItemProps(
69
+ item,
70
+ isItemClickable,
71
+ onClickItem,
72
+ 'dataviews-view-grid__media'
73
+ );
74
+
75
+ const clickablePrimaryItemProps = getClickableItemProps(
76
+ item,
77
+ isItemClickable,
78
+ onClickItem,
79
+ 'dataviews-view-grid__primary-field'
80
+ );
81
+
62
82
  return (
63
83
  <VStack
64
84
  spacing={ 0 }
@@ -81,9 +101,7 @@ function GridItem< Item >( {
81
101
  }
82
102
  } }
83
103
  >
84
- <div className="dataviews-view-grid__media">
85
- { renderedMediaField }
86
- </div>
104
+ <div { ...clickableMediaItemProps }>{ renderedMediaField }</div>
87
105
  <SingleSelectionCheckbox
88
106
  item={ item }
89
107
  selection={ selection }
@@ -96,8 +114,10 @@ function GridItem< Item >( {
96
114
  justify="space-between"
97
115
  className="dataviews-view-grid__title-actions"
98
116
  >
99
- <HStack className="dataviews-view-grid__primary-field">
100
- { renderedPrimaryField }
117
+ <HStack>
118
+ <div { ...clickablePrimaryItemProps }>
119
+ { renderedPrimaryField }
120
+ </div>
101
121
  </HStack>
102
122
  <ItemActions item={ item } actions={ actions } isCompact />
103
123
  </HStack>
@@ -170,6 +190,8 @@ export default function ViewGrid< Item >( {
170
190
  getItemId,
171
191
  isLoading,
172
192
  onChangeSelection,
193
+ onClickItem,
194
+ isItemClickable,
173
195
  selection,
174
196
  view,
175
197
  density,
@@ -223,6 +245,8 @@ export default function ViewGrid< Item >( {
223
245
  key={ getItemId( item ) }
224
246
  selection={ selection }
225
247
  onChangeSelection={ onChangeSelection }
248
+ onClickItem={ onClickItem }
249
+ isItemClickable={ isItemClickable }
226
250
  getItemId={ getItemId }
227
251
  item={ item }
228
252
  actions={ actions }
@@ -17,8 +17,13 @@
17
17
 
18
18
  .dataviews-view-grid__primary-field {
19
19
  min-height: $grid-unit-40; // Preserve layout when there is no ellipsis button
20
+
21
+ &--clickable {
22
+ width: fit-content;
23
+ }
20
24
  }
21
25
 
26
+
22
27
  &.is-selected {
23
28
  .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
24
29
  color: $gray-900;
@@ -32,7 +32,7 @@ import { useRegistry } from '@wordpress/data';
32
32
  */
33
33
  import { unlock } from '../../lock-unlock';
34
34
  import {
35
- ActionsDropdownMenuGroup,
35
+ ActionsMenuGroup,
36
36
  ActionModal,
37
37
  } from '../../components/dataviews-item-actions';
38
38
  import type { Action, NormalizedField, ViewListProps } from '../../types';
@@ -49,7 +49,7 @@ interface ListViewItemProps< Item > {
49
49
  onDropdownTriggerKeyDown: React.KeyboardEventHandler< HTMLButtonElement >;
50
50
  }
51
51
 
52
- const { DropdownMenuV2: DropdownMenu } = unlock( componentsPrivateApis );
52
+ const { Menu } = unlock( componentsPrivateApis );
53
53
 
54
54
  function generateItemWrapperCompositeId( idPrefix: string ) {
55
55
  return `${ idPrefix }-item-wrapper`;
@@ -176,10 +176,10 @@ function ListItem< Item >( {
176
176
  }, [ actions, item ] );
177
177
 
178
178
  const renderedMediaField = mediaField?.render ? (
179
- <mediaField.render item={ item } />
180
- ) : (
181
- <div className="dataviews-view-list__media-placeholder"></div>
182
- );
179
+ <div className="dataviews-view-list__media-wrapper">
180
+ <mediaField.render item={ item } />
181
+ </div>
182
+ ) : null;
183
183
 
184
184
  const renderedPrimaryField = primaryField?.render ? (
185
185
  <primaryField.render item={ item } />
@@ -195,7 +195,7 @@ function ListItem< Item >( {
195
195
  />
196
196
  ) }
197
197
  <div role="gridcell">
198
- <DropdownMenu
198
+ <Menu
199
199
  trigger={
200
200
  <Composite.Item
201
201
  id={ generateDropdownTriggerCompositeId(
@@ -215,11 +215,11 @@ function ListItem< Item >( {
215
215
  }
216
216
  placement="bottom-end"
217
217
  >
218
- <ActionsDropdownMenuGroup
218
+ <ActionsMenuGroup
219
219
  actions={ eligibleActions }
220
220
  item={ item }
221
221
  />
222
- </DropdownMenu>
222
+ </Menu>
223
223
  </div>
224
224
  </HStack>
225
225
  );
@@ -248,9 +248,7 @@ function ListItem< Item >( {
248
248
  />
249
249
  </div>
250
250
  <HStack spacing={ 3 } justify="start" alignment="flex-start">
251
- <div className="dataviews-view-list__media-wrapper">
252
- { renderedMediaField }
253
- </div>
251
+ { renderedMediaField }
254
252
  <VStack
255
253
  spacing={ 1 }
256
254
  className="dataviews-view-list__field-wrapper"
@@ -33,7 +33,7 @@ ul.dataviews-view-list {
33
33
  .dataviews-view-list__item-actions {
34
34
  flex-basis: min-content;
35
35
  overflow: unset;
36
- margin-inline: $grid-unit-10 0;
36
+ padding-inline-end: $grid-unit-05;
37
37
 
38
38
  .components-button {
39
39
  opacity: 1;
@@ -144,12 +144,6 @@ ul.dataviews-view-list {
144
144
  }
145
145
  }
146
146
 
147
- .dataviews-view-list__media-placeholder {
148
- width: $grid-unit-05 * 13;
149
- height: $grid-unit-05 * 13;
150
- background-color: $gray-200;
151
- }
152
-
153
147
  .dataviews-view-list__field-wrapper {
154
148
  min-height: $grid-unit-05 * 13; // Ensures title is centrally aligned when all fields are hidden
155
149
  flex-grow: 1;
@@ -29,7 +29,7 @@ import type {
29
29
  } from '../../types';
30
30
  import { getVisibleFieldIds } from '../index';
31
31
 
32
- const { DropdownMenuV2 } = unlock( componentsPrivateApis );
32
+ const { Menu } = unlock( componentsPrivateApis );
33
33
 
34
34
  interface HeaderMenuProps< Item > {
35
35
  fieldId: string;
@@ -40,12 +40,12 @@ interface HeaderMenuProps< Item > {
40
40
  setOpenedFilter: ( fieldId: string ) => void;
41
41
  }
42
42
 
43
- function WithDropDownMenuSeparators( { children }: { children: ReactNode } ) {
43
+ function WithMenuSeparators( { children }: { children: ReactNode } ) {
44
44
  return Children.toArray( children )
45
45
  .filter( Boolean )
46
46
  .map( ( child, i ) => (
47
47
  <Fragment key={ i }>
48
- { i > 0 && <DropdownMenuV2.Separator /> }
48
+ { i > 0 && <Menu.Separator /> }
49
49
  { child }
50
50
  </Fragment>
51
51
  ) );
@@ -101,7 +101,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
101
101
  }
102
102
 
103
103
  return (
104
- <DropdownMenuV2
104
+ <Menu
105
105
  align="start"
106
106
  trigger={
107
107
  <Button
@@ -120,9 +120,9 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
120
120
  }
121
121
  style={ { minWidth: '240px' } }
122
122
  >
123
- <WithDropDownMenuSeparators>
123
+ <WithMenuSeparators>
124
124
  { isSortable && (
125
- <DropdownMenuV2.Group>
125
+ <Menu.Group>
126
126
  { SORTING_DIRECTIONS.map(
127
127
  ( direction: SortDirection ) => {
128
128
  const isChecked =
@@ -133,7 +133,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
133
133
  const value = `${ fieldId }-${ direction }`;
134
134
 
135
135
  return (
136
- <DropdownMenuV2.RadioItem
136
+ <Menu.RadioItem
137
137
  key={ value }
138
138
  // All sorting radio items share the same name, so that
139
139
  // selecting a sorting option automatically deselects the
@@ -153,18 +153,18 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
153
153
  } );
154
154
  } }
155
155
  >
156
- <DropdownMenuV2.ItemLabel>
156
+ <Menu.ItemLabel>
157
157
  { sortLabels[ direction ] }
158
- </DropdownMenuV2.ItemLabel>
159
- </DropdownMenuV2.RadioItem>
158
+ </Menu.ItemLabel>
159
+ </Menu.RadioItem>
160
160
  );
161
161
  }
162
162
  ) }
163
- </DropdownMenuV2.Group>
163
+ </Menu.Group>
164
164
  ) }
165
165
  { canAddFilter && (
166
- <DropdownMenuV2.Group>
167
- <DropdownMenuV2.Item
166
+ <Menu.Group>
167
+ <Menu.Item
168
168
  prefix={ <Icon icon={ funnel } /> }
169
169
  onClick={ () => {
170
170
  setOpenedFilter( fieldId );
@@ -182,14 +182,14 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
182
182
  } );
183
183
  } }
184
184
  >
185
- <DropdownMenuV2.ItemLabel>
185
+ <Menu.ItemLabel>
186
186
  { __( 'Add filter' ) }
187
- </DropdownMenuV2.ItemLabel>
188
- </DropdownMenuV2.Item>
189
- </DropdownMenuV2.Group>
187
+ </Menu.ItemLabel>
188
+ </Menu.Item>
189
+ </Menu.Group>
190
190
  ) }
191
- <DropdownMenuV2.Group>
192
- <DropdownMenuV2.Item
191
+ <Menu.Group>
192
+ <Menu.Item
193
193
  prefix={ <Icon icon={ arrowLeft } /> }
194
194
  disabled={ index < 1 }
195
195
  onClick={ () => {
@@ -207,11 +207,9 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
207
207
  } );
208
208
  } }
209
209
  >
210
- <DropdownMenuV2.ItemLabel>
211
- { __( 'Move left' ) }
212
- </DropdownMenuV2.ItemLabel>
213
- </DropdownMenuV2.Item>
214
- <DropdownMenuV2.Item
210
+ <Menu.ItemLabel>{ __( 'Move left' ) }</Menu.ItemLabel>
211
+ </Menu.Item>
212
+ <Menu.Item
215
213
  prefix={ <Icon icon={ arrowRight } /> }
216
214
  disabled={ index >= visibleFieldIds.length - 1 }
217
215
  onClick={ () => {
@@ -227,12 +225,10 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
227
225
  } );
228
226
  } }
229
227
  >
230
- <DropdownMenuV2.ItemLabel>
231
- { __( 'Move right' ) }
232
- </DropdownMenuV2.ItemLabel>
233
- </DropdownMenuV2.Item>
228
+ <Menu.ItemLabel>{ __( 'Move right' ) }</Menu.ItemLabel>
229
+ </Menu.Item>
234
230
  { isHidable && field && (
235
- <DropdownMenuV2.Item
231
+ <Menu.Item
236
232
  prefix={ <Icon icon={ unseen } /> }
237
233
  onClick={ () => {
238
234
  onHide( field );
@@ -244,14 +240,14 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
244
240
  } );
245
241
  } }
246
242
  >
247
- <DropdownMenuV2.ItemLabel>
243
+ <Menu.ItemLabel>
248
244
  { __( 'Hide column' ) }
249
- </DropdownMenuV2.ItemLabel>
250
- </DropdownMenuV2.Item>
245
+ </Menu.ItemLabel>
246
+ </Menu.Item>
251
247
  ) }
252
- </DropdownMenuV2.Group>
253
- </WithDropDownMenuSeparators>
254
- </DropdownMenuV2>
248
+ </Menu.Group>
249
+ </WithMenuSeparators>
250
+ </Menu>
255
251
  );
256
252
  } );
257
253