@wordpress/dataviews 0.3.0 → 0.4.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 (45) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/bulk-actions.js +143 -0
  3. package/build/bulk-actions.js.map +1 -0
  4. package/build/dataviews.js +15 -1
  5. package/build/dataviews.js.map +1 -1
  6. package/build/item-actions.js +4 -4
  7. package/build/item-actions.js.map +1 -1
  8. package/build/pagination.js +2 -2
  9. package/build/pagination.js.map +1 -1
  10. package/build/view-actions.js +3 -2
  11. package/build/view-actions.js.map +1 -1
  12. package/build/view-grid.js +11 -8
  13. package/build/view-grid.js.map +1 -1
  14. package/build/view-list.js +13 -1
  15. package/build/view-list.js.map +1 -1
  16. package/build/view-table.js +116 -9
  17. package/build/view-table.js.map +1 -1
  18. package/build-module/bulk-actions.js +136 -0
  19. package/build-module/bulk-actions.js.map +1 -0
  20. package/build-module/dataviews.js +17 -3
  21. package/build-module/dataviews.js.map +1 -1
  22. package/build-module/item-actions.js +4 -4
  23. package/build-module/item-actions.js.map +1 -1
  24. package/build-module/pagination.js +2 -2
  25. package/build-module/pagination.js.map +1 -1
  26. package/build-module/view-actions.js +4 -3
  27. package/build-module/view-actions.js.map +1 -1
  28. package/build-module/view-grid.js +12 -9
  29. package/build-module/view-grid.js.map +1 -1
  30. package/build-module/view-list.js +13 -1
  31. package/build-module/view-list.js.map +1 -1
  32. package/build-module/view-table.js +120 -13
  33. package/build-module/view-table.js.map +1 -1
  34. package/build-style/style-rtl.css +143 -26
  35. package/build-style/style.css +143 -26
  36. package/package.json +11 -11
  37. package/src/bulk-actions.js +187 -0
  38. package/src/dataviews.js +29 -2
  39. package/src/item-actions.js +4 -7
  40. package/src/pagination.js +2 -6
  41. package/src/style.scss +152 -29
  42. package/src/view-actions.js +8 -14
  43. package/src/view-grid.js +14 -12
  44. package/src/view-list.js +20 -1
  45. package/src/view-table.js +161 -15
@@ -97,7 +97,7 @@
97
97
  --wp-block-synced-color: #7a00df;
98
98
  --wp-block-synced-color--rgb: 122, 0, 223;
99
99
  }
100
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
100
+ @media (min-resolution: 192dpi) {
101
101
  :root {
102
102
  --wp-admin-border-width-focus: 1.5px;
103
103
  }
@@ -122,6 +122,10 @@
122
122
  max-width: 240px;
123
123
  }
124
124
 
125
+ .dataviews-filters__view-actions.components-h-stack {
126
+ align-items: center;
127
+ }
128
+
125
129
  .dataviews-filters-button {
126
130
  position: relative;
127
131
  }
@@ -160,6 +164,10 @@
160
164
  margin: 32px 0 16px;
161
165
  }
162
166
 
