@wordpress/dataviews 4.9.1-next.cd6172eb0.0 → 4.11.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 (206) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/LICENSE.md +1 -1
  3. package/README.md +337 -228
  4. package/build/components/dataviews/index.js +13 -1
  5. package/build/components/dataviews/index.js.map +1 -1
  6. package/build/components/dataviews-bulk-actions/index.js +30 -2
  7. package/build/components/dataviews-bulk-actions/index.js.map +1 -1
  8. package/build/components/dataviews-context/index.js +2 -1
  9. package/build/components/dataviews-context/index.js.map +1 -1
  10. package/build/components/dataviews-filters/add-filter.js +36 -30
  11. package/build/components/dataviews-filters/add-filter.js.map +1 -1
  12. package/build/components/dataviews-filters/filter-summary.js +1 -0
  13. package/build/components/dataviews-filters/filter-summary.js.map +1 -1
  14. package/build/components/dataviews-filters/index.js +4 -1
  15. package/build/components/dataviews-filters/index.js.map +1 -1
  16. package/build/components/dataviews-filters/reset-filters.js +1 -0
  17. package/build/components/dataviews-filters/reset-filters.js.map +1 -1
  18. package/build/components/dataviews-filters/search-widget.js +1 -0
  19. package/build/components/dataviews-filters/search-widget.js.map +1 -1
  20. package/build/components/dataviews-item-actions/index.js +68 -79
  21. package/build/components/dataviews-item-actions/index.js.map +1 -1
  22. package/build/components/dataviews-layout/index.js +3 -0
  23. package/build/components/dataviews-layout/index.js.map +1 -1
  24. package/build/components/dataviews-pagination/index.js +1 -0
  25. package/build/components/dataviews-pagination/index.js.map +1 -1
  26. package/build/components/dataviews-selection-checkbox/index.js +4 -3
  27. package/build/components/dataviews-selection-checkbox/index.js.map +1 -1
  28. package/build/components/dataviews-view-config/index.js +235 -161
  29. package/build/components/dataviews-view-config/index.js.map +1 -1
  30. package/build/dataforms-layouts/data-form-layout.js +1 -0
  31. package/build/dataforms-layouts/data-form-layout.js.map +1 -1
  32. package/build/dataforms-layouts/index.js +1 -0
  33. package/build/dataforms-layouts/index.js.map +1 -1
  34. package/build/dataforms-layouts/panel/index.js +1 -0
  35. package/build/dataforms-layouts/panel/index.js.map +1 -1
  36. package/build/dataforms-layouts/regular/index.js +1 -0
  37. package/build/dataforms-layouts/regular/index.js.map +1 -1
  38. package/build/dataviews-layouts/grid/index.js +108 -65
  39. package/build/dataviews-layouts/grid/index.js.map +1 -1
  40. package/build/dataviews-layouts/grid/preview-size-picker.js +22 -25
  41. package/build/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
  42. package/build/dataviews-layouts/index.js +0 -60
  43. package/build/dataviews-layouts/index.js.map +1 -1
  44. package/build/dataviews-layouts/list/index.js +67 -33
  45. package/build/dataviews-layouts/list/index.js.map +1 -1
  46. package/build/dataviews-layouts/table/column-header-menu.js +119 -120
  47. package/build/dataviews-layouts/table/column-header-menu.js.map +1 -1
  48. package/build/dataviews-layouts/table/column-primary.js +59 -0
  49. package/build/dataviews-layouts/table/column-primary.js.map +1 -0
  50. package/build/dataviews-layouts/table/index.js +78 -88
  51. package/build/dataviews-layouts/table/index.js.map +1 -1
  52. package/build/dataviews-layouts/utils/get-clickable-item-props.js +2 -2
  53. package/build/dataviews-layouts/utils/get-clickable-item-props.js.map +1 -1
  54. package/build/filter-and-sort-data-view.js +1 -0
  55. package/build/filter-and-sort-data-view.js.map +1 -1
  56. package/build/normalize-fields.js +1 -0
  57. package/build/normalize-fields.js.map +1 -1
  58. package/build/normalize-form-fields.js +1 -0
  59. package/build/normalize-form-fields.js.map +1 -1
  60. package/build/types.js.map +1 -1
  61. package/build/utils.js +1 -0
  62. package/build/utils.js.map +1 -1
  63. package/build/validation.js +1 -0
  64. package/build/validation.js.map +1 -1
  65. package/build-module/components/dataviews/index.js +13 -1
  66. package/build-module/components/dataviews/index.js.map +1 -1
  67. package/build-module/components/dataviews-bulk-actions/index.js +31 -3
  68. package/build-module/components/dataviews-bulk-actions/index.js.map +1 -1
  69. package/build-module/components/dataviews-context/index.js +2 -1
  70. package/build-module/components/dataviews-context/index.js.map +1 -1
  71. package/build-module/components/dataviews-filters/add-filter.js +37 -31
  72. package/build-module/components/dataviews-filters/add-filter.js.map +1 -1
  73. package/build-module/components/dataviews-filters/filter-summary.js +1 -0
  74. package/build-module/components/dataviews-filters/filter-summary.js.map +1 -1
  75. package/build-module/components/dataviews-filters/index.js +4 -1
  76. package/build-module/components/dataviews-filters/index.js.map +1 -1
  77. package/build-module/components/dataviews-filters/reset-filters.js +1 -0
  78. package/build-module/components/dataviews-filters/reset-filters.js.map +1 -1
  79. package/build-module/components/dataviews-filters/search-widget.js +1 -0
  80. package/build-module/components/dataviews-filters/search-widget.js.map +1 -1
  81. package/build-module/components/dataviews-item-actions/index.js +69 -79
  82. package/build-module/components/dataviews-item-actions/index.js.map +1 -1
  83. package/build-module/components/dataviews-layout/index.js +3 -0
  84. package/build-module/components/dataviews-layout/index.js.map +1 -1
  85. package/build-module/components/dataviews-pagination/index.js +1 -0
  86. package/build-module/components/dataviews-pagination/index.js.map +1 -1
  87. package/build-module/components/dataviews-selection-checkbox/index.js +4 -3
  88. package/build-module/components/dataviews-selection-checkbox/index.js.map +1 -1
  89. package/build-module/components/dataviews-view-config/index.js +240 -166
  90. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  91. package/build-module/dataforms-layouts/data-form-layout.js +1 -0
  92. package/build-module/dataforms-layouts/data-form-layout.js.map +1 -1
  93. package/build-module/dataforms-layouts/index.js +1 -0
  94. package/build-module/dataforms-layouts/index.js.map +1 -1
  95. package/build-module/dataforms-layouts/panel/index.js +1 -0
  96. package/build-module/dataforms-layouts/panel/index.js.map +1 -1
  97. package/build-module/dataforms-layouts/regular/index.js +1 -0
  98. package/build-module/dataforms-layouts/regular/index.js.map +1 -1
  99. package/build-module/dataviews-layouts/grid/index.js +111 -68
  100. package/build-module/dataviews-layouts/grid/index.js.map +1 -1
  101. package/build-module/dataviews-layouts/grid/preview-size-picker.js +22 -25
  102. package/build-module/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
  103. package/build-module/dataviews-layouts/index.js +0 -57
  104. package/build-module/dataviews-layouts/index.js.map +1 -1
  105. package/build-module/dataviews-layouts/list/index.js +67 -33
  106. package/build-module/dataviews-layouts/list/index.js.map +1 -1
  107. package/build-module/dataviews-layouts/table/column-header-menu.js +119 -120
  108. package/build-module/dataviews-layouts/table/column-header-menu.js.map +1 -1
  109. package/build-module/dataviews-layouts/table/column-primary.js +52 -0
  110. package/build-module/dataviews-layouts/table/column-primary.js.map +1 -0
  111. package/build-module/dataviews-layouts/table/index.js +81 -91
  112. package/build-module/dataviews-layouts/table/index.js.map +1 -1
  113. package/build-module/dataviews-layouts/utils/get-clickable-item-props.js +2 -2
  114. package/build-module/dataviews-layouts/utils/get-clickable-item-props.js.map +1 -1
  115. package/build-module/filter-and-sort-data-view.js +1 -0
  116. package/build-module/filter-and-sort-data-view.js.map +1 -1
  117. package/build-module/normalize-fields.js +1 -0
  118. package/build-module/normalize-fields.js.map +1 -1
  119. package/build-module/normalize-form-fields.js +1 -0
  120. package/build-module/normalize-form-fields.js.map +1 -1
  121. package/build-module/types.js.map +1 -1
  122. package/build-module/utils.js +1 -0
  123. package/build-module/utils.js.map +1 -1
  124. package/build-module/validation.js +1 -0
  125. package/build-module/validation.js.map +1 -1
  126. package/build-style/style-rtl.css +123 -121
  127. package/build-style/style.css +123 -121
  128. package/build-types/components/dataviews/index.d.ts +2 -1
  129. package/build-types/components/dataviews/index.d.ts.map +1 -1
  130. package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
  131. package/build-types/components/dataviews/stories/index.story.d.ts +0 -1
  132. package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
  133. package/build-types/components/dataviews-bulk-actions/index.d.ts.map +1 -1
  134. package/build-types/components/dataviews-context/index.d.ts +2 -0
  135. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  136. package/build-types/components/dataviews-filters/add-filter.d.ts +3 -2
  137. package/build-types/components/dataviews-filters/add-filter.d.ts.map +1 -1
  138. package/build-types/components/dataviews-item-actions/index.d.ts +7 -9
  139. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  140. package/build-types/components/dataviews-layout/index.d.ts.map +1 -1
  141. package/build-types/components/dataviews-selection-checkbox/index.d.ts +2 -2
  142. package/build-types/components/dataviews-selection-checkbox/index.d.ts.map +1 -1
  143. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  144. package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -1
  145. package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts.map +1 -1
  146. package/build-types/dataviews-layouts/index.d.ts +0 -4
  147. package/build-types/dataviews-layouts/index.d.ts.map +1 -1
  148. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
  149. package/build-types/dataviews-layouts/table/column-header-menu.d.ts +1 -0
  150. package/build-types/dataviews-layouts/table/column-header-menu.d.ts.map +1 -1
  151. package/build-types/dataviews-layouts/table/column-primary.d.ts +15 -0
  152. package/build-types/dataviews-layouts/table/column-primary.d.ts.map +1 -0
  153. package/build-types/dataviews-layouts/table/index.d.ts +1 -1
  154. package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
  155. package/build-types/dataviews-layouts/utils/get-clickable-item-props.d.ts +3 -3
  156. package/build-types/dataviews-layouts/utils/get-clickable-item-props.d.ts.map +1 -1
  157. package/build-types/test/dataform.d.ts +2 -0
  158. package/build-types/test/dataform.d.ts.map +1 -0
  159. package/build-types/test/dataviews.d.ts +2 -0
  160. package/build-types/test/dataviews.d.ts.map +1 -0
  161. package/build-types/test/normalize-fields.d.ts +2 -0
  162. package/build-types/test/normalize-fields.d.ts.map +1 -0
  163. package/build-types/test/validation.d.ts +2 -0
  164. package/build-types/test/validation.d.ts.map +1 -0
  165. package/build-types/types.d.ts +25 -39
  166. package/build-types/types.d.ts.map +1 -1
  167. package/build-wp/index.js +1892 -1814
  168. package/build.js +1 -1
  169. package/package.json +13 -12
  170. package/src/components/dataviews/index.tsx +15 -1
  171. package/src/components/dataviews/stories/fixtures.tsx +0 -3
  172. package/src/components/dataviews/stories/index.story.tsx +14 -106
  173. package/src/components/dataviews/style.scss +32 -33
  174. package/src/components/dataviews-bulk-actions/index.tsx +43 -3
  175. package/src/components/dataviews-context/index.ts +3 -0
  176. package/src/components/dataviews-filters/add-filter.tsx +43 -39
  177. package/src/components/dataviews-filters/index.tsx +1 -1
  178. package/src/components/dataviews-footer/style.scss +0 -3
  179. package/src/components/dataviews-item-actions/index.tsx +90 -107
  180. package/src/components/dataviews-layout/index.tsx +2 -0
  181. package/src/components/dataviews-selection-checkbox/index.tsx +4 -4
  182. package/src/components/dataviews-view-config/index.tsx +347 -232
  183. package/src/components/dataviews-view-config/style.scss +17 -1
  184. package/src/dataviews-layouts/grid/index.tsx +150 -103
  185. package/src/dataviews-layouts/grid/preview-size-picker.tsx +25 -30
  186. package/src/dataviews-layouts/grid/style.scss +38 -56
  187. package/src/dataviews-layouts/index.ts +0 -88
  188. package/src/dataviews-layouts/list/index.tsx +95 -57
  189. package/src/dataviews-layouts/list/style.scss +10 -9
  190. package/src/dataviews-layouts/table/column-header-menu.tsx +183 -171
  191. package/src/dataviews-layouts/table/column-primary.tsx +65 -0
  192. package/src/dataviews-layouts/table/index.tsx +98 -133
  193. package/src/dataviews-layouts/table/style.scss +4 -1
  194. package/src/dataviews-layouts/utils/get-clickable-item-props.ts +9 -3
  195. package/src/test/dataform.tsx +348 -0
  196. package/src/test/dataviews.tsx +380 -0
  197. package/src/types.ts +27 -46
  198. package/tsconfig.json +14 -4
  199. package/tsconfig.tsbuildinfo +1 -1
  200. package/build/components/form-field-visibility/index.js +0 -32
  201. package/build/components/form-field-visibility/index.js.map +0 -1
  202. package/build-module/components/form-field-visibility/index.js +0 -26
  203. package/build-module/components/form-field-visibility/index.js.map +0 -1
  204. package/build-types/components/form-field-visibility/index.d.ts +0 -11
  205. package/build-types/components/form-field-visibility/index.d.ts.map +0 -1
  206. package/src/components/form-field-visibility/index.tsx +0 -32
