@wordpress/edit-site 5.20.0 → 5.21.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 (231) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/actions/trash-post.js +48 -0
  3. package/build/components/actions/trash-post.js.map +1 -0
  4. package/build/components/add-new-template/add-custom-template-modal-content.js +17 -13
  5. package/build/components/add-new-template/add-custom-template-modal-content.js.map +1 -1
  6. package/build/components/block-editor/resize-handle.js +2 -1
  7. package/build/components/block-editor/resize-handle.js.map +1 -1
  8. package/build/components/create-template-part-modal/index.js +10 -6
  9. package/build/components/create-template-part-modal/index.js.map +1 -1
  10. package/build/components/dataviews/dataviews.js +41 -32
  11. package/build/components/dataviews/dataviews.js.map +1 -1
  12. package/build/components/dataviews/field-actions.js +30 -0
  13. package/build/components/dataviews/field-actions.js.map +1 -0
  14. package/build/components/dataviews/filters.js +61 -0
  15. package/build/components/dataviews/filters.js.map +1 -0
  16. package/build/components/dataviews/in-filter.js +51 -0
  17. package/build/components/dataviews/in-filter.js.map +1 -0
  18. package/build/components/dataviews/index.js +0 -7
  19. package/build/components/dataviews/index.js.map +1 -1
  20. package/build/components/dataviews/pagination.js +75 -27
  21. package/build/components/dataviews/pagination.js.map +1 -1
  22. package/build/components/dataviews/text-filter.js +18 -12
  23. package/build/components/dataviews/text-filter.js.map +1 -1
  24. package/build/components/dataviews/view-actions.js +94 -56
  25. package/build/components/dataviews/view-actions.js.map +1 -1
  26. package/build/components/dataviews/view-grid.js +59 -0
  27. package/build/components/dataviews/view-grid.js.map +1 -0
  28. package/build/components/dataviews/view-list.js +283 -0
  29. package/build/components/dataviews/view-list.js.map +1 -0
  30. package/build/components/editor/index.js +2 -1
  31. package/build/components/editor/index.js.map +1 -1
  32. package/build/components/global-styles/font-library-modal/context.js +16 -10
  33. package/build/components/global-styles/font-library-modal/context.js.map +1 -1
  34. package/build/components/global-styles/font-library-modal/font-collection.js +20 -6
  35. package/build/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  36. package/build/components/global-styles/screen-block.js +1 -2
  37. package/build/components/global-styles/screen-block.js.map +1 -1
  38. package/build/components/global-styles/screen-root.js +1 -2
  39. package/build/components/global-styles/screen-root.js.map +1 -1
  40. package/build/components/global-styles/ui.js +3 -4
  41. package/build/components/global-styles/ui.js.map +1 -1
  42. package/build/components/layout/index.js +10 -2
  43. package/build/components/layout/index.js.map +1 -1
  44. package/build/components/media/index.js +34 -0
  45. package/build/components/media/index.js.map +1 -0
  46. package/build/components/page-actions/index.js +0 -2
  47. package/build/components/page-actions/index.js.map +1 -1
  48. package/build/components/page-pages/index.js +153 -107
  49. package/build/components/page-pages/index.js.map +1 -1
  50. package/build/components/page-patterns/delete-category-menu-item.js +89 -0
  51. package/build/components/page-patterns/delete-category-menu-item.js.map +1 -0
  52. package/build/components/page-patterns/duplicate-menu-item.js +52 -131
  53. package/build/components/page-patterns/duplicate-menu-item.js.map +1 -1
  54. package/build/components/page-patterns/grid-item.js +1 -0
  55. package/build/components/page-patterns/grid-item.js.map +1 -1
  56. package/build/components/page-patterns/header.js +25 -3
  57. package/build/components/page-patterns/header.js.map +1 -1
  58. package/build/components/page-patterns/rename-category-menu-item.js +49 -0
  59. package/build/components/page-patterns/rename-category-menu-item.js.map +1 -0
  60. package/build/components/page-patterns/rename-menu-item.js +1 -1
  61. package/build/components/page-patterns/rename-menu-item.js.map +1 -1
  62. package/build/components/page-patterns/use-patterns.js +1 -0
  63. package/build/components/page-patterns/use-patterns.js.map +1 -1
  64. package/build/components/pattern-modal/duplicate.js +65 -0
  65. package/build/components/pattern-modal/duplicate.js.map +1 -0
  66. package/build/components/pattern-modal/index.js +24 -0
  67. package/build/components/pattern-modal/index.js.map +1 -0
  68. package/build/components/pattern-modal/rename.js +42 -0
  69. package/build/components/pattern-modal/rename.js.map +1 -0
  70. package/build/components/sidebar-edit-mode/template-panel/last-revision.js +3 -0
  71. package/build/components/sidebar-edit-mode/template-panel/last-revision.js.map +1 -1
  72. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js +2 -2
  73. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js.map +1 -1
  74. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js +2 -3
  75. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js.map +1 -1
  76. package/build/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js +29 -0
  77. package/build/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js.map +1 -0
  78. package/build/components/sidebar-navigation-screen-template/home-template-details.js +12 -1
  79. package/build/components/sidebar-navigation-screen-template/home-template-details.js.map +1 -1
  80. package/build/hooks/commands/use-common-commands.js +1 -2
  81. package/build/hooks/commands/use-common-commands.js.map +1 -1
  82. package/build/hooks/commands/use-edit-mode-commands.js +49 -0
  83. package/build/hooks/commands/use-edit-mode-commands.js.map +1 -1
  84. package/build/lock-unlock.js +1 -1
  85. package/build/lock-unlock.js.map +1 -1
  86. package/build/store/selectors.js +4 -5
  87. package/build/store/selectors.js.map +1 -1
  88. package/build-module/components/actions/trash-post.js +41 -0
  89. package/build-module/components/actions/trash-post.js.map +1 -0
  90. package/build-module/components/add-new-template/add-custom-template-modal-content.js +16 -12
  91. package/build-module/components/add-new-template/add-custom-template-modal-content.js.map +1 -1
  92. package/build-module/components/block-editor/resize-handle.js +2 -1
  93. package/build-module/components/block-editor/resize-handle.js.map +1 -1
  94. package/build-module/components/create-template-part-modal/index.js +10 -6
  95. package/build-module/components/create-template-part-modal/index.js.map +1 -1
  96. package/build-module/components/dataviews/dataviews.js +40 -31
  97. package/build-module/components/dataviews/dataviews.js.map +1 -1
  98. package/build-module/components/dataviews/field-actions.js +22 -0
  99. package/build-module/components/dataviews/field-actions.js.map +1 -0
  100. package/build-module/components/dataviews/filters.js +53 -0
  101. package/build-module/components/dataviews/filters.js.map +1 -0
  102. package/build-module/components/dataviews/in-filter.js +43 -0
  103. package/build-module/components/dataviews/in-filter.js.map +1 -0
  104. package/build-module/components/dataviews/index.js +0 -1
  105. package/build-module/components/dataviews/index.js.map +1 -1
  106. package/build-module/components/dataviews/pagination.js +74 -28
  107. package/build-module/components/dataviews/pagination.js.map +1 -1
  108. package/build-module/components/dataviews/text-filter.js +19 -13
  109. package/build-module/components/dataviews/text-filter.js.map +1 -1
  110. package/build-module/components/dataviews/view-actions.js +95 -54
  111. package/build-module/components/dataviews/view-actions.js.map +1 -1
  112. package/build-module/components/dataviews/view-grid.js +51 -0
  113. package/build-module/components/dataviews/view-grid.js.map +1 -0
  114. package/build-module/components/dataviews/view-list.js +274 -0
  115. package/build-module/components/dataviews/view-list.js.map +1 -0
  116. package/build-module/components/editor/index.js +2 -1
  117. package/build-module/components/editor/index.js.map +1 -1
  118. package/build-module/components/global-styles/font-library-modal/context.js +16 -10
  119. package/build-module/components/global-styles/font-library-modal/context.js.map +1 -1
  120. package/build-module/components/global-styles/font-library-modal/font-collection.js +20 -6
  121. package/build-module/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  122. package/build-module/components/global-styles/screen-block.js +1 -2
  123. package/build-module/components/global-styles/screen-block.js.map +1 -1
  124. package/build-module/components/global-styles/screen-root.js +1 -2
  125. package/build-module/components/global-styles/screen-root.js.map +1 -1
  126. package/build-module/components/global-styles/ui.js +3 -4
  127. package/build-module/components/global-styles/ui.js.map +1 -1
  128. package/build-module/components/layout/index.js +11 -3
  129. package/build-module/components/layout/index.js.map +1 -1
  130. package/build-module/components/media/index.js +26 -0
  131. package/build-module/components/media/index.js.map +1 -0
  132. package/build-module/components/page-actions/index.js +0 -2
  133. package/build-module/components/page-actions/index.js.map +1 -1
  134. package/build-module/components/page-pages/index.js +156 -110
  135. package/build-module/components/page-pages/index.js.map +1 -1
  136. package/build-module/components/page-patterns/delete-category-menu-item.js +82 -0
  137. package/build-module/components/page-patterns/delete-category-menu-item.js.map +1 -0
  138. package/build-module/components/page-patterns/duplicate-menu-item.js +54 -133
  139. package/build-module/components/page-patterns/duplicate-menu-item.js.map +1 -1
  140. package/build-module/components/page-patterns/grid-item.js +1 -0
  141. package/build-module/components/page-patterns/grid-item.js.map +1 -1
  142. package/build-module/components/page-patterns/header.js +26 -4
  143. package/build-module/components/page-patterns/header.js.map +1 -1
  144. package/build-module/components/page-patterns/rename-category-menu-item.js +42 -0
  145. package/build-module/components/page-patterns/rename-category-menu-item.js.map +1 -0
  146. package/build-module/components/page-patterns/rename-menu-item.js +1 -1
  147. package/build-module/components/page-patterns/rename-menu-item.js.map +1 -1
  148. package/build-module/components/page-patterns/use-patterns.js +1 -0
  149. package/build-module/components/page-patterns/use-patterns.js.map +1 -1
  150. package/build-module/components/pattern-modal/duplicate.js +57 -0
  151. package/build-module/components/pattern-modal/duplicate.js.map +1 -0
  152. package/build-module/components/pattern-modal/index.js +14 -0
  153. package/build-module/components/pattern-modal/index.js.map +1 -0
  154. package/build-module/components/pattern-modal/rename.js +34 -0
  155. package/build-module/components/pattern-modal/rename.js.map +1 -0
  156. package/build-module/components/sidebar-edit-mode/template-panel/last-revision.js +3 -0
  157. package/build-module/components/sidebar-edit-mode/template-panel/last-revision.js.map +1 -1
  158. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js +2 -2
  159. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js.map +1 -1
  160. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js +2 -3
  161. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js.map +1 -1
  162. package/build-module/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js +22 -0
  163. package/build-module/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js.map +1 -0
  164. package/build-module/components/sidebar-navigation-screen-template/home-template-details.js +12 -1
  165. package/build-module/components/sidebar-navigation-screen-template/home-template-details.js.map +1 -1
  166. package/build-module/hooks/commands/use-common-commands.js +1 -2
  167. package/build-module/hooks/commands/use-common-commands.js.map +1 -1
  168. package/build-module/hooks/commands/use-edit-mode-commands.js +50 -1
  169. package/build-module/hooks/commands/use-edit-mode-commands.js.map +1 -1
  170. package/build-module/lock-unlock.js +1 -1
  171. package/build-module/lock-unlock.js.map +1 -1
  172. package/build-module/store/selectors.js +4 -5
  173. package/build-module/store/selectors.js.map +1 -1
  174. package/build-style/style-rtl.css +42 -9
  175. package/build-style/style.css +42 -9
  176. package/package.json +40 -40
  177. package/src/components/actions/trash-post.js +55 -0
  178. package/src/components/add-new-template/add-custom-template-modal-content.js +22 -17
  179. package/src/components/block-editor/resize-handle.js +1 -0
  180. package/src/components/create-template-part-modal/index.js +9 -5
  181. package/src/components/dataviews/README.md +107 -0
  182. package/src/components/dataviews/dataviews.js +44 -33
  183. package/src/components/dataviews/field-actions.js +28 -0
  184. package/src/components/dataviews/filters.js +57 -0
  185. package/src/components/dataviews/in-filter.js +47 -0
  186. package/src/components/dataviews/index.js +0 -1
  187. package/src/components/dataviews/pagination.js +71 -29
  188. package/src/components/dataviews/style.scss +11 -1
  189. package/src/components/dataviews/text-filter.js +19 -15
  190. package/src/components/dataviews/view-actions.js +108 -63
  191. package/src/components/dataviews/view-grid.js +60 -0
  192. package/src/components/dataviews/view-list.js +348 -0
  193. package/src/components/editor/index.js +2 -0
  194. package/src/components/global-styles/font-library-modal/context.js +17 -11
  195. package/src/components/global-styles/font-library-modal/font-collection.js +18 -10
  196. package/src/components/global-styles/screen-block.js +1 -2
  197. package/src/components/global-styles/screen-root.js +1 -2
  198. package/src/components/global-styles/style.scss +16 -4
  199. package/src/components/global-styles/ui.js +1 -2
  200. package/src/components/layout/index.js +12 -4
  201. package/src/components/media/index.js +25 -0
  202. package/src/components/page-actions/index.js +1 -7
  203. package/src/components/page-pages/index.js +156 -108
  204. package/src/components/page-pages/style.scss +3 -0
  205. package/src/components/page-patterns/delete-category-menu-item.js +104 -0
  206. package/src/components/page-patterns/duplicate-menu-item.js +68 -181
  207. package/src/components/page-patterns/grid-item.js +1 -0
  208. package/src/components/page-patterns/header.js +42 -6
  209. package/src/components/page-patterns/rename-category-menu-item.js +45 -0
  210. package/src/components/page-patterns/rename-menu-item.js +2 -2
  211. package/src/components/page-patterns/style.scss +8 -0
  212. package/src/components/page-patterns/use-patterns.js +5 -0
  213. package/src/components/pattern-modal/duplicate.js +53 -0
  214. package/src/components/pattern-modal/index.js +19 -0
  215. package/src/components/pattern-modal/rename.js +29 -0
  216. package/src/components/sidebar-edit-mode/template-panel/last-revision.js +4 -0
  217. package/src/components/sidebar-navigation-screen/style.scss +17 -5
  218. package/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js +2 -7
  219. package/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js +2 -8
  220. package/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js +32 -0
  221. package/src/components/sidebar-navigation-screen-template/home-template-details.js +21 -7
  222. package/src/hooks/commands/use-common-commands.js +1 -2
  223. package/src/hooks/commands/use-edit-mode-commands.js +41 -0
  224. package/src/lock-unlock.js +1 -1
  225. package/src/store/selectors.js +9 -10
  226. package/src/style.scss +1 -0
  227. package/build/components/dataviews/list-view.js +0 -89
  228. package/build/components/dataviews/list-view.js.map +0 -1
  229. package/build-module/components/dataviews/list-view.js +0 -80
  230. package/build-module/components/dataviews/list-view.js.map +0 -1
  231. package/src/components/dataviews/list-view.js +0 -106
