@wordpress/dataviews 0.2.0 → 0.3.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 (87) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/LICENSE.md +1 -1
  3. package/README.md +30 -6
  4. package/build/add-filter.js +109 -49
  5. package/build/add-filter.js.map +1 -1
  6. package/build/constants.js +24 -2
  7. package/build/constants.js.map +1 -1
  8. package/build/dataviews.js +12 -9
  9. package/build/dataviews.js.map +1 -1
  10. package/build/dropdown-menu-helper.js +72 -0
  11. package/build/dropdown-menu-helper.js.map +1 -0
  12. package/build/filter-summary.js +43 -54
  13. package/build/filter-summary.js.map +1 -1
  14. package/build/filters.js +27 -17
  15. package/build/filters.js.map +1 -1
  16. package/build/index.js +13 -0
  17. package/build/index.js.map +1 -1
  18. package/build/item-actions.js +12 -12
  19. package/build/item-actions.js.map +1 -1
  20. package/build/pagination.js +31 -65
  21. package/build/pagination.js.map +1 -1
  22. package/build/reset-filters.js +8 -8
  23. package/build/reset-filters.js.map +1 -1
  24. package/build/search.js +8 -6
  25. package/build/search.js.map +1 -1
  26. package/build/utils.js +71 -0
  27. package/build/utils.js.map +1 -0
  28. package/build/view-actions.js +72 -95
  29. package/build/view-actions.js.map +1 -1
  30. package/build/view-grid.js +4 -6
  31. package/build/view-grid.js.map +1 -1
  32. package/build/view-list.js +26 -13
  33. package/build/view-list.js.map +1 -1
  34. package/build/view-table.js +153 -154
  35. package/build/view-table.js.map +1 -1
  36. package/build-module/add-filter.js +113 -53
  37. package/build-module/add-filter.js.map +1 -1
  38. package/build-module/constants.js +20 -0
  39. package/build-module/constants.js.map +1 -1
  40. package/build-module/dataviews.js +13 -10
  41. package/build-module/dataviews.js.map +1 -1
  42. package/build-module/dropdown-menu-helper.js +64 -0
  43. package/build-module/dropdown-menu-helper.js.map +1 -0
  44. package/build-module/filter-summary.js +45 -56
  45. package/build-module/filter-summary.js.map +1 -1
  46. package/build-module/filters.js +26 -17
  47. package/build-module/filters.js.map +1 -1
  48. package/build-module/index.js +1 -0
  49. package/build-module/index.js.map +1 -1
  50. package/build-module/item-actions.js +12 -12
  51. package/build-module/item-actions.js.map +1 -1
  52. package/build-module/pagination.js +35 -69
  53. package/build-module/pagination.js.map +1 -1
  54. package/build-module/reset-filters.js +6 -6
  55. package/build-module/reset-filters.js.map +1 -1
  56. package/build-module/search.js +7 -6
  57. package/build-module/search.js.map +1 -1
  58. package/build-module/utils.js +63 -0
  59. package/build-module/utils.js.map +1 -0
  60. package/build-module/view-actions.js +73 -97
  61. package/build-module/view-actions.js.map +1 -1
  62. package/build-module/view-grid.js +4 -6
  63. package/build-module/view-grid.js.map +1 -1
  64. package/build-module/view-list.js +27 -14
  65. package/build-module/view-list.js.map +1 -1
  66. package/build-module/view-table.js +156 -157
  67. package/build-module/view-table.js.map +1 -1
  68. package/build-style/style-rtl.css +180 -70
  69. package/build-style/style.css +180 -70
  70. package/package.json +11 -10
  71. package/src/add-filter.js +227 -68
  72. package/src/constants.js +16 -0
  73. package/src/dataviews.js +19 -12
  74. package/src/dropdown-menu-helper.js +61 -0
  75. package/src/filter-summary.js +70 -103
  76. package/src/filters.js +41 -24
  77. package/src/index.js +1 -0
  78. package/src/item-actions.js +30 -25
  79. package/src/pagination.js +75 -123
  80. package/src/reset-filters.js +5 -5
  81. package/src/search.js +8 -6
  82. package/src/style.scss +182 -48
  83. package/src/utils.js +51 -0
  84. package/src/view-actions.js +113 -114
  85. package/src/view-grid.js +4 -4
  86. package/src/view-list.js +42 -28
  87. package/src/view-table.js +280 -238
package/src/search.js CHANGED
@@ -2,11 +2,11 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
- import { useEffect, useRef } from '@wordpress/element';
5
+ import { useEffect, useRef, memo } from '@wordpress/element';
6
6
  import { SearchControl } from '@wordpress/components';
