@wordpress/dataviews 2.1.0 → 2.2.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 (56) hide show
  1. package/CHANGELOG.md +8 -5
  2. package/build/bulk-actions-toolbar.js +5 -1
  3. package/build/bulk-actions-toolbar.js.map +1 -1
  4. package/build/bulk-actions.js +10 -20
  5. package/build/bulk-actions.js.map +1 -1
  6. package/build/dataviews.js +17 -11
  7. package/build/dataviews.js.map +1 -1
  8. package/build/item-actions.js +16 -5
  9. package/build/item-actions.js.map +1 -1
  10. package/build/lock-unlock.js +1 -1
  11. package/build/lock-unlock.js.map +1 -1
  12. package/build/single-selection-checkbox.js +1 -1
  13. package/build/single-selection-checkbox.js.map +1 -1
  14. package/build/types.js.map +1 -1
  15. package/build/view-list.js +9 -3
  16. package/build/view-list.js.map +1 -1
  17. package/build/view-table.js +11 -5
  18. package/build/view-table.js.map +1 -1
  19. package/build-module/bulk-actions-toolbar.js +5 -1
  20. package/build-module/bulk-actions-toolbar.js.map +1 -1
  21. package/build-module/bulk-actions.js +11 -21
  22. package/build-module/bulk-actions.js.map +1 -1
  23. package/build-module/dataviews.js +18 -12
  24. package/build-module/dataviews.js.map +1 -1
  25. package/build-module/item-actions.js +16 -5
  26. package/build-module/item-actions.js.map +1 -1
  27. package/build-module/lock-unlock.js +1 -1
  28. package/build-module/lock-unlock.js.map +1 -1
  29. package/build-module/single-selection-checkbox.js +1 -1
  30. package/build-module/single-selection-checkbox.js.map +1 -1
  31. package/build-module/types.js.map +1 -1
  32. package/build-module/view-list.js +9 -3
  33. package/build-module/view-list.js.map +1 -1
  34. package/build-module/view-table.js +11 -5
  35. package/build-module/view-table.js.map +1 -1
  36. package/build-types/bulk-actions-toolbar.d.ts.map +1 -1
  37. package/build-types/bulk-actions.d.ts.map +1 -1
  38. package/build-types/dataviews.d.ts +3 -1
  39. package/build-types/dataviews.d.ts.map +1 -1
  40. package/build-types/item-actions.d.ts.map +1 -1
  41. package/build-types/types.d.ts +5 -11
  42. package/build-types/types.d.ts.map +1 -1
  43. package/build-types/view-list.d.ts.map +1 -1
  44. package/build-types/view-table.d.ts.map +1 -1
  45. package/package.json +10 -9
  46. package/src/bulk-actions-toolbar.tsx +5 -1
  47. package/src/bulk-actions.tsx +13 -32
  48. package/src/dataviews.tsx +25 -24
  49. package/src/item-actions.tsx +12 -8
  50. package/src/lock-unlock.ts +1 -1
  51. package/src/single-selection-checkbox.tsx +1 -1
  52. package/src/types.ts +7 -13
  53. package/src/view-list.tsx +10 -7
  54. package/src/view-table.tsx +14 -3
  55. package/tsconfig.json +1 -0
  56. package/tsconfig.tsbuildinfo +1 -1