@@ -6,26 +6,53 @@ import {
6
6
  __experimentalHStack as HStack,
7
7
  __experimentalText as Text,
8
8
  __experimentalNumberControl as NumberControl,
9
+ __experimentalInputControlPrefixWrapper as InputControlPrefixWrapper,
10
+ SelectControl,
9
11
  } from '@wordpress/components';
10
12
  import { createInterpolateElement } from '@wordpress/element';
11
13
  import { sprintf, __, _x, _n } from '@wordpress/i18n';
12
14
 
13
- /**
14
- * Internal dependencies
15
- */
16
- import { PageSizeControl } from './view-actions';
15
+ const PAGE_SIZE_VALUES = [ 5, 20, 50 ];
16
+ function PageSizeControl( { view, onChangeView } ) {
17
+ const label = __( 'Rows per page:' );
18
+ return (
19
+ <SelectControl
20
+ __nextHasNoMarginBottom
21
+ label={ label }
22
+ hideLabelFromVision
23
+ // TODO: This should probably use a label based on the wanted design
24
+ // and we could remove InputControlPrefixWrapper usage.
25
+ prefix={
26
+ <InputControlPrefixWrapper
27
+ as="span"
28
+ className="dataviews__select-control-prefix"
29
+ >
30
+ { label }
31
+ </InputControlPrefixWrapper>
32
+ }
33
+ value={ view.perPage }
34
+ options={ PAGE_SIZE_VALUES.map( ( pageSize ) => ( {
35
+ value: pageSize,
36
+ label: pageSize,
37
+ } ) ) }
38
+ onChange={ ( value ) =>
39
+ onChangeView( { ...view, perPage: value, page: 1 } )
40
+ }
41
+ />
42
+ );
43
+ }
17
44
 
