@wordpress/dataviews 0.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 (84) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE.md +788 -0
  3. package/README.md +224 -0
  4. package/build/add-filter.js +90 -0
  5. package/build/add-filter.js.map +1 -0
  6. package/build/constants.js +55 -0
  7. package/build/constants.js.map +1 -0
  8. package/build/dataviews.js +93 -0
  9. package/build/dataviews.js.map +1 -0
  10. package/build/filter-summary.js +137 -0
  11. package/build/filter-summary.js.map +1 -0
  12. package/build/filters.js +75 -0
  13. package/build/filters.js.map +1 -0
  14. package/build/index.js +21 -0
  15. package/build/index.js.map +1 -0
  16. package/build/item-actions.js +185 -0
  17. package/build/item-actions.js.map +1 -0
  18. package/build/lock-unlock.js +18 -0
  19. package/build/lock-unlock.js.map +1 -0
  20. package/build/pagination.js +123 -0
  21. package/build/pagination.js.map +1 -0
  22. package/build/reset-filters.js +33 -0
  23. package/build/reset-filters.js.map +1 -0
  24. package/build/search.js +46 -0
  25. package/build/search.js.map +1 -0
  26. package/build/view-actions.js +223 -0
  27. package/build/view-actions.js.map +1 -0
  28. package/build/view-grid.js +80 -0
  29. package/build/view-grid.js.map +1 -0
  30. package/build/view-list.js +83 -0
  31. package/build/view-list.js.map +1 -0
  32. package/build/view-table.js +286 -0
  33. package/build/view-table.js.map +1 -0
  34. package/build-module/add-filter.js +83 -0
  35. package/build-module/add-filter.js.map +1 -0
  36. package/build-module/constants.js +41 -0
  37. package/build-module/constants.js.map +1 -0
  38. package/build-module/dataviews.js +85 -0
  39. package/build-module/dataviews.js.map +1 -0
  40. package/build-module/filter-summary.js +130 -0
  41. package/build-module/filter-summary.js.map +1 -0
  42. package/build-module/filters.js +67 -0
  43. package/build-module/filters.js.map +1 -0
  44. package/build-module/index.js +3 -0
  45. package/build-module/index.js.map +1 -0
  46. package/build-module/item-actions.js +178 -0
  47. package/build-module/item-actions.js.map +1 -0
  48. package/build-module/lock-unlock.js +9 -0
  49. package/build-module/lock-unlock.js.map +1 -0
  50. package/build-module/pagination.js +115 -0
  51. package/build-module/pagination.js.map +1 -0
  52. package/build-module/reset-filters.js +26 -0
  53. package/build-module/reset-filters.js.map +1 -0
  54. package/build-module/search.js +39 -0
  55. package/build-module/search.js.map +1 -0
  56. package/build-module/view-actions.js +216 -0
  57. package/build-module/view-actions.js.map +1 -0
  58. package/build-module/view-grid.js +72 -0
  59. package/build-module/view-grid.js.map +1 -0
  60. package/build-module/view-list.js +75 -0
  61. package/build-module/view-list.js.map +1 -0
  62. package/build-module/view-table.js +277 -0
  63. package/build-module/view-table.js.map +1 -0
  64. package/build-style/style-rtl.css +325 -0
  65. package/build-style/style.css +325 -0
  66. package/package.json +49 -0
  67. package/src/add-filter.js +106 -0
  68. package/src/constants.js +50 -0
  69. package/src/dataviews.js +99 -0
  70. package/src/filter-summary.js +221 -0
  71. package/src/filters.js +84 -0
  72. package/src/index.js +2 -0
  73. package/src/item-actions.js +211 -0
  74. package/src/lock-unlock.js +10 -0
  75. package/src/pagination.js +144 -0
  76. package/src/reset-filters.js +26 -0
  77. package/src/search.js +38 -0
  78. package/src/stories/fixtures.js +126 -0
  79. package/src/stories/index.story.js +137 -0
  80. package/src/style.scss +245 -0
  81. package/src/view-actions.js +298 -0
  82. package/src/view-grid.js +100 -0
  83. package/src/view-list.js +99 -0
  84. package/src/view-table.js +425 -0
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Converts a hex value into the rgb equivalent.
3
+ *
4
+ * @param {string} hex - the hexadecimal value to convert
5
+ * @return {string} comma separated rgb values
6
+ */
7
+ /**
8
+ * Colors
9
+ */
10
+ /**
11
+ * Breakpoints & Media Queries
12
+ */
13
+ /**
14
+ * SCSS Variables.
15
+ *
16
+ * Please use variables from this sheet to ensure consistency across the UI.
17
+ * Don't add to this sheet unless you're pretty sure the value will be reused in many places.
18
+ * For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
19
+ */
20
+ /**
21
+ * Converts a hex value into the rgb equivalent.
22
+ *
23
+ * @param {string} hex - the hexadecimal value to convert
24
+ * @return {string} comma separated rgb values
25
+ */
26
+ /**
27
+ * Colors
28
+ */
29
+ /**
30
+ * Fonts & basic variables.
31
+ */
32
+ /**
33
+ * Grid System.
34
+ * https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
35
+ */
36
+ /**
37
+ * Dimensions.
38
+ */
39
+ /**
40
+ * Shadows.
41
+ */
42
+ /**
43
+ * Editor widths.
44
+ */
45
+ /**
46
+ * Block & Editor UI.
47
+ */
48
+ /**
49
+ * Block paddings.
50
+ */
51
+ /**
52
+ * React Native specific.
53
+ * These variables do not appear to be used anywhere else.
54
+ */
55
+ /**
56
+ * Converts a hex value into the rgb equivalent.
57
+ *
58
+ * @param {string} hex - the hexadecimal value to convert
59
+ * @return {string} comma separated rgb values
60
+ */
61
+ /**
62
+ * Long content fade mixin
63
+ *
64
+ * Creates a fading overlay to signify that the content is longer
65
+ * than the space allows.
66
+ */
67
+ /**
68
+ * Breakpoint mixins
69
+ */
70
+ /**
71
+ * Focus styles.
72
+ */
73
+ /**
74
+ * Applies editor left position to the selector passed as argument
75
+ */
76
+ /**
77
+ * Styles that are reused verbatim in a few places
78
+ */
79
+ /**
80
+ * Allows users to opt-out of animations via OS-level preferences.
81
+ */
82
+ /**
83
+ * Reset default styles for JavaScript UI based pages.
84
+ * This is a WP-admin agnostic reset
85
+ */
86
+ /**
87
+ * Reset the WP Admin page styles for Gutenberg-like pages.
88
+ */
89
+ :root {
90
+ --wp-admin-theme-color: #007cba;
91
+ --wp-admin-theme-color--rgb: 0, 124, 186;
92
+ --wp-admin-theme-color-darker-10: #006ba1;
93
+ --wp-admin-theme-color-darker-10--rgb: 0, 107, 161;
94
+ --wp-admin-theme-color-darker-20: #005a87;
95
+ --wp-admin-theme-color-darker-20--rgb: 0, 90, 135;
96
+ --wp-admin-border-width-focus: 2px;
97
+ --wp-block-synced-color: #7a00df;
98
+ --wp-block-synced-color--rgb: 122, 0, 223;
99
+ }
100
+ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
101
+ :root {
102
+ --wp-admin-border-width-focus: 1.5px;
103
+ }
104
+ }
105
+
106
+ .dataviews-wrapper {
107
+ width: 100%;
108
+ height: 100%;
109
+ overflow: auto;
110
+ box-sizing: border-box;
111
+ scroll-padding-bottom: 64px;
112
+ }
113
+ .dataviews-wrapper > div {
114
+ min-height: 100%;
115
+ }
116
+
117
+ .dataviews__filters-view-actions {
118
+ padding: 12px 32px;
119
+ }
120
+
121
+ .dataviews-pagination {
122
+ margin-top: auto;
123
+ position: sticky;
124
+ bottom: 0;
125
+ background-color: #fff;
126
+ padding: 12px 32px;
127
+ border-top: 1px solid #f0f0f0;
128
+ color: #757575;
129
+ }
130
+
131
+ .dataviews-filters-options {
132
+ margin: 32px 0 16px;
133
+ }
134
+
135
+ .dataviews-table-view {
136
+ width: 100%;
137
+ text-indent: 0;
138
+ border-color: inherit;
139
+ border-collapse: collapse;
140
+ position: relative;
141
+ color: #757575;
142
+ }
143
+ .dataviews-table-view a {
144
+ text-decoration: none;
145
+ color: #1e1e1e;
146
+ font-weight: 500;
147
+ }
148
+ .dataviews-table-view th {
149
+ text-align: left;
150
+ color: var(--wp-components-color-foreground, #1e1e1e);
151
+ font-weight: normal;
152
+ font-size: 13px;
153
+ }
154
+ .dataviews-table-view td,
155
+ .dataviews-table-view th {
156
+ padding: 12px;
157
+ min-width: 160px;
158
+ }
159
+ .dataviews-table-view td[data-field-id=actions],
160
+ .dataviews-table-view th[data-field-id=actions] {
161
+ text-align: right;
162
+ }
163
+ .dataviews-table-view tr {
164
+ border-bottom: 1px solid #f0f0f0;
165
+ }
166
+ .dataviews-table-view tr td:first-child,
167
+ .dataviews-table-view tr th:first-child {
168
+ padding-left: 32px;
169
+ }
170
+ .dataviews-table-view tr td:last-child,
171
+ .dataviews-table-view tr th:last-child {
172
+ padding-right: 32px;
173
+ }
174
+ .dataviews-table-view tr:last-child {
175
+ border-bottom: 0;
176
+ }
177
+ .dataviews-table-view thead tr {
178
+ border: 0;
179
+ }
180
+ .dataviews-table-view thead th {
181
+ position: sticky;
182
+ top: -1px;
183
+ background-color: #fafafa;
184
+ box-shadow: inset 0 -1px 0 #f0f0f0;
185
+ border-top: 1px solid #f0f0f0;
186
+ padding-top: 4px;
187
+ padding-bottom: 4px;
188
+ }
189
+
190
+ .dataviews-grid-view {
191
+ margin-bottom: 24px;
192
+ grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
193
+ padding: 0 32px;
194
+ }
195
+ @media (min-width: 1080px) {
196
+ .dataviews-grid-view {
197
+ grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
198
+ }
199
+ }
200
+ @media (min-width: 1440px) {
201
+ .dataviews-grid-view {
202
+ grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
203
+ }
204
+ }
205
+ .dataviews-grid-view .dataviews-view-grid__card h3 {
206
+ white-space: nowrap;
207
+ overflow: hidden;
208
+ text-overflow: ellipsis;
209
+ }
210
+ .dataviews-grid-view .dataviews-view-grid__media {
211
+ width: 100%;
212
+ min-height: 200px;
213
+ aspect-ratio: 1/1;
214
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
215
+ border-radius: 4px;
216
+ overflow: hidden;
217
+ }
218
+ .dataviews-grid-view .dataviews-view-grid__media > * {
219
+ -o-object-fit: cover;
220
+ object-fit: cover;
221
+ width: 100%;
222
+ height: 100%;
223
+ }
224
+ .dataviews-grid-view .dataviews-view-grid__primary-field {
225
+ min-height: 24px;
226
+ }
227
+ .dataviews-grid-view .dataviews-view-grid__primary-field a {
228
+ color: #1e1e1e;
229
+ text-decoration: none;
230
+ font-weight: 500;
231
+ }
232
+ .dataviews-grid-view .dataviews-view-grid__fields {
233
+ position: relative;
234
+ font-size: 12px;
235
+ line-height: 16px;
236
+ }
237
+ .dataviews-grid-view .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-header {
238
+ color: #757575;
239
+ }
240
+ .dataviews-grid-view .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
241
+ color: #1e1e1e;
242
+ }
243
+
244
+ .dataviews-list-view {
245
+ margin: 0;
246
+ }
247
+ .dataviews-list-view li {
248
+ border-bottom: 1px solid #f0f0f0;
249
+ margin: 0;
250
+ }
251
+ .dataviews-list-view li:first-child {
252
+ border-top: 1px solid #f0f0f0;
253
+ }
254
+ .dataviews-list-view li:last-child {
255
+ border-bottom: 0;
256
+ }
257
+ .dataviews-list-view .dataviews-list-view__item {
258
+ padding: 12px 32px;
259
+ cursor: default;
260
+ }
261
+ .dataviews-list-view .dataviews-list-view__item:focus, .dataviews-list-view .dataviews-list-view__item:hover {
262
+ background-color: #f8f8f8;
263
+ }
264
+ .dataviews-list-view .dataviews-list-view__item:focus {
265
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
266
+ }
267
+ .dataviews-list-view .dataviews-list-view__item h3 {
268
+ overflow: hidden;
269
+ text-overflow: ellipsis;
270
+ white-space: nowrap;
271
+ }
272
+ .dataviews-list-view .dataviews-list-view__item-selected,
273
+ .dataviews-list-view .dataviews-list-view__item-selected:hover {
274
+ background-color: #f0f0f0;
275
+ }
276
+ .dataviews-list-view .dataviews-list-view__item-selected:focus,
277
+ .dataviews-list-view .dataviews-list-view__item-selected:hover:focus {
278
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
279
+ }
280
+ .dataviews-list-view .dataviews-list-view__media-wrapper {
281
+ min-width: 32px;
282
+ height: 32px;
283
+ border-radius: 4px;
284
+ overflow: hidden;
285
+ position: relative;
286
+ }
287
+ .dataviews-list-view .dataviews-list-view__media-wrapper::after {
288
+ content: "";
289
+ position: absolute;
290
+ top: 0;
291
+ left: 0;
292
+ width: 100%;
293
+ height: 100%;
294
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
295
+ border-radius: 4px;
296
+ }
297
+ .dataviews-list-view .edit-site-page-pages__featured-image,
298
+ .dataviews-list-view .dataviews-list-view__media-placeholder {
299
+ min-width: 32px;
300
+ height: 32px;
301
+ }
302
+ .dataviews-list-view .dataviews-list-view__media-placeholder {
303
+ background-color: #e0e0e0;
304
+ }
305
+ .dataviews-list-view .dataviews-list-view__fields {
306
+ color: #757575;
307
+ overflow: hidden;
308
+ text-overflow: ellipsis;
309
+ white-space: nowrap;
310
+ }
311
+ .dataviews-list-view .dataviews-list-view__fields .dataviews-list-view__field {
312
+ margin-right: 12px;
313
+ }
314
+ .dataviews-list-view .dataviews-list-view__fields .dataviews-list-view__field:last-child {
315
+ margin-right: 0;
316
+ }
317
+
318
+ .dataviews-action-modal {
319
+ z-index: 1000001;
320
+ }
321
+
322
+ .dataviews-no-results,
323
+ .dataviews-loading {
324
+ padding: 0 32px;
325
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@wordpress/dataviews",
3
+ "version": "0.2.0",
4
+ "description": "DataViews is a component that provides an API to render datasets using different types of layouts (table, grid, list, etc.).",
5
+ "author": "The WordPress Contributors",
6
+ "license": "GPL-2.0-or-later",
7
+ "keywords": [
8
+ "wordpress",
9
+ "gutenberg",
10
+ "dataviews"
11
+ ],
12
+ "homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/dataviews/README.md",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/WordPress/gutenberg.git",
16
+ "directory": "packages/dataviews"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/WordPress/gutenberg/issues"
20
+ },
21
+ "engines": {
22
+ "node": ">=12"
23
+ },
24
+ "main": "build/index.js",
25
+ "module": "build-module/index.js",
26
+ "react-native": "src/index",
27
+ "types": "build-types",
28
+ "sideEffects": false,
29
+ "dependencies": {
30
+ "@babel/runtime": "^7.16.0",
31
+ "@wordpress/a11y": "^3.48.0",
32
+ "@wordpress/components": "^25.14.0",
33
+ "@wordpress/compose": "^6.25.0",
34
+ "@wordpress/element": "^5.25.0",
35
+ "@wordpress/i18n": "^4.48.0",
36
+ "@wordpress/icons": "^9.39.0",
37
+ "@wordpress/keycodes": "^3.48.0",
38
+ "@wordpress/private-apis": "^0.30.0",
39
+ "classnames": "^2.3.1",
40
+ "remove-accents": "^0.5.0"
41
+ },
42
+ "peerDependencies": {
43
+ "react": "^18.0.0"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "gitHead": "fcf61b4beff747222c2c81d09d757ca1a0abd925"
49
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ privateApis as componentsPrivateApis,
6
+ Button,
7
+ Icon,
8
+ } from '@wordpress/components';
9
+ import { chevronRightSmall, plus } from '@wordpress/icons';
10
+ import { __ } from '@wordpress/i18n';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import { unlock } from './lock-unlock';
16
+ import { ENUMERATION_TYPE, OPERATOR_IN } from './constants';
17
+
18
+ const {
19
+ DropdownMenuV2: DropdownMenu,
20
+ DropdownSubMenuV2: DropdownSubMenu,
21
+ DropdownSubMenuTriggerV2: DropdownSubMenuTrigger,
22
+ DropdownMenuItemV2: DropdownMenuItem,
23
+ } = unlock( componentsPrivateApis );
24
+
25
+ export default function AddFilter( { fields, view, onChangeView } ) {
26
+ const filters = [];
27
+ fields.forEach( ( field ) => {
28
+ if ( ! field.type ) {
29
+ return;
30
+ }
31
+
32
+ switch ( field.type ) {
33
+ case ENUMERATION_TYPE:
34
+ filters.push( {
35
+ field: field.id,
36
+ name: field.header,
37
+ elements: field.elements || [],
38
+ isVisible: view.filters.some(
39
+ ( f ) => f.field === field.id
40
+ ),
41
+ } );
42
+ }
43
+ } );
44
+
45
+ if ( filters.length === 0 ) {
46
+ return null;
47
+ }
48
+
49
+ return (
50
+ <DropdownMenu
51
+ label={ __( 'Add filter' ) }
52
+ trigger={
53
+ <Button
54
+ disabled={ filters.length === view.filters?.length }
55
+ __experimentalIsFocusable
56
+ variant="tertiary"
57
+ size="compact"
58
+ >
59
+ <Icon icon={ plus } style={ { flexShrink: 0 } } />
60
+ { __( 'Add filter' ) }
61
+ </Button>
62
+ }
63
+ >
64
+ { filters.map( ( filter ) => {
65
+ if ( filter.isVisible ) {
66
+ return null;
67
+ }
68
+
69
+ return (
70
+ <DropdownSubMenu
71
+ key={ filter.field }
72
+ trigger={
73
+ <DropdownSubMenuTrigger
74
+ suffix={ <Icon icon={ chevronRightSmall } /> }
75
+ >
76
+ { filter.name }
77
+ </DropdownSubMenuTrigger>
78
+ }
79
+ >
80
+ { filter.elements.map( ( element ) => (
81
+ <DropdownMenuItem
82
+ key={ element.value }
83
+ onSelect={ () => {
84
+ onChangeView( ( currentView ) => ( {
85
+ ...currentView,
86
+ page: 1,
87
+ filters: [
88
+ ...currentView.filters,
89
+ {
90
+ field: filter.field,
91
+ operator: OPERATOR_IN,
92
+ value: element.value,
93
+ },
94
+ ],
95
+ } ) );
96
+ } }
97
+ >
98
+ { element.label }
99
+ </DropdownMenuItem>
100
+ ) ) }
101
+ </DropdownSubMenu>
102
+ );
103
+ } ) }
104
+ </DropdownMenu>
105
+ );
106
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __, isRTL } from '@wordpress/i18n';
5
+ import {
6
+ blockTable,
7
+ category,
8
+ formatListBullets,
9
+ formatListBulletsRTL,
10
+ } from '@wordpress/icons';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import ViewTable from './view-table';
16
+ import ViewGrid from './view-grid';
17
+ import ViewList from './view-list';
18
+
19
+ // Field types.
20
+ export const ENUMERATION_TYPE = 'enumeration';
21
+
22
+ // Filter operators.
23
+ export const OPERATOR_IN = 'in';
24
+ export const OPERATOR_NOT_IN = 'notIn';
25
+
26
+ // View layouts.
27
+ export const LAYOUT_TABLE = 'table';
28
+ export const LAYOUT_GRID = 'grid';
29
+ export const LAYOUT_LIST = 'list';
30
+
31
+ export const VIEW_LAYOUTS = [
32
+ {
33
+ type: LAYOUT_TABLE,
34
+ label: __( 'Table' ),
35
+ component: ViewTable,
36
+ icon: blockTable,
37
+ },
38
+ {
39
+ type: LAYOUT_GRID,
40
+ label: __( 'Grid' ),
41
+ component: ViewGrid,
42
+ icon: category,
43
+ },
44
+ {
45
+ type: LAYOUT_LIST,
46
+ label: __( 'List' ),
47
+ component: ViewList,
48
+ icon: isRTL() ? formatListBulletsRTL : formatListBullets,
49
+ },
50
+ ];
@@ -0,0 +1,99 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ __experimentalVStack as VStack,
6
+ __experimentalHStack as HStack,
7
+ } from '@wordpress/components';
8
+ import { useMemo, useState } from '@wordpress/element';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import Pagination from './pagination';
14
+ import ViewActions from './view-actions';
15
+ import Filters from './filters';
16
+ import Search from './search';
17
+ import { VIEW_LAYOUTS } from './constants';
18
+
19
+ export default function DataViews( {
20
+ view,
21
+ onChangeView,
22
+ fields,
23
+ search = true,
24
+ searchLabel = undefined,
25
+ actions,
26
+ data,
27
+ getItemId,
28
+ isLoading = false,
29
+ paginationInfo,
30
+ supportedLayouts,
31
+ onSelectionChange,
32
+ deferredRendering,
33
+ } ) {
34
+ const [ selection, setSelection ] = useState( [] );
35
+
36
+ const onSetSelection = ( items ) => {
37
+ setSelection( items.map( ( item ) => item.id ) );
38
+ onSelectionChange( items );
39
+ };
40
+
41
+ const ViewComponent = VIEW_LAYOUTS.find(
42
+ ( v ) => v.type === view.type
43
+ ).component;
44
+ const _fields = useMemo( () => {
45
+ return fields.map( ( field ) => ( {
46
+ ...field,
47
+ render: field.render || field.getValue,
48
+ } ) );
49
+ }, [ fields ] );
50
+ return (
51
+ <div className="dataviews-wrapper">
52
+ <VStack spacing={ 0 } justify="flex-start">
53
+ <HStack
54
+ alignment="flex-start"
55
+ className="dataviews__filters-view-actions"
56
+ >
57
+ <HStack justify="start" wrap>
58
+ { search && (
59
+ <Search
60
+ label={ searchLabel }
61
+ view={ view }
62
+ onChangeView={ onChangeView }
63
+ />
64
+ ) }
65
+ <Filters
66
+ fields={ fields }
67
+ view={ view }
68
+ onChangeView={ onChangeView }
69
+ />
70
+ </HStack>
71
+ <ViewActions
72
+ fields={ fields }
73
+ view={ view }
74
+ onChangeView={ onChangeView }
75
+ supportedLayouts={ supportedLayouts }
76
+ />
77
+ </HStack>
78
+ <ViewComponent
79
+ fields={ _fields }
80
+ view={ view }
81
+ onChangeView={ onChangeView }
82
+ paginationInfo={ paginationInfo }
83
+ actions={ actions }
84
+ data={ data }
85
+ getItemId={ getItemId }
86
+ isLoading={ isLoading }
87
+ onSelectionChange={ onSetSelection }
88
+ selection={ selection }
89
+ deferredRendering={ deferredRendering }
90
+ />
91
+ <Pagination
92
+ view={ view }
93
+ onChangeView={ onChangeView }
94
+ paginationInfo={ paginationInfo }
95
+ />
96
+ </VStack>
97
+ </div>
98
+ );
99
+ }