@@ -15,6 +15,7 @@ import {
15
15
  import { __ } from '@wordpress/i18n';
16
16
  import { useMemo, useState } from '@wordpress/element';
17
17
  import { moreVertical } from '@wordpress/icons';
18
+ import { useRegistry } from '@wordpress/data';
18
19
 
19
20
  /**
20
21
  * Internal dependencies
@@ -112,16 +113,13 @@ export function ActionModal< Item extends AnyItem >( {
112
113
  title={ action.modalHeader || label }
113
114
  __experimentalHideHeader={ !! action.hideModalHeader }
114
115
  onRequestClose={ closeModal ?? ( () => {} ) }
116
+ focusOnMount="firstContentElement"
117
+ size="small"
115
118
  overlayClassName={ `dataviews-action-modal dataviews-action-modal__${ kebabCase(
116
119
  action.id
117
120
  ) }` }
118
121
  >
119
- <action.RenderModal
120
- items={ items }
121
- closeModal={ closeModal }
122
- onActionStart={ action.onActionStart }
123
- onActionPerformed={ action.onActionPerformed }
124
- />
122
+ <action.RenderModal items={ items } closeModal={ closeModal } />
125
123
  </Modal>
126
124
  );
127
125
  }
@@ -159,6 +157,7 @@ export function ActionsDropdownMenuGroup< Item extends AnyItem >( {
159
157
  actions,
160
158
  item,
161
159
  }: ActionsDropdownMenuGroupProps< Item > ) {
160
+ const registry = useRegistry();
162
161
  return (
163
162
  <DropdownMenuGroup>
164
163
  { actions.map( ( action ) => {
@@ -176,7 +175,9 @@ export function ActionsDropdownMenuGroup< Item extends AnyItem >( {
176
175
  <DropdownMenuItemTrigger
177
176
  key={ action.id }
178
177
  action={ action }
179
- onClick={ () => action.callback( [ item ] ) }
178
+ onClick={ () => {
179
+ action.callback( [ item ], { registry } );
180
+ } }
180
181
  items={ [ item ] }
181
182
  />
182
183
  );
@@ -190,6 +191,7 @@ export default function ItemActions< Item extends AnyItem >( {
190
191
  actions,
191
192
  isCompact,
192
193
  }: ItemActionsProps< Item > ) {
194
+ const registry = useRegistry();
193
195
  const { primaryActions, eligibleActions } = useMemo( () => {
194
196
  // If an action is eligible for all items, doesn't need
195
197
  // to provide the `isEligible` function.
@@ -233,7 +235,9 @@ export default function ItemActions< Item extends AnyItem >( {
233
235
  <ButtonTrigger
234
236
  key={ action.id }
235
237
  action={ action }
236
- onClick={ () => action.callback( [ item ] ) }
238
+ onClick={ () => {
239
+ action.callback( [ item ], { registry } );
240
+ } }
237
241
  items={ [ item ] }
238
242
  />
239
243
  );
@@ -5,6 +5,6 @@ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/pri
5
5
 
6
6
  export const { lock, unlock } =
7
7
  __dangerousOptInToUnstableAPIsOnlyForCoreModules(
8
- 'I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.',
8
+ 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
9
9
  '@wordpress/dataviews'
10
10
  );
@@ -29,7 +29,7 @@ export default function SingleSelectionCheckbox< Item extends AnyItem >( {
29
29
  disabled,
30
30
  }: SingleSelectionCheckboxProps< Item > ) {
31
31
  const id = getItemId( item );
32
- const isSelected = selection.includes( id );
32
+ const isSelected = ! disabled && selection.includes( id );
33
33
  let selectionLabel;
34
34
  if ( primaryField?.getValue && item ) {
35
35
  // eslint-disable-next-line @wordpress/valid-sprintf
package/src/types.ts CHANGED
@@ -327,28 +327,16 @@ interface ActionBase< Item extends AnyItem > {
327
327
 
328
328
  export interface ActionModal< Item extends AnyItem >
329
329
  extends ActionBase< Item > {
330
- /**
331
- * The callback to execute when the action has finished.
332
- */
333
- onActionPerformed: ( ( items: Item[] ) => void ) | undefined;
334
-
335
- /**
336
- * The callback to execute when the action is triggered.
337
- */
338
- onActionStart: ( ( items: Item[] ) => void ) | undefined;
339
-
340
330
  /**
341
331
  * Modal to render when the action is triggered.
342
332
  */
343
333
  RenderModal: ( {
344
334
  items,
345
335
  closeModal,
346
- onActionStart,
347
336
  onActionPerformed,
348
337
  }: {
349
338
  items: Item[];
350
339
  closeModal?: () => void;
351
- onActionStart?: ( items: Item[] ) => void;
352
340
  onActionPerformed?: ( items: Item[] ) => void;
353
341
  } ) => ReactElement;
354
342
 
@@ -368,7 +356,13 @@ export interface ActionButton< Item extends AnyItem >
368
356
  /**
369
357
  * The callback to execute when the action is triggered.
370
358
  */
371
- callback: ( items: Item[] ) => void;
359
+ callback: (
360
+ items: Item[],
361
+ context: {
362
+ registry: any;
363
+ onActionPerformed?: ( items: Item[] ) => void;
364
+ }
365
+ ) => void;
372
366
  }
373
367
 
374
368
  export type Action< Item extends AnyItem > =
package/src/view-list.tsx CHANGED
@@ -27,6 +27,7 @@ import {
27
27
  } from '@wordpress/element';
28
28
  import { __ } from '@wordpress/i18n';
29
29
  import { moreVertical } from '@wordpress/icons';
30
+ import { useRegistry } from '@wordpress/data';
30
31
 