7
7
  import { useDebouncedInput } from '@wordpress/compose';
8
8
 
9
- export default function Search( { label, view, onChangeView } ) {
9
+ const Search = memo( function Search( { label, view, onChangeView } ) {
10
10
  const [ search, setSearch, debouncedSearch ] = useDebouncedInput(
11
11
  view.search
12
12
  );
@@ -18,11 +18,11 @@ export default function Search( { label, view, onChangeView } ) {
18
18
  onChangeViewRef.current = onChangeView;
19
19
  }, [ onChangeView ] );
20
20
  useEffect( () => {
21
- onChangeViewRef.current( ( currentView ) => ( {
22
- ...currentView,
21
+ onChangeViewRef.current( {
22
+ ...view,
23
23
  page: 1,
24
24
  search: debouncedSearch,
25
- } ) );
25
+ } );
26
26
  }, [ debouncedSearch ] );
27
27
  const searchLabel = label || __( 'Filter list' );
28
28
  return (
@@ -35,4 +35,6 @@ export default function Search( { label, view, onChangeView } ) {
35
35
  size="compact"
36
36
  />
37
37
  );
38
- }
38
+ } );
39
+
40
+ export default Search;
package/src/style.scss CHANGED
@@ -10,15 +10,42 @@
10
10
  }
11
11
  }
12
12
 
