@wordpress/dataviews 5.0.0 → 6.0.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 (250) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/README.md +55 -27
  3. package/build/components/dataviews/index.js +13 -4
  4. package/build/components/dataviews/index.js.map +1 -1
  5. package/build/components/dataviews-context/index.js +3 -1
  6. package/build/components/dataviews-context/index.js.map +1 -1
  7. package/build/components/dataviews-filters/filter.js +15 -8
  8. package/build/components/dataviews-filters/filter.js.map +1 -1
  9. package/build/components/dataviews-filters/index.js +16 -5
  10. package/build/components/dataviews-filters/index.js.map +1 -1
  11. package/build/components/dataviews-filters/input-widget.js +7 -1
  12. package/build/components/dataviews-filters/input-widget.js.map +1 -1
  13. package/build/components/dataviews-filters/reset-filters.js +2 -2
  14. package/build/components/dataviews-filters/reset-filters.js.map +1 -1
  15. package/build/components/dataviews-layout/index.js +5 -2
  16. package/build/components/dataviews-layout/index.js.map +1 -1
  17. package/build/components/dataviews-view-config/index.js +4 -3
  18. package/build/components/dataviews-view-config/index.js.map +1 -1
  19. package/build/dataform-controls/boolean.js +15 -1
  20. package/build/dataform-controls/boolean.js.map +1 -1
  21. package/build/dataform-controls/date.js +385 -0
  22. package/build/dataform-controls/date.js.map +1 -0
  23. package/build/dataform-controls/datetime.js +5 -84
  24. package/build/dataform-controls/datetime.js.map +1 -1
  25. package/build/dataform-controls/email.js +15 -1
  26. package/build/dataform-controls/email.js.map +1 -1
  27. package/build/dataform-controls/index.js +2 -0
  28. package/build/dataform-controls/index.js.map +1 -1
  29. package/build/dataform-controls/integer.js +23 -4
  30. package/build/dataform-controls/integer.js.map +1 -1
  31. package/build/dataform-controls/relative-date-control.js +109 -0
  32. package/build/dataform-controls/relative-date-control.js.map +1 -0
  33. package/build/dataform-controls/select.js +12 -5
  34. package/build/dataform-controls/select.js.map +1 -1
  35. package/build/dataform-controls/text.js +15 -1
  36. package/build/dataform-controls/text.js.map +1 -1
  37. package/build/dataviews-layouts/grid/index.js +40 -23
  38. package/build/dataviews-layouts/grid/index.js.map +1 -1
  39. package/build/dataviews-layouts/grid/preview-size-picker.js +39 -85
  40. package/build/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
  41. package/build/dataviews-layouts/list/index.js +7 -3
  42. package/build/dataviews-layouts/list/index.js.map +1 -1
  43. package/build/dataviews-layouts/table/column-primary.js +18 -3
  44. package/build/dataviews-layouts/table/column-primary.js.map +1 -1
  45. package/build/dataviews-layouts/table/index.js +57 -5
  46. package/build/dataviews-layouts/table/index.js.map +1 -1
  47. package/build/field-types/array.js +27 -18
  48. package/build/field-types/array.js.map +1 -1
  49. package/build/field-types/boolean.js +11 -7
  50. package/build/field-types/boolean.js.map +1 -1
  51. package/build/field-types/date.js +21 -12
  52. package/build/field-types/date.js.map +1 -1
  53. package/build/field-types/datetime.js +19 -10
  54. package/build/field-types/datetime.js.map +1 -1
  55. package/build/field-types/email.js +22 -18
  56. package/build/field-types/email.js.map +1 -1
  57. package/build/field-types/index.js +16 -6
  58. package/build/field-types/index.js.map +1 -1
  59. package/build/field-types/integer.js +22 -17
  60. package/build/field-types/integer.js.map +1 -1
  61. package/build/field-types/media.js +19 -10
  62. package/build/field-types/media.js.map +1 -1
  63. package/build/field-types/text.js +19 -10
  64. package/build/field-types/text.js.map +1 -1
  65. package/build/filter-and-sort-data-view.js +6 -4
  66. package/build/filter-and-sort-data-view.js.map +1 -1
  67. package/build/normalize-fields.js +4 -5
  68. package/build/normalize-fields.js.map +1 -1
  69. package/build/types.js.map +1 -1
  70. package/build/validation.js +15 -2
  71. package/build/validation.js.map +1 -1
  72. package/build-module/components/dataviews/index.js +15 -6
  73. package/build-module/components/dataviews/index.js.map +1 -1
  74. package/build-module/components/dataviews-context/index.js +3 -1
  75. package/build-module/components/dataviews-context/index.js.map +1 -1
  76. package/build-module/components/dataviews-filters/filter.js +15 -8
  77. package/build-module/components/dataviews-filters/filter.js.map +1 -1
  78. package/build-module/components/dataviews-filters/index.js +16 -5
  79. package/build-module/components/dataviews-filters/index.js.map +1 -1
  80. package/build-module/components/dataviews-filters/input-widget.js +7 -1
  81. package/build-module/components/dataviews-filters/input-widget.js.map +1 -1
  82. package/build-module/components/dataviews-filters/reset-filters.js +2 -2
  83. package/build-module/components/dataviews-filters/reset-filters.js.map +1 -1
  84. package/build-module/components/dataviews-layout/index.js +5 -2
  85. package/build-module/components/dataviews-layout/index.js.map +1 -1
  86. package/build-module/components/dataviews-view-config/index.js +4 -3
  87. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  88. package/build-module/dataform-controls/boolean.js +17 -2
  89. package/build-module/dataform-controls/boolean.js.map +1 -1
  90. package/build-module/dataform-controls/date.js +376 -0
  91. package/build-module/dataform-controls/date.js.map +1 -0
  92. package/build-module/dataform-controls/datetime.js +3 -84
  93. package/build-module/dataform-controls/datetime.js.map +1 -1
  94. package/build-module/dataform-controls/email.js +17 -2
  95. package/build-module/dataform-controls/email.js.map +1 -1
  96. package/build-module/dataform-controls/index.js +2 -0
  97. package/build-module/dataform-controls/index.js.map +1 -1
  98. package/build-module/dataform-controls/integer.js +24 -5
  99. package/build-module/dataform-controls/integer.js.map +1 -1
  100. package/build-module/dataform-controls/relative-date-control.js +100 -0
  101. package/build-module/dataform-controls/relative-date-control.js.map +1 -0
  102. package/build-module/dataform-controls/select.js +12 -5
  103. package/build-module/dataform-controls/select.js.map +1 -1
  104. package/build-module/dataform-controls/text.js +17 -2
  105. package/build-module/dataform-controls/text.js.map +1 -1
  106. package/build-module/dataviews-layouts/grid/index.js +41 -24
  107. package/build-module/dataviews-layouts/grid/index.js.map +1 -1
  108. package/build-module/dataviews-layouts/grid/preview-size-picker.js +40 -85
  109. package/build-module/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
  110. package/build-module/dataviews-layouts/list/index.js +7 -3
  111. package/build-module/dataviews-layouts/list/index.js.map +1 -1
  112. package/build-module/dataviews-layouts/table/column-primary.js +18 -3
  113. package/build-module/dataviews-layouts/table/column-primary.js.map +1 -1
  114. package/build-module/dataviews-layouts/table/index.js +58 -6
  115. package/build-module/dataviews-layouts/table/index.js.map +1 -1
  116. package/build-module/field-types/array.js +27 -18
  117. package/build-module/field-types/array.js.map +1 -1
  118. package/build-module/field-types/boolean.js +11 -7
  119. package/build-module/field-types/boolean.js.map +1 -1
  120. package/build-module/field-types/date.js +21 -12
  121. package/build-module/field-types/date.js.map +1 -1
  122. package/build-module/field-types/datetime.js +19 -10
  123. package/build-module/field-types/datetime.js.map +1 -1
  124. package/build-module/field-types/email.js +22 -18
  125. package/build-module/field-types/email.js.map +1 -1
  126. package/build-module/field-types/index.js +16 -6
  127. package/build-module/field-types/index.js.map +1 -1
  128. package/build-module/field-types/integer.js +22 -17
  129. package/build-module/field-types/integer.js.map +1 -1
  130. package/build-module/field-types/media.js +19 -10
  131. package/build-module/field-types/media.js.map +1 -1
  132. package/build-module/field-types/text.js +19 -10
  133. package/build-module/field-types/text.js.map +1 -1
  134. package/build-module/filter-and-sort-data-view.js +6 -4
  135. package/build-module/filter-and-sort-data-view.js.map +1 -1
  136. package/build-module/normalize-fields.js +4 -5
  137. package/build-module/normalize-fields.js.map +1 -1
  138. package/build-module/types.js.map +1 -1
  139. package/build-module/validation.js +15 -2
  140. package/build-module/validation.js.map +1 -1
  141. package/build-style/style-rtl.css +78 -43
  142. package/build-style/style.css +78 -43
  143. package/build-types/components/dataform/stories/index.story.d.ts +21 -0
  144. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  145. package/build-types/components/dataviews/index.d.ts +3 -2
  146. package/build-types/components/dataviews/index.d.ts.map +1 -1
  147. package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
  148. package/build-types/components/dataviews/stories/index.story.d.ts +16 -3
  149. package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
  150. package/build-types/components/dataviews-context/index.d.ts +4 -2
  151. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  152. package/build-types/components/dataviews-filters/filter.d.ts.map +1 -1
  153. package/build-types/components/dataviews-filters/index.d.ts.map +1 -1
  154. package/build-types/components/dataviews-filters/input-widget.d.ts.map +1 -1
  155. package/build-types/components/dataviews-filters/reset-filters.d.ts.map +1 -1
  156. package/build-types/components/dataviews-layout/index.d.ts.map +1 -1
  157. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  158. package/build-types/constants.d.ts +2 -2
  159. package/build-types/dataform-controls/boolean.d.ts.map +1 -1
  160. package/build-types/dataform-controls/date.d.ts +3 -0
  161. package/build-types/dataform-controls/date.d.ts.map +1 -0
  162. package/build-types/dataform-controls/datetime.d.ts.map +1 -1
  163. package/build-types/dataform-controls/email.d.ts.map +1 -1
  164. package/build-types/dataform-controls/index.d.ts.map +1 -1
  165. package/build-types/dataform-controls/integer.d.ts.map +1 -1
  166. package/build-types/dataform-controls/relative-date-control.d.ts +46 -0
  167. package/build-types/dataform-controls/relative-date-control.d.ts.map +1 -0
  168. package/build-types/dataform-controls/select.d.ts.map +1 -1
  169. package/build-types/dataform-controls/text.d.ts.map +1 -1
  170. package/build-types/dataviews-layouts/grid/index.d.ts +1 -1
  171. package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -1
  172. package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts +0 -1
  173. package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts.map +1 -1
  174. package/build-types/dataviews-layouts/index.d.ts +3 -3
  175. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
  176. package/build-types/dataviews-layouts/table/column-primary.d.ts.map +1 -1
  177. package/build-types/dataviews-layouts/table/index.d.ts +1 -1
  178. package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
  179. package/build-types/field-types/array.d.ts.map +1 -1
  180. package/build-types/field-types/boolean.d.ts +5 -4
  181. package/build-types/field-types/boolean.d.ts.map +1 -1
  182. package/build-types/field-types/date.d.ts +9 -5
  183. package/build-types/field-types/date.d.ts.map +1 -1
  184. package/build-types/field-types/datetime.d.ts +4 -3
  185. package/build-types/field-types/datetime.d.ts.map +1 -1
  186. package/build-types/field-types/email.d.ts +4 -3
  187. package/build-types/field-types/email.d.ts.map +1 -1
  188. package/build-types/field-types/index.d.ts.map +1 -1
  189. package/build-types/field-types/integer.d.ts +4 -3
  190. package/build-types/field-types/integer.d.ts.map +1 -1
  191. package/build-types/field-types/media.d.ts +4 -3
  192. package/build-types/field-types/media.d.ts.map +1 -1
  193. package/build-types/field-types/text.d.ts +4 -3
  194. package/build-types/field-types/text.d.ts.map +1 -1
  195. package/build-types/filter-and-sort-data-view.d.ts.map +1 -1
  196. package/build-types/normalize-fields.d.ts.map +1 -1
  197. package/build-types/types.d.ts +20 -7
  198. package/build-types/types.d.ts.map +1 -1
  199. package/build-types/validation.d.ts.map +1 -1
  200. package/build-wp/index.js +1561 -670
  201. package/package.json +15 -14
  202. package/src/components/dataform/stories/index.story.tsx +229 -2
  203. package/src/components/dataviews/index.tsx +30 -10
  204. package/src/components/dataviews/stories/fixtures.tsx +3 -1
  205. package/src/components/dataviews/stories/index.story.tsx +49 -29
  206. package/src/components/dataviews/stories/style.css +6 -0
  207. package/src/components/dataviews-context/index.ts +8 -2
  208. package/src/components/dataviews-filters/filter.tsx +17 -7
  209. package/src/components/dataviews-filters/index.tsx +17 -2
  210. package/src/components/dataviews-filters/input-widget.tsx +7 -1
  211. package/src/components/dataviews-filters/reset-filters.tsx +4 -2
  212. package/src/components/dataviews-filters/style.scss +8 -2
  213. package/src/components/dataviews-layout/index.tsx +3 -0
  214. package/src/components/dataviews-view-config/index.tsx +5 -3
  215. package/src/dataform-controls/boolean.tsx +19 -2
  216. package/src/dataform-controls/date.tsx +499 -0
  217. package/src/dataform-controls/datetime.tsx +5 -91
  218. package/src/dataform-controls/email.tsx +19 -2
  219. package/src/dataform-controls/index.tsx +2 -0
  220. package/src/dataform-controls/integer.tsx +30 -4
  221. package/src/dataform-controls/relative-date-control.tsx +106 -0
  222. package/src/dataform-controls/select.tsx +23 -13
  223. package/src/dataform-controls/style.scss +19 -2
  224. package/src/dataform-controls/text.tsx +19 -2
  225. package/src/dataviews-layouts/grid/index.tsx +46 -24
  226. package/src/dataviews-layouts/grid/preview-size-picker.tsx +48 -73
  227. package/src/dataviews-layouts/grid/style.scss +15 -28
  228. package/src/dataviews-layouts/list/index.tsx +7 -4
  229. package/src/dataviews-layouts/list/style.scss +3 -3
  230. package/src/dataviews-layouts/table/column-primary.tsx +29 -5
  231. package/src/dataviews-layouts/table/index.tsx +134 -42
  232. package/src/dataviews-layouts/table/style.scss +45 -1
  233. package/src/field-types/array.tsx +33 -21
  234. package/src/field-types/boolean.tsx +15 -9
  235. package/src/field-types/date.ts +51 -15
  236. package/src/field-types/datetime.tsx +19 -13
  237. package/src/field-types/email.tsx +26 -21
  238. package/src/field-types/index.tsx +18 -8
  239. package/src/field-types/integer.tsx +26 -22
  240. package/src/field-types/media.tsx +19 -13
  241. package/src/field-types/text.tsx +19 -13
  242. package/src/filter-and-sort-data-view.ts +11 -4
  243. package/src/normalize-fields.ts +4 -8
  244. package/src/test/dataviews.tsx +129 -0
  245. package/src/test/filter-and-sort-data-view.js +52 -2
  246. package/src/test/validation.ts +4 -15
  247. package/src/types.ts +28 -8
  248. package/src/validation.ts +30 -1
  249. package/tsconfig.json +1 -0
  250. package/tsconfig.tsbuildinfo +1 -1