@@ -6,6 +6,14 @@
6
6
  line-height: $default-line-height;
7
7
  }
8
8
 
9
+ .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper {
10
+ overflow-y: scroll;
11
+ height: 100%;
12
+ .dataviews-view-config {
13
+ width: auto;
14
+ }
15
+ }
16
+
9
17
  .dataviews-view-config__sort-direction .components-toggle-group-control-option-base {
10
18
  text-transform: uppercase;
11
19
  }
@@ -35,7 +43,6 @@
35
43
  display: none;
36
44
  }
37
45
 
38
- /* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */
39
46
  @container (max-width: 500px) {
40
47
  .dataviews-settings-section.dataviews-settings-section {
41
48
  grid-template-columns: repeat(2, 1fr);
@@ -67,3 +74,12 @@
67
74
  top: unset;
68
75
  }
69
76
  }
77
+
78
+ .dataviews-field-control__icon {
79
+ display: flex;
80
+ width: $icon-size;
81
+ }
82
+
83
+ .dataviews-field-control__label {
84
+ flex-grow: 1;
85
+ }
@@ -13,21 +13,34 @@ import {
13
13
  Spinner,
14
14
  Flex,
15
15
  FlexItem,
16
+ privateApis as componentsPrivateApis,
16
17
  } from '@wordpress/components';
