@wordpress/dataviews 0.8.0 → 0.9.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 (59) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +3 -5
  3. package/build/constants.js +1 -4
  4. package/build/constants.js.map +1 -1
  5. package/build/dataviews.js +2 -12
  6. package/build/dataviews.js.map +1 -1
  7. package/build/filter-and-sort-data-view.js +147 -0
  8. package/build/filter-and-sort-data-view.js.map +1 -0
  9. package/build/filters.js +11 -17
  10. package/build/filters.js.map +1 -1
  11. package/build/index.js +3 -9
  12. package/build/index.js.map +1 -1
  13. package/build/normalize-fields.js +25 -0
  14. package/build/normalize-fields.js.map +1 -0
  15. package/build/utils.js +1 -65
  16. package/build/utils.js.map +1 -1
  17. package/build/view-grid.js +21 -11
  18. package/build/view-grid.js.map +1 -1
  19. package/build/view-list.js +122 -58
  20. package/build/view-list.js.map +1 -1
  21. package/build/view-table.js +27 -13
  22. package/build/view-table.js.map +1 -1
  23. package/build-module/constants.js +0 -3
  24. package/build-module/constants.js.map +1 -1
  25. package/build-module/dataviews.js +2 -12
  26. package/build-module/dataviews.js.map +1 -1
  27. package/build-module/filter-and-sort-data-view.js +139 -0
  28. package/build-module/filter-and-sort-data-view.js.map +1 -0
  29. package/build-module/filters.js +12 -18
  30. package/build-module/filters.js.map +1 -1
  31. package/build-module/index.js +1 -1
  32. package/build-module/index.js.map +1 -1
  33. package/build-module/normalize-fields.js +19 -0
  34. package/build-module/normalize-fields.js.map +1 -0
  35. package/build-module/utils.js +0 -63
  36. package/build-module/utils.js.map +1 -1
  37. package/build-module/view-grid.js +22 -12
  38. package/build-module/view-grid.js.map +1 -1
  39. package/build-module/view-list.js +124 -60
  40. package/build-module/view-list.js.map +1 -1
  41. package/build-module/view-table.js +28 -14
  42. package/build-module/view-table.js.map +1 -1
  43. package/build-style/style-rtl.css +32 -8
  44. package/build-style/style.css +32 -8
  45. package/package.json +11 -11
  46. package/src/constants.js +0 -3
  47. package/src/dataviews.js +2 -12
  48. package/src/filter-and-sort-data-view.js +154 -0
  49. package/src/filters.js +20 -32
  50. package/src/index.js +1 -1
  51. package/src/normalize-fields.js +17 -0
  52. package/src/stories/fixtures.js +75 -1
  53. package/src/stories/index.story.js +5 -113
  54. package/src/style.scss +44 -11
  55. package/src/test/filter-and-sort-data-view.js +276 -0
  56. package/src/utils.js +0 -52
  57. package/src/view-grid.js +32 -10
  58. package/src/view-list.js +159 -69
  59. package/src/view-table.js +29 -13
@@ -272,6 +272,9 @@
272
272
  .dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper > * {
273
273
  flex-grow: 1;
274
274
  }
275
+ .dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper.dataviews-view-table__primary-field a {
276
+ flex-grow: 0;
277
+ }
275
278
  .dataviews-view-table .dataviews-view-table-header-button {
276
279
  padding: 4px 8px;
277
280
  font-size: 11px;
@@ -317,12 +320,12 @@
317
320
  white-space: nowrap;
318
321
  overflow: hidden;
319
322
  display: block;
320
- width: 100%;
323
+ flex-grow: 0;
321
324
  }
322
325
  .dataviews-view-list__primary-field a:hover,
323
326
  .dataviews-view-grid__primary-field a:hover,
324
327
  .dataviews-view-table__primary-field a:hover {
325
- color: #1e1e1e;
328
+ color: var(--wp-admin-theme-color);
326
329
  }
327
330
  .dataviews-view-list__primary-field a:focus,
328
331
  .dataviews-view-grid__primary-field a:focus,
@@ -401,7 +404,22 @@
401
404
  padding: 12px;
402
405
  padding-top: 0;
403
406
  }