@@ -1,11 +1,16 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import type {
5
10
  DataViewRenderFieldProps,
6
11
  SortDirection,
7
- ValidationContext,
8
12
  FieldTypeDefinition,
13
+ NormalizedField,
9
14
  } from '../types';
10
15
  import {
11
16
  OPERATOR_IS_ALL,
@@ -31,25 +36,6 @@ function sort( valueA: any, valueB: any, direction: SortDirection ) {
31
36
  : joinedB.localeCompare( joinedA );
32
37
  }
33
38
 
34
- function isValid( value: any, context?: ValidationContext ) {
35
- if ( ! Array.isArray( value ) ) {
36
- return false;
37
- }
38
-
39
- // Only allow strings for now. Can be extended to other types in the future.
40
- if ( ! value.every( ( v ) => typeof v === 'string' ) ) {
41
- return false;
42
- }
43
-
44
- if ( context?.elements ) {
45
- const validValues = context.elements.map( ( f ) => f.value );
46
- if ( ! value.every( ( v ) => validValues.includes( v ) ) ) {
47
- return false;
48
- }
49
- }
50
- return true;
51
- }
52
-
53
39
  function render( { item, field }: DataViewRenderFieldProps< any > ) {
54
40
  const value = field.getValue( { item } ) || [];
55
41
  return value.join( ', ' );
@@ -57,7 +43,33 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) {
57
43
 
58
44
  const arrayFieldType: FieldTypeDefinition< any > = {
59
45
  sort,
60
- isValid,
46
+ isValid: {
47
+ custom: ( item: any, field: NormalizedField< any > ) => {
48
+ const value = field.getValue( { item } );
49
+
50
+ if (
51
+ ! [ undefined, '', null ].includes( value ) &&
52
+ ! Array.isArray( value )
53
+ ) {
54
+ return __( 'Value must be an array.' );
55
+ }
56
+
57
+ // Only allow strings for now. Can be extended to other types in the future.
58
+ if ( ! value.every( ( v: any ) => typeof v === 'string' ) ) {
59
+ return __( 'Every value must be a string.' );
60
+ }
61
+
62
+ if ( field?.elements ) {
63
+ const validValues = field.elements.map( ( f ) => f.value );
64
+ if (
65
+ ! value.every( ( v: any ) => validValues.includes( v ) )
66
+ ) {
67
+ return __( 'Value must be one of the elements.' );
68
+ }
69
+ }
70
+ return null;
71
+ },
72
+ },
61
73
  Edit: null, // Not implemented yet
62
74
  render,
63
75
  enableSorting: true,
@@ -10,6 +10,7 @@ import type {
10
10
  DataViewRenderFieldProps,
11
11
  SortDirection,
12
12
  FieldTypeDefinition,
13
+ NormalizedField,
13
14
  } from '../types';
14
15
  import { renderFromElements } from '../utils';
15
16
  import { OPERATOR_IS, OPERATOR_IS_NOT } from '../constants';
@@ -31,17 +32,22 @@ function sort( a: any, b: any, direction: SortDirection ) {
31
32
  return boolA ? -1 : 1;
32
33
  }
33
34
 
34
- function isValid( value: any ) {
35
- if ( ! [ true, false, undefined ].includes( value ) ) {
36
- return false;
37
- }
38
-
39
- return true;
40
- }
41
-
42
35
  export default {
43
36
  sort,
44
- isValid,
37
+ isValid: {
38
+ custom: ( item: any, field: NormalizedField< any > ) => {
39
+ const value = field.getValue( { item } );
40
+
41
+ if (
42
+ ! [ undefined, '', null ].includes( value ) &&
43
+ ! [ true, false ].includes( value )
44
+ ) {
45
+ return __( 'Value must be true, false, or undefined' );
46
+ }
47
+
48
+ return null;
49
+ },
50
+ },
45
51
  Edit: 'boolean',
46
52
  render: ( { item, field }: DataViewRenderFieldProps< any > ) => {
47
53
  if ( field.elements ) {
@@ -2,6 +2,7 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { dateI18n, getDate, getSettings } from '@wordpress/date';
5
+ import { __ } from '@wordpress/i18n';
5
6
 
6
7
  /**
7
8
  * Internal dependencies
@@ -9,10 +10,21 @@ import { dateI18n, getDate, getSettings } from '@wordpress/date';
9
10
  import type {
10
11
  DataViewRenderFieldProps,
11
12
  SortDirection,
12
- ValidationContext,
13
+ NormalizedField,
13
14
  FieldTypeDefinition,
14
15
  } from '../types';
15
16
  import { renderFromElements } from '../utils';
17
+ import {
18
+ OPERATOR_ON,
19
+ OPERATOR_NOT_ON,
20
+ OPERATOR_BEFORE,
21
+ OPERATOR_AFTER,
22
+ OPERATOR_BEFORE_INC,
23
+ OPERATOR_AFTER_INC,
24
+ OPERATOR_IN_THE_PAST,
25
+ OPERATOR_OVER,
26
+ OPERATOR_BETWEEN,
27
+ } from '../constants';
16
28
 
17
29
  const getFormattedDate = ( dateToDisplay: string | null ) =>
18
30
  dateI18n( getSettings().formats.date, getDate( dateToDisplay ) );
@@ -24,21 +36,22 @@ function sort( a: any, b: any, direction: SortDirection ) {
24
36
  return direction === 'asc' ? timeA - timeB : timeB - timeA;
25
37
  }
26
38
 
27
- function isValid( value: any, context?: ValidationContext ) {
28
- if ( context?.elements ) {
29
- const validValues = context?.elements.map( ( f ) => f.value );
30
- if ( ! validValues.includes( value ) ) {
31
- return false;
32
- }
33
- }
34
-
35
- return true;
36
- }
37
-
38
39
  export default {
39
40
  sort,
40
- isValid,
41
- Edit: null,
41
+ Edit: 'date',
42
+ isValid: {
43
+ custom: ( item: any, field: NormalizedField< any > ) => {
44
+ const value = field.getValue( { item } );
45
+ if ( field?.elements ) {
46
+ const validValues = field.elements.map( ( f ) => f.value );
47
+ if ( ! validValues.includes( value ) ) {
48
+ return __( 'Value must be one of the elements.' );
49
+ }
50
+ }
51
+
52
+ return null;
53
+ },
54
+ },
42
55
  render: ( { item, field }: DataViewRenderFieldProps< any > ) => {
43
56
  if ( field.elements ) {
44
57
  return renderFromElements( { item, field } );
@@ -52,5 +65,28 @@ export default {
52
65
  return getFormattedDate( value );
53
66
  },
54
67
  enableSorting: true,
55
- filterBy: false,
68
+ filterBy: {
69
+ defaultOperators: [
70
+ OPERATOR_ON,
71
+ OPERATOR_NOT_ON,
72
+ OPERATOR_BEFORE,
73
+ OPERATOR_AFTER,
74
+ OPERATOR_BEFORE_INC,
75
+ OPERATOR_AFTER_INC,
76
+ OPERATOR_IN_THE_PAST,
77
+ OPERATOR_OVER,
78
+ OPERATOR_BETWEEN,
79
+ ],
80
+ validOperators: [
81
+ OPERATOR_ON,
82
+ OPERATOR_NOT_ON,
83
+ OPERATOR_BEFORE,
84
+ OPERATOR_AFTER,
85
+ OPERATOR_BEFORE_INC,
86
+ OPERATOR_AFTER_INC,
87
+ OPERATOR_IN_THE_PAST,
88
+ OPERATOR_OVER,
89
+ OPERATOR_BETWEEN,
90
+ ],
91
+ },
56
92
  } satisfies FieldTypeDefinition< any >;
@@ -1,10 +1,15 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import type {
5
10
  DataViewRenderFieldProps,
6
11
  SortDirection,
7
- ValidationContext,
12
+ NormalizedField,
8
13
  FieldTypeDefinition,
9
14
  } from '../types';
10
15
  import { renderFromElements } from '../utils';
@@ -26,20 +31,21 @@ function sort( a: any, b: any, direction: SortDirection ) {
26
31
  return direction === 'asc' ? timeA - timeB : timeB - timeA;
27
32
  }
28
33
 
29
- function isValid( value: any, context?: ValidationContext ) {
30
- if ( context?.elements ) {
31
- const validValues = context?.elements.map( ( f ) => f.value );
32
- if ( ! validValues.includes( value ) ) {
33
- return false;
34
- }
35
- }
36
-
37
- return true;
38
- }
39
-
40
34
  export default {
41
35
  sort,
42
- isValid,
36
+ isValid: {
37
+ custom: ( item: any, field: NormalizedField< any > ) => {
38
+ const value = field.getValue( { item } );
39
+ if ( field?.elements ) {
40
+ const validValues = field.elements.map( ( f ) => f.value );
41
+ if ( ! validValues.includes( value ) ) {
42
+ return __( 'Value must be one of the elements.' );
43
+ }
44
+ }
45
+
46
+ return null;
47
+ },
48
+ },
43
49
  Edit: 'datetime',
44
50
  render: ( { item, field }: DataViewRenderFieldProps< any > ) => {
45
51
  return field.elements
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { isEmail } from '@wordpress/url';
4
+ import { __ } from '@wordpress/i18n';
5
5
 
6
6
  /**
7
7
  * Internal dependencies
@@ -9,7 +9,7 @@ import { isEmail } from '@wordpress/url';
9
9
  import type {
10
10
  DataViewRenderFieldProps,
11
11
  SortDirection,
12
- ValidationContext,
12
+ NormalizedField,
13
13
  FieldTypeDefinition,
14
14
  } from '../types';
15
15
  import { renderFromElements } from '../utils';
@@ -31,29 +31,34 @@ function sort( valueA: any, valueB: any, direction: SortDirection ) {
31
31
  : valueB.localeCompare( valueA );
32
32
  }
33
33
 
34
- function isValid( value: any, context?: ValidationContext ) {
35
- // TODO: this implicitly means the value is required.
36
- if ( value === '' ) {
37
- return false;
38
- }
34
+ // Email validation regex based on HTML5 spec
35
+ // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
36
+ const emailRegex =
37
+ /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
39
38
 
40
- if ( ! isEmail( value ) ) {
41
- return false;
42
- }
39
+ export default {
40
+ sort,
41
+ isValid: {
42
+ custom: ( item: any, field: NormalizedField< any > ) => {
43
+ const value = field.getValue( { item } );
43
44
 
44
- if ( context?.elements ) {
45
- const validValues = context?.elements?.map( ( f ) => f.value );
46
- if ( ! validValues.includes( value ) ) {
47
- return false;
48
- }
49
- }
45
+ if (
46
+ ! [ undefined, '', null ].includes( value ) &&
47
+ ! emailRegex.test( value )
48
+ ) {
49
+ return __( 'Value must be a valid email address.' );
50
+ }
50
51
 
51
- return true;
52
- }
52
+ if ( field.elements ) {
53
+ const validValues = field.elements.map( ( f ) => f.value );
54
+ if ( ! validValues.includes( value ) ) {
55
+ return __( 'Value must be one of the elements.' );
56
+ }
57
+ }
53
58
 
54
- export default {
55
- sort,
56
- isValid,
59
+ return null;
60
+ },
61
+ },
57
62
  Edit: 'email',
58
63
  render: ( { item, field }: DataViewRenderFieldProps< any > ) => {
59
64
  return field.elements
@@ -1,12 +1,17 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import type {
5
10
  DataViewRenderFieldProps,
11
+ NormalizedField,
6
12
  FieldType,
7
13
  FieldTypeDefinition,
8
14
  SortDirection,
9
- ValidationContext,
10
15
  } from '../types';
11
16
  import { default as email } from './email';
12
17
  import { default as integer } from './integer';
@@ -72,15 +77,20 @@ export default function getFieldTypeDefinition< Item >(
72
77
  ? a.localeCompare( b )
73
78
  : b.localeCompare( a );
74
79
  },
75
- isValid: ( value: any, context?: ValidationContext ) => {
76
- if ( context?.elements ) {
77
- const validValues = context?.elements?.map( ( f ) => f.value );
78
- if ( ! validValues.includes( value ) ) {
79
- return false;
80
+ isValid: {
81
+ custom: ( item: any, field: NormalizedField< any > ) => {
82
+ if ( field?.elements ) {
83
+ const value = field.getValue( { item } );
84
+ const validValues = field?.elements?.map(
85
+ ( f ) => f.value
86
+ );
87
+ if ( ! validValues.includes( value ) ) {
88
+ return __( 'Value must be one of the elements.' );
89
+ }
80
90
  }
81
- }
82
91
 
83
- return true;
92
+ return null;
93
+ },
84
94
  },
85
95
  Edit: null,
86
96
  render: ( { item, field }: DataViewRenderFieldProps< Item > ) => {
@@ -1,10 +1,15 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import type {
5
10
  DataViewRenderFieldProps,
6
11
  SortDirection,
7
- ValidationContext,
12
+ NormalizedField,
8
13
  FieldTypeDefinition,
9
14
  } from '../types';
10
15
  import { renderFromElements } from '../utils';
@@ -26,29 +31,28 @@ function sort( a: any, b: any, direction: SortDirection ) {
26
31
  return direction === 'asc' ? a - b : b - a;
27
32
  }
28
33
 
29
- function isValid( value: any, context?: ValidationContext ) {
30
- // TODO: this implicitly means the value is required.
31
- if ( value === '' ) {
32
- return false;
33
- }
34
-
35
- if ( ! Number.isInteger( Number( value ) ) ) {
36
- return false;
37
- }
38
-
39
- if ( context?.elements ) {
40
- const validValues = context?.elements.map( ( f ) => f.value );
41
- if ( ! validValues.includes( Number( value ) ) ) {
42
- return false;
43
- }
44
- }
45
-
46
- return true;
47
- }
48
-
49
34
  export default {
50
35
  sort,
51
- isValid,
36
+ isValid: {
37
+ custom: ( item: any, field: NormalizedField< any > ) => {
38
+ const value = field.getValue( { item } );
39
+ if (
40
+ ! [ undefined, '', null ].includes( value ) &&
41
+ ! Number.isInteger( value )
42
+ ) {
43
+ return __( 'Value must be an integer.' );
44
+ }
45
+
46
+ if ( field?.elements ) {
47
+ const validValues = field.elements.map( ( f ) => f.value );
48
+ if ( ! validValues.includes( Number( value ) ) ) {
49
+ return __( 'Value must be one of the elements.' );
50
+ }
51
+ }
52
+
53
+ return null;
54
+ },
55
+ },
52
56
  Edit: 'integer',
53
57
  render: ( { item, field }: DataViewRenderFieldProps< any > ) => {
54
58
  return field.elements
@@ -1,26 +1,32 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
- import type { ValidationContext, FieldTypeDefinition } from '../types';
9
+ import type { NormalizedField, FieldTypeDefinition } from '../types';
5
10
 
6
11
  function sort() {
7
12
  return 0;
8
13
  }
9
14
 
10
- function isValid( value: any, context?: ValidationContext ) {
11
- if ( context?.elements ) {
12
- const validValues = context?.elements.map( ( f ) => f.value );
13
- if ( ! validValues.includes( value ) ) {
14
- return false;
15
- }
16
- }
17
-
18
- return true;
19
- }
20
-
21
15
  export default {
22
16
  sort,
23
- isValid,
17
+ isValid: {
18
+ custom: ( item: any, field: NormalizedField< any > ) => {
19
+ const value = field.getValue( { item } );
20
+ if ( field?.elements ) {
21
+ const validValues = field.elements.map( ( f ) => f.value );
22
+ if ( ! validValues.includes( value ) ) {
23
+ return __( 'Value must be one of the elements.' );
24
+ }
25
+ }
26
+
27
+ return null;
28
+ },
29
+ },
24
30
  Edit: null,
25
31
  render: () => null,
26
32
  enableSorting: false,
@@ -1,10 +1,15 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import type {
5
10
  DataViewRenderFieldProps,
6
11
  SortDirection,
7
- ValidationContext,
12
+ NormalizedField,
8
13
  FieldTypeDefinition,
9
14
  } from '../types';
10
15
  import { renderFromElements } from '../utils';
@@ -26,20 +31,21 @@ function sort( valueA: any, valueB: any, direction: SortDirection ) {
26
31
  : valueB.localeCompare( valueA );
27
32
  }
28
33
 
29
- function isValid( value: any, context?: ValidationContext ) {
30
- if ( context?.elements ) {
31
- const validValues = context?.elements?.map( ( f ) => f.value );
32
- if ( ! validValues.includes( value ) ) {
33
- return false;
34
- }
35
- }
36
-
37
- return true;
38
- }
39
-
40
34
  export default {
41
35
  sort,
42
- isValid,
36
+ isValid: {
37
+ custom: ( item: any, field: NormalizedField< any > ) => {
38
+ const value = field.getValue( { item } );
39
+ if ( field?.elements ) {
40
+ const validValues = field.elements.map( ( f ) => f.value );
41
+ if ( ! validValues.includes( value ) ) {
42
+ return __( 'Value must be one of the elements.' );
43
+ }
44
+ }
45
+
46
+ return null;
47
+ },
48
+ },
43
49
  Edit: 'text',
44
50
  render: ( { item, field }: DataViewRenderFieldProps< any > ) => {
45
51
  return field.elements
@@ -98,10 +98,17 @@ export function filterSortAndPaginate< Item >(
98
98
  filteredData = filteredData.filter( ( item ) => {
99
99
  return _fields
100
100
  .filter( ( field ) => field.enableGlobalSearch )
101
- .map( ( field ) => {
102
- return normalizeSearchInput( field.getValue( { item } ) );
103
- } )
104
- .some( ( field ) => field.includes( normalizedSearch ) );
101
+ .some( ( field ) => {
102
+ const fieldValue = field.getValue( { item } );
103
+ const values = Array.isArray( fieldValue )
104
+ ? fieldValue
105
+ : [ fieldValue ];
106
+ return values.some( ( value ) =>
107
+ normalizeSearchInput( String( value ) ).includes(
108
+ normalizedSearch
109
+ )
110
+ );
111
+ } );
105
112
  } );
106
113
  }
107
114
 
@@ -139,14 +139,10 @@ export function normalizeFields< Item >(
139
139
  );
140
140
  };
141
141
 
142
- const isValid =
143
- field.isValid ??
144
- function isValid( item, context ) {
145
- return fieldTypeDefinition.isValid(
146
- getValue( { item } ),
147
- context
148
- );
149
- };
142
+ const isValid = {
143
+ ...fieldTypeDefinition.isValid,
144
+ ...field.isValid,
145
+ };
150
146
 
151
147
  const Edit = getControl( field, fieldTypeDefinition );
152
148