17
18
  import { __ } from '@wordpress/i18n';
19
+ import { useInstanceId } from '@wordpress/compose';
18
20
 
19
21
  /**
20
22
  * Internal dependencies
21
23
  */
24
+ import { unlock } from '../../lock-unlock';
22
25
  import ItemActions from '../../components/dataviews-item-actions';
23
- import SingleSelectionCheckbox from '../../components/dataviews-selection-checkbox';
24
- import { useHasAPossibleBulkAction } from '../../components/dataviews-bulk-actions';
25
- import type { Action, NormalizedField, ViewGridProps } from '../../types';
26
+ import DataViewsSelectionCheckbox from '../../components/dataviews-selection-checkbox';
27
+ import {
28
+ useHasAPossibleBulkAction,
29
+ useSomeItemHasAPossibleBulkAction,
30
+ } from '../../components/dataviews-bulk-actions';
31
+ import type {
32
+ Action,
33
+ NormalizedField,
34
+ ViewGrid as ViewGridType,
35
+ ViewGridProps,
36
+ } from '../../types';
26
37
  import type { SetSelection } from '../../private-types';
27
38
  import getClickableItemProps from '../utils/get-clickable-item-props';
28
39
  import { useUpdatedPreviewSizeOnViewportChange } from './preview-size-picker';
