@wordpress/dataviews 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +31 -23
- package/build/components/dataviews/index.js +9 -11
- package/build/components/dataviews/index.js.map +1 -1
- package/build/components/dataviews-filters/index.js +3 -0
- package/build/components/dataviews-filters/index.js.map +1 -1
- package/build/components/dataviews-filters/search-widget.js +2 -5
- package/build/components/dataviews-filters/search-widget.js.map +1 -1
- package/build/components/dataviews-pagination/index.js +23 -15
- package/build/components/dataviews-pagination/index.js.map +1 -1
- package/build/components/dataviews-view-config/index.js +26 -9
- package/build/components/dataviews-view-config/index.js.map +1 -1
- package/build/dataform-controls/datetime.js +49 -0
- package/build/dataform-controls/datetime.js.map +1 -0
- package/build/dataform-controls/index.js +50 -0
- package/build/dataform-controls/index.js.map +1 -0
- package/build/dataform-controls/integer.js +45 -0
- package/build/dataform-controls/integer.js.map +1 -0
- package/build/dataform-controls/radio.js +45 -0
- package/build/dataform-controls/radio.js.map +1 -0
- package/build/dataform-controls/select.js +58 -0
- package/build/dataform-controls/select.js.map +1 -0
- package/build/dataform-controls/text.js +45 -0
- package/build/dataform-controls/text.js.map +1 -0
- package/build/dataforms-layouts/panel/index.js +6 -3
- package/build/dataforms-layouts/panel/index.js.map +1 -1
- package/build/dataforms-layouts/regular/index.js +6 -3
- package/build/dataforms-layouts/regular/index.js.map +1 -1
- package/build/dataviews-layouts/grid/density-picker.js +23 -52
- package/build/dataviews-layouts/grid/density-picker.js.map +1 -1
- package/build/dataviews-layouts/grid/index.js +1 -1
- package/build/dataviews-layouts/grid/index.js.map +1 -1
- package/build/dataviews-layouts/list/index.js +6 -2
- package/build/dataviews-layouts/list/index.js.map +1 -1
- package/build/dataviews-layouts/table/column-header-menu.js +2 -5
- package/build/dataviews-layouts/table/column-header-menu.js.map +1 -1
- package/build/field-types/datetime.js +30 -0
- package/build/field-types/datetime.js.map +1 -0
- package/build/field-types/index.js +4 -0
- package/build/field-types/index.js.map +1 -1
- package/build/field-types/integer.js +1 -60
- package/build/field-types/integer.js.map +1 -1
- package/build/field-types/text.js +1 -60
- package/build/field-types/text.js.map +1 -1
- package/build/normalize-fields.js +6 -7
- package/build/normalize-fields.js.map +1 -1
- package/build/types.js.map +1 -1
- package/build-module/components/dataviews/index.js +9 -11
- package/build-module/components/dataviews/index.js.map +1 -1
- package/build-module/components/dataviews-filters/index.js +3 -0
- package/build-module/components/dataviews-filters/index.js.map +1 -1
- package/build-module/components/dataviews-filters/search-widget.js +2 -5
- package/build-module/components/dataviews-filters/search-widget.js.map +1 -1
- package/build-module/components/dataviews-pagination/index.js +23 -15
- package/build-module/components/dataviews-pagination/index.js.map +1 -1
- package/build-module/components/dataviews-view-config/index.js +27 -10
- package/build-module/components/dataviews-view-config/index.js.map +1 -1
- package/build-module/dataform-controls/datetime.js +43 -0
- package/build-module/dataform-controls/datetime.js.map +1 -0
- package/build-module/dataform-controls/index.js +42 -0
- package/build-module/dataform-controls/index.js.map +1 -0
- package/build-module/dataform-controls/integer.js +38 -0
- package/build-module/dataform-controls/integer.js.map +1 -0
- package/build-module/dataform-controls/radio.js +38 -0
- package/build-module/dataform-controls/radio.js.map +1 -0
- package/build-module/dataform-controls/select.js +51 -0
- package/build-module/dataform-controls/select.js.map +1 -0
- package/build-module/dataform-controls/text.js +38 -0
- package/build-module/dataform-controls/text.js.map +1 -0
- package/build-module/dataforms-layouts/panel/index.js +6 -3
- package/build-module/dataforms-layouts/panel/index.js.map +1 -1
- package/build-module/dataforms-layouts/regular/index.js +6 -3
- package/build-module/dataforms-layouts/regular/index.js.map +1 -1
- package/build-module/dataviews-layouts/grid/density-picker.js +25 -56
- package/build-module/dataviews-layouts/grid/density-picker.js.map +1 -1
- package/build-module/dataviews-layouts/grid/index.js +1 -1
- package/build-module/dataviews-layouts/grid/index.js.map +1 -1
- package/build-module/dataviews-layouts/list/index.js +5 -2
- package/build-module/dataviews-layouts/list/index.js.map +1 -1
- package/build-module/dataviews-layouts/table/column-header-menu.js +2 -5
- package/build-module/dataviews-layouts/table/column-header-menu.js.map +1 -1
- package/build-module/field-types/datetime.js +24 -0
- package/build-module/field-types/datetime.js.map +1 -0
- package/build-module/field-types/index.js +4 -0
- package/build-module/field-types/index.js.map +1 -1
- package/build-module/field-types/integer.js +2 -60
- package/build-module/field-types/integer.js.map +1 -1
- package/build-module/field-types/text.js +2 -60
- package/build-module/field-types/text.js.map +1 -1
- package/build-module/normalize-fields.js +7 -7
- package/build-module/normalize-fields.js.map +1 -1
- package/build-module/types.js.map +1 -1
- package/build-style/style-rtl.css +15 -18
- package/build-style/style.css +15 -18
- package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
- package/build-types/components/dataviews/index.d.ts.map +1 -1
- package/build-types/components/dataviews/stories/fixtures.d.ts +22 -3
- package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
- package/build-types/components/dataviews/stories/index.story.d.ts +9 -0
- package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/index.d.ts +1 -1
- package/build-types/components/dataviews-filters/index.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/search-widget.d.ts.map +1 -1
- package/build-types/components/dataviews-pagination/index.d.ts.map +1 -1
- package/build-types/components/dataviews-view-config/index.d.ts +4 -3
- package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
- package/build-types/dataform-controls/datetime.d.ts +6 -0
- package/build-types/dataform-controls/datetime.d.ts.map +1 -0
- package/build-types/dataform-controls/index.d.ts +11 -0
- package/build-types/dataform-controls/index.d.ts.map +1 -0
- package/build-types/dataform-controls/integer.d.ts +6 -0
- package/build-types/dataform-controls/integer.d.ts.map +1 -0
- package/build-types/dataform-controls/radio.d.ts +6 -0
- package/build-types/dataform-controls/radio.d.ts.map +1 -0
- package/build-types/dataform-controls/select.d.ts +6 -0
- package/build-types/dataform-controls/select.d.ts.map +1 -0
- package/build-types/dataform-controls/text.d.ts +6 -0
- package/build-types/dataform-controls/text.d.ts.map +1 -0
- package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
- package/build-types/dataforms-layouts/regular/index.d.ts.map +1 -1
- package/build-types/dataviews-layouts/grid/density-picker.d.ts.map +1 -1
- package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
- package/build-types/dataviews-layouts/table/column-header-menu.d.ts.map +1 -1
- package/build-types/field-types/datetime.d.ts +13 -0
- package/build-types/field-types/datetime.d.ts.map +1 -0
- package/build-types/field-types/index.d.ts +1 -1
- package/build-types/field-types/index.d.ts.map +1 -1
- package/build-types/field-types/integer.d.ts +2 -3
- package/build-types/field-types/integer.d.ts.map +1 -1
- package/build-types/field-types/text.d.ts +2 -3
- package/build-types/field-types/text.d.ts.map +1 -1
- package/build-types/normalize-fields.d.ts.map +1 -1
- package/build-types/types.d.ts +41 -21
- package/build-types/types.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/components/dataform/stories/index.story.tsx +43 -2
- package/src/components/dataviews/index.tsx +13 -13
- package/src/components/dataviews/stories/fixtures.js +29 -1
- package/src/components/dataviews/stories/index.story.js +7 -1
- package/src/components/dataviews/style.scss +0 -12
- package/src/components/dataviews-bulk-actions-toolbar/style.scss +1 -1
- package/src/components/dataviews-filters/index.tsx +3 -0
- package/src/components/dataviews-filters/search-widget.tsx +1 -8
- package/src/components/dataviews-filters/style.scss +1 -1
- package/src/components/dataviews-pagination/index.tsx +35 -16
- package/src/components/dataviews-pagination/style.scss +9 -4
- package/src/components/dataviews-view-config/index.tsx +45 -16
- package/src/dataform-controls/datetime.tsx +43 -0
- package/src/dataform-controls/index.tsx +61 -0
- package/src/dataform-controls/integer.tsx +38 -0
- package/src/dataform-controls/radio.tsx +42 -0
- package/src/dataform-controls/select.tsx +52 -0
- package/src/dataform-controls/style.scss +4 -0
- package/src/dataform-controls/text.tsx +40 -0
- package/src/dataforms-layouts/panel/index.tsx +6 -2
- package/src/dataforms-layouts/regular/index.tsx +6 -2
- package/src/dataviews-layouts/grid/density-picker.tsx +33 -67
- package/src/dataviews-layouts/grid/index.tsx +1 -1
- package/src/dataviews-layouts/grid/style.scss +0 -4
- package/src/dataviews-layouts/list/index.tsx +6 -2
- package/src/dataviews-layouts/table/column-header-menu.tsx +3 -5
- package/src/field-types/datetime.tsx +28 -0
- package/src/field-types/index.tsx +5 -0
- package/src/field-types/integer.tsx +2 -71
- package/src/field-types/text.tsx +2 -70
- package/src/normalize-fields.ts +8 -10
- package/src/style.scss +1 -0
- package/src/test/filter-and-sort-data-view.js +28 -0
- package/src/types.ts +54 -32
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { SelectControl } from '@wordpress/components';
|
|
5
|
+
import { useCallback } from '@wordpress/element';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import type { DataFormControlProps } from '../types';
|
|
12
|
+
|
|
13
|
+
export default function Select< Item >( {
|
|
14
|
+
data,
|
|
15
|
+
field,
|
|
16
|
+
onChange,
|
|
17
|
+
hideLabelFromVision,
|
|
18
|
+
}: DataFormControlProps< Item > ) {
|
|
19
|
+
const { id, label } = field;
|
|
20
|
+
const value = field.getValue( { item: data } ) ?? '';
|
|
21
|
+
const onChangeControl = useCallback(
|
|
22
|
+
( newValue: any ) =>
|
|
23
|
+
onChange( {
|
|
24
|
+
[ id ]: newValue,
|
|
25
|
+
} ),
|
|
26
|
+
[ id, onChange ]
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const elements = [
|
|
30
|
+
/*
|
|
31
|
+
* Value can be undefined when:
|
|
32
|
+
*
|
|
33
|
+
* - the field is not required
|
|
34
|
+
* - in bulk editing
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
{ label: __( 'Select item' ), value: '' },
|
|
38
|
+
...( field?.elements ?? [] ),
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<SelectControl
|
|
43
|
+
label={ label }
|
|
44
|
+
value={ value }
|
|
45
|
+
options={ elements }
|
|
46
|
+
onChange={ onChangeControl }
|
|
47
|
+
__next40pxDefaultSize
|
|
48
|
+
__nextHasNoMarginBottom
|
|
49
|
+
hideLabelFromVision={ hideLabelFromVision }
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { TextControl } from '@wordpress/components';
|
|
5
|
+
import { useCallback } from '@wordpress/element';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import type { DataFormControlProps } from '../types';
|
|
11
|
+
|
|
12
|
+
export default function Text< Item >( {
|
|
13
|
+
data,
|
|
14
|
+
field,
|
|
15
|
+
onChange,
|
|
16
|
+
hideLabelFromVision,
|
|
17
|
+
}: DataFormControlProps< Item > ) {
|
|
18
|
+
const { id, label, placeholder } = field;
|
|
19
|
+
const value = field.getValue( { item: data } );
|
|
20
|
+
|
|
21
|
+
const onChangeControl = useCallback(
|
|
22
|
+
( newValue: string ) =>
|
|
23
|
+
onChange( {
|
|
24
|
+
[ id ]: newValue,
|
|
25
|
+
} ),
|
|
26
|
+
[ id, onChange ]
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<TextControl
|
|
31
|
+
label={ label }
|
|
32
|
+
placeholder={ placeholder }
|
|
33
|
+
value={ value ?? '' }
|
|
34
|
+
onChange={ onChangeControl }
|
|
35
|
+
__next40pxDefaultSize
|
|
36
|
+
__nextHasNoMarginBottom
|
|
37
|
+
hideLabelFromVision={ hideLabelFromVision }
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -17,7 +17,7 @@ import { closeSmall } from '@wordpress/icons';
|
|
|
17
17
|
* Internal dependencies
|
|
18
18
|
*/
|
|
19
19
|
import { normalizeFields } from '../../normalize-fields';
|
|
20
|
-
import type { DataFormProps, NormalizedField } from '../../types';
|
|
20
|
+
import type { DataFormProps, NormalizedField, Field } from '../../types';
|
|
21
21
|
|
|
22
22
|
interface FormFieldProps< Item > {
|
|
23
23
|
data: Item;
|
|
@@ -142,7 +142,11 @@ export default function FormPanel< Item >( {
|
|
|
142
142
|
const visibleFields = useMemo(
|
|
143
143
|
() =>
|
|
144
144
|
normalizeFields(
|
|
145
|
-
|
|
145
|
+
( form.fields ?? [] )
|
|
146
|
+
.map( ( fieldId ) =>
|
|
147
|
+
fields.find( ( { id } ) => id === fieldId )
|
|
148
|
+
)
|
|
149
|
+
.filter( ( field ): field is Field< Item > => !! field )
|
|
146
150
|
),
|
|
147
151
|
[ fields, form.fields ]
|
|
148
152
|
);
|
|
@@ -8,7 +8,7 @@ import { useMemo } from '@wordpress/element';
|
|
|
8
8
|
* Internal dependencies
|
|
9
9
|
*/
|
|
10
10
|
import { normalizeFields } from '../../normalize-fields';
|
|
11
|
-
import type { DataFormProps } from '../../types';
|
|
11
|
+
import type { DataFormProps, Field } from '../../types';
|
|
12
12
|
|
|
13
13
|
export default function FormRegular< Item >( {
|
|
14
14
|
data,
|
|
@@ -19,7 +19,11 @@ export default function FormRegular< Item >( {
|
|
|
19
19
|
const visibleFields = useMemo(
|
|
20
20
|
() =>
|
|
21
21
|
normalizeFields(
|
|
22
|
-
|
|
22
|
+
( form.fields ?? [] )
|
|
23
|
+
.map( ( fieldId ) =>
|
|
24
|
+
fields.find( ( { id } ) => id === fieldId )
|
|
25
|
+
)
|
|
26
|
+
.filter( ( field ): field is Field< Item > => !! field )
|
|
23
27
|
),
|
|
24
28
|
[ fields, form.fields ]
|
|
25
29
|
);
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { RangeControl
|
|
4
|
+
import { RangeControl } from '@wordpress/components';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
6
|
import { useViewportMatch } from '@wordpress/compose';
|
|
7
|
-
import {
|
|
8
|
-
import { useEffect } from '@wordpress/element';
|
|
7
|
+
import { useEffect, useMemo } from '@wordpress/element';
|
|
9
8
|
|
|
10
9
|
const viewportBreaks = {
|
|
11
10
|
xhuge: { min: 3, max: 6, default: 5 },
|
|
@@ -40,21 +39,6 @@ function useViewPortBreakpoint() {
|
|
|
40
39
|
return null;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
// Value is number from 0 to 100 representing how big an item is in the grid
|
|
44
|
-
// 100 being the biggest and 0 being the smallest.
|
|
45
|
-
// The size is relative to the viewport size, if one a given viewport the
|
|
46
|
-
// number of allowed items in a grid is 3 to 6 a 0 ( the smallest ) will mean that the grid will
|
|
47
|
-
// have 6 items in a row, a 100 ( the biggest ) will mean that the grid will have 3 items in a row.
|
|
48
|
-
// A value of 75 will mean that the grid will have 4 items in a row.
|
|
49
|
-
function getRangeValue(
|
|
50
|
-
density: number,
|
|
51
|
-
breakValues: { min: number; max: number; default: number }
|
|
52
|
-
) {
|
|
53
|
-
const inverseDensity = breakValues.max - density;
|
|
54
|
-
const max = breakValues.max - breakValues.min;
|
|
55
|
-
return Math.round( ( inverseDensity * 100 ) / max );
|
|
56
|
-
}
|
|
57
|
-
|
|
58
42
|
export default function DensityPicker( {
|
|
59
43
|
density,
|
|
60
44
|
setDensity,
|
|
@@ -78,59 +62,41 @@ export default function DensityPicker( {
|
|
|
78
62
|
return _density;
|
|
79
63
|
} );
|
|
80
64
|
}, [ setDensity, viewport ] );
|
|
65
|
+
const breakValues = viewportBreaks[ viewport || 'mobile' ];
|
|
66
|
+
const densityToUse = density || breakValues.default;
|
|
67
|
+
|
|
68
|
+
const marks = useMemo(
|
|
69
|
+
() =>
|
|
70
|
+
Array.from(
|
|
71
|
+
{ length: breakValues.max - breakValues.min + 1 },
|
|
72
|
+
( _, i ) => {
|
|
73
|
+
return {
|
|
74
|
+
value: breakValues.min + i,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
),
|
|
78
|
+
[ breakValues ]
|
|
79
|
+
);
|
|
80
|
+
|
|
81
81
|
if ( ! viewport ) {
|
|
82
82
|
return null;
|
|
83
83
|
}
|
|
84
|
-
const breakValues = viewportBreaks[ viewport ];
|
|
85
|
-
const densityToUse = density || breakValues.default;
|
|
86
|
-
const rangeValue = getRangeValue( densityToUse, breakValues );
|
|
87
84
|
|
|
88
|
-
const step = 100 / ( breakValues.max - breakValues.min + 1 );
|
|
89
85
|
return (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
label={ __( 'Item size' ) }
|
|
106
|
-
hideLabelFromVision
|
|
107
|
-
value={ rangeValue }
|
|
108
|
-
min={ 0 }
|
|
109
|
-
max={ 100 }
|
|
110
|
-
withInputField={ false }
|
|
111
|
-
onChange={ ( value = 0 ) => {
|
|
112
|
-
const inverseValue = 100 - value;
|
|
113
|
-
setDensity(
|
|
114
|
-
Math.round(
|
|
115
|
-
( inverseValue *
|
|
116
|
-
( breakValues.max - breakValues.min ) ) /
|
|
117
|
-
100 +
|
|
118
|
-
breakValues.min
|
|
119
|
-
)
|
|
120
|
-
);
|
|
121
|
-
} }
|
|
122
|
-
step={ step }
|
|
123
|
-
/>
|
|
124
|
-
<Button
|
|
125
|
-
size="compact"
|
|
126
|
-
icon={ plus }
|
|
127
|
-
disabled={ rangeValue >= 100 }
|
|
128
|
-
accessibleWhenDisabled
|
|
129
|
-
label={ __( 'Increase size' ) }
|
|
130
|
-
onClick={ () => {
|
|
131
|
-
setDensity( densityToUse - 1 );
|
|
132
|
-
} }
|
|
133
|
-
/>
|
|
134
|
-
</>
|
|
86
|
+
<RangeControl
|
|
87
|
+
__nextHasNoMarginBottom
|
|
88
|
+
__next40pxDefaultSize
|
|
89
|
+
showTooltip={ false }
|
|
90
|
+
label={ __( 'Preview size' ) }
|
|
91
|
+
value={ breakValues.max + breakValues.min - densityToUse }
|
|
92
|
+
marks={ marks }
|
|
93
|
+
min={ breakValues.min }
|
|
94
|
+
max={ breakValues.max }
|
|
95
|
+
withInputField={ false }
|
|
96
|
+
onChange={ ( value = 0 ) => {
|
|
97
|
+
setDensity( breakValues.max + breakValues.min - value );
|
|
98
|
+
} }
|
|
99
|
+
step={ 1 }
|
|
100
|
+
/>
|
|
135
101
|
);
|
|
136
102
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
+
// TODO: use the @wordpress/components one once public
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports
|
|
7
|
+
import { useStoreState } from '@ariakit/react';
|
|
5
8
|
// Import CompositeStore type, which is not exported from @wordpress/components.
|
|
6
9
|
// eslint-disable-next-line no-restricted-imports
|
|
7
10
|
import type { CompositeStore } from '@ariakit/react';
|
|
@@ -358,10 +361,11 @@ export default function ViewList< Item >( props: ViewListProps< Item > ) {
|
|
|
358
361
|
|
|
359
362
|
const store = useCompositeStore( {
|
|
360
363
|
defaultActiveId: getItemDomId( selectedItem ),
|
|
361
|
-
} );
|
|
364
|
+
} ) as CompositeStore; // TODO, remove once composite APIs are public
|
|
362
365
|
|
|
363
366
|
// Manage focused item, when the active one is removed from the list.
|
|
364
|
-
const isActiveIdInList =
|
|
367
|
+
const isActiveIdInList = useStoreState(
|
|
368
|
+
store,
|
|
365
369
|
( state: { items: any[]; activeId: any } ) =>
|
|
366
370
|
state.items.some(
|
|
367
371
|
( item: { id: any } ) => item.id === state.activeId
|
|
@@ -72,7 +72,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
|
|
|
72
72
|
);
|
|
73
73
|
const index = view.fields?.indexOf( fieldId ) as number;
|
|
74
74
|
if ( !! combinedField ) {
|
|
75
|
-
return combinedField.label;
|
|
75
|
+
return combinedField.header || combinedField.label;
|
|
76
76
|
}
|
|
77
77
|
const field = fields.find( ( f ) => f.id === fieldId );
|
|
78
78
|
if ( ! field ) {
|
|
@@ -91,9 +91,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
|
|
|
91
91
|
!! field.elements?.length &&
|
|
92
92
|
!! operators.length &&
|
|
93
93
|
! field.filterBy?.isPrimary;
|
|
94
|
-
|
|
95
|
-
return field.label;
|
|
96
|
-
}
|
|
94
|
+
|
|
97
95
|
return (
|
|
98
96
|
<DropdownMenu
|
|
99
97
|
align="start"
|
|
@@ -104,7 +102,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
|
|
|
104
102
|
ref={ ref }
|
|
105
103
|
variant="tertiary"
|
|
106
104
|
>
|
|
107
|
-
{ field.
|
|
105
|
+
{ field.header }
|
|
108
106
|
{ view.sort && isSorted && (
|
|
109
107
|
<span aria-hidden="true">
|
|
110
108
|
{ sortArrows[ view.sort.direction ] }
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { SortDirection, ValidationContext } from '../types';
|
|
5
|
+
|
|
6
|
+
function sort( a: any, b: any, direction: SortDirection ) {
|
|
7
|
+
const timeA = new Date( a ).getTime();
|
|
8
|
+
const timeB = new Date( b ).getTime();
|
|
9
|
+
|
|
10
|
+
return direction === 'asc' ? timeA - timeB : timeB - timeA;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isValid( value: any, context?: ValidationContext ) {
|
|
14
|
+
if ( context?.elements ) {
|
|
15
|
+
const validValues = context?.elements.map( ( f ) => f.value );
|
|
16
|
+
if ( ! validValues.includes( value ) ) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
sort,
|
|
26
|
+
isValid,
|
|
27
|
+
Edit: 'datetime',
|
|
28
|
+
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { FieldType, SortDirection, ValidationContext } from '../types';
|
|
5
5
|
import { default as integer } from './integer';
|
|
6
6
|
import { default as text } from './text';
|
|
7
|
+
import { default as datetime } from './datetime';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
*
|
|
@@ -20,6 +21,10 @@ export default function getFieldTypeDefinition( type?: FieldType ) {
|
|
|
20
21
|
return text;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
if ( 'datetime' === type ) {
|
|
25
|
+
return datetime;
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
return {
|
|
24
29
|
sort: ( a: any, b: any, direction: SortDirection ) => {
|
|
25
30
|
if ( typeof a === 'number' && typeof b === 'number' ) {
|
|
@@ -1,21 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import {
|
|
5
|
-
__experimentalNumberControl as NumberControl,
|
|
6
|
-
SelectControl,
|
|
7
|
-
} from '@wordpress/components';
|
|
8
|
-
import { useCallback } from '@wordpress/element';
|
|
9
|
-
import { __ } from '@wordpress/i18n';
|
|
10
|
-
|
|
11
1
|
/**
|
|
12
2
|
* Internal dependencies
|
|
13
3
|
*/
|
|
14
|
-
import type {
|
|
15
|
-
SortDirection,
|
|
16
|
-
ValidationContext,
|
|
17
|
-
DataFormControlProps,
|
|
18
|
-
} from '../types';
|
|
4
|
+
import type { SortDirection, ValidationContext } from '../types';
|
|
19
5
|
|
|
20
6
|
function sort( a: any, b: any, direction: SortDirection ) {
|
|
21
7
|
return direction === 'asc' ? a - b : b - a;
|
|
@@ -41,63 +27,8 @@ function isValid( value: any, context?: ValidationContext ) {
|
|
|
41
27
|
return true;
|
|
42
28
|
}
|
|
43
29
|
|
|
44
|
-
function Edit< Item >( {
|
|
45
|
-
data,
|
|
46
|
-
field,
|
|
47
|
-
onChange,
|
|
48
|
-
hideLabelFromVision,
|
|
49
|
-
}: DataFormControlProps< Item > ) {
|
|
50
|
-
const { id, label, description } = field;
|
|
51
|
-
const value = field.getValue( { item: data } ) ?? '';
|
|
52
|
-
const onChangeControl = useCallback(
|
|
53
|
-
( newValue: string | undefined ) =>
|
|
54
|
-
onChange( ( prevItem: Item ) => ( {
|
|
55
|
-
...prevItem,
|
|
56
|
-
[ id ]: newValue,
|
|
57
|
-
} ) ),
|
|
58
|
-
[ id, onChange ]
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
if ( field.elements ) {
|
|
62
|
-
const elements = [
|
|
63
|
-
/*
|
|
64
|
-
* Value can be undefined when:
|
|
65
|
-
*
|
|
66
|
-
* - the field is not required
|
|
67
|
-
* - in bulk editing
|
|
68
|
-
*
|
|
69
|
-
*/
|
|
70
|
-
{ label: __( 'Select item' ), value: '' },
|
|
71
|
-
...field.elements,
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<SelectControl
|
|
76
|
-
label={ label }
|
|
77
|
-
value={ value }
|
|
78
|
-
options={ elements }
|
|
79
|
-
onChange={ onChangeControl }
|
|
80
|
-
__next40pxDefaultSize
|
|
81
|
-
__nextHasNoMarginBottom
|
|
82
|
-
hideLabelFromVision={ hideLabelFromVision }
|
|
83
|
-
/>
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<NumberControl
|
|
89
|
-
label={ label }
|
|
90
|
-
help={ description }
|
|
91
|
-
value={ value }
|
|
92
|
-
onChange={ onChangeControl }
|
|
93
|
-
__next40pxDefaultSize
|
|
94
|
-
hideLabelFromVision={ hideLabelFromVision }
|
|
95
|
-
/>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
30
|
export default {
|
|
100
31
|
sort,
|
|
101
32
|
isValid,
|
|
102
|
-
Edit,
|
|
33
|
+
Edit: 'integer',
|
|
103
34
|
};
|
package/src/field-types/text.tsx
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { SelectControl, TextControl } from '@wordpress/components';
|
|
5
|
-
import { useCallback } from '@wordpress/element';
|
|
6
|
-
import { __ } from '@wordpress/i18n';
|
|
7
|
-
|
|
8
1
|
/**
|
|
9
2
|
* Internal dependencies
|
|
10
3
|
*/
|
|
11
|
-
import type {
|
|
12
|
-
SortDirection,
|
|
13
|
-
ValidationContext,
|
|
14
|
-
DataFormControlProps,
|
|
15
|
-
} from '../types';
|
|
4
|
+
import type { SortDirection, ValidationContext } from '../types';
|
|
16
5
|
|
|
17
6
|
function sort( valueA: any, valueB: any, direction: SortDirection ) {
|
|
18
7
|
return direction === 'asc'
|
|
@@ -31,65 +20,8 @@ function isValid( value: any, context?: ValidationContext ) {
|
|
|
31
20
|
return true;
|
|
32
21
|
}
|
|
33
22
|
|
|
34
|
-
function Edit< Item >( {
|
|
35
|
-
data,
|
|
36
|
-
field,
|
|
37
|
-
onChange,
|
|
38
|
-
hideLabelFromVision,
|
|
39
|
-
}: DataFormControlProps< Item > ) {
|
|
40
|
-
const { id, label, placeholder } = field;
|
|
41
|
-
const value = field.getValue( { item: data } );
|
|
42
|
-
|
|
43
|
-
const onChangeControl = useCallback(
|
|
44
|
-
( newValue: string ) =>
|
|
45
|
-
onChange( ( prevItem: Item ) => ( {
|
|
46
|
-
...prevItem,
|
|
47
|
-
[ id ]: newValue,
|
|
48
|
-
} ) ),
|
|
49
|
-
[ id, onChange ]
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
if ( field.elements ) {
|
|
53
|
-
const elements = [
|
|
54
|
-
/*
|
|
55
|
-
* Value can be undefined when:
|
|
56
|
-
*
|
|
57
|
-
* - the field is not required
|
|
58
|
-
* - in bulk editing
|
|
59
|
-
*
|
|
60
|
-
*/
|
|
61
|
-
{ label: __( 'Select item' ), value: '' },
|
|
62
|
-
...field.elements,
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<SelectControl
|
|
67
|
-
label={ label }
|
|
68
|
-
value={ value }
|
|
69
|
-
options={ elements }
|
|
70
|
-
onChange={ onChangeControl }
|
|
71
|
-
__next40pxDefaultSize
|
|
72
|
-
__nextHasNoMarginBottom
|
|
73
|
-
hideLabelFromVision={ hideLabelFromVision }
|
|
74
|
-
/>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<TextControl
|
|
80
|
-
label={ label }
|
|
81
|
-
placeholder={ placeholder }
|
|
82
|
-
value={ value ?? '' }
|
|
83
|
-
onChange={ onChangeControl }
|
|
84
|
-
__next40pxDefaultSize
|
|
85
|
-
__nextHasNoMarginBottom
|
|
86
|
-
hideLabelFromVision={ hideLabelFromVision }
|
|
87
|
-
/>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
23
|
export default {
|
|
92
24
|
sort,
|
|
93
25
|
isValid,
|
|
94
|
-
Edit,
|
|
26
|
+
Edit: 'text',
|
|
95
27
|
};
|
package/src/normalize-fields.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import getFieldTypeDefinition from './field-types';
|
|
5
5
|
import type { Field, NormalizedField } from './types';
|
|
6
|
+
import { getControl } from './dataform-controls';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Apply default values and normalize the fields config.
|
|
@@ -17,8 +18,7 @@ export function normalizeFields< Item >(
|
|
|
17
18
|
const fieldTypeDefinition = getFieldTypeDefinition( field.type );
|
|
18
19
|
|
|
19
20
|
const getValue =
|
|
20
|
-
field.getValue ||
|
|
21
|
-
( ( { item }: { item: Item } ) => item[ field.id as keyof Item ] );
|
|
21
|
+
field.getValue || ( ( { item } ) => ( item as any )[ field.id ] );
|
|
22
22
|
|
|
23
23
|
const sort =
|
|
24
24
|
field.sort ??
|
|
@@ -39,17 +39,14 @@ export function normalizeFields< Item >(
|
|
|
39
39
|
);
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const Edit = field
|
|
42
|
+
const Edit = getControl( field, fieldTypeDefinition );
|
|
43
43
|
|
|
44
44
|
const renderFromElements = ( { item }: { item: Item } ) => {
|
|
45
45
|
const value = getValue( { item } );
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} )?.label;
|
|
51
|
-
|
|
52
|
-
return label || value;
|
|
46
|
+
return (
|
|
47
|
+
field?.elements?.find( ( element ) => element.value === value )
|
|
48
|
+
?.label || getValue( { item } )
|
|
49
|
+
);
|
|
53
50
|
};
|
|
54
51
|
|
|
55
52
|
const render =
|
|
@@ -58,6 +55,7 @@ export function normalizeFields< Item >(
|
|
|
58
55
|
return {
|
|
59
56
|
...field,
|
|
60
57
|
label: field.label || field.id,
|
|
58
|
+
header: field.header || field.label || field.id,
|
|
61
59
|
getValue,
|
|
62
60
|
render,
|
|
63
61
|
sort,
|
package/src/style.scss
CHANGED
|
@@ -268,6 +268,34 @@ describe( 'sorting', () => {
|
|
|
268
268
|
expect( result[ 1 ].title ).toBe( 'Neptune' );
|
|
269
269
|
} );
|
|
270
270
|
|
|
271
|
+
it( 'should sort datetime field types', () => {
|
|
272
|
+
const { data: resultDesc } = filterSortAndPaginate(
|
|
273
|
+
data,
|
|
274
|
+
{
|
|
275
|
+
sort: { field: 'date', direction: 'desc' },
|
|
276
|
+
},
|
|
277
|
+
fields
|
|
278
|
+
);
|
|
279
|
+
expect( resultDesc ).toHaveLength( 11 );
|
|
280
|
+
expect( resultDesc[ 0 ].title ).toBe( 'NASA' );
|
|
281
|
+
expect( resultDesc[ 1 ].title ).toBe( 'Earth' );
|
|
282
|
+
expect( resultDesc[ 9 ].title ).toBe( 'Space' );
|
|
283
|
+
expect( resultDesc[ 10 ].title ).toBe( 'Jupiter' );
|
|
284
|
+
|
|
285
|
+
const { data: resultAsc } = filterSortAndPaginate(
|
|
286
|
+
data,
|
|
287
|
+
{
|
|
288
|
+
sort: { field: 'date', direction: 'asc' },
|
|
289
|
+
},
|
|
290
|
+
fields
|
|
291
|
+
);
|
|
292
|
+
expect( resultAsc ).toHaveLength( 11 );
|
|
293
|
+
expect( resultAsc[ 0 ].title ).toBe( 'Jupiter' );
|
|
294
|
+
expect( resultAsc[ 1 ].title ).toBe( 'Space' );
|
|
295
|
+
expect( resultAsc[ 9 ].title ).toBe( 'Earth' );
|
|
296
|
+
expect( resultAsc[ 10 ].title ).toBe( 'NASA' );
|
|
297
|
+
} );
|
|
298
|
+
|
|
271
299
|
it( 'should sort untyped fields if the value is a number', () => {
|
|
272
300
|
const { data: result } = filterSortAndPaginate(
|
|
273
301
|
data,
|