167
+ .dataviews-view-table-wrapper {
168
+ overflow-x: auto;
169
+ }
170
+
163
171
  .dataviews-view-table {
164
172
  width: 100%;
165
173
  text-indent: 0;
@@ -182,12 +190,26 @@
182
190
  .dataviews-view-table td,
183
191
  .dataviews-view-table th {
184
192
  padding: 12px;
185
- min-width: 160px;
193
+ white-space: nowrap;
194
+ }
195
+ @media (min-width: 1440px) {
196
+ .dataviews-view-table td,
197
+ .dataviews-view-table th {
198
+ min-width: 200px;
199
+ }
186
200
  }
187
201
  .dataviews-view-table td[data-field-id=actions],
188
202
  .dataviews-view-table th[data-field-id=actions] {
189
203
  text-align: right;
190
204
  }
205
+ .dataviews-view-table td.dataviews-view-table__checkbox-column,
206
+ .dataviews-view-table th.dataviews-view-table__checkbox-column {
207
+ padding-right: 0;
208
+ }
209
+ .dataviews-view-table td .components-checkbox-control__input-container,
210
+ .dataviews-view-table th .components-checkbox-control__input-container {
211
+ margin: 4px;
212
+ }
191
213
  .dataviews-view-table tr {
192
214
  border-bottom: 1px solid #f0f0f0;
193
215
  }
@@ -211,9 +233,25 @@
211
233
  .dataviews-view-table tr:last-child {
212
234
  border-bottom: 0;
213
235
  }
214
- .dataviews-view-table tr:hover td {
236
+ .dataviews-view-table tr:hover {
215
237
  background-color: #f8f8f8;
216
238
  }
239
+ .dataviews-view-table tr .components-checkbox-control__input {
240
+ opacity: 0;
241
+ }
242
+ .dataviews-view-table tr .components-checkbox-control__input:checked, .dataviews-view-table tr .components-checkbox-control__input:indeterminate, .dataviews-view-table tr .components-checkbox-control__input:focus {
243
+ opacity: 1;
244
+ }
245
+ .dataviews-view-table tr:focus-within .components-checkbox-control__input, .dataviews-view-table tr:hover .components-checkbox-control__input {
246
+ opacity: 1;
247
+ }
248
+ .dataviews-view-table tr.is-selected {
249
+ background-color: rgba(var(--wp-admin-theme-color--rgb), 0.04);
250
+ color: #757575;
251
+ }
252
+ .dataviews-view-table tr.is-selected:hover {
253
+ background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
254
+ }
217
255
  .dataviews-view-table thead tr {
218
256
  border: 0;
219
257
  }
@@ -230,6 +268,14 @@
230
268
  font-weight: 500;
231
269
  padding-left: 4px;
232
270
  }
271
+ .dataviews-view-table tbody td {
272
+ vertical-align: top;
273
+ }
274
+ .dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper {
275
+ min-height: 32px;
276
+ display: flex;
277
+ align-items: center;
278
+ }
233
279
  .dataviews-view-table .dataviews-view-table-header-button {
234
280
  padding: 4px 8px;
235
281
  font-size: 11px;
@@ -248,6 +294,50 @@
248
294
  .dataviews-view-table .dataviews-view-table-header {
249
295
  padding-left: 4px;
250
296
  }
297
+ .dataviews-view-table .dataviews-view-table__actions-column {
298
+ width: 1%;
299
+ }
300
+
301
+ .dataviews-view-list__primary-field,
302
+ .dataviews-view-grid__primary-field,
303
+ .dataviews-view-table__primary-field {
304
+ font-size: 13px;
305
+ font-weight: 500;
306
+ color: #1e1e1e;
307
+ text-overflow: ellipsis;
308
+ white-space: nowrap;
309
+ overflow: hidden;
310
+ display: block;
311
+ width: 100%;
312
+ }
313
+ .dataviews-view-list__primary-field a,
314
+ .dataviews-view-grid__primary-field a,
315
+ .dataviews-view-table__primary-field a {
316
+ text-decoration: none;
317
+ color: inherit;
318
+ text-overflow: ellipsis;
319
+ white-space: nowrap;
320
+ overflow: hidden;
321
+ display: block;
322
+ width: 100%;
323
+ }
324
+ .dataviews-view-list__primary-field a:hover,
325
+ .dataviews-view-grid__primary-field a:hover,
326
+ .dataviews-view-table__primary-field a:hover {
327
+ color: #1e1e1e;
328
+ }
329
+ .dataviews-view-list__primary-field button.components-button.is-link,
330
+ .dataviews-view-grid__primary-field button.components-button.is-link,
331
+ .dataviews-view-table__primary-field button.components-button.is-link {
332
+ text-decoration: none;
333
+ color: inherit;
334
+ font-weight: inherit;
335
+ text-overflow: ellipsis;
336
+ white-space: nowrap;
337
+ overflow: hidden;
338
+ display: block;
339
+ width: 100%;
340
+ }
251
341
 
252
342
  .dataviews-view-grid {
253
343
  margin-bottom: 24px;
@@ -264,47 +354,45 @@
264
354
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
265
355
  }
266
356
  }
267
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__primary-field .dataviews-view-grid__title-field {
268
- white-space: nowrap;
269
- overflow: hidden;
270
- text-overflow: ellipsis;
271
- display: block;
272
- font-size: 13px;
273
- width: 100%;
357
+ .dataviews-view-grid .dataviews-view-grid__card {
358
+ border-radius: 4px;
359
+ border: 1px solid #e0e0e0;
360
+ height: 100%;
361
+ justify-content: flex-start;
274
362
  }
275
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__primary-field .dataviews-view-grid__title-field a,
276
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__primary-field button.dataviews-view-grid__title-field {
277
- font-weight: 500;
278
- color: #1e1e1e;
279
- text-decoration: none;
363
+ .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions {
364
+ padding: 0 4px;
365
+ }
366
+ .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__primary-field {
367
+ min-height: 40px;
280
368
  }
281
369
  .dataviews-view-grid .dataviews-view-grid__media {
282
370
  width: 100%;
283
371
  min-height: 200px;
284
372
  aspect-ratio: 1/1;
285
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
286
- border-radius: 4px;
287
- overflow: hidden;
373
+ border-bottom: 1px solid #e0e0e0;
374
+ background-color: #f0f0f0;
375
+ border-radius: 3px 3px 0 0;
288
376
  }
289
- .dataviews-view-grid .dataviews-view-grid__media > * {
290
- -o-object-fit: cover;
291
- object-fit: cover;
377
+ .dataviews-view-grid .dataviews-view-grid__media img {
378
+ object-fit: cover;
292
379
  width: 100%;
293
380
  height: 100%;
294
381
  }
295
382
  .dataviews-view-grid .dataviews-view-grid__primary-field {
296
- min-height: 24px;
383
+ padding: 8px;
297
384
  }
298
385
  .dataviews-view-grid .dataviews-view-grid__fields {
299
386
  position: relative;
300
387
  font-size: 12px;
301
388
  line-height: 16px;
302
389
  }
303
- .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-header {
304
- color: #757575;
390
+ .dataviews-view-grid .dataviews-view-grid__fields:not(:empty) {
391
+ padding: 12px;
392
+ padding-top: 0;
305
393
  }
306
394
  .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
307
- color: #1e1e1e;
395
+ color: #757575;
308
396
  }
309
397
 
310
398
  .dataviews-view-list {
@@ -331,6 +419,7 @@
331
419
  .dataviews-view-list li:not(.is-selected):hover {
332
420
  color: var(--wp-admin-theme-color);
333
421
  }
422
+ .dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__primary-field,
334
423
  .dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__fields {
335
424
  color: var(--wp-admin-theme-color);
336
425
  }
@@ -339,8 +428,10 @@
339
428
  background-color: var(--wp-admin-theme-color);
340
429
  color: #fff;
341
430
  }
431
+ .dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__primary-field,
342
432
  .dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,
343
433
  .dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .components-button,
434
+ .dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__primary-field,
344
435
  .dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,
345
436
  .dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .components-button {
346
437
  color: #fff;
@@ -371,11 +462,18 @@
371
462
  white-space: nowrap;
372
463
  }
373
464
  .dataviews-view-list .dataviews-view-list__media-wrapper {
374
- min-width: 32px;
465
+ width: 32px;
375
466
  height: 32px;
376
467
  border-radius: 4px;
377
468
  overflow: hidden;
378
469
  position: relative;
470
+ flex-shrink: 0;
471
+ background-color: #f0f0f0;
472
+ }
473
+ .dataviews-view-list .dataviews-view-list__media-wrapper img {
474
+ width: 100%;
475
+ height: 100%;
476
+ object-fit: cover;
379
477
  }
380
478
  .dataviews-view-list .dataviews-view-list__media-wrapper::after {
381
479
  content: "";
@@ -404,6 +502,9 @@
404
502
  .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:last-child {
405
503
  margin-right: 0;
406
504
  }
505
+ .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:empty {
506
+ display: none;
507
+ }
407
508
  .dataviews-view-list + .dataviews-pagination {
408
509
  justify-content: space-between;
409
510
  }
@@ -429,7 +530,23 @@
429
530
  padding: 0 32px;
430
531
  }
431
532
 
533
+ .dataviews-view-table-selection-checkbox label {
534
+ position: absolute;
535
+ width: 1px;
536
+ height: 1px;
537
+ padding: 0;
538
+ margin: -1px;
539
+ overflow: hidden;
540
+ clip: rect(0, 0, 0, 0);
541
+ white-space: nowrap;
542
+ border: 0;
543
+ }
544
+
432
545
  .dataviews-filters__custom-menu-radio-item-prefix {
433
546
  display: block;
434
547
  width: 24px;
548
+ }
549
+
550
+ .dataviews-bulk-edit-button.components-button {
551
+ flex-shrink: 0;
435
552
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/dataviews",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "DataViews is a component that provides an API to render datasets using different types of layouts (table, grid, list, etc.).",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -28,15 +28,15 @@
28
28
  "sideEffects": false,
29
29
  "dependencies": {
30
30
  "@babel/runtime": "^7.16.0",
31
- "@wordpress/a11y": "^3.49.0",
32
- "@wordpress/components": "^25.15.0",
33
- "@wordpress/compose": "^6.26.0",
34
- "@wordpress/element": "^5.26.0",
35
- "@wordpress/i18n": "^4.49.0",
36
- "@wordpress/icons": "^9.40.0",
37
- "@wordpress/keycodes": "^3.49.0",
38
- "@wordpress/primitives": "^3.47.0",
39
- "@wordpress/private-apis": "^0.31.0",
31
+ "@wordpress/a11y": "^3.50.0",
32
+ "@wordpress/components": "^25.16.0",
33
+ "@wordpress/compose": "^6.27.0",
34
+ "@wordpress/element": "^5.27.0",
35
+ "@wordpress/i18n": "^4.50.0",
36
+ "@wordpress/icons": "^9.41.0",
37
+ "@wordpress/keycodes": "^3.50.0",
38
+ "@wordpress/primitives": "^3.48.0",
39
+ "@wordpress/private-apis": "^0.32.0",
40
40
  "classnames": "^2.3.1",
41
41
  "remove-accents": "^0.5.0"
42
42
  },
@@ -46,5 +46,5 @@
46
46
  "publishConfig": {
47
47
  "access": "public"
48
48
  },
49
- "gitHead": "5e6f9caa205d3bfdbac131952b7bf9c6ec60569b"
49
+ "gitHead": "45de2cb4212fed7f2763e95f10300d1ff9d0ec08"
50
50
  }
@@ -0,0 +1,187 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ privateApis as componentsPrivateApis,
6
+ Button,
7
+ Modal,
8
+ } from '@wordpress/components';
9
+ import { __, sprintf, _n } from '@wordpress/i18n';
10
+ import { useMemo, useState, useCallback } from '@wordpress/element';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import { unlock } from './lock-unlock';
16
+
17
+ const {
18
+ DropdownMenuV2: DropdownMenu,
19
+ DropdownMenuGroupV2: DropdownMenuGroup,
20
+ DropdownMenuItemV2: DropdownMenuItem,
21
+ DropdownMenuSeparatorV2: DropdownMenuSeparator,
22
+ } = unlock( componentsPrivateApis );
23
+
24
+ function ActionWithModal( {
25
+ action,
26
+ selectedItems,
27
+ setActionWithModal,
28
+ onMenuOpenChange,
29
+ } ) {
30
+ const eligibleItems = useMemo( () => {
31
+ return selectedItems.filter( ( item ) => action.isEligible( item ) );
32
+ }, [ action, selectedItems ] );
33
+ const { RenderModal, hideModalHeader } = action;
34
+ const onCloseModal = useCallback( () => {
35
+ setActionWithModal( undefined );
36
+ }, [ setActionWithModal ] );
37
+ return (
38
+ <Modal
39
+ title={ ! hideModalHeader && action.label }
40
+ __experimentalHideHeader={ !! hideModalHeader }
41
+ onRequestClose={ onCloseModal }
42
+ overlayClassName="dataviews-action-modal"
43
+ >
44
+ <RenderModal
45
+ items={ eligibleItems }
46
+ closeModal={ onCloseModal }
47
+ onPerform={ () => onMenuOpenChange( false ) }
48
+ />
49
+ </Modal>
50
+ );
51
+ }
52
+
53
+ function BulkActionItem( { action, selectedItems, setActionWithModal } ) {
54
+ const eligibleItems = useMemo( () => {
55
+ return selectedItems.filter( ( item ) => action.isEligible( item ) );
56
+ }, [ action, selectedItems ] );
57
+
58
+ const shouldShowModal = !! action.RenderModal;
59
+
60
+ return (
61
+ <DropdownMenuItem
62
+ key={ action.id }
63
+ disabled={ eligibleItems.length === 0 }
64
+ hideOnClick={ ! shouldShowModal }
65
+ onClick={ async () => {
66
+ if ( shouldShowModal ) {
67
+ setActionWithModal( action );
68
+ } else {
69
+ await action.callback( eligibleItems );
70
+ }
71
+ } }
72
+ suffix={
73
+ eligibleItems.length > 0 ? eligibleItems.length : undefined
74
+ }
75
+ >
76
+ { action.label }
77
+ </DropdownMenuItem>
78
+ );
79
+ }
80
+
81
+ function ActionsMenuGroup( { actions, selectedItems, setActionWithModal } ) {
82
+ return (
83
+ <>
84
+ <DropdownMenuGroup>
85
+ { actions.map( ( action ) => (
86
+ <BulkActionItem
87
+ key={ action.id }
88
+ action={ action }
89
+ selectedItems={ selectedItems }
90
+ setActionWithModal={ setActionWithModal }
91
+ />
92
+ ) ) }
93
+ </DropdownMenuGroup>
94
+ <DropdownMenuSeparator />
95
+ </>
96
+ );
97
+ }
98
+
99
+ export default function BulkActions( {
100
+ data,
101
+ actions,
102
+ selection,
103
+ onSelectionChange,
104
+ getItemId,
105
+ } ) {
106
+ const bulkActions = useMemo(
107
+ () => actions.filter( ( action ) => action.supportsBulk ),
108
+ [ actions ]
109
+ );
110
+ const areAllSelected = selection && selection.length === data.length;
111
+ const [ isMenuOpen, onMenuOpenChange ] = useState( false );
112
+ const [ actionWithModal, setActionWithModal ] = useState();
113
+ const selectedItems = useMemo( () => {
114
+ return data.filter( ( item ) =>
115
+ selection.includes( getItemId( item ) )
116
+ );
117
+ }, [ selection, data, getItemId ] );
118
+
119
+ if ( bulkActions.length === 0 ) {
120
+ return null;
121
+ }
122
+ return (
123
+ <>
124
+ <DropdownMenu
125
+ open={ isMenuOpen }
126
+ onOpenChange={ onMenuOpenChange }
127
+ label={ __( 'Bulk actions' ) }
128
+ style={ { minWidth: '240px' } }
129
+ trigger={
130
+ <Button
131
+ className="dataviews-bulk-edit-button"
132
+ __next40pxDefaultSize
133
+ variant="tertiary"
134
+ size="compact"
135
+ >
136
+ { selection.length
137
+ ? sprintf(
138
+ /* translators: %d: Number of items. */
139
+ _n(
140
+ 'Edit %d item',
141
+ 'Edit %d items',
142
+ selection.length
143
+ ),
144
+ selection.length
145
+ )
146
+ : __( 'Bulk edit' ) }
147
+ </Button>
148
+ }
149
+ >
150
+ <ActionsMenuGroup
151
+ actions={ bulkActions }
152
+ setActionWithModal={ setActionWithModal }
153
+ selectedItems={ selectedItems }
154
+ />
155
+ <DropdownMenuGroup>
156
+ <DropdownMenuItem
157
+ disabled={ areAllSelected }
158
+ hideOnClick={ false }
159
+ onClick={ () => {
160
+ onSelectionChange( data );
161
+ } }
162
+ suffix={ data.length }
163
+ >
164
+ { __( 'Select all' ) }
165
+ </DropdownMenuItem>
166
+ <DropdownMenuItem
167
+ disabled={ selection.length === 0 }
168
+ hideOnClick={ false }
169
+ onClick={ () => {
170
+ onSelectionChange( [] );
171
+ } }
172
+ >
173
+ { __( 'Deselect' ) }
174
+ </DropdownMenuItem>
175
+ </DropdownMenuGroup>
176
+ </DropdownMenu>
177
+ { actionWithModal && (
178
+ <ActionWithModal
179
+ action={ actionWithModal }
180
+ selectedItems={ selectedItems }
181
+ setActionWithModal={ setActionWithModal }
182
+ onMenuOpenChange={ onMenuOpenChange }
183
+ />
184
+ ) }
185
+ </>
186
+ );
187
+ }
package/src/dataviews.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  __experimentalVStack as VStack,
6
6
  __experimentalHStack as HStack,
7
7
  } from '@wordpress/components';
8
- import { useMemo, useState, useCallback } from '@wordpress/element';
8
+ import { useMemo, useState, useCallback, useEffect } from '@wordpress/element';
9
9
 
10
10
  /**
11
11
  * Internal dependencies
@@ -14,7 +14,8 @@ import Pagination from './pagination';
14
14
  import ViewActions from './view-actions';
15
15
  import Filters from './filters';
16
16
  import Search from './search';
17
- import { VIEW_LAYOUTS } from './constants';
17
+ import { VIEW_LAYOUTS, LAYOUT_TABLE } from './constants';
18
+ import BulkActions from './bulk-actions';
18
19
 
19
20
  const defaultGetItemId = ( item ) => item.id;
20
21
  const defaultOnSelectionChange = () => {};
@@ -37,6 +38,23 @@ export default function DataViews( {
37
38
  } ) {
38
39
  const [ selection, setSelection ] = useState( [] );
39
40
 
41
+ useEffect( () => {
42
+ if (
43
+ selection.length > 0 &&
44
+ selection.some(
45
+ ( id ) => ! data.some( ( item ) => item.id === id )
46
+ )
47
+ ) {
48
+ const newSelection = selection.filter( ( id ) =>
49
+ data.some( ( item ) => item.id === id )
50
+ );
51
+ setSelection( newSelection );
52
+ onSelectionChange(
53
+ data.filter( ( item ) => newSelection.includes( item.id ) )
54
+ );
55
+ }
56
+ }, [ selection, data, onSelectionChange ] );
57
+
40
58
  const onSetSelection = useCallback(
41
59
  ( items ) => {
42
60
  setSelection( items.map( ( item ) => item.id ) );
@@ -75,6 +93,15 @@ export default function DataViews( {
75
93
  onChangeView={ onChangeView }
76
94
  />
77
95
  </HStack>
96
+ { view.type === LAYOUT_TABLE && (
97
+ <BulkActions
98
+ actions={ actions }
99
+ data={ data }
100
+ onSelectionChange={ onSetSelection }
101
+ selection={ selection }
102
+ getItemId={ getItemId }
103
+ />
104
+ ) }
78
105
  <ViewActions
79
106
  fields={ _fields }
80
107
  view={ view }
@@ -59,10 +59,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
59
59
  <ActionTrigger { ...actionTriggerProps } />
60
60
  { isModalOpen && (
61
61
  <Modal
62
- title={
63
- ( ! hideModalHeader && action.modalHeader ) ||
64
- action.label
65
- }
62
+ title={ action.modalHeader || action.label }
66
63
  __experimentalHideHeader={ !! hideModalHeader }
67
64
  onRequestClose={ () => {
68
65
  setIsModalOpen( false );
@@ -72,7 +69,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
72
69
  ) }` }
73
70
  >
74
71
  <RenderModal
75
- item={ item }
72
+ items={ [ item ] }
76
73
  closeModal={ () => setIsModalOpen( false ) }
77
74
  />
78
75
  </Modal>
@@ -99,7 +96,7 @@ function ActionsDropdownMenuGroup( { actions, item } ) {
99
96
  <DropdownMenuItemTrigger
100
97
  key={ action.id }
101
98
  action={ action }
102
- onClick={ () => action.callback( item ) }
99
+ onClick={ () => action.callback( [ item ] ) }
103
100
  />
104
101
  );
105
102
  } ) }
@@ -160,7 +157,7 @@ export default function ItemActions( { item, actions, isCompact } ) {
160
157
  <ButtonTrigger
161
158
  key={ action.id }
162
159
  action={ action }
163
- onClick={ () => action.callback( item ) }
160
+ onClick={ () => action.callback( [ item ] ) }
164
161
  />
165
162
  );
166
163
  } ) }
package/src/pagination.js CHANGED
@@ -30,12 +30,8 @@ const Pagination = memo( function Pagination( {
30
30
  <HStack justify="flex-start" expanded={ false } spacing={ 2 }>
31
31
  { createInterpolateElement(
32
32
  sprintf(
33
- // translators: %1$s: Current page number, %2$s: Total number of pages.
34
- _x(
35
- 'Page <CurrenPageControl /> of %2$s',
36
- 'paging'
37
- ),
38
- view.page,
33
+ // translators: %s: Total number of pages.
34
+ _x( 'Page <CurrenPageControl /> of %s', 'paging' ),
39
35
  totalPages
40
36
  ),
41
37
  {