40
+ const { Badge } = unlock( componentsPrivateApis );
29
41
 
30
42
  interface GridItemProps< Item > {
43
+ view: ViewGridType;
31
44
  selection: string[];
32
45
  onChangeSelection: SetSelection;
33
46
  getItemId: ( item: Item ) => string;
@@ -35,14 +48,16 @@ interface GridItemProps< Item > {
35
48
  isItemClickable: ( item: Item ) => boolean;
36
49
  item: Item;
37
50
  actions: Action< Item >[];
51
+ titleField?: NormalizedField< Item >;
38
52
  mediaField?: NormalizedField< Item >;
39
- primaryField?: NormalizedField< Item >;
40
- visibleFields: NormalizedField< Item >[];
53
+ descriptionField?: NormalizedField< Item >;
54
+ regularFields: NormalizedField< Item >[];
41
55
  badgeFields: NormalizedField< Item >[];
42
- columnFields?: string[];
56
+ hasBulkActions: boolean;
43
57
  }
44
58
 
45
59
  function GridItem< Item >( {
60
+ view,
46
61
  selection,
47
62
  onChangeSelection,
48
63
  onClickItem,
@@ -51,20 +66,24 @@ function GridItem< Item >( {
51
66
  item,
52
67
  actions,
53
68
  mediaField,
54
- primaryField,
55
- visibleFields,
69
+ titleField,
70
+ descriptionField,
71
+ regularFields,
56
72
  badgeFields,
57
- columnFields,
73
+ hasBulkActions,
58
74
  }: GridItemProps< Item > ) {
75
+ const { showTitle = true, showMedia = true, showDescription = true } = view;
59
76
  const hasBulkAction = useHasAPossibleBulkAction( actions, item );
60
77
  const id = getItemId( item );
78
+ const instanceId = useInstanceId( GridItem );
61
79
  const isSelected = selection.includes( id );
62
80
  const renderedMediaField = mediaField?.render ? (
63
81
  <mediaField.render item={ item } />
64
82
  ) : null;
65
- const renderedPrimaryField = primaryField?.render ? (
66
- <primaryField.render item={ item } />
67
- ) : null;
83
+ const renderedTitleField =
84
+ showTitle && titleField?.render ? (
85
+ <titleField.render item={ item } />
86
+ ) : null;
68
87
 
69
88
  const clickableMediaItemProps = getClickableItemProps( {
70
89
  item,
@@ -73,13 +92,30 @@ function GridItem< Item >( {
73
92
  className: 'dataviews-view-grid__media',
74
93
  } );
75
94
 
76
- const clickablePrimaryItemProps = getClickableItemProps( {
95
+ const clickableTitleItemProps = getClickableItemProps( {
77
96
  item,
78
97
  isItemClickable,
79
98
  onClickItem,
80
- className: 'dataviews-view-grid__primary-field',
99
+ className: 'dataviews-view-grid__title-field dataviews-title-field',
81
100
  } );
82
101
 
102
+ let mediaA11yProps;
103
+ let titleA11yProps;
104
+ if ( isItemClickable( item ) && onClickItem ) {
105
+ if ( renderedTitleField ) {
106
+ mediaA11yProps = {
107
+ 'aria-labelledby': `dataviews-view-grid__title-field-${ instanceId }`,
108
+ };
109
+ titleA11yProps = {
110
+ id: `dataviews-view-grid__title-field-${ instanceId }`,
111
+ };
112
+ } else {
113
+ mediaA11yProps = {
114
+ 'aria-label': __( 'Navigate to item' ),
115
+ };
116
+ }
117
+ }
118
+
83
119
  return (
84
120
  <VStack
85
121
  spacing={ 0 }
@@ -102,82 +138,89 @@ function GridItem< Item >( {
102
138
  }
103
139
  } }
104
140
  >
105
- <div { ...clickableMediaItemProps }>{ renderedMediaField }</div>
106
- <SingleSelectionCheckbox
107
- item={ item }
108
- selection={ selection }
109
- onChangeSelection={ onChangeSelection }
110
- getItemId={ getItemId }
111
- primaryField={ primaryField }
112
- disabled={ ! hasBulkAction }
113
- />
141
+ { showMedia && renderedMediaField && (
142
+ <div { ...clickableMediaItemProps } { ...mediaA11yProps }>
143
+ { renderedMediaField }
144
+ </div>
145
+ ) }
146
+ { hasBulkActions && showMedia && renderedMediaField && (
147
+ <DataViewsSelectionCheckbox
148
+ item={ item }
149
+ selection={ selection }
150
+ onChangeSelection={ onChangeSelection }
151
+ getItemId={ getItemId }
152
+ titleField={ titleField }
153
+ disabled={ ! hasBulkAction }
154
+ />
155
+ ) }
114
156
  <HStack
115
157
  justify="space-between"
116
158
  className="dataviews-view-grid__title-actions"
117
159
  >
118
- <div { ...clickablePrimaryItemProps }>
119
- { renderedPrimaryField }
160
+ <div { ...clickableTitleItemProps } { ...titleA11yProps }>
161
+ { renderedTitleField }
120
162
  </div>
121
- <ItemActions item={ item } actions={ actions } isCompact />
163
+ { !! actions?.length && (
164
+ <ItemActions item={ item } actions={ actions } isCompact />
165
+ ) }
122
166
  </HStack>
123
- { !! badgeFields?.length && (
124
- <HStack
125
- className="dataviews-view-grid__badge-fields"
126
- spacing={ 2 }
127
- wrap
128
- alignment="top"
129
- justify="flex-start"
130
- >
131
- { badgeFields.map( ( field ) => {
132
- return (
133
- <FlexItem
134
- key={ field.id }
135
- className="dataviews-view-grid__field-value"
136
- >
137
- <field.render item={ item } />
138
- </FlexItem>
139
- );
140
- } ) }
141
- </HStack>
142
- ) }
143
- { !! visibleFields?.length && (
144
- <VStack className="dataviews-view-grid__fields" spacing={ 1 }>
145
- { visibleFields.map( ( field ) => {
146
- return (
147
- <Flex
148
- className={ clsx(
149
- 'dataviews-view-grid__field',
150
- columnFields?.includes( field.id )
151
- ? 'is-column'
152
- : 'is-row'
153
- ) }
154
- key={ field.id }
155
- gap={ 1 }
156
- justify="flex-start"
157
- expanded
158
- style={ { height: 'auto' } }
159
- direction={
160
- columnFields?.includes( field.id )
161
- ? 'column'
162
- : 'row'
163
- }
164
- >
165
- <>
166
- <FlexItem className="dataviews-view-grid__field-name">
167
- { field.header }
168
- </FlexItem>
169
- <FlexItem
170
- className="dataviews-view-grid__field-value"
171
- style={ { maxHeight: 'none' } }
172
- >
173
- <field.render item={ item } />
174
- </FlexItem>
175
- </>
176
- </Flex>
177
- );
178
- } ) }
179
- </VStack>
180
- ) }
167
+ <VStack spacing={ 1 }>
168
+ { showDescription && descriptionField?.render && (
169
+ <descriptionField.render item={ item } />
170
+ ) }
171
+ { !! badgeFields?.length && (
172
+ <HStack
173
+ className="dataviews-view-grid__badge-fields"
174
+ spacing={ 2 }
175
+ wrap
176
+ alignment="top"
177
+ justify="flex-start"
178
+ >
179
+ { badgeFields.map( ( field ) => {
180
+ return (
181
+ <Badge
182
+ key={ field.id }
183
+ className="dataviews-view-grid__field-value"
184
+ >
185
+ <field.render item={ item } />
186
+ </Badge>
187
+ );
188
+ } ) }
189
+ </HStack>
190
+ ) }
191
+ { !! regularFields?.length && (
192
+ <VStack
193
+ className="dataviews-view-grid__fields"
194
+ spacing={ 1 }
195
+ >
196
+ { regularFields.map( ( field ) => {
197
+ return (
198
+ <Flex
199
+ className="dataviews-view-grid__field"
200
+ key={ field.id }
201
+ gap={ 1 }
202
+ justify="flex-start"
203
+ expanded
204
+ style={ { height: 'auto' } }
205
+ direction="row"
206
+ >
207
+ <>
208
+ <FlexItem className="dataviews-view-grid__field-name">
209
+ { field.header }
210
+ </FlexItem>
211
+ <FlexItem
212
+ className="dataviews-view-grid__field-value"
213
+ style={ { maxHeight: 'none' } }
214
+ >
215
+ <field.render item={ item } />
216
+ </FlexItem>
217
+ </>
218
+ </Flex>
219
+ );
220
+ } ) }
221
+ </VStack>
222
+ ) }
223
+ </VStack>
181
224
  </VStack>
182
225
  );
183
226
  }
@@ -194,36 +237,38 @@ export default function ViewGrid< Item >( {
194
237
  selection,
195
238
  view,
196
239
  }: ViewGridProps< Item > ) {
240
+ const titleField = fields.find(
241
+ ( field ) => field.id === view?.titleField
242
+ );
197
243
  const mediaField = fields.find(
198
- ( field ) => field.id === view.layout?.mediaField
244
+ ( field ) => field.id === view?.mediaField
199
245
  );
200
- const primaryField = fields.find(
201
- ( field ) => field.id === view.layout?.primaryField
246
+ const descriptionField = fields.find(
247
+ ( field ) => field.id === view?.descriptionField
202
248
  );
203
- const viewFields = view.fields || fields.map( ( field ) => field.id );
204
- const { visibleFields, badgeFields } = fields.reduce(
205
- ( accumulator: Record< string, NormalizedField< Item >[] >, field ) => {
206
- if (
207
- ! viewFields.includes( field.id ) ||
208
- [
209
- view.layout?.mediaField,
210
- view?.layout?.primaryField,
211
- ].includes( field.id )
212
- ) {
249
+ const otherFields = view.fields ?? [];
250
+ const { regularFields, badgeFields } = otherFields.reduce(
251
+ (
252
+ accumulator: Record< string, NormalizedField< Item >[] >,
253
+ fieldId
254
+ ) => {
255
+ const field = fields.find( ( f ) => f.id === fieldId );
256
+ if ( ! field ) {
213
257
  return accumulator;
214
258
  }
215
259
  // If the field is a badge field, add it to the badgeFields array
216
260
  // otherwise add it to the rest visibleFields array.
217
- const key = view.layout?.badgeFields?.includes( field.id )
261
+ const key = view.layout?.badgeFields?.includes( fieldId )
218
262
  ? 'badgeFields'
219
- : 'visibleFields';
263
+ : 'regularFields';
220
264
  accumulator[ key ].push( field );
221
265
  return accumulator;
222
266
  },
223
- { visibleFields: [], badgeFields: [] }
267
+ { regularFields: [], badgeFields: [] }
224
268
  );
225
269
  const hasData = !! data?.length;
226
270
  const updatedPreviewSize = useUpdatedPreviewSizeOnViewportChange();
271
+ const hasBulkActions = useSomeItemHasAPossibleBulkAction( actions, data );
227
272
  const usedPreviewSize = updatedPreviewSize || view.layout?.previewSize;
228
273
  const gridStyle = usedPreviewSize
229
274
  ? {
@@ -245,6 +290,7 @@ export default function ViewGrid< Item >( {
245
290
  return (
246
291
  <GridItem
247
292
  key={ getItemId( item ) }
293
+ view={ view }
248
294
  selection={ selection }
249
295
  onChangeSelection={ onChangeSelection }
250
296
  onClickItem={ onClickItem }
@@ -253,10 +299,11 @@ export default function ViewGrid< Item >( {
253
299
  item={ item }
254
300
  actions={ actions }
255
301
  mediaField={ mediaField }
256
- primaryField={ primaryField }
257
- visibleFields={ visibleFields }
302
+ titleField={ titleField }
303
+ descriptionField={ descriptionField }
304
+ regularFields={ regularFields }
258
305
  badgeFields={ badgeFields }
259
- columnFields={ view.layout?.columnFields }
306
+ hasBulkActions={ hasBulkActions }
260
307
  />
261
308
  );
262
309
  } ) }
@@ -3,7 +3,6 @@
3
3
  */
4
4
  import { RangeControl } from '@wordpress/components';
5
5
  import { __ } from '@wordpress/i18n';
6
- import { useViewportMatch } from '@wordpress/compose';
7
6
  import { useMemo, useContext } from '@wordpress/element';
8
7
 
9
8
  /**
@@ -12,7 +11,9 @@ import { useMemo, useContext } from '@wordpress/element';
12
11
  import DataViewsContext from '../../components/dataviews-context';
13
12
  import type { ViewGrid } from '../../types';
14
13
 
15
- const viewportBreaks = {
14
+ const viewportBreaks: {
15
+ [ key: string ]: { min: number; max: number; default: number };
16
+ } = {
16
17
  xhuge: { min: 3, max: 6, default: 5 },
17
18
  huge: { min: 2, max: 4, default: 4 },
18
19
  xlarge: { min: 2, max: 3, default: 3 },
@@ -20,38 +21,35 @@ const viewportBreaks = {
20
21
  mobile: { min: 1, max: 2, default: 2 },
21
22
  };
22
23
 
23
- function useViewPortBreakpoint() {
24
- const isXHuge = useViewportMatch( 'xhuge', '>=' );
25
- const isHuge = useViewportMatch( 'huge', '>=' );
26
- const isXlarge = useViewportMatch( 'xlarge', '>=' );
27
- const isLarge = useViewportMatch( 'large', '>=' );
28
- const isMobile = useViewportMatch( 'mobile', '>=' );
24
+ /**
25
+ * Breakpoints were adjusted from media queries breakpoints to account for
26
+ * the sidebar width. This was done to match the existing styles we had.
27
+ */
28
+ const BREAKPOINTS = {
29
+ xhuge: 1520,
30
+ huge: 1140,
31
+ xlarge: 780,
32
+ large: 480,
33
+ mobile: 0,
34
+ };
29
35
 
30
- if ( isXHuge ) {
31
- return 'xhuge';
32
- }
33
- if ( isHuge ) {
34
- return 'huge';
35
- }
36
- if ( isXlarge ) {
37
- return 'xlarge';
38
- }
39
- if ( isLarge ) {
40
- return 'large';
41
- }
42
- if ( isMobile ) {
43
- return 'mobile';
36
+ function useViewPortBreakpoint() {
37
+ const containerWidth = useContext( DataViewsContext ).containerWidth;
38
+ for ( const [ key, value ] of Object.entries( BREAKPOINTS ) ) {
39
+ if ( containerWidth >= value ) {
40
+ return key;
41
+ }
44
42
  }
45
- return null;
43
+ return 'mobile';
46
44
  }
47
45
 
48
46
  export function useUpdatedPreviewSizeOnViewportChange() {
49
- const viewport = useViewPortBreakpoint();
50
47
  const view = useContext( DataViewsContext ).view as ViewGrid;
48
+ const viewport = useViewPortBreakpoint();
51
49
  return useMemo( () => {
52
50
  const previewSize = view.layout?.previewSize;
53
51
  let newPreviewSize;
54
- if ( ! viewport || ! previewSize ) {
52
+ if ( ! previewSize ) {
55
53
  return;
56
54
  }
57
55
  const breakValues = viewportBreaks[ viewport ];
@@ -69,9 +67,8 @@ export default function PreviewSizePicker() {
69
67
  const viewport = useViewPortBreakpoint();
70
68
  const context = useContext( DataViewsContext );
71
69
  const view = context.view as ViewGrid;
72
- const breakValues = viewportBreaks[ viewport || 'mobile' ];
70
+ const breakValues = viewportBreaks[ viewport ];
73
71
  const previewSizeToUse = view.layout?.previewSize || breakValues.default;
74
-
75
72
  const marks = useMemo(
76
73
  () =>
77
74
  Array.from(
@@ -84,11 +81,9 @@ export default function PreviewSizePicker() {
84
81
  ),
85
82
  [ breakValues ]
86
83
  );
87
-
88
- if ( ! viewport ) {
84
+ if ( viewport === 'mobile' ) {
89
85
  return null;
90
86
  }
91
-
92
87
  return (
93
88
  <RangeControl
94
89
  __nextHasNoMarginBottom
@@ -3,6 +3,7 @@
3
3
  grid-template-rows: max-content;
4
4
  padding: 0 $grid-unit-60 $grid-unit-30;
5
5
  transition: padding ease-out 0.1s;
6
+ container-type: inline-size;
6
7
  @include reduce-motion("transition");
7
8
 
8
9
 
@@ -15,7 +16,7 @@
15
16
  padding: $grid-unit-10 0 $grid-unit-05;
16
17
  }
17
18
 
18
- .dataviews-view-grid__primary-field {
19
+ .dataviews-view-grid__title-field {
19
20
  min-height: $grid-unit-30; // Preserve layout when there is no ellipsis button
20
21
  display: flex;
21
22
  align-items: center;
@@ -30,11 +31,16 @@
30
31
  .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
31
32
  color: $gray-900;
32
33
  }
33
-
34
- .dataviews-view-grid__media::after {
35
- background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
36
- box-shadow: inset 0 0 0 $border-width var(--wp-admin-theme-color);
37
- }
34
+ }
35
+ &.is-selected .dataviews-view-grid__media::after,
36
+ .dataviews-view-grid__media:focus::after {
37
+ background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
38
+ }
39
+ &.is-selected .dataviews-view-grid__media::after {
40
+ box-shadow: inset 0 0 0 $border-width var(--wp-admin-theme-color);
41
+ }
42
+ .dataviews-view-grid__media:focus::after {
43
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
38
44
  }
39
45
  }
40
46
 
@@ -81,36 +87,23 @@
81
87
  }
82
88
 
83
89
  .dataviews-view-grid__field {
84
- align-items: flex-start;
85
90
  min-height: $grid-unit-30;
91
+ align-items: center;
86
92
 
87
- &:not(:has(.dataviews-view-grid__field-value:not(:empty))) {
88
- display: none;
89
- }
90
-
91
- &:not(.is-column) {
92
- align-items: center;
93
-
94
- .dataviews-view-grid__field-name {
95
- width: 35%;
96
- }
97
-
98
- .dataviews-view-grid__field-value {
99
- width: 65%;
100
- overflow: hidden;
101
- text-overflow: ellipsis;
102
- white-space: nowrap;
103
- }
93
+ .dataviews-view-grid__field-name {
94
+ width: 35%;
95
+ color: $gray-700;
104
96
  }
105
97
 
106
- &.is-column {
107
- & + .is-row {
108
- margin-top: $grid-unit-05;
109
- }
98
+ .dataviews-view-grid__field-value {
99
+ width: 65%;
100
+ overflow: hidden;
101
+ text-overflow: ellipsis;
102
+ white-space: nowrap;
110
103
  }
111
104
 
112
- .dataviews-view-grid__field-name {
113
- color: $gray-700;
105
+ &:not(:has(.dataviews-view-grid__field-value:not(:empty))) {
106
+ display: none;
114
107
  }
115
108
  }
116
109
  }
@@ -119,36 +112,29 @@
119
112
  &:not(:empty) {
120
113
  padding-bottom: $grid-unit-15;
121
114
  }
122
-
123
- .dataviews-view-grid__field-value {
124
- width: fit-content;
125
- background: $gray-100;
126
- padding: 0 $grid-unit-10;
127
- min-height: $grid-unit-30;
128
- border-radius: $radius-small;
129
- display: flex;
130
- align-items: center;
131
- font-size: 12px;
132
- }
133
115
  }
134
116
  }
135
117
 
136
118
  .dataviews-view-grid.dataviews-view-grid {
137
- grid-template-columns: repeat(1, minmax(0, 1fr));
138
-
139
- @include break-mobile() {
119
+ /**
120
+ * Breakpoints were adjusted from media queries breakpoints to account for
121
+ * the sidebar width. This was done to match the existing styles we had.
122
+ */
123
+ @container (max-width: 480px) {
124
+ grid-template-columns: repeat(1, minmax(0, 1fr));
125
+ padding-left: $grid-unit-30;
126
+ padding-right: $grid-unit-30;
127
+ }
128
+ @container (min-width: 480px) {
140
129
  grid-template-columns: repeat(2, minmax(0, 1fr));
141
130
  }
142
-
143
- @include break-xlarge() {
131
+ @container (min-width: 780px) {
144
132
  grid-template-columns: repeat(3, minmax(0, 1fr));
145
133
  }
146
-
147
- @include break-huge() {
134
+ @container (min-width: 1140px) {
148
135
  grid-template-columns: repeat(4, minmax(0, 1fr));
149
136
  }
150
-
151
- @include break-xhuge() {
137
+ @container (min-width: 1520px) {
152
138
  grid-template-columns: repeat(5, minmax(0, 1fr));
153
139
  }
154
140
  }
@@ -171,10 +157,6 @@
171
157
  top: $grid-unit-10;
172
158
  }
173
159
 
174
- /* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */
175
- @container (max-width: 430px) {
176
- .dataviews-view-grid {
177
- padding-left: $grid-unit-30;
178
- padding-right: $grid-unit-30;
179
- }
160
+ .dataviews-view-grid__media--clickable {
161
+ cursor: pointer;
180
162
  }