404
- .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
407
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field {
408
+ align-items: flex-start;
409
+ }
410
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(.is-column) {
411
+ align-items: center;
412
+ }
413
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(.is-column) .dataviews-view-grid__field-name {
414
+ width: 35%;
415
+ }
416
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(.is-column) .dataviews-view-grid__field-value {
417
+ width: 65%;
418
+ overflow: hidden;
419
+ text-overflow: ellipsis;
420
+ white-space: nowrap;
421
+ }
422
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name {
405
423
  color: #757575;
406
424
  }
407
425
 
@@ -411,6 +429,7 @@
411
429
  }
412
430
  .dataviews-view-list li {
413
431
  margin: 0;
432
+ cursor: pointer;
414
433
  }
415
434
  .dataviews-view-list li .dataviews-view-list__item-wrapper {
416
435
  position: relative;
@@ -426,11 +445,15 @@
426
445
  background: #f0f0f0;
427
446
  height: 1px;
428
447
  }
429
- .dataviews-view-list li:not(.is-selected):hover {
448
+ .dataviews-view-list li .dataviews-view-list__item-wrapper > * {
449
+ width: 100%;
450
+ }
451
+ .dataviews-view-list li:not(.is-selected):hover, .dataviews-view-list li:not(.is-selected):focus-within {
430
452
  color: var(--wp-admin-theme-color);
431
453
  }
432
454
  .dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__primary-field,
433
- .dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__fields {
455
+ .dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__fields, .dataviews-view-list li:not(.is-selected):focus-within .dataviews-view-list__primary-field,
456
+ .dataviews-view-list li:not(.is-selected):focus-within .dataviews-view-list__fields {
434
457
  color: var(--wp-admin-theme-color);
435
458
  }
436
459
  .dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper,
@@ -453,9 +476,9 @@
453
476
  .dataviews-view-list .dataviews-view-list__item {
454
477
  padding: 12px 0 12px 24px;
455
478
  width: 100%;
456
- cursor: pointer;
479
+ scroll-margin: 8px 0;
457
480
  }
458
- .dataviews-view-list .dataviews-view-list__item:focus::before {
481
+ .dataviews-view-list .dataviews-view-list__item:focus-visible::before {
459
482
  position: absolute;
460
483
  content: "";
461
484
  top: -1px;
@@ -468,6 +491,7 @@
468
491
  }
469
492
  .dataviews-view-list .dataviews-view-list__item .dataviews-view-list__primary-field {
470
493
  min-height: 20px;
494
+ overflow: hidden;
471
495
  }
472
496
  .dataviews-view-list .dataviews-view-list__media-wrapper {
473
497
  width: 40px;
@@ -506,7 +530,7 @@
506
530
  font-size: 12px;
507
531
  line-height: 16px;
508
532
  }
509
- .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:empty {
533
+ .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty) {
510
534
  display: none;
511
535
  }
512
536
  .dataviews-view-list + .dataviews-pagination {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/dataviews",
3
- "version": "0.8.0",
3
+ "version": "0.9.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",
@@ -29,15 +29,15 @@
29
29
  "dependencies": {
30
30
  "@ariakit/react": "^0.3.12",
31
31
  "@babel/runtime": "^7.16.0",
32
- "@wordpress/a11y": "^3.54.0",
33
- "@wordpress/components": "^27.2.0",
34
- "@wordpress/compose": "^6.31.0",
35
- "@wordpress/element": "^5.31.0",
36
- "@wordpress/i18n": "^4.54.0",
37
- "@wordpress/icons": "^9.45.0",
38
- "@wordpress/keycodes": "^3.54.0",
39
- "@wordpress/primitives": "^3.52.0",
40
- "@wordpress/private-apis": "^0.36.0",
32
+ "@wordpress/a11y": "^3.55.0",
33
+ "@wordpress/components": "^27.3.0",
34
+ "@wordpress/compose": "^6.32.0",
35
+ "@wordpress/element": "^5.32.0",
36
+ "@wordpress/i18n": "^4.55.0",
37
+ "@wordpress/icons": "^9.46.0",
38
+ "@wordpress/keycodes": "^3.55.0",
39
+ "@wordpress/primitives": "^3.53.0",
40
+ "@wordpress/private-apis": "^0.37.0",
41
41
  "classnames": "^2.3.1",
42
42
  "remove-accents": "^0.5.0"
43
43
  },
@@ -47,5 +47,5 @@
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
- "gitHead": "ffc07735d0abfb3f69e91d48f25b7fe8d1ef92d2"
50
+ "gitHead": "ac2b13783c28f959770cf029a797a712f59e1958"
51
51
  }
package/src/constants.js CHANGED
@@ -16,9 +16,6 @@ import ViewTable from './view-table';
16
16
  import ViewGrid from './view-grid';
17
17
  import ViewList from './view-list';
18
18
 
19
- // Field types.
20
- export const ENUMERATION_TYPE = 'enumeration';
21
-
22
19
  // Filter operators.
23
20
  export const OPERATOR_IS = 'is';
24
21
  export const OPERATOR_IS_NOT = 'isNot';
package/src/dataviews.js CHANGED
@@ -13,6 +13,7 @@ import Filters from './filters';
13
13
  import Search from './search';
14
14
  import { VIEW_LAYOUTS, LAYOUT_TABLE, LAYOUT_GRID } from './constants';
15
15
  import BulkActions from './bulk-actions';
16
+ import { normalizeFields } from './normalize-fields';
16
17
 
17
18
  const defaultGetItemId = ( item ) => item.id;
18
19
  const defaultOnSelectionChange = () => {};
@@ -76,18 +77,7 @@ export default function DataViews( {
76
77
  const ViewComponent = VIEW_LAYOUTS.find(
77
78
  ( v ) => v.type === view.type
78
79
  ).component;
79
- const _fields = useMemo( () => {
80
- return fields.map( ( field ) => {
81
- const getValue =
82
- field.getValue || ( ( { item } ) => item[ field.id ] );
83
-
84
- return {
85
- ...field,
86
- getValue,
87
- render: field.render || getValue,
88
- };
89
- } );
90
- }, [ fields ] );
80
+ const _fields = useMemo( () => normalizeFields( fields ), [ fields ] );
91
81
 
92
82
  const hasPossibleBulkAction = useSomeItemHasAPossibleBulkAction(
93
83
  actions,
@@ -0,0 +1,154 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import removeAccents from 'remove-accents';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import {
10
+ OPERATOR_IS,
11
+ OPERATOR_IS_NOT,
12
+ OPERATOR_IS_NONE,
13
+ OPERATOR_IS_ANY,
14
+ OPERATOR_IS_ALL,
15
+ OPERATOR_IS_NOT_ALL,
16
+ } from './constants';
17
+ import { normalizeFields } from './normalize-fields';
18
+
19
+ function normalizeSearchInput( input = '' ) {
20
+ return removeAccents( input.trim().toLowerCase() );
21
+ }
22
+
23
+ const EMPTY_ARRAY = [];
24
+
25
+ /**
26
+ * Applies the filtering, sorting and pagination to the raw data based on the view configuration.
27
+ *
28
+ * @param {any[]} data Raw data.
29
+ * @param {Object} view View config.
30
+ * @param {Object[]} fields Fields config.
31
+ *
32
+ * @return {Object} { data: any[], paginationInfo: { totalItems: number, totalPages: number } }
33
+ */
34
+ export function filterSortAndPaginate( data, view, fields ) {
35
+ if ( ! data ) {
36
+ return {
37
+ data: EMPTY_ARRAY,
38
+ paginationInfo: { totalItems: 0, totalPages: 0 },
39
+ };
40
+ }
41
+ const _fields = normalizeFields( fields );
42
+ let filteredData = [ ...data ];
43
+ // Handle global search.
44
+ if ( view.search ) {
45
+ const normalizedSearch = normalizeSearchInput( view.search );
46
+ filteredData = filteredData.filter( ( item ) => {
47
+ return _fields
48
+ .filter( ( field ) => field.enableGlobalSearch )
49
+ .map( ( field ) => {
50
+ return normalizeSearchInput( field.getValue( { item } ) );
51
+ } )
52
+ .some( ( field ) => field.includes( normalizedSearch ) );
53
+ } );
54
+ }
55
+
56
+ if ( view.filters.length > 0 ) {
57
+ view.filters.forEach( ( filter ) => {
58
+ const field = _fields.find(
59
+ ( _field ) => _field.id === filter.field
60
+ );
61
+ if (
62
+ filter.operator === OPERATOR_IS_ANY &&
63
+ filter?.value?.length > 0
64
+ ) {
65
+ filteredData = filteredData.filter( ( item ) => {
66
+ const fieldValue = field.getValue( { item } );
67
+ if ( Array.isArray( fieldValue ) ) {
68
+ return filter.value.some( ( filterValue ) =>
69
+ fieldValue.includes( filterValue )
70
+ );
71
+ } else if ( typeof fieldValue === 'string' ) {
72
+ return filter.value.includes( fieldValue );
73
+ }
74
+ return false;
75
+ } );
76
+ } else if (
77
+ filter.operator === OPERATOR_IS_NONE &&
78
+ filter?.value?.length > 0
79
+ ) {
80
+ filteredData = filteredData.filter( ( item ) => {
81
+ const fieldValue = field.getValue( { item } );
82
+ if ( Array.isArray( fieldValue ) ) {
83
+ return ! filter.value.some( ( filterValue ) =>
84
+ fieldValue.includes( filterValue )
85
+ );
86
+ } else if ( typeof fieldValue === 'string' ) {
87
+ return ! filter.value.includes( fieldValue );
88
+ }
89
+ return false;
90
+ } );
91
+ } else if (
92
+ filter.operator === OPERATOR_IS_ALL &&
93
+ filter?.value?.length > 0
94
+ ) {
95
+ filteredData = filteredData.filter( ( item ) => {
96
+ return filter.value.every( ( value ) => {
97
+ return field.getValue( { item } ).includes( value );
98
+ } );
99
+ } );
100
+ } else if (
101
+ filter.operator === OPERATOR_IS_NOT_ALL &&
102
+ filter?.value?.length > 0
103
+ ) {
104
+ filteredData = filteredData.filter( ( item ) => {
105
+ return filter.value.every( ( value ) => {
106
+ return ! field.getValue( { item } ).includes( value );
107
+ } );
108
+ } );
109
+ } else if ( filter.operator === OPERATOR_IS ) {
110
+ filteredData = filteredData.filter( ( item ) => {
111
+ return filter.value === field.getValue( { item } );
112
+ } );
113
+ } else if ( filter.operator === OPERATOR_IS_NOT ) {
114
+ filteredData = filteredData.filter( ( item ) => {
115
+ return filter.value !== field.getValue( { item } );
116
+ } );
117
+ }
118
+ } );
119
+ }
120
+
121
+ // Handle sorting.
122
+ if ( view.sort ) {
123
+ const fieldId = view.sort.field;
124
+ const fieldToSort = _fields.find( ( field ) => {
125
+ return field.id === fieldId;
126
+ } );
127
+ filteredData.sort( ( a, b ) => {
128
+ const valueA = fieldToSort.getValue( { item: a } ) ?? '';
129
+ const valueB = fieldToSort.getValue( { item: b } ) ?? '';
130
+ return view.sort.direction === 'asc'
131
+ ? valueA.localeCompare( valueB )
132
+ : valueB.localeCompare( valueA );
133
+ } );
134
+ }
135
+
136
+ // Handle pagination.
137
+ const hasPagination = view.page && view.perPage;
138
+ const start = hasPagination ? ( view.page - 1 ) * view.perPage : 0;
139
+ const totalItems = filteredData?.length || 0;
140
+ const totalPages = hasPagination
141
+ ? Math.ceil( totalItems / view.perPage )
142
+ : 1;
143
+ filteredData = hasPagination
144
+ ? filteredData?.slice( start, start + view.perPage )
145
+ : filteredData;
146
+
147
+ return {
148
+ data: filteredData,
149
+ paginationInfo: {
150
+ totalItems,
151
+ totalPages,
152
+ },
153
+ };
154
+ }
package/src/filters.js CHANGED
@@ -10,12 +10,7 @@ import FilterSummary from './filter-summary';
10
10
  import AddFilter from './add-filter';
11
11
  import ResetFilters from './reset-filters';
12
12
  import { sanitizeOperators } from './utils';
13
- import {
14
- ENUMERATION_TYPE,
15
- ALL_OPERATORS,
16
- OPERATOR_IS,
17
- OPERATOR_IS_NOT,
18
- } from './constants';
13
+ import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from './constants';
19
14
  import { __experimentalHStack as HStack } from '@wordpress/components';
20
15
 
21
16
  const Filters = memo( function Filters( {
@@ -28,7 +23,7 @@ const Filters = memo( function Filters( {
28
23
  const addFilterRef = useRef();
29
24
  const filters = [];
30
25
  fields.forEach( ( field ) => {
31
- if ( ! field.type ) {
26
+ if ( ! field.elements?.length ) {
32
27
  return;
33
28
  }
34
29
 
@@ -37,31 +32,24 @@ const Filters = memo( function Filters( {
37
32
  return;
38
33
  }
39
34
 
40
- switch ( field.type ) {
41
- case ENUMERATION_TYPE:
42
- if ( ! field.elements?.length ) {
43
- return;
44
- }
45
-
46
- const isPrimary = !! field.filterBy?.isPrimary;
47
- filters.push( {
48
- field: field.id,
49
- name: field.header,
50
- elements: field.elements,
51
- singleSelection: operators.some( ( op ) =>
52
- [ OPERATOR_IS, OPERATOR_IS_NOT ].includes( op )
53
- ),
54
- operators,
55
- isVisible:
56
- isPrimary ||
57
- view.filters.some(
58
- ( f ) =>
59
- f.field === field.id &&
60
- ALL_OPERATORS.includes( f.operator )
61
- ),
62
- isPrimary,
63
- } );
64
- }
35
+ const isPrimary = !! field.filterBy?.isPrimary;
36
+ filters.push( {
37
+ field: field.id,
38
+ name: field.header,
39
+ elements: field.elements,
40
+ singleSelection: operators.some( ( op ) =>
41
+ [ OPERATOR_IS, OPERATOR_IS_NOT ].includes( op )
42
+ ),
43
+ operators,
44
+ isVisible:
45
+ isPrimary ||
46
+ view.filters.some(
47
+ ( f ) =>
48
+ f.field === field.id &&
49
+ ALL_OPERATORS.includes( f.operator )
50
+ ),
51
+ isPrimary,
52
+ } );
65
53
  } );
66
54
  // Sort filters by primary property. We need the primary filters to be first.
67
55
  // Then we sort by name.
package/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { default as DataViews } from './dataviews';
2
- export { sortByTextFields, getPaginationResults } from './utils';
3
2
  export { VIEW_LAYOUTS } from './constants';
3
+ export { filterSortAndPaginate } from './filter-and-sort-data-view';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Apply default values and normalize the fields config.
3
+ *
4
+ * @param {Object[]} fields Raw Fields.
5
+ * @return {Object[]} Normalized fields.
6
+ */
7
+ export function normalizeFields( fields ) {
8
+ return fields.map( ( field ) => {
9
+ const getValue = field.getValue || ( ( { item } ) => item[ field.id ] );
10
+
11
+ return {
12
+ ...field,
13
+ getValue,
14
+ render: field.render || getValue,
15
+ };
16
+ } );
17
+ }
@@ -21,6 +21,7 @@ export const data = [
21
21
  description: 'Apollo description',
22
22
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
23
23
  type: 'Not a planet',
24
+ categories: [ 'Space', 'NASA' ],
24
25
  },
25
26
  {
26
27
  id: 2,
@@ -28,6 +29,7 @@ export const data = [
28
29
  description: 'Space description',
29
30
  image: 'https://live.staticflickr.com/5678/21911065441_92e2d44708_b.jpg',
30
31
  type: 'Not a planet',
32
+ categories: [ 'Space' ],
31
33
  },
32
34
  {
33
35
  id: 3,
@@ -35,6 +37,7 @@ export const data = [
35
37
  description: 'NASA photo',
36
38
  image: 'https://live.staticflickr.com/742/21712365770_8f70a2c91e_b.jpg',
37
39
  type: 'Not a planet',
40
+ categories: [ 'NASA' ],
38
41
  },
39
42
  {
40
43
  id: 4,
@@ -42,6 +45,7 @@ export const data = [
42
45
  description: 'Neptune description',
43
46
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
44
47
  type: 'Ice giant',
48
+ categories: [ 'Space', 'Planet', 'Solar system' ],
45
49
  },
46
50
  {
47
51
  id: 5,
@@ -49,13 +53,15 @@ export const data = [
49
53
  description: 'Mercury description',
50
54
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
51
55
  type: 'Terrestrial',
56
+ categories: [ 'Space', 'Planet', 'Solar system' ],
52
57
  },
53
58
  {
54
59
  id: 6,
55
60
  title: 'Venus',
56
- description: 'Venus description',
61
+ description: 'La planète Vénus',
57
62
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
58
63
  type: 'Terrestrial',
64
+ categories: [ 'Space', 'Planet', 'Solar system' ],
59
65
  },
60
66
  {
61
67
  id: 7,
@@ -63,6 +69,7 @@ export const data = [
63
69
  description: 'Earth description',
64
70
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
65
71
  type: 'Terrestrial',
72
+ categories: [ 'Space', 'Planet', 'Solar system' ],
66
73
  },
67
74
  {
68
75
  id: 8,
@@ -70,6 +77,7 @@ export const data = [
70
77
  description: 'Mars description',
71
78
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
72
79
  type: 'Terrestrial',
80
+ categories: [ 'Space', 'Planet', 'Solar system' ],
73
81
  },
74
82
  {
75
83
  id: 9,
@@ -77,6 +85,7 @@ export const data = [
77
85
  description: 'Jupiter description',
78
86
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
79
87
  type: 'Gas giant',
88
+ categories: [ 'Space', 'Planet', 'Solar system' ],
80
89
  },
81
90
  {
82
91
  id: 10,
@@ -84,6 +93,7 @@ export const data = [
84
93
  description: 'Saturn description',
85
94
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
86
95
  type: 'Gas giant',
96
+ categories: [ 'Space', 'Planet', 'Solar system' ],
87
97
  },
88
98
  {
89
99
  id: 11,
@@ -91,6 +101,7 @@ export const data = [
91
101
  description: 'Uranus description',
92
102
  image: 'https://live.staticflickr.com/5725/21726228300_51333bd62c_b.jpg',
93
103
  type: 'Ice giant',
104
+ categories: [ 'Space', 'Ice giant', 'Solar system' ],
94
105
  },
95
106
  ];
96
107
 
@@ -135,3 +146,66 @@ export const actions = [
135
146
  callback() {},
136
147
  },
137
148
  ];
149
+
150
+ export const fields = [
151
+ {
152
+ header: 'Image',
153
+ id: 'image',
154
+ render: ( { item } ) => {
155
+ return (
156
+ <img src={ item.image } alt="" style={ { width: '100%' } } />
157
+ );
158
+ },
159
+ width: 50,
160
+ enableSorting: false,
161
+ },
162
+ {
163
+ header: 'Title',
164
+ id: 'title',
165
+ maxWidth: 400,
166
+ enableHiding: false,
167
+ enableGlobalSearch: true,
168
+ },
169
+ {
170
+ header: 'Type',
171
+ id: 'type',
172
+ maxWidth: 400,
173
+ enableHiding: false,
174
+ type: 'enumeration',
175
+ elements: [
176
+ { value: 'Not a planet', label: 'Not a planet' },
177
+ { value: 'Ice giant', label: 'Ice giant' },
178
+ { value: 'Terrestrial', label: 'Terrestrial' },
179
+ { value: 'Gas giant', label: 'Gas giant' },
180
+ ],
181
+ },
182
+ {
183
+ header: 'Description',
184
+ id: 'description',
185
+ maxWidth: 200,
186
+ enableSorting: false,
187
+ enableGlobalSearch: true,
188
+ },
189
+ {
190
+ header: 'Categories',
191
+ id: 'categories',
192
+ type: 'enumeration',
193
+ elements: [
194
+ { value: 'Space', label: 'Space' },
195
+ { value: 'NASA', label: 'NASA' },
196
+ { value: 'Planet', label: 'Planet' },
197
+ { value: 'Solar system', label: 'Solar system' },
198
+ { value: 'Ice giant', label: 'Ice giant' },
199
+ ],
200
+ filterBy: {
201
+ operators: [ 'isAny', 'isNone', 'isAll', 'isNotAll' ],
202
+ },
203
+ getValue: ( { item } ) => {
204
+ return item.categories;
205
+ },
206
+ render: ( { item } ) => {
207
+ return item.categories.join( ',' );
208
+ },
209
+ enableSorting: false,
210
+ },
211
+ ];