18
45
  // For now this is copied from the patterns list Pagination component, because
19
46
  // the datatable pagination starts from index zero(`0`). Eventually all lists will be
20
47
  // using this one.
21
- export function Pagination( {
22
- dataView,
23
- // If passed, use it, as it's for controlled pagination.
24
- totalItems = 0,
48
+ function Pagination( {
49
+ view,
50
+ onChangeView,
51
+ paginationInfo: { totalItems = 0, totalPages },
25
52
  } ) {
26
- const currentPage = dataView.getState().pagination.pageIndex + 1;
27
- const numPages = dataView.getPageCount();
28
- const _totalItems = totalItems || dataView.getCoreRowModel().rows.length;
53
+ if ( ! totalItems || ! totalPages ) {
54
+ return null;
55
+ }
29
56
  return (
30
57
  <HStack
31
58
  expanded={ false }
@@ -38,25 +65,27 @@ export function Pagination( {
38
65
  // translators: %s: Total number of entries.
39
66
  sprintf(
40
67
  // translators: %s: Total number of entries.
41
- _n( '%s item', '%s items', _totalItems ),
42
- _totalItems
68
+ _n( '%s item', '%s items', totalItems ),
69
+ totalItems
43
70
  )
44
71
  }
45
72
  </Text>
46
- { !! _totalItems && (
73
+ { !! totalItems && (
47
74
  <HStack expanded={ false } spacing={ 1 }>
48
75
  <Button
49
76
  variant="tertiary"
50
- onClick={ () => dataView.setPageIndex( 0 ) }
51
- disabled={ ! dataView.getCanPreviousPage() }
77
+ onClick={ () => onChangeView( { ...view, page: 1 } ) }
78
+ disabled={ view.page === 1 }
52
79
  aria-label={ __( 'First page' ) }
53
80
  >
54
81
  «
55
82
  </Button>
56
83
  <Button
57
84
  variant="tertiary"
58
- onClick={ () => dataView.previousPage() }
59
- disabled={ ! dataView.getCanPreviousPage() }
85
+ onClick={ () =>
86
+ onChangeView( { ...view, page: view.page - 1 } )
87
+ }
88
+ disabled={ view.page === 1 }
60
89
  aria-label={ __( 'Previous page' ) }
61
90
  >
62
91
 
@@ -70,21 +99,30 @@ export function Pagination( {
70
99
  sprintf(
71
100
  // translators: %1$s: Current page number, %2$s: Total number of pages.
72
101
  _x( '<CurrenPageControl /> of %2$s', 'paging' ),
73
- currentPage,
74
- numPages
102
+ view.page,
103
+ totalPages
75
104
  ),
76
105
  {
77
106
  CurrenPageControl: (
78
107
  <NumberControl
79
108
  aria-label={ __( 'Current page' ) }
80
109
  min={ 1 }
81
- max={ numPages }
110
+ max={ totalPages }
82
111
  onChange={ ( value ) => {
83
- if ( value > numPages ) return;
84
- dataView.setPageIndex( value - 1 );
112
+ if (
113
+ ! value ||
114
+ value < 1 ||
115
+ value > totalPages
116
+ ) {
117
+ return;
118
+ }
119
+ onChangeView( {
120
+ ...view,
121
+ page: value,
122
+ } );
85
123
  } }
86
124
  step="1"
87
- value={ currentPage }
125
+ value={ view.page }
88
126
  isDragEnabled={ false }
89
127
  spinControls="none"
90
128
  />
@@ -94,8 +132,10 @@ export function Pagination( {
94
132
  </HStack>
95
133
  <Button
96
134
  variant="tertiary"
97
- onClick={ () => dataView.nextPage() }
98
- disabled={ ! dataView.getCanNextPage() }
135
+ onClick={ () =>
136
+ onChangeView( { ...view, page: view.page + 1 } )
137
+ }
138
+ disabled={ view.page >= totalPages }
99
139
  aria-label={ __( 'Next page' ) }
100
140
  >
101
141
 
@@ -103,16 +143,18 @@ export function Pagination( {
103
143
  <Button
104
144
  variant="tertiary"
105
145
  onClick={ () =>
106
- dataView.setPageIndex( dataView.getPageCount() - 1 )
146
+ onChangeView( { ...view, page: totalPages } )
107
147
  }
108
- disabled={ ! dataView.getCanNextPage() }
148
+ disabled={ view.page >= totalPages }
109
149
  aria-label={ __( 'Last page' ) }
110
150
  >
111
151
  »
112
152
  </Button>
113
153
  </HStack>
114
154
  ) }
115
- <PageSizeControl dataView={ dataView } />
155
+ <PageSizeControl view={ view } onChangeView={ onChangeView } />
116
156
  </HStack>
117
157
  );
118
158
  }
159
+
160
+ export default Pagination;
@@ -30,7 +30,17 @@
30
30
  }
31
31
  }
32
32
 
33
- .dataviews__per-page-control-prefix {
33
+ .dataviews__select-control-prefix {
34
34
  color: $gray-700;
35
35
  text-wrap: nowrap;
36
36
  }
37
+
38
+ .dataviews-view-grid__media {
39
+ width: 100%;
40
+ min-height: 200px;
41
+
42
+ > * {
43
+ max-width: 100%;
44
+ object-fit: cover;
45
+ }
46
+ }
@@ -1,13 +1,8 @@
1
- /**
2
- * External dependencies
3
- */
4
- import classnames from 'classnames';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
4
  import { __ } from '@wordpress/i18n';
10
- import { useEffect } from '@wordpress/element';
5
+ import { useEffect, useRef } from '@wordpress/element';
11
6
  import { SearchControl } from '@wordpress/components';
12
7
 
13
8
  /**
@@ -15,18 +10,27 @@ import { SearchControl } from '@wordpress/components';
15
10
  */
16
11
  import useDebouncedInput from '../../utils/use-debounced-input';
17
12
 
18
- export default function TextFilter( {
19
- className,
20
- searchLabel = __( 'Filter list' ),
21
- onChange,
22
- } ) {
23
- const [ search, setSearch, debouncedSearch ] = useDebouncedInput();
13
+ export default function TextFilter( { id, view, onChangeView } ) {
14
+ const [ search, setSearch, debouncedSearch ] = useDebouncedInput(
15
+ view.filters[ id ]
16
+ );
17
+ const onChangeViewRef = useRef( onChangeView );
18
+ useEffect( () => {
19
+ onChangeViewRef.current = onChangeView;
20
+ }, [ onChangeView ] );
24
21
  useEffect( () => {
25
- onChange( debouncedSearch );
26
- }, [ debouncedSearch, onChange ] );
22
+ onChangeViewRef.current( ( currentView ) => ( {
23
+ ...currentView,
24
+ page: 1,
25
+ filters: {
26
+ ...currentView.filters,
27
+ [ id ]: debouncedSearch,
28
+ },
29
+ } ) );
30
+ }, [ debouncedSearch ] );
31
+ const searchLabel = __( 'Filter list' );
27
32
  return (
28
33
  <SearchControl
29
- className={ classnames( 'dataviews__text-filter', className ) }
30
34
  onChange={ setSearch }
31
35
  value={ search }
32
36
  label={ searchLabel }
@@ -4,9 +4,7 @@
4
4
  import {
5
5
  Button,
6
6
  Icon,
7
- SelectControl,
8
7
  privateApis as componentsPrivateApis,
9
- __experimentalInputControlPrefixWrapper as InputControlPrefixWrapper,
10
8
  } from '@wordpress/components';
11
9
  import {
12
10
  chevronRightSmall,
@@ -31,44 +29,68 @@ const {
31
29
  DropdownSubMenuTriggerV2,
32
30
  } = unlock( componentsPrivateApis );
33
31
 
34
- export const PAGE_SIZE_VALUES = [ 5, 20, 50 ];
32
+ const availableViews = [
33
+ {
34
+ id: 'list',
35
+ label: __( 'List' ),
36
+ },
37
+ {
38
+ id: 'grid',
39
+ label: __( 'Grid' ),
40
+ },
41
+ ];
35
42
 
36
- export function PageSizeControl( { dataView } ) {
37
- const label = __( 'Rows per page:' );
43
+ function ViewTypeMenu( { view, onChangeView } ) {
44
+ const activeView = availableViews.find( ( v ) => view.type === v.id );
38
45
  return (
39
- <SelectControl
40
- __nextHasNoMarginBottom
41
- label={ label }
42
- hideLabelFromVision
43
- // TODO: This should probably use a label based on the wanted design
44
- // and we could remove InputControlPrefixWrapper usage.
45
- prefix={
46
- <InputControlPrefixWrapper
47
- as="span"
48
- className="dataviews__per-page-control-prefix"
46
+ <DropdownSubMenuV2
47
+ trigger={
48
+ <DropdownSubMenuTriggerV2
49
+ suffix={
50
+ <>
51
+ { activeView.label }
52
+ <Icon icon={ chevronRightSmall } />
53
+ </>
54
+ }
49
55
  >
50
- { label }
51
- </InputControlPrefixWrapper>
56
+ { __( 'Layout' ) }
57
+ </DropdownSubMenuTriggerV2>
52
58
  }
53
- value={ dataView.getState().pagination.pageSize }
54
- options={ PAGE_SIZE_VALUES.map( ( pageSize ) => ( {
55
- value: pageSize,
56
- label: pageSize,
57
- } ) ) }
58
- onChange={ ( value ) => dataView.setPageSize( +value ) }
59
- />
59
+ >
60
+ { availableViews.map( ( availableView ) => {
61
+ return (
62
+ <DropdownMenuItemV2
63
+ key={ availableView.id }
64
+ prefix={
65
+ availableView.id === view.type && (
66
+ <Icon icon={ check } />
67
+ )
68
+ }
69
+ onSelect={ ( event ) => {
70
+ // We need to handle this on DropDown component probably..
71
+ event.preventDefault();
72
+ onChangeView( { ...view, type: availableView.id } );
73
+ } }
74
+ // TODO: check about role and a11y.
75
+ role="menuitemcheckbox"
76
+ >
77
+ { availableView.label }
78
+ </DropdownMenuItemV2>
79
+ );
80
+ } ) }
81
+ </DropdownSubMenuV2>
60
82
  );
61
83
  }
62
84
 
63
- function PageSizeMenu( { dataView } ) {
64
- const currenPageSize = dataView.getState().pagination.pageSize;
85
+ const PAGE_SIZE_VALUES = [ 5, 20, 50 ];
86
+ function PageSizeMenu( { view, onChangeView } ) {
65
87
  return (
66
88
  <DropdownSubMenuV2
67
89
  trigger={
68
90
  <DropdownSubMenuTriggerV2
69
91
  suffix={
70
92
  <>
71
- { currenPageSize }
93
+ { view.perPage }
72
94
  <Icon icon={ chevronRightSmall } />
73
95
  </>
74
96
  }
@@ -83,12 +105,12 @@ function PageSizeMenu( { dataView } ) {
83
105
  <DropdownMenuItemV2
84
106
  key={ size }
85
107
  prefix={
86
- currenPageSize === size && <Icon icon={ check } />
108
+ view.perPage === size && <Icon icon={ check } />
87
109
  }
88
110
  onSelect={ ( event ) => {
89
111
  // We need to handle this on DropDown component probably..
90
112
  event.preventDefault();
91
- dataView.setPageSize( size );
113
+ onChangeView( { ...view, perPage: size, page: 1 } );
92
114
  } }
93
115
  // TODO: check about role and a11y.
94
116
  role="menuitemcheckbox"
@@ -101,11 +123,11 @@ function PageSizeMenu( { dataView } ) {
101
123
  );
102
124
  }
103
125
 
104
- function FieldsVisibilityMenu( { dataView } ) {
105
- const hideableFields = dataView
106
- .getAllColumns()
107
- .filter( ( columnn ) => columnn.getCanHide() );
108
- if ( ! hideableFields?.length ) {
126
+ function FieldsVisibilityMenu( { view, onChangeView, fields } ) {
127
+ const hidableFields = fields.filter(
128
+ ( field ) => field.enableHiding !== false
129
+ );
130
+ if ( ! hidableFields?.length ) {
109
131
  return null;
110
132
  }
111
133
  return (
@@ -118,20 +140,31 @@ function FieldsVisibilityMenu( { dataView } ) {
118
140
  </DropdownSubMenuTriggerV2>
119
141
  }
120
142
  >
121
- { hideableFields?.map( ( field ) => {
143
+ { hidableFields?.map( ( field ) => {
122
144
  return (
123
145
  <DropdownMenuItemV2
124
146
  key={ field.id }
125
147
  prefix={
126
- field.getIsVisible() && <Icon icon={ check } />
148
+ ! view.hiddenFields?.includes( field.id ) && (
149
+ <Icon icon={ check } />
150
+ )
127
151
  }
128
152
  onSelect={ ( event ) => {
129
153
  event.preventDefault();
130
- field.getToggleVisibilityHandler()( event );
154
+ onChangeView( {
155
+ ...view,
156
+ hiddenFields: view.hiddenFields?.includes(
157
+ field.id
158
+ )
159
+ ? view.hiddenFields.filter(
160
+ ( id ) => id !== field.id
161
+ )
162
+ : [ ...view.hiddenFields, field.id ],
163
+ } );
131
164
  } }
132
165
  role="menuitemcheckbox"
133
166
  >
134
- { field.columnDef.header }
167
+ { field.header }
135
168
  </DropdownMenuItemV2>
136
169
  );
137
170
  } ) }
@@ -144,15 +177,15 @@ const sortingItemsInfo = {
144
177
  asc: { icon: arrowUp, label: __( 'Sort ascending' ) },
145
178
  desc: { icon: arrowDown, label: __( 'Sort descending' ) },
146
179
  };
147
- function SortMenu( { dataView } ) {
148
- const sortableFields = dataView
149
- .getAllColumns()
150
- .filter( ( columnn ) => columnn.getCanSort() );
180
+ function SortMenu( { fields, view, onChangeView } ) {
181
+ const sortableFields = fields.filter(
182
+ ( field ) => field.enableSorting !== false
183
+ );
151
184
  if ( ! sortableFields?.length ) {
152
185
  return null;
153
186
  }
154
- const currentSortedField = sortableFields.find( ( field ) =>
155
- field.getIsSorted()
187
+ const currentSortedField = fields.find(
188
+ ( field ) => field.id === view.sort?.field
156
189
  );
157
190
  return (
158
191
  <DropdownSubMenuV2
@@ -160,7 +193,7 @@ function SortMenu( { dataView } ) {
160
193
  <DropdownSubMenuTriggerV2
161
194
  suffix={
162
195
  <>
163
- { currentSortedField?.columnDef.header }
196
+ { currentSortedField?.header }
164
197
  <Icon icon={ chevronRightSmall } />
165
198
  </>
166
199
  }
@@ -170,7 +203,7 @@ function SortMenu( { dataView } ) {
170
203
  }
171
204
  >
172
205
  { sortableFields?.map( ( field ) => {
173
- const sortedDirection = field.getIsSorted();
206
+ const sortedDirection = view.sort?.direction;
174
207
  return (
175
208
  <DropdownSubMenuV2
176
209
  key={ field.id }
@@ -178,37 +211,41 @@ function SortMenu( { dataView } ) {
178
211
  <DropdownSubMenuTriggerV2
179
212
  suffix={ <Icon icon={ chevronRightSmall } /> }
180
213
  >
181
- { field.columnDef.header }
214
+ { field.header }
182
215
  </DropdownSubMenuTriggerV2>
183
216
  }
184
217
  side="left"
185
218
  >
186
219
  { Object.entries( sortingItemsInfo ).map(
187
220
  ( [ direction, info ] ) => {
221
+ const isActive =
222
+ currentSortedField &&
223
+ sortedDirection === direction &&
224
+ field.id === currentSortedField.id;
188
225
  return (
189
226
  <DropdownMenuItemV2
190
227
  key={ direction }
191
228
  prefix={ <Icon icon={ info.icon } /> }
192
229
  suffix={
193
- sortedDirection === direction && (
194
- <Icon icon={ check } />
195
- )
230
+ isActive && <Icon icon={ check } />
196
231
  }
197
232
  onSelect={ ( event ) => {
198
233
  event.preventDefault();
199
234
  if (
200
235
  sortedDirection === direction
201
236
  ) {
202
- dataView.resetSorting();
237
+ onChangeView( {
238
+ ...view,
239
+ sort: undefined,
240
+ } );
203
241
  } else {
204
- dataView.setSorting( [
205
- {
206
- id: field.id,
207
- desc:
208
- direction ===
209
- 'desc',
242
+ onChangeView( {
243
+ ...view,
244
+ sort: {
245
+ field: field.id,
246
+ direction,
210
247
  },
211
- ] );
248
+ } );
212
249
  }
213
250
  } }
214
251
  >
@@ -224,11 +261,10 @@ function SortMenu( { dataView } ) {
224
261
  );
225
262
  }
226
263
 
227
- export default function ViewActions( { dataView, className } ) {
264
+ export default function ViewActions( { fields, view, onChangeView } ) {
228
265
  return (
229
266
  <DropdownMenuV2
230
267
  label={ __( 'Actions' ) }
231
- className={ className }
232
268
  trigger={
233
269
  <Button variant="tertiary" icon={ blockTable }>
234
270
  { __( 'View' ) }
@@ -237,9 +273,18 @@ export default function ViewActions( { dataView, className } ) {
237
273
  }
238
274
  >
239
275
  <DropdownMenuGroupV2>
240
- <SortMenu dataView={ dataView } />
241
- <FieldsVisibilityMenu dataView={ dataView } />
242
- <PageSizeMenu dataView={ dataView } />
276
+ <ViewTypeMenu view={ view } onChangeView={ onChangeView } />
277
+ <SortMenu
278
+ fields={ fields }
279
+ view={ view }
280
+ onChangeView={ onChangeView }
281
+ />
282
+ <FieldsVisibilityMenu
283
+ fields={ fields }
284
+ view={ view }
285
+ onChangeView={ onChangeView }
286
+ />
287
+ <PageSizeMenu view={ view } onChangeView={ onChangeView } />
243
288
  </DropdownMenuGroupV2>
244
289
  </DropdownMenuV2>
245
290
  );
@@ -0,0 +1,60 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ __experimentalGrid as Grid,
6
+ __experimentalHStack as HStack,
7
+ __experimentalVStack as VStack,
8
+ FlexBlock,
9
+ Placeholder,
10
+ } from '@wordpress/components';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import FieldActions from './field-actions';
16
+
17
+ export function ViewGrid( { data, fields, view, actions } ) {
18
+ const mediaField = fields.find(
19
+ ( field ) => field.id === view.layout.mediaField
20
+ );
21
+ const visibleFields = fields.filter(
22
+ ( field ) =>
23
+ ! view.hiddenFields.includes( field.id ) &&
24
+ field.id !== view.layout.mediaField
25
+ );
26
+ return (
27
+ <Grid gap={ 8 } columns={ 2 } alignment="top">
28
+ { data.map( ( item, index ) => {
29
+ return (
30
+ <VStack key={ index }>
31
+ <div className="dataviews-view-grid__media">
32
+ { mediaField?.render( { item, view } ) || (
33
+ <Placeholder
34
+ withIllustration
35
+ style={ {
36
+ width: '100%',
37
+ minHeight: '200px',
38
+ } }
39
+ />
40
+ ) }
41
+ </div>
42
+
43
+ <HStack justify="space-between" alignment="top">
44
+ <FlexBlock>
45
+ <VStack>
46
+ { visibleFields.map( ( field ) => (
47
+ <div key={ field.id }>
48
+ { field.render( { item, view } ) }
49
+ </div>
50
+ ) ) }
51
+ </VStack>
52
+ </FlexBlock>
53
+ <FieldActions item={ item } actions={ actions } />
54
+ </HStack>
55
+ </VStack>
56
+ );
57
+ } ) }
58
+ </Grid>
59
+ );
60
+ }