@wordpress/dataviews 14.1.1-next.v.202604091042.0 → 14.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 +18 -1
- package/build/components/dataform-controls/array.cjs +2 -2
- package/build/components/dataform-controls/array.cjs.map +2 -2
- package/build/components/dataform-controls/date.cjs +16 -5
- package/build/components/dataform-controls/date.cjs.map +3 -3
- package/build/components/dataform-controls/datetime.cjs +6 -2
- package/build/components/dataform-controls/datetime.cjs.map +3 -3
- package/build/components/dataform-controls/utils/use-disabled-date-matchers.cjs +48 -0
- package/build/components/dataform-controls/utils/use-disabled-date-matchers.cjs.map +7 -0
- package/build/components/dataform-layouts/card/index.cjs.map +2 -2
- package/build/components/dataform-layouts/panel/summary-button.cjs +0 -1
- package/build/components/dataform-layouts/panel/summary-button.cjs.map +2 -2
- package/build/components/dataviews-context/index.cjs.map +1 -1
- package/build/components/dataviews-filters/search-widget.cjs +2 -7
- package/build/components/dataviews-filters/search-widget.cjs.map +2 -2
- package/build/components/dataviews-layouts/activity/activity-item.cjs +2 -3
- package/build/components/dataviews-layouts/activity/activity-item.cjs.map +2 -2
- package/build/components/dataviews-layouts/grid/composite-grid.cjs +2 -2
- package/build/components/dataviews-layouts/grid/composite-grid.cjs.map +2 -2
- package/build/components/dataviews-layouts/list/index.cjs +2 -2
- package/build/components/dataviews-layouts/list/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/picker-grid/index.cjs +3 -6
- package/build/components/dataviews-layouts/picker-grid/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/picker-table/index.cjs +15 -12
- package/build/components/dataviews-layouts/picker-table/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/table/index.cjs +0 -1
- package/build/components/dataviews-layouts/table/index.cjs.map +2 -2
- package/build/dataviews/index.cjs +10 -8
- package/build/dataviews/index.cjs.map +2 -2
- package/build/dataviews-picker/index.cjs +16 -9
- package/build/dataviews-picker/index.cjs.map +2 -2
- package/build/field-types/date.cjs +4 -1
- package/build/field-types/date.cjs.map +2 -2
- package/build/field-types/datetime.cjs +4 -1
- package/build/field-types/datetime.cjs.map +2 -2
- package/build/field-types/utils/get-is-valid.cjs +29 -24
- package/build/field-types/utils/get-is-valid.cjs.map +2 -2
- package/build/field-types/utils/is-valid-date-boundary.cjs +64 -0
- package/build/field-types/utils/is-valid-date-boundary.cjs.map +7 -0
- package/build/types/dataviews.cjs.map +1 -1
- package/build/types/field-api.cjs.map +1 -1
- package/build-module/components/dataform-controls/array.mjs +2 -2
- package/build-module/components/dataform-controls/array.mjs.map +2 -2
- package/build-module/components/dataform-controls/date.mjs +16 -5
- package/build-module/components/dataform-controls/date.mjs.map +2 -2
- package/build-module/components/dataform-controls/datetime.mjs +6 -2
- package/build-module/components/dataform-controls/datetime.mjs.map +2 -2
- package/build-module/components/dataform-controls/utils/use-disabled-date-matchers.mjs +27 -0
- package/build-module/components/dataform-controls/utils/use-disabled-date-matchers.mjs.map +7 -0
- package/build-module/components/dataform-layouts/card/index.mjs.map +2 -2
- package/build-module/components/dataform-layouts/panel/summary-button.mjs +0 -1
- package/build-module/components/dataform-layouts/panel/summary-button.mjs.map +2 -2
- package/build-module/components/dataviews-context/index.mjs.map +1 -1
- package/build-module/components/dataviews-filters/search-widget.mjs +3 -13
- package/build-module/components/dataviews-filters/search-widget.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/activity/activity-item.mjs +2 -3
- package/build-module/components/dataviews-layouts/activity/activity-item.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/grid/composite-grid.mjs +2 -2
- package/build-module/components/dataviews-layouts/grid/composite-grid.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/list/index.mjs +2 -3
- package/build-module/components/dataviews-layouts/list/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/picker-grid/index.mjs +3 -6
- package/build-module/components/dataviews-layouts/picker-grid/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/picker-table/index.mjs +15 -12
- package/build-module/components/dataviews-layouts/picker-table/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/table/index.mjs +0 -1
- package/build-module/components/dataviews-layouts/table/index.mjs.map +2 -2
- package/build-module/dataviews/index.mjs +10 -8
- package/build-module/dataviews/index.mjs.map +2 -2
- package/build-module/dataviews-picker/index.mjs +16 -9
- package/build-module/dataviews-picker/index.mjs.map +2 -2
- package/build-module/field-types/date.mjs +4 -1
- package/build-module/field-types/date.mjs.map +2 -2
- package/build-module/field-types/datetime.mjs +4 -1
- package/build-module/field-types/datetime.mjs.map +2 -2
- package/build-module/field-types/utils/get-is-valid.mjs +29 -24
- package/build-module/field-types/utils/get-is-valid.mjs.map +2 -2
- package/build-module/field-types/utils/is-valid-date-boundary.mjs +38 -0
- package/build-module/field-types/utils/is-valid-date-boundary.mjs.map +7 -0
- package/build-style/style-rtl.css +12 -13
- package/build-style/style.css +12 -13
- package/build-types/components/dataform-controls/array.d.ts.map +1 -1
- package/build-types/components/dataform-controls/date.d.ts.map +1 -1
- package/build-types/components/dataform-controls/datetime.d.ts.map +1 -1
- package/build-types/components/dataform-controls/utils/use-disabled-date-matchers.d.ts +16 -0
- package/build-types/components/dataform-controls/utils/use-disabled-date-matchers.d.ts.map +1 -0
- package/build-types/components/dataform-layouts/card/index.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/panel/summary-button.d.ts.map +1 -1
- package/build-types/components/dataviews-context/index.d.ts +2 -2
- package/build-types/components/dataviews-context/index.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/search-widget.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/activity/activity-item.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/list/index.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/picker-grid/index.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/picker-table/index.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/table/index.d.ts.map +1 -1
- package/build-types/dataform/stories/index.story.d.ts.map +1 -1
- package/build-types/dataform/stories/layout-regular.d.ts.map +1 -1
- package/build-types/dataform/stories/validation.d.ts.map +1 -1
- package/build-types/dataviews/index.d.ts +1 -1
- package/build-types/dataviews/index.d.ts.map +1 -1
- package/build-types/dataviews/stories/free-composition.d.ts.map +1 -1
- package/build-types/dataviews/stories/index.story.d.ts.map +1 -1
- package/build-types/dataviews/stories/layout-activity.d.ts.map +1 -1
- package/build-types/dataviews/stories/layout-grid.d.ts.map +1 -1
- package/build-types/dataviews/stories/layout-list.d.ts.map +1 -1
- package/build-types/dataviews/stories/layout-table.d.ts.map +1 -1
- package/build-types/dataviews/stories/with-card.d.ts.map +1 -1
- package/build-types/dataviews-picker/index.d.ts +3 -2
- package/build-types/dataviews-picker/index.d.ts.map +1 -1
- package/build-types/dataviews-picker/stories/index.story.d.ts.map +1 -1
- package/build-types/field-types/date.d.ts +3 -0
- package/build-types/field-types/date.d.ts.map +1 -1
- package/build-types/field-types/datetime.d.ts +3 -0
- package/build-types/field-types/datetime.d.ts.map +1 -1
- package/build-types/field-types/utils/get-is-valid.d.ts.map +1 -1
- package/build-types/field-types/utils/is-valid-date-boundary.d.ts +7 -0
- package/build-types/field-types/utils/is-valid-date-boundary.d.ts.map +1 -0
- package/build-types/types/dataviews.d.ts +8 -0
- package/build-types/types/dataviews.d.ts.map +1 -1
- package/build-types/types/field-api.d.ts +11 -9
- package/build-types/types/field-api.d.ts.map +1 -1
- package/build-wp/index.js +1173 -1017
- package/package.json +16 -16
- package/src/components/dataform-controls/array.tsx +3 -2
- package/src/components/dataform-controls/date.tsx +17 -2
- package/src/components/dataform-controls/datetime.tsx +15 -1
- package/src/components/dataform-controls/utils/use-disabled-date-matchers.ts +48 -0
- package/src/components/dataform-layouts/card/index.tsx +0 -3
- package/src/components/dataform-layouts/panel/style.scss +4 -5
- package/src/components/dataform-layouts/panel/summary-button.tsx +0 -1
- package/src/components/dataviews-context/index.ts +2 -2
- package/src/components/dataviews-filters/search-widget.tsx +4 -14
- package/src/components/dataviews-filters/style.scss +2 -2
- package/src/components/dataviews-layouts/activity/activity-item.tsx +2 -3
- package/src/components/dataviews-layouts/activity/style.scss +1 -1
- package/src/components/dataviews-layouts/grid/composite-grid.tsx +3 -3
- package/src/components/dataviews-layouts/grid/style.scss +1 -1
- package/src/components/dataviews-layouts/list/index.tsx +2 -3
- package/src/components/dataviews-layouts/list/style.scss +1 -1
- package/src/components/dataviews-layouts/picker-grid/index.tsx +5 -9
- package/src/components/dataviews-layouts/picker-grid/style.scss +1 -1
- package/src/components/dataviews-layouts/picker-table/index.tsx +9 -7
- package/src/components/dataviews-layouts/picker-table/style.scss +1 -1
- package/src/components/dataviews-layouts/table/index.tsx +0 -2
- package/src/dataform/stories/content.story.tsx +1 -1
- package/src/dataform/stories/data-adapter.tsx +6 -6
- package/src/dataform/stories/layout-card.tsx +8 -8
- package/src/dataform/stories/layout-details.tsx +5 -5
- package/src/dataform/stories/layout-panel.tsx +9 -9
- package/src/dataform/stories/layout-regular.tsx +16 -9
- package/src/dataform/stories/layout-row.tsx +9 -9
- package/src/dataform/stories/validation.tsx +25 -10
- package/src/dataviews/index.tsx +11 -7
- package/src/dataviews/stories/empty.tsx +6 -6
- package/src/dataviews/stories/fixtures.tsx +2 -2
- package/src/dataviews/stories/free-composition.tsx +10 -13
- package/src/dataviews/stories/infinite-scroll.tsx +4 -4
- package/src/dataviews/stories/layout-activity.tsx +7 -9
- package/src/dataviews/stories/layout-custom.tsx +1 -1
- package/src/dataviews/stories/layout-grid.tsx +5 -7
- package/src/dataviews/stories/layout-list.tsx +6 -8
- package/src/dataviews/stories/layout-table.tsx +5 -7
- package/src/dataviews/stories/minimal-ui.tsx +1 -1
- package/src/dataviews/stories/with-card.tsx +4 -7
- package/src/dataviews/style.scss +1 -1
- package/src/dataviews/test/dataviews.tsx +73 -6
- package/src/dataviews-picker/index.tsx +17 -7
- package/src/dataviews-picker/stories/index.story.tsx +1 -5
- package/src/dataviews-picker/test/dataviews-picker.tsx +79 -2
- package/src/field-types/date.tsx +3 -0
- package/src/field-types/datetime.tsx +3 -0
- package/src/field-types/stories/index.story.tsx +1 -1
- package/src/field-types/test/normalize-fields.ts +44 -0
- package/src/field-types/utils/get-is-valid.ts +44 -31
- package/src/field-types/utils/is-valid-date-boundary.ts +80 -0
- package/src/hooks/test/use-form-validity.ts +479 -0
- package/src/types/dataviews.ts +9 -0
- package/src/types/field-api.ts +11 -9
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
pin,
|
|
16
16
|
link,
|
|
17
17
|
} from '@wordpress/icons';
|
|
18
|
-
import { Button, __experimentalText as
|
|
18
|
+
import { Button, __experimentalText as WCText } from '@wordpress/components';
|
|
19
19
|
import { Stack } from '@wordpress/ui';
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -555,7 +555,7 @@ export const orderEventActions: Action< OrderEvent >[] = [
|
|
|
555
555
|
};
|
|
556
556
|
return (
|
|
557
557
|
<Stack direction="column" gap="xl">
|
|
558
|
-
<
|
|
558
|
+
<WCText>{ label }</WCText>
|
|
559
559
|
<Stack direction="row" gap="sm" justify="right">
|
|
560
560
|
<Button
|
|
561
561
|
__next40pxDefaultSize
|
|
@@ -640,13 +640,11 @@ const LayoutActivityComponent = ( {
|
|
|
640
640
|
|
|
641
641
|
return (
|
|
642
642
|
<div
|
|
643
|
-
style={
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
} as React.CSSProperties
|
|
649
|
-
}
|
|
643
|
+
style={ {
|
|
644
|
+
height: '100%',
|
|
645
|
+
maxWidth: fullWidth ? undefined : '400px',
|
|
646
|
+
'--wp-dataviews-color-background': backgroundColor,
|
|
647
|
+
} }
|
|
650
648
|
>
|
|
651
649
|
<DataViews
|
|
652
650
|
getItemId={ ( item ) => item.id.toString() }
|
|
@@ -130,7 +130,7 @@ export const LayoutCustomComponent = ( {
|
|
|
130
130
|
view={ view }
|
|
131
131
|
fields={ fields }
|
|
132
132
|
onChangeView={ setView }
|
|
133
|
-
defaultLayouts={ { table:
|
|
133
|
+
defaultLayouts={ { table: true } }
|
|
134
134
|
>
|
|
135
135
|
<div style={ { padding: '2px', height: containerHeight } }>
|
|
136
136
|
<DataViews.Search />
|
|
@@ -61,12 +61,10 @@ export const LayoutTableComponent = ( {
|
|
|
61
61
|
}, [ view ] );
|
|
62
62
|
return (
|
|
63
63
|
<div
|
|
64
|
-
style={
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
} as React.CSSProperties
|
|
69
|
-
}
|
|
64
|
+
style={ {
|
|
65
|
+
height: '100%',
|
|
66
|
+
'--wp-dataviews-color-background': backgroundColor,
|
|
67
|
+
} }
|
|
70
68
|
>
|
|
71
69
|
<DataViews
|
|
72
70
|
getItemId={ ( item ) => item.id.toString() }
|
|
@@ -97,7 +95,7 @@ export const LayoutTableComponent = ( {
|
|
|
97
95
|
) }
|
|
98
96
|
isItemClickable={ () => hasClickableItems }
|
|
99
97
|
defaultLayouts={ {
|
|
100
|
-
[ LAYOUT_GRID ]:
|
|
98
|
+
[ LAYOUT_GRID ]: true,
|
|
101
99
|
} }
|
|
102
100
|
config={ { perPageSizes } }
|
|
103
101
|
/>
|
|
@@ -63,13 +63,11 @@ export const LayoutTableComponent = ( {
|
|
|
63
63
|
}, [ view ] );
|
|
64
64
|
return (
|
|
65
65
|
<div
|
|
66
|
-
style={
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
} as React.CSSProperties
|
|
72
|
-
}
|
|
66
|
+
style={ {
|
|
67
|
+
height: '100%',
|
|
68
|
+
maxWidth: fullWidth ? undefined : '400px',
|
|
69
|
+
'--wp-dataviews-color-background': backgroundColor,
|
|
70
|
+
} }
|
|
73
71
|
>
|
|
74
72
|
<DataViews
|
|
75
73
|
getItemId={ ( item ) => item.id.toString() }
|
|
@@ -100,7 +98,7 @@ export const LayoutTableComponent = ( {
|
|
|
100
98
|
) }
|
|
101
99
|
isItemClickable={ () => hasClickableItems }
|
|
102
100
|
defaultLayouts={ {
|
|
103
|
-
[ LAYOUT_LIST ]:
|
|
101
|
+
[ LAYOUT_LIST ]: true,
|
|
104
102
|
} }
|
|
105
103
|
config={ { perPageSizes } }
|
|
106
104
|
/>
|
|
@@ -62,12 +62,10 @@ export const LayoutTableComponent = ( {
|
|
|
62
62
|
}, [ view ] );
|
|
63
63
|
return (
|
|
64
64
|
<div
|
|
65
|
-
style={
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
} as React.CSSProperties
|
|
70
|
-
}
|
|
65
|
+
style={ {
|
|
66
|
+
height: '100%',
|
|
67
|
+
'--wp-dataviews-color-background': backgroundColor,
|
|
68
|
+
} }
|
|
71
69
|
>
|
|
72
70
|
<DataViews
|
|
73
71
|
getItemId={ ( item ) => item.id.toString() }
|
|
@@ -98,7 +96,7 @@ export const LayoutTableComponent = ( {
|
|
|
98
96
|
) }
|
|
99
97
|
isItemClickable={ () => hasClickableItems }
|
|
100
98
|
defaultLayouts={ {
|
|
101
|
-
[ LAYOUT_TABLE ]:
|
|
99
|
+
[ LAYOUT_TABLE ]: true,
|
|
102
100
|
} }
|
|
103
101
|
config={ { perPageSizes } }
|
|
104
102
|
/>
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { useState, useMemo } from '@wordpress/element';
|
|
5
|
-
// TODO: enable in the ESlint rule once we complete
|
|
6
|
-
// https://github.com/WordPress/gutenberg/issues/76135.
|
|
7
|
-
// eslint-disable-next-line @wordpress/use-recommended-components
|
|
8
5
|
import { Card } from '@wordpress/ui';
|
|
9
6
|
|
|
10
7
|
/**
|
|
@@ -59,10 +56,10 @@ const WithCardComponent = ( {
|
|
|
59
56
|
( action ) => ! action.supportsBulk
|
|
60
57
|
) }
|
|
61
58
|
defaultLayouts={ {
|
|
62
|
-
[ LAYOUT_TABLE ]:
|
|
63
|
-
[ LAYOUT_GRID ]:
|
|
64
|
-
[ LAYOUT_LIST ]:
|
|
65
|
-
[ LAYOUT_ACTIVITY ]:
|
|
59
|
+
[ LAYOUT_TABLE ]: true,
|
|
60
|
+
[ LAYOUT_GRID ]: true,
|
|
61
|
+
[ LAYOUT_LIST ]: true,
|
|
62
|
+
[ LAYOUT_ACTIVITY ]: true,
|
|
66
63
|
} }
|
|
67
64
|
/>
|
|
68
65
|
</Card.FullBleed>
|
package/src/dataviews/style.scss
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
LAYOUT_LIST,
|
|
20
20
|
LAYOUT_TABLE,
|
|
21
21
|
} from '../../constants';
|
|
22
|
-
import type { Action, View } from '../../types';
|
|
22
|
+
import type { Action, SupportedLayouts, View } from '../../types';
|
|
23
23
|
import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
|
|
24
24
|
|
|
25
25
|
type Data = {
|
|
@@ -38,11 +38,11 @@ const DEFAULT_VIEW = {
|
|
|
38
38
|
filters: [],
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
const defaultLayouts = {
|
|
42
|
-
[ LAYOUT_TABLE ]:
|
|
43
|
-
[ LAYOUT_GRID ]:
|
|
44
|
-
[ LAYOUT_LIST ]:
|
|
45
|
-
[ LAYOUT_ACTIVITY ]:
|
|
41
|
+
const defaultLayouts: SupportedLayouts = {
|
|
42
|
+
[ LAYOUT_TABLE ]: true,
|
|
43
|
+
[ LAYOUT_GRID ]: true,
|
|
44
|
+
[ LAYOUT_LIST ]: true,
|
|
45
|
+
[ LAYOUT_ACTIVITY ]: true,
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
const fields = [
|
|
@@ -737,4 +737,71 @@ describe( 'DataViews component', () => {
|
|
|
737
737
|
).toEqual( 3 );
|
|
738
738
|
} );
|
|
739
739
|
} );
|
|
740
|
+
describe( 'Default layouts', () => {
|
|
741
|
+
/**
|
|
742
|
+
* A minimal wrapper that intentionally omits the `defaultLayouts` prop so
|
|
743
|
+
* DataViews falls back to its internal DEFAULT_LAYOUTS constant
|
|
744
|
+
* ({ table: true, grid: true, list: true }).
|
|
745
|
+
*/
|
|
746
|
+
function DataViewWrapperWithoutDefaultLayouts() {
|
|
747
|
+
const [ view, setView ] = useState< View >( {
|
|
748
|
+
...DEFAULT_VIEW,
|
|
749
|
+
fields: [ 'title', 'order', 'author' ],
|
|
750
|
+
} );
|
|
751
|
+
|
|
752
|
+
const { data: shownData, paginationInfo } = useMemo( () => {
|
|
753
|
+
return filterSortAndPaginate( data, view, fields );
|
|
754
|
+
}, [ view ] );
|
|
755
|
+
|
|
756
|
+
return (
|
|
757
|
+
<DataViews
|
|
758
|
+
getItemId={ ( item: Data ) => item.id.toString() }
|
|
759
|
+
paginationInfo={ paginationInfo }
|
|
760
|
+
data={ shownData }
|
|
761
|
+
view={ view }
|
|
762
|
+
fields={ fields }
|
|
763
|
+
onChangeView={ setView }
|
|
764
|
+
// No `defaultLayouts` prop — falls back to DEFAULT_LAYOUTS
|
|
765
|
+
/>
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
it( 'renders Table, Grid, and List layout options when defaultLayouts is not provided', async () => {
|
|
770
|
+
render( <DataViewWrapperWithoutDefaultLayouts /> );
|
|
771
|
+
|
|
772
|
+
const user = userEvent.setup();
|
|
773
|
+
|
|
774
|
+
// All three default layouts are available, so the Layout switcher
|
|
775
|
+
// button (rendered by ViewTypeMenu) must be present.
|
|
776
|
+
const layoutButton = screen.getByRole( 'button', {
|
|
777
|
+
name: 'Layout',
|
|
778
|
+
} );
|
|
779
|
+
expect( layoutButton ).toBeInTheDocument();
|
|
780
|
+
|
|
781
|
+
// Open the layout menu.
|
|
782
|
+
await user.click( layoutButton );
|
|
783
|
+
|
|
784
|
+
// Table, Grid, and List options must all appear.
|
|
785
|
+
expect(
|
|
786
|
+
screen.getByRole( 'menuitemradio', { name: 'Table' } )
|
|
787
|
+
).toBeInTheDocument();
|
|
788
|
+
expect(
|
|
789
|
+
screen.getByRole( 'menuitemradio', { name: 'Grid' } )
|
|
790
|
+
).toBeInTheDocument();
|
|
791
|
+
expect(
|
|
792
|
+
screen.getByRole( 'menuitemradio', { name: 'List' } )
|
|
793
|
+
).toBeInTheDocument();
|
|
794
|
+
|
|
795
|
+
// Table is the default active layout.
|
|
796
|
+
expect(
|
|
797
|
+
screen.getByRole( 'menuitemradio', { name: 'Table' } )
|
|
798
|
+
).toBeChecked();
|
|
799
|
+
expect(
|
|
800
|
+
screen.getByRole( 'menuitemradio', { name: 'Grid' } )
|
|
801
|
+
).not.toBeChecked();
|
|
802
|
+
expect(
|
|
803
|
+
screen.getByRole( 'menuitemradio', { name: 'List' } )
|
|
804
|
+
).not.toBeChecked();
|
|
805
|
+
} );
|
|
806
|
+
} );
|
|
740
807
|
} );
|
|
@@ -62,7 +62,7 @@ type DataViewsPickerProps< Item > = {
|
|
|
62
62
|
totalItems: number;
|
|
63
63
|
totalPages: number;
|
|
64
64
|
};
|
|
65
|
-
defaultLayouts
|
|
65
|
+
defaultLayouts?: SupportedLayouts;
|
|
66
66
|
selection: string[];
|
|
67
67
|
onChangeSelection: ( items: string[] ) => void;
|
|
68
68
|
children?: ReactNode;
|
|
@@ -71,12 +71,17 @@ type DataViewsPickerProps< Item > = {
|
|
|
71
71
|
};
|
|
72
72
|
itemListLabel?: string;
|
|
73
73
|
empty?: ReactNode;
|
|
74
|
+
onReset?: ( () => void ) | false;
|
|
74
75
|
} & ( Item extends ItemWithId
|
|
75
76
|
? { getItemId?: ( item: Item ) => string }
|
|
76
77
|
: { getItemId: ( item: Item ) => string } );
|
|
77
78
|
|
|
78
79
|
const defaultGetItemId = ( item: ItemWithId ) => item.id;
|
|
79
80
|
const EMPTY_ARRAY: any[] = [];
|
|
81
|
+
const DEFAULT_PICKER_LAYOUTS: SupportedLayouts = {
|
|
82
|
+
pickerGrid: true,
|
|
83
|
+
pickerTable: true,
|
|
84
|
+
};
|
|
80
85
|
|
|
81
86
|
type DefaultUIProps = Pick<
|
|
82
87
|
DataViewsPickerProps< any >,
|
|
@@ -132,13 +137,14 @@ function DataViewsPicker< Item >( {
|
|
|
132
137
|
getItemId = defaultGetItemId,
|
|
133
138
|
isLoading = false,
|
|
134
139
|
paginationInfo,
|
|
135
|
-
defaultLayouts: defaultLayoutsProperty,
|
|
140
|
+
defaultLayouts: defaultLayoutsProperty = DEFAULT_PICKER_LAYOUTS,
|
|
136
141
|
selection,
|
|
137
142
|
onChangeSelection,
|
|
138
143
|
children,
|
|
139
144
|
config = { perPageSizes: [ 10, 20, 50, 100 ] },
|
|
140
145
|
itemListLabel,
|
|
141
146
|
empty,
|
|
147
|
+
onReset,
|
|
142
148
|
}: DataViewsPickerProps< Item > ) {
|
|
143
149
|
// useData ensures data loading is correct whether infinite scroll is enabled or pagination is used.
|
|
144
150
|
const { data: displayData, setVisibleEntries } = useData( {
|
|
@@ -198,17 +204,20 @@ function DataViewsPicker< Item >( {
|
|
|
198
204
|
}
|
|
199
205
|
}, [ hasPrimaryOrLockedFilters, isShowingFilter ] );
|
|
200
206
|
|
|
201
|
-
// Filter out
|
|
207
|
+
// Filter out non-picker layouts and normalize `true` to `{}`.
|
|
202
208
|
const defaultLayouts = useMemo(
|
|
203
209
|
() =>
|
|
204
210
|
Object.fromEntries(
|
|
205
|
-
Object.entries( defaultLayoutsProperty )
|
|
206
|
-
( [ layoutType ] ) => {
|
|
211
|
+
Object.entries( defaultLayoutsProperty )
|
|
212
|
+
.filter( ( [ layoutType ] ) => {
|
|
207
213
|
return dataViewsPickerLayouts.some(
|
|
208
214
|
( viewLayout ) => viewLayout.type === layoutType
|
|
209
215
|
);
|
|
210
|
-
}
|
|
211
|
-
|
|
216
|
+
} )
|
|
217
|
+
.map( ( [ key, value ] ) => [
|
|
218
|
+
key,
|
|
219
|
+
value === true ? {} : value,
|
|
220
|
+
] )
|
|
212
221
|
),
|
|
213
222
|
[ defaultLayoutsProperty ]
|
|
214
223
|
);
|
|
@@ -243,6 +252,7 @@ function DataViewsPicker< Item >( {
|
|
|
243
252
|
config,
|
|
244
253
|
itemListLabel,
|
|
245
254
|
empty,
|
|
255
|
+
onReset,
|
|
246
256
|
hasInitiallyLoaded: true,
|
|
247
257
|
intersectionObserver,
|
|
248
258
|
} }
|
|
@@ -14,7 +14,7 @@ import { Stack } from '@wordpress/ui';
|
|
|
14
14
|
* Internal dependencies
|
|
15
15
|
*/
|
|
16
16
|
import DataViewsPicker from '../index';
|
|
17
|
-
import { LAYOUT_PICKER_GRID
|
|
17
|
+
import { LAYOUT_PICKER_GRID } from '../../constants';
|
|
18
18
|
import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
|
|
19
19
|
import type { ActionButton, View } from '../../types';
|
|
20
20
|
import { data, fields, type SpaceObject } from './fixtures';
|
|
@@ -187,10 +187,6 @@ const DataViewsPickerContent = ( {
|
|
|
187
187
|
onChangeView={ setView }
|
|
188
188
|
config={ { perPageSizes } }
|
|
189
189
|
itemListLabel="Galactic Bodies"
|
|
190
|
-
defaultLayouts={ {
|
|
191
|
-
[ LAYOUT_PICKER_GRID ]: {},
|
|
192
|
-
[ LAYOUT_PICKER_TABLE ]: {},
|
|
193
|
-
} }
|
|
194
190
|
/>
|
|
195
191
|
</>
|
|
196
192
|
);
|
|
@@ -14,7 +14,12 @@ import { useMemo, useState } from '@wordpress/element';
|
|
|
14
14
|
*/
|
|
15
15
|
import DataViewsPicker from '../index';
|
|
16
16
|
import { LAYOUT_PICKER_GRID } from '../../constants';
|
|
17
|
-
import type {
|
|
17
|
+
import type {
|
|
18
|
+
ActionButton,
|
|
19
|
+
SupportedLayouts,
|
|
20
|
+
View,
|
|
21
|
+
ViewPickerGrid,
|
|
22
|
+
} from '../../types';
|
|
18
23
|
import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
|
|
19
24
|
|
|
20
25
|
type Data = {
|
|
@@ -107,7 +112,7 @@ function Picker( {
|
|
|
107
112
|
paginationInfo,
|
|
108
113
|
data: shownData,
|
|
109
114
|
view,
|
|
110
|
-
defaultLayouts: { [ LAYOUT_PICKER_GRID ]:
|
|
115
|
+
defaultLayouts: { [ LAYOUT_PICKER_GRID ]: true } as SupportedLayouts,
|
|
111
116
|
fields: [],
|
|
112
117
|
onChangeView: setView,
|
|
113
118
|
multiselect,
|
|
@@ -475,4 +480,76 @@ describe( 'DataViews Picker', () => {
|
|
|
475
480
|
} );
|
|
476
481
|
} );
|
|
477
482
|
} );
|
|
483
|
+
|
|
484
|
+
describe( 'Default layouts', () => {
|
|
485
|
+
/**
|
|
486
|
+
* A minimal Picker that intentionally omits the `defaultLayouts` prop so
|
|
487
|
+
* that DataViewsPicker falls back to its internal DEFAULT_PICKER_LAYOUTS
|
|
488
|
+
* constant ({ pickerGrid: true, pickerTable: true }).
|
|
489
|
+
*/
|
|
490
|
+
function PickerWithoutDefaultLayouts() {
|
|
491
|
+
const [ view, setView ] = useState< View >( {
|
|
492
|
+
type: LAYOUT_PICKER_GRID,
|
|
493
|
+
fields: [],
|
|
494
|
+
titleField: 'title',
|
|
495
|
+
mediaField: 'image',
|
|
496
|
+
search: '',
|
|
497
|
+
page: 1,
|
|
498
|
+
perPage: 10,
|
|
499
|
+
filters: [],
|
|
500
|
+
} satisfies ViewPickerGrid );
|
|
501
|
+
|
|
502
|
+
const [ selection, setSelection ] = useState< string[] >( [] );
|
|
503
|
+
|
|
504
|
+
const { data: shownData, paginationInfo } = useMemo( () => {
|
|
505
|
+
return filterSortAndPaginate( data, view, [] );
|
|
506
|
+
}, [ view ] );
|
|
507
|
+
|
|
508
|
+
return (
|
|
509
|
+
<DataViewsPicker
|
|
510
|
+
getItemId={ ( item: Data ) => item.id.toString() }
|
|
511
|
+
paginationInfo={ paginationInfo }
|
|
512
|
+
data={ shownData }
|
|
513
|
+
view={ view }
|
|
514
|
+
fields={ [] }
|
|
515
|
+
onChangeView={ setView }
|
|
516
|
+
selection={ selection }
|
|
517
|
+
onChangeSelection={ setSelection }
|
|
518
|
+
// No `defaultLayouts` prop falls back to DEFAULT_PICKER_LAYOUTS
|
|
519
|
+
/>
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
it( 'renders both picker layout options when defaultLayouts is not provided', async () => {
|
|
524
|
+
render( <PickerWithoutDefaultLayouts /> );
|
|
525
|
+
|
|
526
|
+
const user = userEvent.setup();
|
|
527
|
+
|
|
528
|
+
// Both picker layouts are available, so the Layout switcher button
|
|
529
|
+
// (rendered by ViewTypeMenu) must be present.
|
|
530
|
+
const layoutButton = screen.getByRole( 'button', {
|
|
531
|
+
name: 'Layout',
|
|
532
|
+
} );
|
|
533
|
+
expect( layoutButton ).toBeInTheDocument();
|
|
534
|
+
|
|
535
|
+
// Open the layout menu.
|
|
536
|
+
await user.click( layoutButton );
|
|
537
|
+
|
|
538
|
+
// Both "Grid" and "Table" picker layout options must appear in the menu.
|
|
539
|
+
expect(
|
|
540
|
+
screen.getByRole( 'menuitemradio', { name: 'Grid' } )
|
|
541
|
+
).toBeInTheDocument();
|
|
542
|
+
expect(
|
|
543
|
+
screen.getByRole( 'menuitemradio', { name: 'Table' } )
|
|
544
|
+
).toBeInTheDocument();
|
|
545
|
+
|
|
546
|
+
// The grid layout is active by default.
|
|
547
|
+
expect(
|
|
548
|
+
screen.getByRole( 'menuitemradio', { name: 'Grid' } )
|
|
549
|
+
).toBeChecked();
|
|
550
|
+
expect(
|
|
551
|
+
screen.getByRole( 'menuitemradio', { name: 'Table' } )
|
|
552
|
+
).not.toBeChecked();
|
|
553
|
+
} );
|
|
554
|
+
} );
|
|
478
555
|
} );
|
package/src/field-types/date.tsx
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
OPERATOR_BETWEEN,
|
|
22
22
|
} from '../constants';
|
|
23
23
|
import isValidRequired from './utils/is-valid-required';
|
|
24
|
+
import { isValidMaxDate, isValidMinDate } from './utils/is-valid-date-boundary';
|
|
24
25
|
import render from './utils/render-default';
|
|
25
26
|
|
|
26
27
|
const format = {
|
|
@@ -91,5 +92,7 @@ export default {
|
|
|
91
92
|
validate: {
|
|
92
93
|
required: isValidRequired,
|
|
93
94
|
elements: isValidElements,
|
|
95
|
+
min: isValidMinDate,
|
|
96
|
+
max: isValidMaxDate,
|
|
94
97
|
},
|
|
95
98
|
} satisfies FieldType< any >;
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
OPERATOR_OVER,
|
|
21
21
|
} from '../constants';
|
|
22
22
|
import isValidRequired from './utils/is-valid-required';
|
|
23
|
+
import { isValidMaxDate, isValidMinDate } from './utils/is-valid-date-boundary';
|
|
23
24
|
import render from './utils/render-default';
|
|
24
25
|
|
|
25
26
|
const format = {
|
|
@@ -88,5 +89,7 @@ export default {
|
|
|
88
89
|
validate: {
|
|
89
90
|
required: isValidRequired,
|
|
90
91
|
elements: isValidElements,
|
|
92
|
+
min: isValidMinDate,
|
|
93
|
+
max: isValidMaxDate,
|
|
91
94
|
},
|
|
92
95
|
} satisfies FieldType< any >;
|
|
@@ -339,6 +339,50 @@ describe( 'normalizeFields: default getValue', () => {
|
|
|
339
339
|
} );
|
|
340
340
|
} );
|
|
341
341
|
|
|
342
|
+
describe( 'validation normalization', () => {
|
|
343
|
+
it( 'ignores string min/max rules on numeric fields', () => {
|
|
344
|
+
const fields: Field< {} >[] = [
|
|
345
|
+
{
|
|
346
|
+
id: 'price',
|
|
347
|
+
type: 'number',
|
|
348
|
+
isValid: {
|
|
349
|
+
min: '1',
|
|
350
|
+
max: '10',
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
];
|
|
354
|
+
const normalizedFields = normalizeFields( fields );
|
|
355
|
+
expect( normalizedFields[ 0 ].isValid.min ).toBeUndefined();
|
|
356
|
+
expect( normalizedFields[ 0 ].isValid.max ).toBeUndefined();
|
|
357
|
+
} );
|
|
358
|
+
|
|
359
|
+
it( 'ignores numeric min/max rules on date-like fields', () => {
|
|
360
|
+
const fields: Field< {} >[] = [
|
|
361
|
+
{
|
|
362
|
+
id: 'publishDate',
|
|
363
|
+
type: 'date',
|
|
364
|
+
isValid: {
|
|
365
|
+
min: 1,
|
|
366
|
+
max: 10,
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
id: 'publishedAt',
|
|
371
|
+
type: 'datetime',
|
|
372
|
+
isValid: {
|
|
373
|
+
min: 1,
|
|
374
|
+
max: 10,
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
];
|
|
378
|
+
const normalizedFields = normalizeFields( fields );
|
|
379
|
+
expect( normalizedFields[ 0 ].isValid.min ).toBeUndefined();
|
|
380
|
+
expect( normalizedFields[ 0 ].isValid.max ).toBeUndefined();
|
|
381
|
+
expect( normalizedFields[ 1 ].isValid.min ).toBeUndefined();
|
|
382
|
+
expect( normalizedFields[ 1 ].isValid.max ).toBeUndefined();
|
|
383
|
+
} );
|
|
384
|
+
} );
|
|
385
|
+
|
|
342
386
|
describe( 'format normalization', () => {
|
|
343
387
|
it( 'applies default format when not provided for date fields', () => {
|
|
344
388
|
const fields: Field< {} >[] = [
|