13
- .dataviews__filters-view-actions {
13
+ .dataviews-filters__view-actions {
14
14
  padding: $grid-unit-15 $grid-unit-40;
15
+ .components-search-control {
16
+ flex-grow: 1;
17
+ max-width: 240px;
18
+ }
19
+ }
20
+
21
+ .dataviews-filters-button {
22
+ position: relative;
23
+ }
24
+
25
+ .dataviews-filters-count {
26
+ position: absolute;
27
+ top: 0;
28
+ right: 0;
29
+ height: $grid-unit-20;
30
+ color: var(--wp-components-color-accent-inverted, $white);
31
+ background-color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #007cba));
32
+ border-radius: $grid-unit-10;
33
+ min-width: $grid-unit-20;
34
+ padding: 0 $grid-unit-05;
35
+ transform: translateX(40%) translateY(-40%);
36
+ display: flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ font-size: 11px;
40
+ font-weight: 300;
15
41
  }
16
42
 
17
43
  .dataviews-pagination {
18
44
  margin-top: auto;
19
45
  position: sticky;
20
46
  bottom: 0;
21
- background-color: $white;
47
+ background-color: rgba($white, 0.8);
48
+ backdrop-filter: blur(6px);
22
49
  padding: $grid-unit-15 $grid-unit-40;
23
50
  border-top: $border-width solid $gray-100;
24
51
  color: $gray-700;
@@ -28,7 +55,7 @@
28
55
  margin: $grid-unit-40 0 $grid-unit-20;
29
56
  }
30
57
 
31
- .dataviews-table-view {
58
+ .dataviews-view-table {
32
59
  width: 100%;
33
60
  text-indent: 0;
34
61
  border-color: inherit;
@@ -58,9 +85,18 @@
58
85
  tr {
59
86
  border-bottom: 1px solid $gray-100;
60
87
 
88
+ .dataviews-view-table-header-button {
89
+ gap: $grid-unit-05;
90
+ }
91
+
61
92
  td:first-child,
62
93
  th:first-child {
63
94
  padding-left: $grid-unit-40;
95
+
96
+ .dataviews-view-table-header-button,
97
+ .dataviews-view-table-header {
98
+ margin-left: - #{$grid-unit-10};
99
+ }
64
100
  }
65
101
 
66
102
  td:last-child,
@@ -71,6 +107,12 @@
71
107
  &:last-child {
72
108
  border-bottom: 0;
73
109
  }
110
+
111
+ &:hover {
112
+ td {
113
+ background-color: #f8f8f8;
114
+ }
115
+ }
74
116
  }
75
117
  thead {
76
118
  tr {
@@ -79,16 +121,43 @@
79
121
  th {
80
122
  position: sticky;
81
123
  top: -1px;
82
- background-color: lighten($gray-100, 4%);
124
+ background-color: $white;
83
125
  box-shadow: inset 0 -#{$border-width} 0 $gray-100;
84
- border-top: 1px solid $gray-100;
85
- padding-top: $grid-unit-05;
86
- padding-bottom: $grid-unit-05;
126
+ padding-top: $grid-unit-10;
127
+ padding-bottom: $grid-unit-10;
128
+ z-index: 1;
129
+ font-size: 11px;
130
+ text-transform: uppercase;
131
+ font-weight: 500;
132
+ padding-left: $grid-unit-05;
133
+ }
134
+ }
135
+
136
+ .dataviews-view-table-header-button {
137
+ padding: $grid-unit-05 $grid-unit-10;
138
+ font-size: 11px;
139
+ text-transform: uppercase;
140
+ font-weight: 500;
141
+
142
+ &:not(:hover) {
143
+ color: $gray-900;
144
+ }
145
+
146
+ span {
147
+ speak: none;
148
+
149
+ &:empty {
150
+ display: none;
151
+ }
87
152
  }
88
153
  }
154
+
155
+ .dataviews-view-table-header {
156
+ padding-left: $grid-unit-05;
157
+ }
89
158
  }
90
159
 
91
- .dataviews-grid-view {
160
+ .dataviews-view-grid {
92
161
  margin-bottom: $grid-unit-30;
93
162
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
94
163
  padding: 0 $grid-unit-40;
@@ -102,10 +171,22 @@
102
171
  }
103
172
 
104
173
  .dataviews-view-grid__card {
105
- h3 { // Todo: A better way to target this
106
- white-space: nowrap;
107
- overflow: hidden;
108
- text-overflow: ellipsis;
174
+ .dataviews-view-grid__primary-field {
175
+ .dataviews-view-grid__title-field {
176
+ white-space: nowrap;
177
+ overflow: hidden;
178
+ text-overflow: ellipsis;
179
+ display: block;
180
+ font-size: $default-font-size;
181
+ width: 100%;
182
+ }
183
+
184
+ .dataviews-view-grid__title-field a,
185
+ button.dataviews-view-grid__title-field {
186
+ font-weight: 500;
187
+ color: $gray-900;
188
+ text-decoration: none;
189
+ }
109
190
  }
110
191
  }
111
192
 
@@ -126,12 +207,6 @@
126
207
 
127
208
  .dataviews-view-grid__primary-field {
128
209
  min-height: $grid-unit-30;
129
-
130
- a {
131
- color: $gray-900;
132
- text-decoration: none;
133
- font-weight: 500;
134
- }
135
210
  }
136
211
 
137
212
  .dataviews-view-grid__fields {
@@ -150,29 +225,71 @@
150
225
  }
151
226
  }
152
227
 
153
- .dataviews-list-view {
228
+ .dataviews-view-list {
154
229
  margin: 0;
230
+ padding: $grid-unit-10;
155
231
 
156
232
  li {
157
- border-bottom: $border-width solid $gray-100;
158
233
  margin: 0;
159
- &:first-child {
160
- border-top: $border-width solid $gray-100;
234
+
235
+ .dataviews-view-list__item-wrapper {
236
+ position: relative;
237
+ padding-right: $grid-unit-30;
238
+ border-radius: $grid-unit-05;
239
+
240
+ &::after {
241
+ position: absolute;
242
+ content: "";
243
+ top: 100%;
244
+ left: $grid-unit-30;
245
+ right: $grid-unit-30;
246
+ background: $gray-100;
247
+ height: 1px;
248
+ }
161
249
  }
162
- &:last-child {
163
- border-bottom: 0;
250
+
251
+ &:not(.is-selected):hover {
252
+ color: var(--wp-admin-theme-color);
253
+
254
+ .dataviews-view-list__fields {
255
+ color: var(--wp-admin-theme-color);
256
+ }
164
257
  }
165
258
  }
166
259
 
167
- .dataviews-list-view__item {
168
- padding: $grid-unit-15 $grid-unit-40;
169
- cursor: default;
170
- &:focus,
171
- &:hover {
172
- background-color: lighten($gray-100, 3%);
260
+ li.is-selected,
261
+ li.is-selected:focus-within {
262
+ .dataviews-view-list__item-wrapper {
263
+ background-color: var(--wp-admin-theme-color);
264
+ color: $white;
265
+
266
+ .dataviews-view-list__fields,
267
+ .components-button {
268
+ color: $white;
269
+ }
270
+
271
+ &::after {
272
+ background: transparent;
273
+ }
173
274
  }
275
+ }
276
+
277
+ .dataviews-view-list__item {
278
+ padding: $grid-unit-15 0 $grid-unit-15 $grid-unit-30;
279
+ width: 100%;
280
+ cursor: pointer;
174
281
  &:focus {
175
- box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
282
+ &::before {
283
+ position: absolute;
284
+ content: "";
285
+ top: -1px;
286
+ right: -1px;
287
+ bottom: -1px;
288
+ left: -1px;
289
+ box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
290
+ z-index: -1;
291
+ border-radius: $grid-unit-05;
292
+ }
176
293
  }
177
294
  h3 {
178
295
  overflow: hidden;
@@ -181,16 +298,7 @@
181
298
  }
182
299
  }
183
300
 
184
- .dataviews-list-view__item-selected,
185
- .dataviews-list-view__item-selected:hover {
186
- background-color: $gray-100;
187
-
188
- &:focus {
189
- box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
190
- }
191
- }
192
-
193
- .dataviews-list-view__media-wrapper {
301
+ .dataviews-view-list__media-wrapper {
194
302
  min-width: $grid-unit-40;
195
303
  height: $grid-unit-40;
196
304
  border-radius: $grid-unit-05;
@@ -209,23 +317,19 @@
209
317
  }
210
318
  }
211
319
 
212
- .edit-site-page-pages__featured-image,
213
- .dataviews-list-view__media-placeholder {
320
+ .dataviews-view-list__media-placeholder {
214
321
  min-width: $grid-unit-40;
215
322
  height: $grid-unit-40;
216
- }
217
-
218
- .dataviews-list-view__media-placeholder {
219
323
  background-color: $gray-200;
220
324
  }
221
325
 
222
- .dataviews-list-view__fields {
326
+ .dataviews-view-list__fields {
223
327
  color: $gray-700;
224
328
  overflow: hidden;
225
329
  text-overflow: ellipsis;
226
330
  white-space: nowrap;
227
331
 
228
- .dataviews-list-view__field {
332
+ .dataviews-view-list__field {
229
333
  margin-right: $grid-unit-15;
230
334
 
231
335
  &:last-child {
@@ -233,6 +337,31 @@
233
337
  }
234
338
  }
235
339
  }
340
+
341
+ & + .dataviews-pagination {
342
+ justify-content: space-between;
343
+ }
344
+
345
+ .dataviews-view-list__details-button {
346
+ align-self: center;
347
+ opacity: 0;
348
+ }
349
+
350
+ li.is-selected,
351
+ li:hover,
352
+ li:focus-within {
353
+ .dataviews-view-list__details-button {
354
+ opacity: 1;
355
+ }
356
+ }
357
+
358
+ li.is-selected {
359
+ .dataviews-view-list__details-button {
360
+ &:focus {
361
+ box-shadow: 0 0 0 var(--wp-admin-border-width-focus) currentColor;
362
+ }
363
+ }
364
+ }
236
365
  }
237
366
 
238
367
  .dataviews-action-modal {
@@ -243,3 +372,8 @@
243
372
  .dataviews-loading {
244
373
  padding: 0 $grid-unit-40;
245
374
  }
375
+
376
+ .dataviews-filters__custom-menu-radio-item-prefix {
377
+ display: block;
378
+ width: 24px;
379
+ }
package/src/utils.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Helper util to sort data by text fields, when sorting is done client side.
3
+ *
4
+ * @param {Object} params Function params.
5
+ * @param {Object[]} params.data Data to sort.
6
+ * @param {Object} params.view Current view object.
7
+ * @param {Object[]} params.fields Array of available fields.
8
+ * @param {string[]} params.textFields Array of the field ids to sort.
9
+ *
10
+ * @return {Object[]} Sorted data.
11
+ */
12
+ export const sortByTextFields = ( { data, view, fields, textFields } ) => {
13
+ const sortedData = [ ...data ];
14
+ const fieldId = view.sort.field;
15
+ if ( textFields.includes( fieldId ) ) {
16
+ const fieldToSort = fields.find( ( field ) => {
17
+ return field.id === fieldId;
18
+ } );
19
+ sortedData.sort( ( a, b ) => {
20
+ const valueA = fieldToSort.getValue( { item: a } ) ?? '';
21
+ const valueB = fieldToSort.getValue( { item: b } ) ?? '';
22
+ return view.sort.direction === 'asc'
23
+ ? valueA.localeCompare( valueB )
24
+ : valueB.localeCompare( valueA );
25
+ } );
26
+ }
27
+ return sortedData;
28
+ };
29
+
30
+ /**
31
+ * Helper util to get the paginated data and the paginateInfo needed,
32
+ * when pagination is done client side.
33
+ *
34
+ * @param {Object} params Function params.
35
+ * @param {Object[]} params.data Available data.
36
+ * @param {Object} params.view Current view object.
37
+ *
38
+ * @return {Object} Paginated data and paginationInfo.
39
+ */
40
+ export function getPaginationResults( { data, view } ) {
41
+ const start = ( view.page - 1 ) * view.perPage;
42
+ const totalItems = data?.length || 0;
43
+ data = data?.slice( start, start + view.perPage );
44
+ return {
45
+ data,
46
+ paginationInfo: {
47
+ totalItems,
48
+ totalPages: Math.ceil( totalItems / view.perPage ),
49
+ },
50
+ };
51
+ }