@wordpress/dataviews 11.2.1-next.v.0 → 11.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -1
- package/build/components/dataform-controls/combobox.cjs +80 -0
- package/build/components/dataform-controls/combobox.cjs.map +7 -0
- package/build/components/dataform-controls/date.cjs +35 -10
- package/build/components/dataform-controls/date.cjs.map +2 -2
- package/build/components/dataform-controls/index.cjs +2 -0
- package/build/components/dataform-controls/index.cjs.map +3 -3
- package/build/components/dataform-layouts/card/index.cjs +58 -3
- package/build/components/dataform-layouts/card/index.cjs.map +3 -3
- package/build/components/dataform-layouts/panel/dropdown.cjs +18 -8
- package/build/components/dataform-layouts/panel/dropdown.cjs.map +3 -3
- package/build/components/dataform-layouts/panel/index.cjs +5 -3
- package/build/components/dataform-layouts/panel/index.cjs.map +2 -2
- package/build/components/dataform-layouts/panel/modal.cjs +16 -10
- package/build/components/dataform-layouts/panel/modal.cjs.map +3 -3
- package/build/components/dataviews-bulk-actions/index.cjs +16 -18
- package/build/components/dataviews-bulk-actions/index.cjs.map +3 -3
- package/build/components/dataviews-item-actions/index.cjs +4 -1
- package/build/components/dataviews-item-actions/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/activity/activity-item.cjs +6 -1
- package/build/components/dataviews-layouts/activity/activity-item.cjs.map +2 -2
- package/build/components/dataviews-layouts/table/column-header-menu.cjs +73 -66
- package/build/components/dataviews-layouts/table/column-header-menu.cjs.map +2 -2
- package/build/components/dataviews-layouts/table/index.cjs +3 -2
- package/build/components/dataviews-layouts/table/index.cjs.map +2 -2
- package/build/components/dataviews-picker-footer/index.cjs +8 -15
- package/build/components/dataviews-picker-footer/index.cjs.map +3 -3
- package/build/field-types/index.cjs +2 -0
- package/build/field-types/index.cjs.map +3 -3
- package/build/field-types/utils/get-filter.cjs +36 -0
- package/build/field-types/utils/get-filter.cjs.map +7 -0
- package/build/hooks/use-report-validity.cjs +39 -0
- package/build/hooks/use-report-validity.cjs.map +7 -0
- package/build/types/field-api.cjs.map +1 -1
- package/build/utils/filter-sort-and-paginate.cjs +6 -174
- package/build/utils/filter-sort-and-paginate.cjs.map +2 -2
- package/build/utils/get-footer-message.cjs +49 -0
- package/build/utils/get-footer-message.cjs.map +7 -0
- package/build/utils/operators.cjs +203 -24
- package/build/utils/operators.cjs.map +2 -2
- package/build-module/components/dataform-controls/combobox.mjs +49 -0
- package/build-module/components/dataform-controls/combobox.mjs.map +7 -0
- package/build-module/components/dataform-controls/date.mjs +35 -10
- package/build-module/components/dataform-controls/date.mjs.map +2 -2
- package/build-module/components/dataform-controls/index.mjs +2 -0
- package/build-module/components/dataform-controls/index.mjs.map +2 -2
- package/build-module/components/dataform-layouts/card/index.mjs +59 -3
- package/build-module/components/dataform-layouts/card/index.mjs.map +2 -2
- package/build-module/components/dataform-layouts/panel/dropdown.mjs +20 -10
- package/build-module/components/dataform-layouts/panel/dropdown.mjs.map +2 -2
- package/build-module/components/dataform-layouts/panel/index.mjs +5 -3
- package/build-module/components/dataform-layouts/panel/index.mjs.map +2 -2
- package/build-module/components/dataform-layouts/panel/modal.mjs +18 -12
- package/build-module/components/dataform-layouts/panel/modal.mjs.map +2 -2
- package/build-module/components/dataviews-bulk-actions/index.mjs +17 -19
- package/build-module/components/dataviews-bulk-actions/index.mjs.map +2 -2
- package/build-module/components/dataviews-item-actions/index.mjs +4 -1
- package/build-module/components/dataviews-item-actions/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/activity/activity-item.mjs +6 -1
- package/build-module/components/dataviews-layouts/activity/activity-item.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/table/column-header-menu.mjs +74 -67
- package/build-module/components/dataviews-layouts/table/column-header-menu.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/table/index.mjs +4 -3
- package/build-module/components/dataviews-layouts/table/index.mjs.map +2 -2
- package/build-module/components/dataviews-picker-footer/index.mjs +8 -15
- package/build-module/components/dataviews-picker-footer/index.mjs.map +2 -2
- package/build-module/field-types/index.mjs +2 -0
- package/build-module/field-types/index.mjs.map +2 -2
- package/build-module/field-types/utils/get-filter.mjs +15 -0
- package/build-module/field-types/utils/get-filter.mjs.map +7 -0
- package/build-module/hooks/use-report-validity.mjs +18 -0
- package/build-module/hooks/use-report-validity.mjs.map +7 -0
- package/build-module/utils/filter-sort-and-paginate.mjs +7 -198
- package/build-module/utils/filter-sort-and-paginate.mjs.map +2 -2
- package/build-module/utils/get-footer-message.mjs +28 -0
- package/build-module/utils/get-footer-message.mjs.map +7 -0
- package/build-module/utils/operators.mjs +203 -24
- package/build-module/utils/operators.mjs.map +2 -2
- package/build-style/style-rtl.css +15 -16
- package/build-style/style.css +15 -16
- package/build-types/components/dataform-controls/combobox.d.ts +6 -0
- package/build-types/components/dataform-controls/combobox.d.ts.map +1 -0
- package/build-types/components/dataform-controls/date.d.ts.map +1 -1
- package/build-types/components/dataform-controls/index.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/card/index.d.ts +2 -0
- package/build-types/components/dataform-layouts/card/index.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/panel/dropdown.d.ts +3 -2
- package/build-types/components/dataform-layouts/panel/dropdown.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/panel/index.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/panel/modal.d.ts +3 -2
- package/build-types/components/dataform-layouts/panel/modal.d.ts.map +1 -1
- package/build-types/components/dataviews-bulk-actions/index.d.ts.map +1 -1
- package/build-types/components/dataviews-item-actions/index.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/table/column-header-menu.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/table/index.d.ts.map +1 -1
- package/build-types/components/dataviews-picker-footer/index.d.ts.map +1 -1
- package/build-types/dataform/stories/content.story.d.ts +14 -0
- package/build-types/dataform/stories/content.story.d.ts.map +1 -0
- package/build-types/dataform/stories/index.story.d.ts +1 -1
- package/build-types/dataform/stories/index.story.d.ts.map +1 -1
- package/build-types/dataform/stories/validation.d.ts +1 -1
- package/build-types/dataform/stories/validation.d.ts.map +1 -1
- package/build-types/dataviews/stories/fixtures.d.ts.map +1 -1
- package/build-types/dataviews/stories/index.story.d.ts +4 -1
- package/build-types/dataviews/stories/index.story.d.ts.map +1 -1
- package/build-types/dataviews/stories/layout-custom.d.ts +11 -0
- package/build-types/dataviews/stories/layout-custom.d.ts.map +1 -0
- package/build-types/dataviews-picker/stories/fixtures.d.ts.map +1 -1
- package/build-types/dataviews-picker/stories/index.story.d.ts +1 -1
- package/build-types/dataviews-picker/stories/index.story.d.ts.map +1 -1
- package/build-types/field-types/index.d.ts.map +1 -1
- package/build-types/field-types/stories/index.story.d.ts +1 -1
- package/build-types/field-types/stories/index.story.d.ts.map +1 -1
- package/build-types/field-types/utils/get-filter.d.ts +7 -0
- package/build-types/field-types/utils/get-filter.d.ts.map +1 -0
- package/build-types/hooks/use-report-validity.d.ts +14 -0
- package/build-types/hooks/use-report-validity.d.ts.map +1 -0
- package/build-types/types/field-api.d.ts +3 -0
- package/build-types/types/field-api.d.ts.map +1 -1
- package/build-types/utils/filter-sort-and-paginate.d.ts.map +1 -1
- package/build-types/utils/get-footer-message.d.ts +10 -0
- package/build-types/utils/get-footer-message.d.ts.map +1 -0
- package/build-types/utils/operators.d.ts +2 -1
- package/build-types/utils/operators.d.ts.map +1 -1
- package/build-wp/index.js +2730 -2179
- package/package.json +22 -20
- package/src/components/dataform-controls/combobox.tsx +58 -0
- package/src/components/dataform-controls/date.tsx +45 -10
- package/src/components/dataform-controls/index.tsx +2 -0
- package/src/components/dataform-layouts/card/index.tsx +81 -3
- package/src/components/dataform-layouts/panel/dropdown.tsx +26 -11
- package/src/components/dataform-layouts/panel/index.tsx +6 -4
- package/src/components/dataform-layouts/panel/modal.tsx +24 -12
- package/src/components/dataviews-bulk-actions/index.tsx +23 -20
- package/src/components/dataviews-bulk-actions/style.scss +0 -3
- package/src/components/dataviews-item-actions/index.tsx +6 -1
- package/src/components/dataviews-layouts/activity/activity-item.tsx +8 -1
- package/src/components/dataviews-layouts/table/column-header-menu.tsx +99 -73
- package/src/components/dataviews-layouts/table/index.tsx +12 -3
- package/src/components/dataviews-layouts/table/style.scss +14 -7
- package/src/components/dataviews-picker-footer/index.tsx +8 -18
- package/src/dataform/stories/content.story.mdx +159 -0
- package/src/dataform/stories/content.story.tsx +390 -0
- package/src/dataform/stories/index.story.tsx +8 -1
- package/src/dataform/stories/validation.tsx +98 -5
- package/src/dataviews/stories/best-practices.story.mdx +55 -0
- package/src/dataviews/stories/fixtures.tsx +1 -3
- package/src/dataviews/stories/index.story.tsx +6 -1
- package/src/dataviews/stories/layout-custom.tsx +140 -0
- package/src/dataviews/test/dataviews.tsx +66 -1
- package/src/dataviews-picker/stories/fixtures.tsx +1 -3
- package/src/dataviews-picker/stories/index.story.tsx +1 -1
- package/src/field-types/index.tsx +2 -0
- package/src/field-types/stories/index.story.tsx +2 -0
- package/src/field-types/utils/get-filter.ts +18 -0
- package/src/hooks/use-report-validity.ts +32 -0
- package/src/types/field-api.ts +11 -0
- package/src/utils/filter-sort-and-paginate.ts +11 -306
- package/src/utils/get-footer-message.ts +41 -0
- package/src/utils/operators.tsx +303 -31
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useState, useMemo } from '@wordpress/element';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import DataViews from '../index';
|
|
10
|
+
import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
|
|
11
|
+
import type { View } from '../../types';
|
|
12
|
+
import { data, fields } from './fixtures';
|
|
13
|
+
import { LAYOUT_TABLE } from '../../constants';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Poster/hero style layout that displays items as large image cards
|
|
17
|
+
* with overlaid text content.
|
|
18
|
+
*/
|
|
19
|
+
function PosterGrid( { items }: { items: typeof data } ) {
|
|
20
|
+
return (
|
|
21
|
+
<div
|
|
22
|
+
style={ {
|
|
23
|
+
display: 'grid',
|
|
24
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
|
|
25
|
+
gap: '16px',
|
|
26
|
+
padding: '16px 0',
|
|
27
|
+
} }
|
|
28
|
+
>
|
|
29
|
+
{ items.map( ( item ) => (
|
|
30
|
+
<div
|
|
31
|
+
key={ item.id }
|
|
32
|
+
style={ {
|
|
33
|
+
position: 'relative',
|
|
34
|
+
aspectRatio: '4 / 3',
|
|
35
|
+
borderRadius: '8px',
|
|
36
|
+
overflow: 'hidden',
|
|
37
|
+
backgroundImage: `url(${ item.image })`,
|
|
38
|
+
backgroundSize: 'cover',
|
|
39
|
+
backgroundPosition: 'center',
|
|
40
|
+
} }
|
|
41
|
+
>
|
|
42
|
+
<div
|
|
43
|
+
style={ {
|
|
44
|
+
position: 'absolute',
|
|
45
|
+
bottom: 0,
|
|
46
|
+
left: 0,
|
|
47
|
+
right: 0,
|
|
48
|
+
padding: '48px 16px 16px',
|
|
49
|
+
background:
|
|
50
|
+
'linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 60%, transparent 100%)',
|
|
51
|
+
color: 'white',
|
|
52
|
+
} }
|
|
53
|
+
>
|
|
54
|
+
<h3
|
|
55
|
+
style={ {
|
|
56
|
+
margin: '0 0 4px',
|
|
57
|
+
fontSize: '18px',
|
|
58
|
+
fontWeight: 600,
|
|
59
|
+
textShadow: '0 1px 2px rgba(0,0,0,0.5)',
|
|
60
|
+
} }
|
|
61
|
+
>
|
|
62
|
+
{ item.name.title }
|
|
63
|
+
</h3>
|
|
64
|
+
<p
|
|
65
|
+
style={ {
|
|
66
|
+
margin: '0 0 8px',
|
|
67
|
+
fontSize: '13px',
|
|
68
|
+
opacity: 0.9,
|
|
69
|
+
overflow: 'hidden',
|
|
70
|
+
textOverflow: 'ellipsis',
|
|
71
|
+
whiteSpace: 'nowrap',
|
|
72
|
+
} }
|
|
73
|
+
>
|
|
74
|
+
{ item.name.description }
|
|
75
|
+
</p>
|
|
76
|
+
<div style={ { display: 'flex', gap: '6px' } }>
|
|
77
|
+
{ item.categories.slice( 0, 2 ).map( ( cat ) => (
|
|
78
|
+
<span
|
|
79
|
+
key={ cat }
|
|
80
|
+
style={ {
|
|
81
|
+
fontSize: '11px',
|
|
82
|
+
padding: '2px 8px',
|
|
83
|
+
borderRadius: '4px',
|
|
84
|
+
backgroundColor:
|
|
85
|
+
'rgba(255,255,255,0.2)',
|
|
86
|
+
} }
|
|
87
|
+
>
|
|
88
|
+
{ cat }
|
|
89
|
+
</span>
|
|
90
|
+
) ) }
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
) ) }
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Demonstrates a custom poster/hero layout using free composition.
|
|
101
|
+
*
|
|
102
|
+
* This story shows how to:
|
|
103
|
+
* - Use `<DataViews>` as a context provider with custom children
|
|
104
|
+
* - Render a completely custom layout (poster grid) instead of `<DataViews.Layout />`
|
|
105
|
+
* - Still leverage DataViews sub-components for search and pagination
|
|
106
|
+
*/
|
|
107
|
+
export const LayoutCustomComponent = () => {
|
|
108
|
+
const [ view, setView ] = useState< View >( {
|
|
109
|
+
type: LAYOUT_TABLE,
|
|
110
|
+
search: '',
|
|
111
|
+
page: 1,
|
|
112
|
+
perPage: 6,
|
|
113
|
+
filters: [],
|
|
114
|
+
fields: [],
|
|
115
|
+
} );
|
|
116
|
+
|
|
117
|
+
const { data: processedData, paginationInfo } = useMemo( () => {
|
|
118
|
+
return filterSortAndPaginate( data, view, fields );
|
|
119
|
+
}, [ view ] );
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<DataViews
|
|
123
|
+
getItemId={ ( item ) => item.id.toString() }
|
|
124
|
+
paginationInfo={ paginationInfo }
|
|
125
|
+
data={ processedData }
|
|
126
|
+
view={ view }
|
|
127
|
+
fields={ fields }
|
|
128
|
+
onChangeView={ setView }
|
|
129
|
+
defaultLayouts={ { table: {} } }
|
|
130
|
+
>
|
|
131
|
+
<div style={ { padding: '2px' } }>
|
|
132
|
+
<DataViews.Search />
|
|
133
|
+
<PosterGrid items={ processedData } />
|
|
134
|
+
<DataViews.Pagination />
|
|
135
|
+
</div>
|
|
136
|
+
</DataViews>
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export default LayoutCustomComponent;
|
|
@@ -13,7 +13,12 @@ import { useMemo, useState } from '@wordpress/element';
|
|
|
13
13
|
* Internal dependencies
|
|
14
14
|
*/
|
|
15
15
|
import DataViews from '../index';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
LAYOUT_ACTIVITY,
|
|
18
|
+
LAYOUT_GRID,
|
|
19
|
+
LAYOUT_LIST,
|
|
20
|
+
LAYOUT_TABLE,
|
|
21
|
+
} from '../../constants';
|
|
17
22
|
import type { Action, View } from '../../types';
|
|
18
23
|
import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
|
|
19
24
|
|
|
@@ -37,6 +42,7 @@ const defaultLayouts = {
|
|
|
37
42
|
[ LAYOUT_TABLE ]: {},
|
|
38
43
|
[ LAYOUT_GRID ]: {},
|
|
39
44
|
[ LAYOUT_LIST ]: {},
|
|
45
|
+
[ LAYOUT_ACTIVITY ]: {},
|
|
40
46
|
};
|
|
41
47
|
|
|
42
48
|
const fields = [
|
|
@@ -147,6 +153,10 @@ function DataViewWrapper( {
|
|
|
147
153
|
// jest.useFakeTimers();
|
|
148
154
|
|
|
149
155
|
// Tests run against a DataView which is 500px wide.
|
|
156
|
+
const mockUseViewportMatch = jest.fn(
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
158
|
+
( _viewport: string, _operator: string ) => false
|
|
159
|
+
);
|
|
150
160
|
jest.mock( '@wordpress/compose', () => {
|
|
151
161
|
return {
|
|
152
162
|
...jest.requireActual( '@wordpress/compose' ),
|
|
@@ -160,6 +170,8 @@ jest.mock( '@wordpress/compose', () => {
|
|
|
160
170
|
}, 0 );
|
|
161
171
|
return () => {};
|
|
162
172
|
} ),
|
|
173
|
+
useViewportMatch: ( viewport: string, operator: string ): boolean =>
|
|
174
|
+
mockUseViewportMatch( viewport, operator ),
|
|
163
175
|
};
|
|
164
176
|
} );
|
|
165
177
|
|
|
@@ -619,4 +631,57 @@ describe( 'DataViews component', () => {
|
|
|
619
631
|
).toEqual( 3 );
|
|
620
632
|
} );
|
|
621
633
|
} );
|
|
634
|
+
|
|
635
|
+
describe( 'actions on mobile viewport', () => {
|
|
636
|
+
const testActions: Action< Data >[] = [
|
|
637
|
+
{
|
|
638
|
+
id: 'edit',
|
|
639
|
+
label: 'Edit',
|
|
640
|
+
isPrimary: true,
|
|
641
|
+
callback: () => {},
|
|
642
|
+
},
|
|
643
|
+
];
|
|
644
|
+
|
|
645
|
+
beforeEach( () => {
|
|
646
|
+
// Simulate mobile viewport
|
|
647
|
+
mockUseViewportMatch.mockImplementation(
|
|
648
|
+
( viewport: string, operator: string ) =>
|
|
649
|
+
viewport === 'medium' && operator === '<'
|
|
650
|
+
);
|
|
651
|
+
} );
|
|
652
|
+
|
|
653
|
+
afterEach( () => {
|
|
654
|
+
mockUseViewportMatch.mockImplementation( () => false );
|
|
655
|
+
} );
|
|
656
|
+
|
|
657
|
+
it( 'should show actions dropdown on mobile even when there is only one action in table layout', () => {
|
|
658
|
+
render(
|
|
659
|
+
<DataViewWrapper
|
|
660
|
+
view={ {
|
|
661
|
+
type: LAYOUT_TABLE,
|
|
662
|
+
} }
|
|
663
|
+
actions={ testActions }
|
|
664
|
+
/>
|
|
665
|
+
);
|
|
666
|
+
// On mobile, the dropdown should be visible even with only primary actions
|
|
667
|
+
expect(
|
|
668
|
+
screen.getAllByRole( 'button', { name: 'Actions' } ).length
|
|
669
|
+
).toEqual( 3 );
|
|
670
|
+
} );
|
|
671
|
+
|
|
672
|
+
it( 'should show actions dropdown on mobile even when there is only one action in activity layout', () => {
|
|
673
|
+
render(
|
|
674
|
+
<DataViewWrapper
|
|
675
|
+
view={ {
|
|
676
|
+
type: LAYOUT_ACTIVITY,
|
|
677
|
+
} }
|
|
678
|
+
actions={ testActions }
|
|
679
|
+
/>
|
|
680
|
+
);
|
|
681
|
+
// On mobile, the dropdown should be visible even with only primary actions
|
|
682
|
+
expect(
|
|
683
|
+
screen.getAllByRole( 'button', { name: 'Actions' } ).length
|
|
684
|
+
).toEqual( 3 );
|
|
685
|
+
} );
|
|
686
|
+
} );
|
|
622
687
|
} );
|
|
@@ -326,9 +326,7 @@ export const fields: Field< SpaceObject >[] = [
|
|
|
326
326
|
</Stack>
|
|
327
327
|
),
|
|
328
328
|
render: ( { item } ) => {
|
|
329
|
-
return
|
|
330
|
-
<img src={ item.image } alt="" style={ { width: '100%' } } />
|
|
331
|
-
);
|
|
329
|
+
return <img src={ item.image } alt="" />;
|
|
332
330
|
},
|
|
333
331
|
},
|
|
334
332
|
{
|
|
@@ -28,6 +28,7 @@ import { default as color } from './color';
|
|
|
28
28
|
import { default as url } from './url';
|
|
29
29
|
import { default as noType } from './no-type';
|
|
30
30
|
import getIsValid from './utils/get-is-valid';
|
|
31
|
+
import getFilter from './utils/get-filter';
|
|
31
32
|
import getFormat from './utils/get-format';
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -111,6 +112,7 @@ export default function normalizeFields< Item >(
|
|
|
111
112
|
fieldType.defaultOperators,
|
|
112
113
|
fieldType.validOperators
|
|
113
114
|
),
|
|
115
|
+
filter: getFilter( fieldType ),
|
|
114
116
|
format: getFormat( field, fieldType ),
|
|
115
117
|
getValueFormatted:
|
|
116
118
|
field.getValueFormatted ?? fieldType.getValueFormatted,
|
|
@@ -37,6 +37,7 @@ const meta = {
|
|
|
37
37
|
'array',
|
|
38
38
|
'checkbox',
|
|
39
39
|
'color',
|
|
40
|
+
'combobox',
|
|
40
41
|
'date',
|
|
41
42
|
'datetime',
|
|
42
43
|
'email',
|
|
@@ -530,6 +531,7 @@ type ControlTypes =
|
|
|
530
531
|
| 'array'
|
|
531
532
|
| 'checkbox'
|
|
532
533
|
| 'color'
|
|
534
|
+
| 'combobox'
|
|
533
535
|
| 'date'
|
|
534
536
|
| 'datetime'
|
|
535
537
|
| 'email'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { FilterOperatorMap } from '../../types';
|
|
5
|
+
import type { FieldType } from '../../types/private';
|
|
6
|
+
import { getOperatorByName } from '../../utils/operators';
|
|
7
|
+
|
|
8
|
+
export default function getFilter< Item >(
|
|
9
|
+
fieldType: FieldType< Item >
|
|
10
|
+
): FilterOperatorMap< Item > {
|
|
11
|
+
return fieldType.validOperators.reduce( ( accumulator, operator ) => {
|
|
12
|
+
const operatorObj = getOperatorByName( operator );
|
|
13
|
+
if ( operatorObj?.filter ) {
|
|
14
|
+
accumulator[ operator ] = operatorObj.filter;
|
|
15
|
+
}
|
|
16
|
+
return accumulator;
|
|
17
|
+
}, {} as FilterOperatorMap< Item > );
|
|
18
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useEffect } from '@wordpress/element';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Triggers `reportValidity()` on all form inputs within a container element.
|
|
8
|
+
* This fires the browser's `invalid` event on each input, which validated
|
|
9
|
+
* controls listen to in order to display their error states.
|
|
10
|
+
*
|
|
11
|
+
* Used by panel and card layouts to show validation errors
|
|
12
|
+
* immediately when their content becomes visible after prior interaction.
|
|
13
|
+
*
|
|
14
|
+
* @param ref A ref to the container element.
|
|
15
|
+
* @param shouldReport Whether to trigger reportValidity. Typically
|
|
16
|
+
* derived from `touched` state and open/visible state.
|
|
17
|
+
*/
|
|
18
|
+
export default function useReportValidity(
|
|
19
|
+
ref: React.RefObject< HTMLElement | null >,
|
|
20
|
+
shouldReport: boolean
|
|
21
|
+
) {
|
|
22
|
+
useEffect( () => {
|
|
23
|
+
if ( shouldReport && ref.current ) {
|
|
24
|
+
const inputs = ref.current.querySelectorAll(
|
|
25
|
+
'input, textarea, select'
|
|
26
|
+
);
|
|
27
|
+
inputs.forEach( ( input ) => {
|
|
28
|
+
( input as HTMLInputElement ).reportValidity();
|
|
29
|
+
} );
|
|
30
|
+
}
|
|
31
|
+
}, [ shouldReport, ref ] );
|
|
32
|
+
}
|
package/src/types/field-api.ts
CHANGED
|
@@ -104,6 +104,16 @@ export type CustomValidator< Item > =
|
|
|
104
104
|
field: NormalizedField< Item >
|
|
105
105
|
) => Promise< null | string > );
|
|
106
106
|
|
|
107
|
+
export type FilterOperator< Item > = (
|
|
108
|
+
item: Item,
|
|
109
|
+
field: NormalizedField< Item >,
|
|
110
|
+
filterValue: any
|
|
111
|
+
) => boolean;
|
|
112
|
+
|
|
113
|
+
export type FilterOperatorMap< Item > = Partial<
|
|
114
|
+
Record< Operator, FilterOperator< Item > >
|
|
115
|
+
>;
|
|
116
|
+
|
|
107
117
|
type NormalizedRule< Item, ConstraintType > = {
|
|
108
118
|
constraint: ConstraintType;
|
|
109
119
|
validate: Validator< Item >;
|
|
@@ -356,6 +366,7 @@ export type NormalizedField< Item > = Omit<
|
|
|
356
366
|
enableHiding: boolean;
|
|
357
367
|
enableSorting: boolean;
|
|
358
368
|
filterBy: Required< FilterByConfig > | false;
|
|
369
|
+
filter: FilterOperatorMap< Item >;
|
|
359
370
|
readOnly: boolean;
|
|
360
371
|
format:
|
|
361
372
|
| {}
|