@wordpress/dataviews 9.0.1-next.6f42e1382.0 → 9.1.1-next.f56bd8138.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.
- package/CHANGELOG.md +22 -2
- package/README.md +107 -11
- package/build/components/dataviews-filters/input-widget.js +48 -4
- package/build/components/dataviews-filters/input-widget.js.map +1 -1
- package/build/components/dataviews-view-config/index.js +22 -3
- package/build/components/dataviews-view-config/index.js.map +1 -1
- package/build/dataform-controls/array.js +117 -29
- package/build/dataform-controls/array.js.map +1 -1
- package/build/dataform-controls/checkbox.js +31 -20
- package/build/dataform-controls/checkbox.js.map +1 -1
- package/build/dataform-controls/color.js +29 -24
- package/build/dataform-controls/color.js.map +1 -1
- package/build/dataform-controls/date.js +32 -24
- package/build/dataform-controls/date.js.map +1 -1
- package/build/dataform-controls/datetime.js +133 -19
- package/build/dataform-controls/datetime.js.map +1 -1
- package/build/dataform-controls/email.js +7 -1
- package/build/dataform-controls/email.js.map +1 -1
- package/build/dataform-controls/index.js +23 -0
- package/build/dataform-controls/index.js.map +1 -1
- package/build/dataform-controls/integer.js +47 -34
- package/build/dataform-controls/integer.js.map +1 -1
- package/build/dataform-controls/radio.js +42 -9
- package/build/dataform-controls/radio.js.map +1 -1
- package/build/dataform-controls/relative-date-control.js +6 -10
- package/build/dataform-controls/relative-date-control.js.map +1 -1
- package/build/dataform-controls/select.js +41 -10
- package/build/dataform-controls/select.js.map +1 -1
- package/build/dataform-controls/telephone.js +7 -1
- package/build/dataform-controls/telephone.js.map +1 -1
- package/build/dataform-controls/text.js +14 -2
- package/build/dataform-controls/text.js.map +1 -1
- package/build/dataform-controls/textarea.js +33 -20
- package/build/dataform-controls/textarea.js.map +1 -1
- package/build/dataform-controls/toggle-group.js +36 -6
- package/build/dataform-controls/toggle-group.js.map +1 -1
- package/build/dataform-controls/toggle.js +33 -22
- package/build/dataform-controls/toggle.js.map +1 -1
- package/build/dataform-controls/url.js +7 -1
- package/build/dataform-controls/url.js.map +1 -1
- package/build/dataform-controls/utils/validated-input.js +34 -32
- package/build/dataform-controls/utils/validated-input.js.map +1 -1
- package/build/dataforms-layouts/panel/dropdown.js +10 -14
- package/build/dataforms-layouts/panel/dropdown.js.map +1 -1
- package/build/dataforms-layouts/panel/index.js +24 -11
- package/build/dataforms-layouts/panel/index.js.map +1 -1
- package/build/dataforms-layouts/panel/modal.js +22 -27
- package/build/dataforms-layouts/panel/modal.js.map +1 -1
- package/build/dataforms-layouts/panel/summary-button.js +67 -0
- package/build/dataforms-layouts/panel/summary-button.js.map +1 -0
- package/build/field-types/array.js +0 -6
- package/build/field-types/array.js.map +1 -1
- package/build/index.js +7 -0
- package/build/index.js.map +1 -1
- package/build/normalize-fields.js +17 -0
- package/build/normalize-fields.js.map +1 -1
- package/build/types.js.map +1 -1
- package/build/validation.js +18 -1
- package/build/validation.js.map +1 -1
- package/build-module/components/dataviews-filters/input-widget.js +48 -4
- package/build-module/components/dataviews-filters/input-widget.js.map +1 -1
- package/build-module/components/dataviews-view-config/index.js +22 -3
- package/build-module/components/dataviews-view-config/index.js.map +1 -1
- package/build-module/dataform-controls/array.js +120 -32
- package/build-module/dataform-controls/array.js.map +1 -1
- package/build-module/dataform-controls/checkbox.js +31 -21
- package/build-module/dataform-controls/checkbox.js.map +1 -1
- package/build-module/dataform-controls/color.js +28 -24
- package/build-module/dataform-controls/color.js.map +1 -1
- package/build-module/dataform-controls/date.js +32 -24
- package/build-module/dataform-controls/date.js.map +1 -1
- package/build-module/dataform-controls/datetime.js +135 -21
- package/build-module/dataform-controls/datetime.js.map +1 -1
- package/build-module/dataform-controls/email.js +7 -1
- package/build-module/dataform-controls/email.js.map +1 -1
- package/build-module/dataform-controls/index.js +23 -0
- package/build-module/dataform-controls/index.js.map +1 -1
- package/build-module/dataform-controls/integer.js +46 -34
- package/build-module/dataform-controls/integer.js.map +1 -1
- package/build-module/dataform-controls/radio.js +44 -11
- package/build-module/dataform-controls/radio.js.map +1 -1
- package/build-module/dataform-controls/relative-date-control.js +6 -10
- package/build-module/dataform-controls/relative-date-control.js.map +1 -1
- package/build-module/dataform-controls/select.js +43 -12
- package/build-module/dataform-controls/select.js.map +1 -1
- package/build-module/dataform-controls/telephone.js +7 -1
- package/build-module/dataform-controls/telephone.js.map +1 -1
- package/build-module/dataform-controls/text.js +14 -2
- package/build-module/dataform-controls/text.js.map +1 -1
- package/build-module/dataform-controls/textarea.js +32 -20
- package/build-module/dataform-controls/textarea.js.map +1 -1
- package/build-module/dataform-controls/toggle-group.js +38 -8
- package/build-module/dataform-controls/toggle-group.js.map +1 -1
- package/build-module/dataform-controls/toggle.js +33 -23
- package/build-module/dataform-controls/toggle.js.map +1 -1
- package/build-module/dataform-controls/url.js +7 -1
- package/build-module/dataform-controls/url.js.map +1 -1
- package/build-module/dataform-controls/utils/validated-input.js +34 -33
- package/build-module/dataform-controls/utils/validated-input.js.map +1 -1
- package/build-module/dataforms-layouts/panel/dropdown.js +10 -15
- package/build-module/dataforms-layouts/panel/dropdown.js.map +1 -1
- package/build-module/dataforms-layouts/panel/index.js +24 -11
- package/build-module/dataforms-layouts/panel/index.js.map +1 -1
- package/build-module/dataforms-layouts/panel/modal.js +22 -28
- package/build-module/dataforms-layouts/panel/modal.js.map +1 -1
- package/build-module/dataforms-layouts/panel/summary-button.js +60 -0
- package/build-module/dataforms-layouts/panel/summary-button.js.map +1 -0
- package/build-module/field-types/array.js +0 -6
- package/build-module/field-types/array.js.map +1 -1
- package/build-module/index.js +1 -0
- package/build-module/index.js.map +1 -1
- package/build-module/normalize-fields.js +15 -0
- package/build-module/normalize-fields.js.map +1 -1
- package/build-module/types.js.map +1 -1
- package/build-module/validation.js +18 -1
- package/build-module/validation.js.map +1 -1
- package/build-types/components/dataform/stories/index.story.d.ts +3 -0
- package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
- package/build-types/components/dataviews/stories/fixtures.d.ts +4 -2
- package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/input-widget.d.ts.map +1 -1
- package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
- package/build-types/dataform-controls/array.d.ts.map +1 -1
- package/build-types/dataform-controls/checkbox.d.ts.map +1 -1
- package/build-types/dataform-controls/color.d.ts.map +1 -1
- package/build-types/dataform-controls/date.d.ts.map +1 -1
- package/build-types/dataform-controls/datetime.d.ts.map +1 -1
- package/build-types/dataform-controls/email.d.ts.map +1 -1
- package/build-types/dataform-controls/index.d.ts +1 -1
- package/build-types/dataform-controls/index.d.ts.map +1 -1
- package/build-types/dataform-controls/integer.d.ts.map +1 -1
- package/build-types/dataform-controls/radio.d.ts.map +1 -1
- package/build-types/dataform-controls/relative-date-control.d.ts +6 -5
- package/build-types/dataform-controls/relative-date-control.d.ts.map +1 -1
- package/build-types/dataform-controls/select.d.ts.map +1 -1
- package/build-types/dataform-controls/telephone.d.ts.map +1 -1
- package/build-types/dataform-controls/text.d.ts +1 -1
- package/build-types/dataform-controls/text.d.ts.map +1 -1
- package/build-types/dataform-controls/textarea.d.ts +1 -1
- package/build-types/dataform-controls/textarea.d.ts.map +1 -1
- package/build-types/dataform-controls/toggle-group.d.ts.map +1 -1
- package/build-types/dataform-controls/toggle.d.ts.map +1 -1
- package/build-types/dataform-controls/url.d.ts.map +1 -1
- package/build-types/dataform-controls/utils/validated-input.d.ts +4 -4
- package/build-types/dataform-controls/utils/validated-input.d.ts.map +1 -1
- package/build-types/dataforms-layouts/panel/dropdown.d.ts +2 -1
- package/build-types/dataforms-layouts/panel/dropdown.d.ts.map +1 -1
- package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
- package/build-types/dataforms-layouts/panel/modal.d.ts +2 -1
- package/build-types/dataforms-layouts/panel/modal.d.ts.map +1 -1
- package/build-types/dataforms-layouts/panel/summary-button.d.ts +15 -0
- package/build-types/dataforms-layouts/panel/summary-button.d.ts.map +1 -0
- package/build-types/field-types/array.d.ts.map +1 -1
- package/build-types/field-types/stories/index.story.d.ts.map +1 -1
- package/build-types/index.d.ts +1 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/normalize-fields.d.ts +3 -0
- package/build-types/normalize-fields.d.ts.map +1 -1
- package/build-types/types.d.ts +68 -4
- package/build-types/types.d.ts.map +1 -1
- package/build-types/validation.d.ts.map +1 -1
- package/build-wp/index.js +2009 -1489
- package/package.json +16 -15
- package/src/components/dataform/stories/index.story.tsx +509 -8
- package/src/components/dataviews/stories/fixtures.tsx +99 -41
- package/src/components/dataviews/stories/index.story.tsx +1 -1
- package/src/components/dataviews-filters/input-widget.tsx +44 -5
- package/src/components/dataviews-picker/stories/index.story.tsx +1 -1
- package/src/components/dataviews-view-config/index.tsx +18 -3
- package/src/dataform-controls/array.tsx +139 -44
- package/src/dataform-controls/checkbox.tsx +41 -24
- package/src/dataform-controls/color.tsx +33 -24
- package/src/dataform-controls/date.tsx +47 -21
- package/src/dataform-controls/datetime.tsx +171 -23
- package/src/dataform-controls/email.tsx +9 -1
- package/src/dataform-controls/index.tsx +26 -0
- package/src/dataform-controls/integer.tsx +82 -49
- package/src/dataform-controls/radio.tsx +53 -11
- package/src/dataform-controls/relative-date-control.tsx +11 -10
- package/src/dataform-controls/select.tsx +53 -10
- package/src/dataform-controls/telephone.tsx +9 -1
- package/src/dataform-controls/text.tsx +18 -1
- package/src/dataform-controls/textarea.tsx +38 -24
- package/src/dataform-controls/toggle-group.tsx +50 -10
- package/src/dataform-controls/toggle.tsx +41 -24
- package/src/dataform-controls/url.tsx +9 -1
- package/src/dataform-controls/utils/validated-input.tsx +50 -50
- package/src/dataforms-layouts/panel/dropdown.tsx +12 -23
- package/src/dataforms-layouts/panel/index.tsx +39 -16
- package/src/dataforms-layouts/panel/modal.tsx +24 -30
- package/src/dataforms-layouts/panel/summary-button.tsx +92 -0
- package/src/field-types/array.tsx +0 -8
- package/src/field-types/stories/index.story.tsx +89 -1
- package/src/index.ts +1 -0
- package/src/normalize-fields.ts +18 -0
- package/src/test/filter-and-sort-data-view.js +148 -138
- package/src/test/normalize-fields.ts +114 -0
- package/src/test/validation.ts +192 -0
- package/src/types.ts +75 -4
- package/src/validation.ts +30 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import deepMerge from 'deepmerge';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* WordPress dependencies
|
|
3
8
|
*/
|
|
4
9
|
import { privateApis } from '@wordpress/components';
|
|
5
|
-
import { useState } from '@wordpress/element';
|
|
10
|
+
import { useState, useCallback } from '@wordpress/element';
|
|
6
11
|
|
|
7
12
|
/**
|
|
8
13
|
* Internal dependencies
|
|
@@ -18,7 +23,7 @@ export default function Checkbox< Item >( {
|
|
|
18
23
|
data,
|
|
19
24
|
hideLabelFromVision,
|
|
20
25
|
}: DataFormControlProps< Item > ) {
|
|
21
|
-
const {
|
|
26
|
+
const { getValue, setValue, label, description } = field;
|
|
22
27
|
const [ customValidity, setCustomValidity ] =
|
|
23
28
|
useState<
|
|
24
29
|
React.ComponentProps<
|
|
@@ -26,36 +31,48 @@ export default function Checkbox< Item >( {
|
|
|
26
31
|
>[ 'customValidity' ]
|
|
27
32
|
>( undefined );
|
|
28
33
|
|
|
34
|
+
const onChangeControl = useCallback( () => {
|
|
35
|
+
onChange(
|
|
36
|
+
setValue( { item: data, value: ! getValue( { item: data } ) } )
|
|
37
|
+
);
|
|
38
|
+
}, [ data, getValue, onChange, setValue ] );
|
|
39
|
+
|
|
40
|
+
const onValidateControl = useCallback(
|
|
41
|
+
( newValue: any ) => {
|
|
42
|
+
const message = field.isValid?.custom?.(
|
|
43
|
+
deepMerge(
|
|
44
|
+
data,
|
|
45
|
+
setValue( {
|
|
46
|
+
item: data,
|
|
47
|
+
value: newValue,
|
|
48
|
+
} ) as Partial< Item >
|
|
49
|
+
),
|
|
50
|
+
field
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if ( message ) {
|
|
54
|
+
setCustomValidity( {
|
|
55
|
+
type: 'invalid',
|
|
56
|
+
message,
|
|
57
|
+
} );
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setCustomValidity( undefined );
|
|
62
|
+
},
|
|
63
|
+
[ data, field, setValue ]
|
|
64
|
+
);
|
|
65
|
+
|
|
29
66
|
return (
|
|
30
67
|
<ValidatedCheckboxControl
|
|
31
68
|
required={ !! field.isValid?.required }
|
|
32
|
-
onValidate={
|
|
33
|
-
const message = field.isValid?.custom?.(
|
|
34
|
-
{
|
|
35
|
-
...data,
|
|
36
|
-
[ id ]: newValue,
|
|
37
|
-
},
|
|
38
|
-
field
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
if ( message ) {
|
|
42
|
-
setCustomValidity( {
|
|
43
|
-
type: 'invalid',
|
|
44
|
-
message,
|
|
45
|
-
} );
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
setCustomValidity( undefined );
|
|
50
|
-
} }
|
|
69
|
+
onValidate={ onValidateControl }
|
|
51
70
|
customValidity={ customValidity }
|
|
52
71
|
hidden={ hideLabelFromVision }
|
|
53
72
|
label={ label }
|
|
54
73
|
help={ description }
|
|
55
74
|
checked={ getValue( { item: data } ) }
|
|
56
|
-
onChange={
|
|
57
|
-
onChange( { [ id ]: ! getValue( { item: data } ) } )
|
|
58
|
-
}
|
|
75
|
+
onChange={ onChangeControl }
|
|
59
76
|
/>
|
|
60
77
|
);
|
|
61
78
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { colord } from 'colord';
|
|
5
|
+
import deepMerge from 'deepmerge';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* WordPress dependencies
|
|
@@ -75,7 +76,7 @@ export default function Color< Item >( {
|
|
|
75
76
|
onChange,
|
|
76
77
|
hideLabelFromVision,
|
|
77
78
|
}: DataFormControlProps< Item > ) {
|
|
78
|
-
const {
|
|
79
|
+
const { label, placeholder, description, setValue } = field;
|
|
79
80
|
const value = field.getValue( { item: data } ) || '';
|
|
80
81
|
const [ customValidity, setCustomValidity ] =
|
|
81
82
|
useState<
|
|
@@ -86,40 +87,48 @@ export default function Color< Item >( {
|
|
|
86
87
|
|
|
87
88
|
const handleColorChange = useCallback(
|
|
88
89
|
( colorObject: any ) => {
|
|
89
|
-
onChange( {
|
|
90
|
+
onChange( setValue( { item: data, value: colorObject.toHex() } ) );
|
|
90
91
|
},
|
|
91
|
-
[
|
|
92
|
+
[ data, onChange, setValue ]
|
|
92
93
|
);
|
|
93
94
|
|
|
94
95
|
const handleInputChange = useCallback(
|
|
95
96
|
( newValue: string | undefined ) => {
|
|
96
|
-
onChange( {
|
|
97
|
+
onChange( setValue( { item: data, value: newValue || '' } ) );
|
|
97
98
|
},
|
|
98
|
-
[
|
|
99
|
+
[ data, onChange, setValue ]
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const onValidateControl = useCallback(
|
|
103
|
+
( newValue: any ) => {
|
|
104
|
+
const message = field.isValid?.custom?.(
|
|
105
|
+
deepMerge(
|
|
106
|
+
data,
|
|
107
|
+
setValue( {
|
|
108
|
+
item: data,
|
|
109
|
+
value: newValue,
|
|
110
|
+
} ) as Partial< Item >
|
|
111
|
+
),
|
|
112
|
+
field
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if ( message ) {
|
|
116
|
+
setCustomValidity( {
|
|
117
|
+
type: 'invalid',
|
|
118
|
+
message,
|
|
119
|
+
} );
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
setCustomValidity( undefined );
|
|
124
|
+
},
|
|
125
|
+
[ data, field, setValue ]
|
|
99
126
|
);
|
|
100
127
|
|
|
101
128
|
return (
|
|
102
129
|
<ValidatedInputControl
|
|
103
130
|
required={ !! field.isValid?.required }
|
|
104
|
-
onValidate={
|
|
105
|
-
const message = field.isValid?.custom?.(
|
|
106
|
-
{
|
|
107
|
-
...data,
|
|
108
|
-
[ id ]: newValue,
|
|
109
|
-
},
|
|
110
|
-
field
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
if ( message ) {
|
|
114
|
-
setCustomValidity( {
|
|
115
|
-
type: 'invalid',
|
|
116
|
-
message,
|
|
117
|
-
} );
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
setCustomValidity( undefined );
|
|
122
|
-
} }
|
|
131
|
+
onValidate={ onValidateControl }
|
|
123
132
|
customValidity={ customValidity }
|
|
124
133
|
label={ label }
|
|
125
134
|
placeholder={ placeholder }
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
*/
|
|
32
32
|
import RelativeDateControl, {
|
|
33
33
|
TIME_UNITS_OPTIONS,
|
|
34
|
+
type DateRelative,
|
|
34
35
|
} from './relative-date-control';
|
|
35
36
|
import {
|
|
36
37
|
OPERATOR_IN_THE_PAST,
|
|
@@ -42,6 +43,8 @@ import type { DataFormControlProps } from '../types';
|
|
|
42
43
|
|
|
43
44
|
const { DateCalendar, DateRangeCalendar } = unlock( componentsPrivateApis );
|
|
44
45
|
|
|
46
|
+
type DateRange = [ string, string ] | undefined;
|
|
47
|
+
|
|
45
48
|
const DATE_PRESETS: {
|
|
46
49
|
id: string;
|
|
47
50
|
label: string;
|
|
@@ -146,7 +149,7 @@ function CalendarDateControl( {
|
|
|
146
149
|
}: {
|
|
147
150
|
id: string;
|
|
148
151
|
value: string | undefined;
|
|
149
|
-
onChange: ( value:
|
|
152
|
+
onChange: ( value: string | undefined ) => void;
|
|
150
153
|
label: string;
|
|
151
154
|
hideLabelFromVision?: boolean;
|
|
152
155
|
className?: string;
|
|
@@ -165,10 +168,10 @@ function CalendarDateControl( {
|
|
|
165
168
|
const dateValue = newDate
|
|
166
169
|
? format( newDate, 'yyyy-MM-dd' )
|
|
167
170
|
: undefined;
|
|
168
|
-
onChange(
|
|
171
|
+
onChange( dateValue );
|
|
169
172
|
setSelectedPresetId( null );
|
|
170
173
|
},
|
|
171
|
-
[
|
|
174
|
+
[ onChange ]
|
|
172
175
|
);
|
|
173
176
|
|
|
174
177
|
const handlePresetClick = useCallback(
|
|
@@ -177,15 +180,15 @@ function CalendarDateControl( {
|
|
|
177
180
|
const dateValue = formatDate( presetDate );
|
|
178
181
|
|
|
179
182
|
setCalendarMonth( presetDate );
|
|
180
|
-
onChange(
|
|
183
|
+
onChange( dateValue );
|
|
181
184
|
setSelectedPresetId( preset.id );
|
|
182
185
|
},
|
|
183
|
-
[
|
|
186
|
+
[ onChange ]
|
|
184
187
|
);
|
|
185
188
|
|
|
186
189
|
const handleManualDateChange = useCallback(
|
|
187
190
|
( newValue?: string ) => {
|
|
188
|
-
onChange(
|
|
191
|
+
onChange( newValue );
|
|
189
192
|
if ( newValue ) {
|
|
190
193
|
const parsedDate = parseDate( newValue );
|
|
191
194
|
if ( parsedDate ) {
|
|
@@ -194,7 +197,7 @@ function CalendarDateControl( {
|
|
|
194
197
|
}
|
|
195
198
|
setSelectedPresetId( null );
|
|
196
199
|
},
|
|
197
|
-
[
|
|
200
|
+
[ onChange ]
|
|
198
201
|
);
|
|
199
202
|
|
|
200
203
|
const {
|
|
@@ -276,8 +279,8 @@ function CalendarDateRangeControl( {
|
|
|
276
279
|
className,
|
|
277
280
|
}: {
|
|
278
281
|
id: string;
|
|
279
|
-
value:
|
|
280
|
-
onChange: ( value:
|
|
282
|
+
value: DateRange;
|
|
283
|
+
onChange: ( value: DateRange ) => void;
|
|
281
284
|
label: string;
|
|
282
285
|
hideLabelFromVision?: boolean;
|
|
283
286
|
className?: string;
|
|
@@ -305,15 +308,13 @@ function CalendarDateRangeControl( {
|
|
|
305
308
|
const updateDateRange = useCallback(
|
|
306
309
|
( fromDate?: Date | string, toDate?: Date | string ) => {
|
|
307
310
|
if ( fromDate && toDate ) {
|
|
308
|
-
onChange(
|
|
309
|
-
[ id ]: [ formatDate( fromDate ), formatDate( toDate ) ],
|
|
310
|
-
} );
|
|
311
|
+
onChange( [ formatDate( fromDate ), formatDate( toDate ) ] );
|
|
311
312
|
} else if ( ! fromDate && ! toDate ) {
|
|
312
|
-
onChange(
|
|
313
|
+
onChange( undefined );
|
|
313
314
|
}
|
|
314
315
|
// Do nothing if only one date is set - wait for both
|
|
315
316
|
},
|
|
316
|
-
[
|
|
317
|
+
[ onChange ]
|
|
317
318
|
);
|
|
318
319
|
|
|
319
320
|
const onSelectCalendarRange = useCallback(
|
|
@@ -446,8 +447,33 @@ export default function DateControl< Item >( {
|
|
|
446
447
|
hideLabelFromVision,
|
|
447
448
|
operator,
|
|
448
449
|
}: DataFormControlProps< Item > ) {
|
|
449
|
-
const { id, label } = field;
|
|
450
|
-
const value =
|
|
450
|
+
const { id, label, getValue, setValue } = field;
|
|
451
|
+
const value = getValue( { item: data } );
|
|
452
|
+
|
|
453
|
+
const onChangeRelativeDateControl = useCallback(
|
|
454
|
+
( newValue: DateRelative ) => {
|
|
455
|
+
onChange( setValue( { item: data, value: newValue } ) );
|
|
456
|
+
},
|
|
457
|
+
[ data, onChange, setValue ]
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
const onChangeCalendarDateRangeControl = useCallback(
|
|
461
|
+
( newValue: DateRange ) => {
|
|
462
|
+
onChange(
|
|
463
|
+
setValue( {
|
|
464
|
+
item: data,
|
|
465
|
+
value: newValue,
|
|
466
|
+
} )
|
|
467
|
+
);
|
|
468
|
+
},
|
|
469
|
+
[ data, onChange, setValue ]
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
const onChangeCalendarDateControl = useCallback(
|
|
473
|
+
( newValue: string | undefined ) =>
|
|
474
|
+
onChange( setValue( { item: data, value: newValue } ) ),
|
|
475
|
+
[ data, onChange, setValue ]
|
|
476
|
+
);
|
|
451
477
|
|
|
452
478
|
if ( operator === OPERATOR_IN_THE_PAST || operator === OPERATOR_OVER ) {
|
|
453
479
|
return (
|
|
@@ -455,7 +481,7 @@ export default function DateControl< Item >( {
|
|
|
455
481
|
className="dataviews-controls__date"
|
|
456
482
|
id={ id }
|
|
457
483
|
value={ value && typeof value === 'object' ? value : {} }
|
|
458
|
-
onChange={
|
|
484
|
+
onChange={ onChangeRelativeDateControl }
|
|
459
485
|
label={ label }
|
|
460
486
|
hideLabelFromVision={ hideLabelFromVision }
|
|
461
487
|
options={ TIME_UNITS_OPTIONS[ operator ] }
|
|
@@ -464,14 +490,14 @@ export default function DateControl< Item >( {
|
|
|
464
490
|
}
|
|
465
491
|
|
|
466
492
|
if ( operator === OPERATOR_BETWEEN ) {
|
|
467
|
-
let dateRangeValue:
|
|
493
|
+
let dateRangeValue: DateRange;
|
|
468
494
|
if (
|
|
469
495
|
Array.isArray( value ) &&
|
|
470
496
|
value.length === 2 &&
|
|
471
497
|
value.every( ( date ) => typeof date === 'string' )
|
|
472
498
|
) {
|
|
473
499
|
// Ensure the value is expected format
|
|
474
|
-
dateRangeValue = value as
|
|
500
|
+
dateRangeValue = value as DateRange;
|
|
475
501
|
}
|
|
476
502
|
|
|
477
503
|
return (
|
|
@@ -479,7 +505,7 @@ export default function DateControl< Item >( {
|
|
|
479
505
|
className="dataviews-controls__date"
|
|
480
506
|
id={ id }
|
|
481
507
|
value={ dateRangeValue }
|
|
482
|
-
onChange={
|
|
508
|
+
onChange={ onChangeCalendarDateRangeControl }
|
|
483
509
|
label={ label }
|
|
484
510
|
hideLabelFromVision={ hideLabelFromVision }
|
|
485
511
|
/>
|
|
@@ -491,7 +517,7 @@ export default function DateControl< Item >( {
|
|
|
491
517
|
className="dataviews-controls__date"
|
|
492
518
|
id={ id }
|
|
493
519
|
value={ typeof value === 'string' ? value : undefined }
|
|
494
|
-
onChange={
|
|
520
|
+
onChange={ onChangeCalendarDateControl }
|
|
495
521
|
label={ label }
|
|
496
522
|
hideLabelFromVision={ hideLabelFromVision }
|
|
497
523
|
/>
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
BaseControl,
|
|
6
|
+
privateApis as componentsPrivateApis,
|
|
7
|
+
__experimentalInputControl as InputControl,
|
|
8
|
+
__experimentalVStack as VStack,
|
|
9
|
+
} from '@wordpress/components';
|
|
10
|
+
import { useCallback, useState } from '@wordpress/element';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
import { getDate, getSettings } from '@wordpress/date';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* External dependencies
|
|
16
|
+
*/
|
|
17
|
+
import { format, isValid } from 'date-fns';
|
|
6
18
|
|
|
7
19
|
/**
|
|
8
20
|
* Internal dependencies
|
|
@@ -11,7 +23,142 @@ import type { DataFormControlProps } from '../types';
|
|
|
11
23
|
import { OPERATOR_IN_THE_PAST, OPERATOR_OVER } from '../constants';
|
|
12
24
|
import RelativeDateControl, {
|
|
13
25
|
TIME_UNITS_OPTIONS,
|
|
26
|
+
type DateRelative,
|
|
14
27
|
} from './relative-date-control';
|
|
28
|
+
import { unlock } from '../lock-unlock';
|
|
29
|
+
|
|
30
|
+
const { DateCalendar } = unlock( componentsPrivateApis );
|
|
31
|
+
|
|
32
|
+
const parseDateTime = ( dateTimeString?: string ): Date | null => {
|
|
33
|
+
if ( ! dateTimeString ) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const parsed = getDate( dateTimeString );
|
|
37
|
+
return parsed && isValid( parsed ) ? parsed : null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const formatDateTime = ( date?: Date | string ): string => {
|
|
41
|
+
if ( ! date ) {
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
if ( typeof date === 'string' ) {
|
|
45
|
+
return date;
|
|
46
|
+
}
|
|
47
|
+
// Format as datetime-local input expects: YYYY-MM-DDTHH:mm
|
|
48
|
+
return format( date, "yyyy-MM-dd'T'HH:mm" );
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function CalendarDateTimeControl( {
|
|
52
|
+
id,
|
|
53
|
+
value,
|
|
54
|
+
onChange,
|
|
55
|
+
label,
|
|
56
|
+
description,
|
|
57
|
+
hideLabelFromVision,
|
|
58
|
+
}: {
|
|
59
|
+
id: string;
|
|
60
|
+
value: string | undefined;
|
|
61
|
+
onChange: ( value: string | undefined ) => void;
|
|
62
|
+
label: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
hideLabelFromVision?: boolean;
|
|
65
|
+
} ) {
|
|
66
|
+
const [ calendarMonth, setCalendarMonth ] = useState< Date >( () => {
|
|
67
|
+
const parsedDate = parseDateTime( value );
|
|
68
|
+
return parsedDate || new Date(); // Default to current month
|
|
69
|
+
} );
|
|
70
|
+
|
|
71
|
+
const onSelectDate = useCallback(
|
|
72
|
+
( newDate: Date | undefined | null ) => {
|
|
73
|
+
if ( newDate ) {
|
|
74
|
+
// Preserve time if it exists in current value, otherwise use current time
|
|
75
|
+
let finalDateTime = newDate;
|
|
76
|
+
|
|
77
|
+
if ( value ) {
|
|
78
|
+
const currentDateTime = parseDateTime( value );
|
|
79
|
+
if ( currentDateTime ) {
|
|
80
|
+
// Preserve the time part
|
|
81
|
+
finalDateTime = new Date( newDate );
|
|
82
|
+
finalDateTime.setHours( currentDateTime.getHours() );
|
|
83
|
+
finalDateTime.setMinutes(
|
|
84
|
+
currentDateTime.getMinutes()
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const dateTimeValue = finalDateTime.toISOString();
|
|
90
|
+
onChange( dateTimeValue );
|
|
91
|
+
} else {
|
|
92
|
+
onChange( undefined );
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
[ onChange, value ]
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const handleManualDateTimeChange = useCallback(
|
|
99
|
+
( newValue?: string ) => {
|
|
100
|
+
if ( newValue ) {
|
|
101
|
+
// Convert from datetime-local format to ISO string
|
|
102
|
+
const dateTime = new Date( newValue );
|
|
103
|
+
onChange( dateTime.toISOString() );
|
|
104
|
+
|
|
105
|
+
// Update calendar month to match
|
|
106
|
+
const parsedDate = parseDateTime( dateTime.toISOString() );
|
|
107
|
+
if ( parsedDate ) {
|
|
108
|
+
setCalendarMonth( parsedDate );
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
onChange( undefined );
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
[ onChange ]
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const {
|
|
118
|
+
timezone: { string: timezoneString },
|
|
119
|
+
l10n: { startOfWeek },
|
|
120
|
+
} = getSettings();
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<BaseControl
|
|
124
|
+
__nextHasNoMarginBottom
|
|
125
|
+
id={ id }
|
|
126
|
+
label={ label }
|
|
127
|
+
help={ description }
|
|
128
|
+
hideLabelFromVision={ hideLabelFromVision }
|
|
129
|
+
>
|
|
130
|
+
<VStack spacing={ 4 }>
|
|
131
|
+
{ /* Calendar widget */ }
|
|
132
|
+
<DateCalendar
|
|
133
|
+
style={ { width: '100%' } }
|
|
134
|
+
selected={
|
|
135
|
+
value ? parseDateTime( value ) || undefined : undefined
|
|
136
|
+
}
|
|
137
|
+
onSelect={ onSelectDate }
|
|
138
|
+
month={ calendarMonth }
|
|
139
|
+
onMonthChange={ setCalendarMonth }
|
|
140
|
+
timeZone={ timezoneString || undefined }
|
|
141
|
+
weekStartsOn={ startOfWeek }
|
|
142
|
+
/>
|
|
143
|
+
{ /* Manual datetime input */ }
|
|
144
|
+
<InputControl
|
|
145
|
+
__next40pxDefaultSize
|
|
146
|
+
type="datetime-local"
|
|
147
|
+
label={ __( 'Date time' ) }
|
|
148
|
+
hideLabelFromVision
|
|
149
|
+
value={
|
|
150
|
+
value
|
|
151
|
+
? formatDateTime(
|
|
152
|
+
parseDateTime( value ) || undefined
|
|
153
|
+
)
|
|
154
|
+
: ''
|
|
155
|
+
}
|
|
156
|
+
onChange={ handleManualDateTimeChange }
|
|
157
|
+
/>
|
|
158
|
+
</VStack>
|
|
159
|
+
</BaseControl>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
15
162
|
|
|
16
163
|
export default function DateTime< Item >( {
|
|
17
164
|
data,
|
|
@@ -20,20 +167,28 @@ export default function DateTime< Item >( {
|
|
|
20
167
|
hideLabelFromVision,
|
|
21
168
|
operator,
|
|
22
169
|
}: DataFormControlProps< Item > ) {
|
|
23
|
-
const { id, label } = field;
|
|
24
|
-
const value =
|
|
170
|
+
const { id, label, description, getValue, setValue } = field;
|
|
171
|
+
const value = getValue( { item: data } );
|
|
25
172
|
|
|
26
|
-
const
|
|
27
|
-
( newValue:
|
|
28
|
-
|
|
173
|
+
const onChangeRelativeDateControl = useCallback(
|
|
174
|
+
( newValue: DateRelative ) =>
|
|
175
|
+
onChange( setValue( { item: data, value: newValue } ) ),
|
|
176
|
+
[ data, onChange, setValue ]
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
const onChangeCalendarDateTimeControl = useCallback(
|
|
180
|
+
( newValue: string | undefined ) =>
|
|
181
|
+
onChange( setValue( { item: data, value: newValue } ) ),
|
|
182
|
+
[ data, onChange, setValue ]
|
|
29
183
|
);
|
|
30
184
|
|
|
31
185
|
if ( operator === OPERATOR_IN_THE_PAST || operator === OPERATOR_OVER ) {
|
|
32
186
|
return (
|
|
33
187
|
<RelativeDateControl
|
|
188
|
+
className="dataviews-controls__datetime"
|
|
34
189
|
id={ id }
|
|
35
190
|
value={ value && typeof value === 'object' ? value : {} }
|
|
36
|
-
onChange={
|
|
191
|
+
onChange={ onChangeRelativeDateControl }
|
|
37
192
|
label={ label }
|
|
38
193
|
hideLabelFromVision={ hideLabelFromVision }
|
|
39
194
|
options={ TIME_UNITS_OPTIONS[ operator ] }
|
|
@@ -42,20 +197,13 @@ export default function DateTime< Item >( {
|
|
|
42
197
|
}
|
|
43
198
|
|
|
44
199
|
return (
|
|
45
|
-
<
|
|
46
|
-
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{ hideLabelFromVision
|
|
52
|
-
|
|
53
|
-
) }
|
|
54
|
-
<TimePicker
|
|
55
|
-
currentTime={ typeof value === 'string' ? value : undefined }
|
|
56
|
-
onChange={ onChangeControl }
|
|
57
|
-
hideLabelFromVision
|
|
58
|
-
/>
|
|
59
|
-
</fieldset>
|
|
200
|
+
<CalendarDateTimeControl
|
|
201
|
+
id={ id }
|
|
202
|
+
value={ typeof value === 'string' ? value : undefined }
|
|
203
|
+
onChange={ onChangeCalendarDateTimeControl }
|
|
204
|
+
label={ label }
|
|
205
|
+
description={ description }
|
|
206
|
+
hideLabelFromVision={ hideLabelFromVision }
|
|
207
|
+
/>
|
|
60
208
|
);
|
|
61
209
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
+
import {
|
|
5
|
+
Icon,
|
|
6
|
+
__experimentalInputControlPrefixWrapper as InputControlPrefixWrapper,
|
|
7
|
+
} from '@wordpress/components';
|
|
4
8
|
import { atSymbol } from '@wordpress/icons';
|
|
5
9
|
|
|
6
10
|
/**
|
|
@@ -23,7 +27,11 @@ export default function Email< Item >( {
|
|
|
23
27
|
onChange,
|
|
24
28
|
hideLabelFromVision,
|
|
25
29
|
type: 'email',
|
|
26
|
-
|
|
30
|
+
prefix: (
|
|
31
|
+
<InputControlPrefixWrapper variant="icon">
|
|
32
|
+
<Icon icon={ atSymbol } />
|
|
33
|
+
</InputControlPrefixWrapper>
|
|
34
|
+
),
|
|
27
35
|
} }
|
|
28
36
|
/>
|
|
29
37
|
);
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
DataFormControlProps,
|
|
11
11
|
Field,
|
|
12
12
|
FieldTypeDefinition,
|
|
13
|
+
EditConfig,
|
|
13
14
|
} from '../types';
|
|
14
15
|
import checkbox from './checkbox';
|
|
15
16
|
import datetime from './datetime';
|
|
@@ -51,6 +52,23 @@ const FORM_CONTROLS: FormControls = {
|
|
|
51
52
|
toggleGroup,
|
|
52
53
|
};
|
|
53
54
|
|
|
55
|
+
function isEditConfig( value: any ): value is EditConfig {
|
|
56
|
+
return (
|
|
57
|
+
value && typeof value === 'object' && typeof value.control === 'string'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function createConfiguredControl( config: EditConfig ) {
|
|
62
|
+
const { control, ...controlConfig } = config;
|
|
63
|
+
const BaseControlType = getControlByType( control );
|
|
64
|
+
|
|
65
|
+
return function ConfiguredControl< Item >(
|
|
66
|
+
props: DataFormControlProps< Item >
|
|
67
|
+
) {
|
|
68
|
+
return <BaseControlType { ...props } config={ controlConfig } />;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
54
72
|
export function getControl< Item >(
|
|
55
73
|
field: Field< Item >,
|
|
56
74
|
fieldTypeDefinition: FieldTypeDefinition< Item >
|
|
@@ -63,6 +81,10 @@ export function getControl< Item >(
|
|
|
63
81
|
return getControlByType( field.Edit );
|
|
64
82
|
}
|
|
65
83
|
|
|
84
|
+
if ( isEditConfig( field.Edit ) ) {
|
|
85
|
+
return createConfiguredControl( field.Edit );
|
|
86
|
+
}
|
|
87
|
+
|
|
66
88
|
if ( field.elements && field.type !== 'array' ) {
|
|
67
89
|
return getControlByType( 'select' );
|
|
68
90
|
}
|
|
@@ -71,6 +93,10 @@ export function getControl< Item >(
|
|
|
71
93
|
return getControlByType( fieldTypeDefinition.Edit );
|
|
72
94
|
}
|
|
73
95
|
|
|
96
|
+
if ( isEditConfig( fieldTypeDefinition.Edit ) ) {
|
|
97
|
+
return createConfiguredControl( fieldTypeDefinition.Edit );
|
|
98
|
+
}
|
|
99
|
+
|
|
74
100
|
return fieldTypeDefinition.Edit;
|
|
75
101
|
}
|
|
76
102
|
|