31
32
  /**
32
33
  * Internal dependencies
@@ -67,6 +68,7 @@ function ListItem< Item extends AnyItem >( {
67
68
  store,
68
69
  visibleFields,
69
70
  }: ListViewItemProps< Item > ) {
71
+ const registry = useRegistry();
70
72
  const itemRef = useRef< HTMLElement >( null );
71
73
  const labelId = `${ id }-label`;
72
74
  const descriptionId = `${ id }-description`;
@@ -182,7 +184,7 @@ function ListItem< Item extends AnyItem >( {
182
184
  </HStack>
183
185
  </CompositeItem>
184
186
  </div>
185
- { actions?.length > 0 && (
187
+ { eligibleActions?.length > 0 && (
186
188
  <HStack
187
189
  spacing={ 1 }
188
190
  justify="flex-end"
@@ -235,11 +237,12 @@ function ListItem< Item extends AnyItem >( {
235
237
  primaryAction.isDestructive
236
238
  }
237
239
  size="compact"
238
- onClick={ () =>
239
- primaryAction.callback( [
240
- item,
241
- ] )
242
- }
240
+ onClick={ () => {
241
+ primaryAction.callback(
242
+ [ item ],
243
+ { registry }
244
+ );
245
+ } }
243
246
  />
244
247
  }
245
248
  />
@@ -315,7 +318,7 @@ export default function ViewList< Item extends AnyItem >(
315
318
  } = props;
316
319
  const baseId = useInstanceId( ViewList, 'view-list' );
317
320
  const selectedItem = data?.findLast( ( item ) =>
318
- selection.includes( item.id )
321
+ selection.includes( getItemId( item ) )
319
322
  );
320
323
 
321
324
  const mediaField = fields.find(
@@ -75,6 +75,7 @@ interface BulkSelectionCheckboxProps< Item extends AnyItem > {
75
75
  onSelectionChange: ( items: Item[] ) => void;
76
76
  data: Item[];
77
77
  actions: Action< Item >[];
78
+ getItemId: ( item: Item ) => string;
78
79
  }
79
80
 
80
81
  interface TableRowProps< Item extends AnyItem > {
@@ -249,6 +250,7 @@ function BulkSelectionCheckbox< Item extends AnyItem >( {
249
250
  onSelectionChange,
250
251
  data,
251
252
  actions,
253
+ getItemId,
252
254
  }: BulkSelectionCheckboxProps< Item > ) {
253
255
  const selectableItems = useMemo( () => {
254
256
  return data.filter( ( item ) => {
@@ -259,13 +261,18 @@ function BulkSelectionCheckbox< Item extends AnyItem >( {
259
261
  );
260
262
  } );
261
263
  }, [ data, actions ] );
262
- const areAllSelected = selection.length === selectableItems.length;
264
+ const selectedItems = data.filter(
265
+ ( item ) =>
266
+ selection.includes( getItemId( item ) ) &&
267
+ selectableItems.includes( item )
268
+ );
269
+ const areAllSelected = selectedItems.length === selectableItems.length;
263
270
  return (
264
271
  <CheckboxControl
265
272
  className="dataviews-view-table-selection-checkbox"
266
273
  __nextHasNoMarginBottom
267
274
  checked={ areAllSelected }
268
- indeterminate={ ! areAllSelected && !! selection.length }
275
+ indeterminate={ ! areAllSelected && !! selectedItems.length }
269
276
  onChange={ () => {
270
277
  if ( areAllSelected ) {
271
278
  onSelectionChange( [] );
@@ -293,7 +300,7 @@ function TableRow< Item extends AnyItem >( {
293
300
  data,
294
301
  }: TableRowProps< Item > ) {
295
302
  const hasPossibleBulkAction = useHasAPossibleBulkAction( actions, item );
296
- const isSelected = selection.includes( id );
303
+ const isSelected = hasPossibleBulkAction && selection.includes( id );
297
304
 
298
305
  const [ isHovered, setIsHovered ] = useState( false );
299
306
 
@@ -323,6 +330,9 @@ function TableRow< Item extends AnyItem >( {
323
330
  isTouchDevice.current = true;
324
331
  } }
325
332
  onClick={ () => {
333
+ if ( ! hasPossibleBulkAction ) {
334
+ return;
335
+ }
326
336
  if (
327
337
  ! isTouchDevice.current &&
328
338
  document.getSelection()?.type !== 'Range'
@@ -495,6 +505,7 @@ function ViewTable< Item extends AnyItem >( {
495
505
  onSelectionChange={ onSelectionChange }
496
506
  data={ data }
497
507
  actions={ actions }
508
+ getItemId={ getItemId }
498
509
  />
499
510
  </th>
500
511
  ) }
package/tsconfig.json CHANGED
@@ -9,6 +9,7 @@
9
9
  "references": [
10
10
  { "path": "../components" },
11
11
  { "path": "../compose" },
12
+ { "path": "../data" },
12
13
  { "path": "../element" },
13
14
  { "path": "../i18n" },
14
15
  { "path": "../icons" },