@wordpress/dataviews 13.1.1-next.v.202603161435.0 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -6
- package/README.md +17 -2
- package/build/components/dataform-controls/datetime.cjs +8 -4
- package/build/components/dataform-controls/datetime.cjs.map +2 -2
- package/build/components/dataform-layouts/card/index.cjs +132 -128
- package/build/components/dataform-layouts/card/index.cjs.map +3 -3
- package/build/components/dataviews-bulk-actions/index.cjs +28 -5
- package/build/components/dataviews-bulk-actions/index.cjs.map +2 -2
- package/build/components/dataviews-context/index.cjs +2 -2
- package/build/components/dataviews-context/index.cjs.map +2 -2
- package/build/components/dataviews-footer/index.cjs +2 -3
- package/build/components/dataviews-footer/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/grid/composite-grid.cjs +378 -249
- package/build/components/dataviews-layouts/grid/composite-grid.cjs.map +2 -2
- package/build/components/dataviews-layouts/picker-grid/index.cjs +63 -30
- package/build/components/dataviews-layouts/picker-grid/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/picker-table/index.cjs +34 -22
- package/build/components/dataviews-layouts/picker-table/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/utils/use-infinite-scroll.cjs +62 -0
- package/build/components/dataviews-layouts/utils/use-infinite-scroll.cjs.map +7 -0
- package/build/components/dataviews-picker-footer/index.cjs +23 -4
- package/build/components/dataviews-picker-footer/index.cjs.map +2 -2
- package/build/components/dataviews-search/index.cjs +2 -1
- package/build/components/dataviews-search/index.cjs.map +2 -2
- package/build/components/dataviews-selection-checkbox/index.cjs +3 -2
- package/build/components/dataviews-selection-checkbox/index.cjs.map +2 -2
- package/build/components/dataviews-view-config/index.cjs +0 -2
- package/build/components/dataviews-view-config/index.cjs.map +3 -3
- package/build/components/dataviews-view-config/infinite-scroll-toggle.cjs +0 -3
- package/build/components/dataviews-view-config/infinite-scroll-toggle.cjs.map +2 -2
- package/build/dataviews/index.cjs +37 -37
- package/build/dataviews/index.cjs.map +3 -3
- package/build/dataviews-picker/index.cjs +25 -24
- package/build/dataviews-picker/index.cjs.map +3 -3
- package/build/hooks/index.cjs +11 -2
- package/build/hooks/index.cjs.map +2 -2
- package/build/hooks/use-data.cjs +146 -9
- package/build/hooks/use-data.cjs.map +2 -2
- package/build/hooks/use-infinite-scroll.cjs +208 -0
- package/build/hooks/use-infinite-scroll.cjs.map +7 -0
- package/build/hooks/use-selected-items.cjs +57 -0
- package/build/hooks/use-selected-items.cjs.map +7 -0
- package/build/types/dataviews.cjs.map +1 -1
- package/build/types/field-api.cjs.map +1 -1
- package/build/utils/filter-sort-and-paginate.cjs +5 -1
- package/build/utils/filter-sort-and-paginate.cjs.map +2 -2
- package/build/utils/get-footer-message.cjs +8 -8
- package/build/utils/get-footer-message.cjs.map +2 -2
- package/build-module/components/dataform-controls/datetime.mjs +8 -4
- package/build-module/components/dataform-controls/datetime.mjs.map +2 -2
- package/build-module/components/dataform-layouts/card/index.mjs +132 -133
- package/build-module/components/dataform-layouts/card/index.mjs.map +2 -2
- package/build-module/components/dataviews-bulk-actions/index.mjs +28 -5
- package/build-module/components/dataviews-bulk-actions/index.mjs.map +2 -2
- package/build-module/components/dataviews-context/index.mjs +2 -2
- package/build-module/components/dataviews-context/index.mjs.map +2 -2
- package/build-module/components/dataviews-footer/index.mjs +2 -3
- package/build-module/components/dataviews-footer/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/grid/composite-grid.mjs +387 -250
- package/build-module/components/dataviews-layouts/grid/composite-grid.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/picker-grid/index.mjs +67 -31
- package/build-module/components/dataviews-layouts/picker-grid/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/picker-table/index.mjs +34 -22
- package/build-module/components/dataviews-layouts/picker-table/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/utils/use-infinite-scroll.mjs +26 -0
- package/build-module/components/dataviews-layouts/utils/use-infinite-scroll.mjs.map +7 -0
- package/build-module/components/dataviews-picker-footer/index.mjs +23 -4
- package/build-module/components/dataviews-picker-footer/index.mjs.map +2 -2
- package/build-module/components/dataviews-search/index.mjs +2 -1
- package/build-module/components/dataviews-search/index.mjs.map +2 -2
- package/build-module/components/dataviews-selection-checkbox/index.mjs +3 -2
- package/build-module/components/dataviews-selection-checkbox/index.mjs.map +2 -2
- package/build-module/components/dataviews-view-config/index.mjs +0 -2
- package/build-module/components/dataviews-view-config/index.mjs.map +2 -2
- package/build-module/components/dataviews-view-config/infinite-scroll-toggle.mjs +0 -3
- package/build-module/components/dataviews-view-config/infinite-scroll-toggle.mjs.map +2 -2
- package/build-module/dataviews/index.mjs +45 -39
- package/build-module/dataviews/index.mjs.map +2 -2
- package/build-module/dataviews-picker/index.mjs +33 -26
- package/build-module/dataviews-picker/index.mjs.map +2 -2
- package/build-module/hooks/index.mjs +7 -1
- package/build-module/hooks/index.mjs.map +2 -2
- package/build-module/hooks/use-data.mjs +147 -10
- package/build-module/hooks/use-data.mjs.map +2 -2
- package/build-module/hooks/use-infinite-scroll.mjs +188 -0
- package/build-module/hooks/use-infinite-scroll.mjs.map +7 -0
- package/build-module/hooks/use-selected-items.mjs +36 -0
- package/build-module/hooks/use-selected-items.mjs.map +7 -0
- package/build-module/utils/filter-sort-and-paginate.mjs +5 -1
- package/build-module/utils/filter-sort-and-paginate.mjs.map +2 -2
- package/build-module/utils/get-footer-message.mjs +8 -8
- package/build-module/utils/get-footer-message.mjs.map +2 -2
- package/build-style/style-rtl.css +61 -37
- package/build-style/style.css +61 -37
- package/build-types/components/dataform-controls/datetime.d.ts +1 -1
- package/build-types/components/dataform-controls/datetime.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/card/index.d.ts.map +1 -1
- package/build-types/components/dataviews-bulk-actions/index.d.ts +2 -1
- package/build-types/components/dataviews-bulk-actions/index.d.ts.map +1 -1
- package/build-types/components/dataviews-context/index.d.ts +1 -1
- package/build-types/components/dataviews-context/index.d.ts.map +1 -1
- package/build-types/components/dataviews-footer/index.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/grid/composite-grid.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/utils/use-infinite-scroll.d.ts +22 -0
- package/build-types/components/dataviews-layouts/utils/use-infinite-scroll.d.ts.map +1 -0
- package/build-types/components/dataviews-picker-footer/index.d.ts.map +1 -1
- package/build-types/components/dataviews-search/index.d.ts.map +1 -1
- package/build-types/components/dataviews-selection-checkbox/index.d.ts.map +1 -1
- package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
- package/build-types/components/dataviews-view-config/infinite-scroll-toggle.d.ts +1 -1
- package/build-types/components/dataviews-view-config/infinite-scroll-toggle.d.ts.map +1 -1
- package/build-types/dataviews/index.d.ts +0 -1
- package/build-types/dataviews/index.d.ts.map +1 -1
- package/build-types/dataviews/stories/fixtures.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 +11 -0
- package/build-types/dataviews/stories/index.story.d.ts.map +1 -1
- package/build-types/dataviews/stories/infinite-scroll.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 +0 -1
- package/build-types/dataviews-picker/index.d.ts.map +1 -1
- package/build-types/dataviews-picker/stories/fixtures.d.ts.map +1 -1
- package/build-types/dataviews-picker/stories/index.story.d.ts.map +1 -1
- package/build-types/field-types/stories/index.story.d.ts.map +1 -1
- package/build-types/hooks/index.d.ts +3 -0
- package/build-types/hooks/index.d.ts.map +1 -1
- package/build-types/hooks/test/use-data.d.ts +2 -0
- package/build-types/hooks/test/use-data.d.ts.map +1 -0
- package/build-types/hooks/use-data.d.ts +41 -3
- package/build-types/hooks/use-data.d.ts.map +1 -1
- package/build-types/hooks/use-infinite-scroll.d.ts +21 -0
- package/build-types/hooks/use-infinite-scroll.d.ts.map +1 -0
- package/build-types/hooks/use-selected-items.d.ts +19 -0
- package/build-types/hooks/use-selected-items.d.ts.map +1 -0
- package/build-types/types/dataviews.d.ts +7 -1
- package/build-types/types/dataviews.d.ts.map +1 -1
- package/build-types/types/field-api.d.ts +15 -4
- 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 +3 -2
- package/build-types/utils/get-footer-message.d.ts.map +1 -1
- package/build-wp/index.js +3013 -2613
- package/package.json +19 -19
- package/src/components/dataform-controls/datetime.tsx +19 -11
- package/src/components/dataform-layouts/card/index.tsx +171 -146
- package/src/components/dataform-layouts/card/style.scss +8 -5
- package/src/components/dataviews-bulk-actions/index.tsx +28 -1
- package/src/components/dataviews-context/index.ts +2 -2
- package/src/components/dataviews-footer/index.tsx +1 -6
- package/src/components/dataviews-layouts/grid/composite-grid.tsx +433 -284
- package/src/components/dataviews-layouts/grid/style.scss +4 -0
- package/src/components/dataviews-layouts/picker-grid/index.tsx +53 -15
- package/src/components/dataviews-layouts/picker-table/index.tsx +42 -22
- package/src/components/dataviews-layouts/utils/use-infinite-scroll.ts +64 -0
- package/src/components/dataviews-picker-footer/index.tsx +21 -1
- package/src/components/dataviews-search/index.tsx +2 -1
- package/src/components/dataviews-selection-checkbox/index.tsx +4 -2
- package/src/components/dataviews-view-config/index.tsx +0 -2
- package/src/components/dataviews-view-config/infinite-scroll-toggle.tsx +0 -5
- package/src/dataviews/index.tsx +57 -52
- package/src/dataviews/stories/fixtures.tsx +288 -0
- package/src/dataviews/stories/free-composition.tsx +12 -11
- package/src/dataviews/stories/index.story.tsx +19 -2
- package/src/dataviews/stories/infinite-scroll.tsx +12 -92
- package/src/dataviews/stories/with-card.tsx +30 -23
- package/src/dataviews/style.scss +5 -7
- package/src/dataviews/test/dataviews.tsx +21 -9
- package/src/dataviews-picker/index.tsx +40 -34
- package/src/dataviews-picker/stories/fixtures.tsx +270 -0
- package/src/dataviews-picker/stories/index.story.tsx +62 -129
- package/src/field-types/stories/index.story.tsx +12 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/test/use-data.ts +791 -0
- package/src/hooks/use-data.ts +288 -21
- package/src/hooks/use-infinite-scroll.ts +304 -0
- package/src/hooks/use-selected-items.ts +72 -0
- package/src/types/dataviews.ts +8 -1
- package/src/types/field-api.ts +16 -3
- package/src/utils/filter-sort-and-paginate.ts +13 -1
- package/src/utils/get-footer-message.ts +12 -9
- package/src/utils/test/filter-sort-and-paginate.js +78 -54
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/dataviews",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "DataViews is a component that provides an API to render datasets using different types of layouts (table, grid, list, etc.).",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -53,20 +53,20 @@
|
|
|
53
53
|
"sideEffects": false,
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@ariakit/react": "^0.4.21",
|
|
56
|
-
"@wordpress/base-styles": "^6.
|
|
57
|
-
"@wordpress/components": "^32.
|
|
58
|
-
"@wordpress/compose": "^7.
|
|
59
|
-
"@wordpress/data": "^10.
|
|
60
|
-
"@wordpress/date": "^5.
|
|
61
|
-
"@wordpress/deprecated": "^4.
|
|
62
|
-
"@wordpress/element": "^6.
|
|
63
|
-
"@wordpress/i18n": "^6.
|
|
64
|
-
"@wordpress/icons": "^12.
|
|
65
|
-
"@wordpress/keycodes": "^4.
|
|
66
|
-
"@wordpress/primitives": "^4.
|
|
67
|
-
"@wordpress/private-apis": "^1.
|
|
68
|
-
"@wordpress/ui": "^0.
|
|
69
|
-
"@wordpress/warning": "^3.
|
|
56
|
+
"@wordpress/base-styles": "^6.19.0",
|
|
57
|
+
"@wordpress/components": "^32.5.0",
|
|
58
|
+
"@wordpress/compose": "^7.43.0",
|
|
59
|
+
"@wordpress/data": "^10.43.0",
|
|
60
|
+
"@wordpress/date": "^5.43.0",
|
|
61
|
+
"@wordpress/deprecated": "^4.43.0",
|
|
62
|
+
"@wordpress/element": "^6.43.0",
|
|
63
|
+
"@wordpress/i18n": "^6.16.0",
|
|
64
|
+
"@wordpress/icons": "^12.1.0",
|
|
65
|
+
"@wordpress/keycodes": "^4.43.0",
|
|
66
|
+
"@wordpress/primitives": "^4.43.0",
|
|
67
|
+
"@wordpress/private-apis": "^1.43.0",
|
|
68
|
+
"@wordpress/ui": "^0.10.0",
|
|
69
|
+
"@wordpress/warning": "^3.43.0",
|
|
70
70
|
"clsx": "^2.1.1",
|
|
71
71
|
"colord": "^2.7.0",
|
|
72
72
|
"date-fns": "^4.1.0",
|
|
@@ -75,12 +75,12 @@
|
|
|
75
75
|
"remove-accents": "^0.5.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@storybook/addon-docs": "^10.
|
|
79
|
-
"@storybook/react-vite": "^10.
|
|
78
|
+
"@storybook/addon-docs": "^10.2.8",
|
|
79
|
+
"@storybook/react-vite": "^10.2.8",
|
|
80
80
|
"@testing-library/jest-dom": "^6.9.1",
|
|
81
81
|
"@types/jest": "^29.5.14",
|
|
82
82
|
"esbuild": "^0.27.2",
|
|
83
|
-
"storybook": "^10.
|
|
83
|
+
"storybook": "^10.2.8"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
86
|
"react": "^18.0.0",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"scripts": {
|
|
93
93
|
"build:wp": "node build.cjs"
|
|
94
94
|
},
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "2cea90674d11aa521ec3f71652fb3a6a4c383969"
|
|
96
96
|
}
|
|
@@ -37,7 +37,9 @@ function CalendarDateTimeControl< Item >( {
|
|
|
37
37
|
hideLabelFromVision,
|
|
38
38
|
markWhenOptional,
|
|
39
39
|
validity,
|
|
40
|
+
config,
|
|
40
41
|
}: DataFormControlProps< Item > ) {
|
|
42
|
+
const { compact } = config || {};
|
|
41
43
|
const { id, label, description, setValue, getValue, isValid } = field;
|
|
42
44
|
const fieldValue = getValue( { item: data } );
|
|
43
45
|
const value = typeof fieldValue === 'string' ? fieldValue : undefined;
|
|
@@ -179,17 +181,21 @@ function CalendarDateTimeControl< Item >( {
|
|
|
179
181
|
onChange={ handleManualDateTimeChange }
|
|
180
182
|
/>
|
|
181
183
|
{ /* Calendar widget */ }
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
184
|
+
{ ! compact && (
|
|
185
|
+
<DateCalendar
|
|
186
|
+
style={ { width: '100%' } }
|
|
187
|
+
selected={
|
|
188
|
+
value
|
|
189
|
+
? parseDateTime( value ) || undefined
|
|
190
|
+
: undefined
|
|
191
|
+
}
|
|
192
|
+
onSelect={ onSelectDate }
|
|
193
|
+
month={ calendarMonth }
|
|
194
|
+
onMonthChange={ setCalendarMonth }
|
|
195
|
+
timeZone={ timezoneString || undefined }
|
|
196
|
+
weekStartsOn={ weekStartsOn }
|
|
197
|
+
/>
|
|
198
|
+
) }
|
|
193
199
|
</Stack>
|
|
194
200
|
</BaseControl>
|
|
195
201
|
);
|
|
@@ -203,6 +209,7 @@ export default function DateTime< Item >( {
|
|
|
203
209
|
markWhenOptional,
|
|
204
210
|
operator,
|
|
205
211
|
validity,
|
|
212
|
+
config,
|
|
206
213
|
}: DataFormControlProps< Item > ) {
|
|
207
214
|
if ( operator === OPERATOR_IN_THE_PAST || operator === OPERATOR_OVER ) {
|
|
208
215
|
return (
|
|
@@ -225,6 +232,7 @@ export default function DateTime< Item >( {
|
|
|
225
232
|
hideLabelFromVision={ hideLabelFromVision }
|
|
226
233
|
markWhenOptional={ markWhenOptional }
|
|
227
234
|
validity={ validity }
|
|
235
|
+
config={ config }
|
|
228
236
|
/>
|
|
229
237
|
);
|
|
230
238
|
}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
Button,
|
|
6
|
-
Card,
|
|
7
|
-
CardBody,
|
|
8
|
-
CardHeader as OriginalCardHeader,
|
|
9
|
-
} from '@wordpress/components';
|
|
10
|
-
import { useInstanceId } from '@wordpress/compose';
|
|
11
4
|
import {
|
|
12
5
|
useCallback,
|
|
13
6
|
useContext,
|
|
@@ -16,7 +9,10 @@ import {
|
|
|
16
9
|
useRef,
|
|
17
10
|
useState,
|
|
18
11
|
} from '@wordpress/element';
|
|
19
|
-
|
|
12
|
+
// TODO: enable in the ESlint rule once we complete
|
|
13
|
+
// https://github.com/WordPress/gutenberg/issues/76135.
|
|
14
|
+
// eslint-disable-next-line @wordpress/use-recommended-components
|
|
15
|
+
import { Card, CollapsibleCard, Stack } from '@wordpress/ui';
|
|
20
16
|
|
|
21
17
|
/**
|
|
22
18
|
* Internal dependencies
|
|
@@ -87,6 +83,113 @@ function isSummaryFieldVisible< Item >(
|
|
|
87
83
|
return true;
|
|
88
84
|
}
|
|
89
85
|
|
|
86
|
+
function HeaderContent< Item >( {
|
|
87
|
+
data,
|
|
88
|
+
fields,
|
|
89
|
+
label,
|
|
90
|
+
layout,
|
|
91
|
+
isOpen,
|
|
92
|
+
touched,
|
|
93
|
+
validity,
|
|
94
|
+
}: {
|
|
95
|
+
data: Item;
|
|
96
|
+
fields: NormalizedField< Item >[];
|
|
97
|
+
label: string | undefined;
|
|
98
|
+
layout: NormalizedCardLayout;
|
|
99
|
+
isOpen: boolean;
|
|
100
|
+
touched: boolean;
|
|
101
|
+
validity: FieldLayoutProps< Item >[ 'validity' ];
|
|
102
|
+
} ) {
|
|
103
|
+
const summaryFields = getSummaryFields< Item >( layout.summary, fields );
|
|
104
|
+
|
|
105
|
+
const visibleSummaryFields = summaryFields.filter( ( summaryField ) =>
|
|
106
|
+
isSummaryFieldVisible( summaryField, layout.summary, isOpen )
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const hasBadge = touched && layout.isCollapsible;
|
|
110
|
+
const hasSummary = visibleSummaryFields.length > 0 && layout.withHeader;
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<Stack
|
|
114
|
+
align="center"
|
|
115
|
+
justify="space-between"
|
|
116
|
+
className="dataforms-layouts-card__field-header-content"
|
|
117
|
+
>
|
|
118
|
+
<Card.Title>{ label }</Card.Title>
|
|
119
|
+
{ ( hasBadge || hasSummary ) && (
|
|
120
|
+
<CollapsibleCard.HeaderDescription className="dataforms-layouts-card__field-header-content-description">
|
|
121
|
+
{ hasBadge && <ValidationBadge validity={ validity } /> }
|
|
122
|
+
{ hasSummary && (
|
|
123
|
+
<div className="dataforms-layouts-card__field-summary">
|
|
124
|
+
{ visibleSummaryFields.map( ( summaryField ) => (
|
|
125
|
+
<summaryField.render
|
|
126
|
+
key={ summaryField.id }
|
|
127
|
+
item={ data }
|
|
128
|
+
field={ summaryField }
|
|
129
|
+
/>
|
|
130
|
+
) ) }
|
|
131
|
+
</div>
|
|
132
|
+
) }
|
|
133
|
+
</CollapsibleCard.HeaderDescription>
|
|
134
|
+
) }
|
|
135
|
+
</Stack>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function BodyContent< Item >( {
|
|
140
|
+
data,
|
|
141
|
+
field,
|
|
142
|
+
form,
|
|
143
|
+
onChange,
|
|
144
|
+
hideLabelFromVision,
|
|
145
|
+
markWhenOptional,
|
|
146
|
+
validity,
|
|
147
|
+
withHeader,
|
|
148
|
+
}: {
|
|
149
|
+
data: Item;
|
|
150
|
+
field: FieldLayoutProps< Item >[ 'field' ];
|
|
151
|
+
form: NormalizedForm;
|
|
152
|
+
onChange: FieldLayoutProps< Item >[ 'onChange' ];
|
|
153
|
+
hideLabelFromVision?: boolean;
|
|
154
|
+
markWhenOptional?: boolean;
|
|
155
|
+
validity: FieldLayoutProps< Item >[ 'validity' ];
|
|
156
|
+
withHeader: boolean;
|
|
157
|
+
} ) {
|
|
158
|
+
if ( field.children ) {
|
|
159
|
+
return (
|
|
160
|
+
<>
|
|
161
|
+
{ field.description && (
|
|
162
|
+
<div className="dataforms-layouts-card__field-description">
|
|
163
|
+
{ field.description }
|
|
164
|
+
</div>
|
|
165
|
+
) }
|
|
166
|
+
<DataFormLayout
|
|
167
|
+
data={ data }
|
|
168
|
+
form={ form }
|
|
169
|
+
onChange={ onChange }
|
|
170
|
+
validity={ validity?.children }
|
|
171
|
+
/>
|
|
172
|
+
</>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const SingleFieldLayout = getFormFieldLayout( 'regular' )?.component;
|
|
177
|
+
if ( ! SingleFieldLayout ) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
<SingleFieldLayout
|
|
183
|
+
data={ data }
|
|
184
|
+
field={ field }
|
|
185
|
+
onChange={ onChange }
|
|
186
|
+
hideLabelFromVision={ hideLabelFromVision || withHeader }
|
|
187
|
+
markWhenOptional={ markWhenOptional }
|
|
188
|
+
validity={ validity }
|
|
189
|
+
/>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
90
193
|
export default function FormCardField< Item >( {
|
|
91
194
|
data,
|
|
92
195
|
field,
|
|
@@ -97,10 +200,7 @@ export default function FormCardField< Item >( {
|
|
|
97
200
|
}: FieldLayoutProps< Item > ) {
|
|
98
201
|
const { fields } = useContext( DataFormContext );
|
|
99
202
|
const layout = field.layout as NormalizedCardLayout;
|
|
100
|
-
const
|
|
101
|
-
const instanceId = useInstanceId( FormCardField );
|
|
102
|
-
const bodyId = `dataforms-layouts-card-card-body-${ instanceId }`;
|
|
103
|
-
const titleId = `dataforms-layouts-card-card-title-${ instanceId }`;
|
|
203
|
+
const contentRef = useRef< HTMLDivElement >( null );
|
|
104
204
|
|
|
105
205
|
const form: NormalizedForm = useMemo(
|
|
106
206
|
() => ( {
|
|
@@ -111,7 +211,7 @@ export default function FormCardField< Item >( {
|
|
|
111
211
|
);
|
|
112
212
|
|
|
113
213
|
const { isOpened, isCollapsible } = layout;
|
|
114
|
-
const [
|
|
214
|
+
const [ isOpen, setIsOpen ] = useState( isOpened );
|
|
115
215
|
const [ touched, setTouched ] = useState( false );
|
|
116
216
|
|
|
117
217
|
// Sync internal state when the isOpened prop changes.
|
|
@@ -120,67 +220,32 @@ export default function FormCardField< Item >( {
|
|
|
120
220
|
setIsOpen( isOpened );
|
|
121
221
|
}, [ isOpened ] );
|
|
122
222
|
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return ! prev;
|
|
130
|
-
} );
|
|
223
|
+
const handleOpenChange = useCallback( ( open: boolean ) => {
|
|
224
|
+
// Mark as touched when collapsing (going from open to closed)
|
|
225
|
+
if ( ! open ) {
|
|
226
|
+
setTouched( true );
|
|
227
|
+
}
|
|
228
|
+
setIsOpen( open );
|
|
131
229
|
}, [] );
|
|
132
230
|
|
|
133
|
-
const isOpen = isCollapsible ? internalIsOpen : true;
|
|
134
|
-
|
|
135
231
|
// Mark the card as touched when any field inside it is blurred.
|
|
136
232
|
// This aligns with how validated controls show errors on blur.
|
|
137
233
|
const handleBlur = useCallback( () => {
|
|
138
234
|
setTouched( true );
|
|
139
|
-
}, [
|
|
235
|
+
}, [] );
|
|
140
236
|
|
|
141
237
|
// When the card is expanded after being touched (collapsed with errors),
|
|
142
238
|
// trigger reportValidity to show field-level errors.
|
|
143
|
-
useReportValidity(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const visibleSummaryFields = summaryFields.filter( ( summaryField ) =>
|
|
148
|
-
isSummaryFieldVisible( summaryField, layout.summary, isOpen )
|
|
239
|
+
useReportValidity(
|
|
240
|
+
contentRef,
|
|
241
|
+
( isCollapsible ? isOpen : true ) && touched
|
|
149
242
|
);
|
|
150
243
|
|
|
151
|
-
const validationBadge =
|
|
152
|
-
touched && layout.isCollapsible ? (
|
|
153
|
-
<ValidationBadge validity={ validity } />
|
|
154
|
-
) : null;
|
|
155
|
-
|
|
156
|
-
const sizeCard = {
|
|
157
|
-
blockStart: 'medium' as const,
|
|
158
|
-
blockEnd: 'medium' as const,
|
|
159
|
-
inlineStart: 'medium' as const,
|
|
160
|
-
inlineEnd: 'medium' as const,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
244
|
let label = field.label;
|
|
164
245
|
let withHeader: boolean;
|
|
165
|
-
let bodyContent: React.ReactNode;
|
|
166
246
|
|
|
167
247
|
if ( field.children ) {
|
|
168
248
|
withHeader = !! label && layout.withHeader;
|
|
169
|
-
bodyContent = (
|
|
170
|
-
<>
|
|
171
|
-
{ field.description && (
|
|
172
|
-
<div className="dataforms-layouts-card__field-description">
|
|
173
|
-
{ field.description }
|
|
174
|
-
</div>
|
|
175
|
-
) }
|
|
176
|
-
<DataFormLayout
|
|
177
|
-
data={ data }
|
|
178
|
-
form={ form }
|
|
179
|
-
onChange={ onChange }
|
|
180
|
-
validity={ validity?.children }
|
|
181
|
-
/>
|
|
182
|
-
</>
|
|
183
|
-
);
|
|
184
249
|
} else {
|
|
185
250
|
const fieldDefinition = fields.find(
|
|
186
251
|
( fieldDef ) => fieldDef.id === field.id
|
|
@@ -190,101 +255,61 @@ export default function FormCardField< Item >( {
|
|
|
190
255
|
return null;
|
|
191
256
|
}
|
|
192
257
|
|
|
193
|
-
const SingleFieldLayout = getFormFieldLayout( 'regular' )?.component;
|
|
194
|
-
if ( ! SingleFieldLayout ) {
|
|
195
|
-
return null;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
258
|
label = fieldDefinition.label;
|
|
199
259
|
withHeader = !! label && layout.withHeader;
|
|
200
|
-
bodyContent = (
|
|
201
|
-
<SingleFieldLayout
|
|
202
|
-
data={ data }
|
|
203
|
-
field={ field }
|
|
204
|
-
onChange={ onChange }
|
|
205
|
-
hideLabelFromVision={ hideLabelFromVision || withHeader }
|
|
206
|
-
markWhenOptional={ markWhenOptional }
|
|
207
|
-
validity={ validity }
|
|
208
|
-
/>
|
|
209
|
-
);
|
|
210
260
|
}
|
|
211
261
|
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
262
|
+
const bodyContent = (
|
|
263
|
+
<BodyContent
|
|
264
|
+
data={ data }
|
|
265
|
+
field={ field }
|
|
266
|
+
form={ form }
|
|
267
|
+
onChange={ onChange }
|
|
268
|
+
hideLabelFromVision={ hideLabelFromVision }
|
|
269
|
+
markWhenOptional={ markWhenOptional }
|
|
270
|
+
validity={ validity }
|
|
271
|
+
withHeader={ withHeader }
|
|
272
|
+
/>
|
|
273
|
+
);
|
|
218
274
|
|
|
219
|
-
|
|
220
|
-
<
|
|
221
|
-
{
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
className="dataforms-layouts-card__field-header-label"
|
|
244
|
-
>
|
|
245
|
-
{ label }
|
|
246
|
-
</span>
|
|
247
|
-
{ validationBadge }
|
|
248
|
-
{ visibleSummaryFields.length > 0 &&
|
|
249
|
-
layout.withHeader && (
|
|
250
|
-
<div className="dataforms-layouts-card__field-summary">
|
|
251
|
-
{ visibleSummaryFields.map(
|
|
252
|
-
( summaryField ) => (
|
|
253
|
-
<summaryField.render
|
|
254
|
-
key={ summaryField.id }
|
|
255
|
-
item={ data }
|
|
256
|
-
field={ summaryField }
|
|
257
|
-
/>
|
|
258
|
-
)
|
|
259
|
-
) }
|
|
260
|
-
</div>
|
|
261
|
-
) }
|
|
262
|
-
</div>
|
|
263
|
-
{ isCollapsible && (
|
|
264
|
-
<Button
|
|
265
|
-
__next40pxDefaultSize
|
|
266
|
-
variant="tertiary"
|
|
267
|
-
icon={ isOpen ? chevronUp : chevronDown }
|
|
268
|
-
aria-expanded={ isOpen }
|
|
269
|
-
aria-controls={ bodyId }
|
|
270
|
-
aria-labelledby={ titleId }
|
|
271
|
-
/>
|
|
272
|
-
) }
|
|
273
|
-
</OriginalCardHeader>
|
|
274
|
-
) }
|
|
275
|
-
{ ( isOpen || ! withHeader ) && (
|
|
276
|
-
// If it doesn't have a header, keep it open.
|
|
277
|
-
// Otherwise, the card will not be visible.
|
|
278
|
-
<CardBody
|
|
279
|
-
id={ bodyId }
|
|
280
|
-
size={ sizeCardBody }
|
|
281
|
-
className="dataforms-layouts-card__field-control"
|
|
282
|
-
ref={ cardBodyRef }
|
|
275
|
+
const headerContent = (
|
|
276
|
+
<HeaderContent
|
|
277
|
+
data={ data }
|
|
278
|
+
fields={ fields }
|
|
279
|
+
label={ label }
|
|
280
|
+
layout={ layout }
|
|
281
|
+
isOpen={ isCollapsible ? !! isOpen : true }
|
|
282
|
+
touched={ touched }
|
|
283
|
+
validity={ validity }
|
|
284
|
+
/>
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
if ( withHeader && isCollapsible ) {
|
|
288
|
+
return (
|
|
289
|
+
<CollapsibleCard.Root
|
|
290
|
+
className="dataforms-layouts-card__field"
|
|
291
|
+
open={ isOpen }
|
|
292
|
+
onOpenChange={ handleOpenChange }
|
|
293
|
+
>
|
|
294
|
+
<CollapsibleCard.Header>
|
|
295
|
+
{ headerContent }
|
|
296
|
+
</CollapsibleCard.Header>
|
|
297
|
+
<CollapsibleCard.Content
|
|
298
|
+
ref={ contentRef }
|
|
283
299
|
onBlur={ handleBlur }
|
|
284
300
|
>
|
|
285
301
|
{ bodyContent }
|
|
286
|
-
</
|
|
287
|
-
|
|
288
|
-
|
|
302
|
+
</CollapsibleCard.Content>
|
|
303
|
+
</CollapsibleCard.Root>
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
<Card.Root className="dataforms-layouts-card__field">
|
|
309
|
+
{ withHeader && <Card.Header>{ headerContent }</Card.Header> }
|
|
310
|
+
<Card.Content ref={ contentRef } onBlur={ handleBlur }>
|
|
311
|
+
{ bodyContent }
|
|
312
|
+
</Card.Content>
|
|
313
|
+
</Card.Root>
|
|
289
314
|
);
|
|
290
315
|
}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
@use "@wordpress/base-styles/colors" as *;
|
|
2
2
|
@use "@wordpress/base-styles/variables" as *;
|
|
3
|
-
@use "@wordpress/base-styles/mixins" as *;
|
|
4
|
-
|
|
5
|
-
.dataforms-layouts-card__field-header-label {
|
|
6
|
-
@include heading-large();
|
|
7
|
-
}
|
|
8
3
|
|
|
9
4
|
.dataforms-layouts-card__field {
|
|
10
5
|
width: 100%;
|
|
11
6
|
}
|
|
12
7
|
|
|
8
|
+
.dataforms-layouts-card__field-header-content {
|
|
9
|
+
min-height: 24px; // TODO: use size / height DS token when available
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.dataforms-layouts-card__field-header-content-description {
|
|
13
|
+
display: contents;
|
|
14
|
+
}
|
|
15
|
+
|
|
13
16
|
.dataforms-layouts-card__field-description {
|
|
14
17
|
color: $gray-700;
|
|
15
18
|
display: block;
|
|
@@ -95,6 +95,7 @@ interface BulkSelectionCheckboxProps< Item > {
|
|
|
95
95
|
data: Item[];
|
|
96
96
|
actions: Action< Item >[];
|
|
97
97
|
getItemId: ( item: Item ) => string;
|
|
98
|
+
disableSelectAll?: boolean;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
export function BulkSelectionCheckbox< Item >( {
|
|
@@ -103,6 +104,7 @@ export function BulkSelectionCheckbox< Item >( {
|
|
|
103
104
|
data,
|
|
104
105
|
actions,
|
|
105
106
|
getItemId,
|
|
107
|
+
disableSelectAll = false,
|
|
106
108
|
}: BulkSelectionCheckboxProps< Item > ) {
|
|
107
109
|
const selectableItems = useMemo( () => {
|
|
108
110
|
return data.filter( ( item ) => {
|
|
@@ -118,7 +120,23 @@ export function BulkSelectionCheckbox< Item >( {
|
|
|
118
120
|
selection.includes( getItemId( item ) ) &&
|
|
119
121
|
selectableItems.includes( item )
|
|
120
122
|
);
|
|
123
|
+
const hasSelection = selection.length > 0;
|
|
121
124
|
const areAllSelected = selectedItems.length === selectableItems.length;
|
|
125
|
+
|
|
126
|
+
if ( disableSelectAll ) {
|
|
127
|
+
return (
|
|
128
|
+
<CheckboxControl
|
|
129
|
+
className="dataviews-view-table-selection-checkbox"
|
|
130
|
+
checked={ hasSelection }
|
|
131
|
+
disabled={ ! hasSelection }
|
|
132
|
+
onChange={ () => {
|
|
133
|
+
onChangeSelection( [] );
|
|
134
|
+
} }
|
|
135
|
+
aria-label={ __( 'Deselect all' ) }
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
122
140
|
return (
|
|
123
141
|
<CheckboxControl
|
|
124
142
|
className="dataviews-view-table-selection-checkbox"
|
|
@@ -153,6 +171,7 @@ interface ToolbarContentProps< Item > {
|
|
|
153
171
|
data: Item[];
|
|
154
172
|
actions: Action< Item >[];
|
|
155
173
|
getItemId: ( item: Item ) => string;
|
|
174
|
+
isInfiniteScroll: boolean;
|
|
156
175
|
paginationInfo: {
|
|
157
176
|
totalItems: number;
|
|
158
177
|
totalPages: number;
|
|
@@ -241,6 +260,7 @@ function renderFooterContent< Item >(
|
|
|
241
260
|
data: Item[],
|
|
242
261
|
actions: Action< Item >[],
|
|
243
262
|
getItemId: ( item: Item ) => string,
|
|
263
|
+
isInfiniteScroll: boolean,
|
|
244
264
|
selection: string[],
|
|
245
265
|
actionsToShow: Action< Item >[],
|
|
246
266
|
selectedItems: Item[],
|
|
@@ -255,7 +275,8 @@ function renderFooterContent< Item >(
|
|
|
255
275
|
const message = getFooterMessage(
|
|
256
276
|
selection.length,
|
|
257
277
|
data.length,
|
|
258
|
-
paginationInfo.totalItems
|
|
278
|
+
paginationInfo.totalItems,
|
|
279
|
+
isInfiniteScroll
|
|
259
280
|
);
|
|
260
281
|
return (
|
|
261
282
|
<Stack
|
|
@@ -270,6 +291,7 @@ function renderFooterContent< Item >(
|
|
|
270
291
|
data={ data }
|
|
271
292
|
actions={ actions }
|
|
272
293
|
getItemId={ getItemId }
|
|
294
|
+
disableSelectAll={ isInfiniteScroll }
|
|
273
295
|
/>
|
|
274
296
|
<span className="dataviews-bulk-actions-footer__item-count">
|
|
275
297
|
{ message }
|
|
@@ -315,6 +337,7 @@ function FooterContent< Item >( {
|
|
|
315
337
|
onChangeSelection,
|
|
316
338
|
data,
|
|
317
339
|
getItemId,
|
|
340
|
+
isInfiniteScroll,
|
|
318
341
|
paginationInfo,
|
|
319
342
|
}: ToolbarContentProps< Item > ) {
|
|
320
343
|
const [ actionInProgress, setActionInProgress ] = useState< string | null >(
|
|
@@ -365,6 +388,7 @@ function FooterContent< Item >( {
|
|
|
365
388
|
data,
|
|
366
389
|
actions,
|
|
367
390
|
getItemId,
|
|
391
|
+
isInfiniteScroll,
|
|
368
392
|
selection,
|
|
369
393
|
actionsToShow,
|
|
370
394
|
selectedItems,
|
|
@@ -378,6 +402,7 @@ function FooterContent< Item >( {
|
|
|
378
402
|
data,
|
|
379
403
|
actions,
|
|
380
404
|
getItemId,
|
|
405
|
+
isInfiniteScroll,
|
|
381
406
|
selection,
|
|
382
407
|
actionsToShow,
|
|
383
408
|
selectedItems,
|
|
@@ -398,6 +423,7 @@ export function BulkActionsFooter() {
|
|
|
398
423
|
onChangeSelection,
|
|
399
424
|
getItemId,
|
|
400
425
|
paginationInfo,
|
|
426
|
+
view,
|
|
401
427
|
} = useContext( DataViewsContext );
|
|
402
428
|
return (
|
|
403
429
|
<FooterContent
|
|
@@ -406,6 +432,7 @@ export function BulkActionsFooter() {
|
|
|
406
432
|
data={ data }
|
|
407
433
|
actions={ actions }
|
|
408
434
|
getItemId={ getItemId }
|
|
435
|
+
isInfiniteScroll={ !! view.infiniteScrollEnabled }
|
|
409
436
|
paginationInfo={ paginationInfo }
|
|
410
437
|
/>
|
|
411
438
|
);
|
|
@@ -57,9 +57,9 @@ type DataViewsContextType< Item > = {
|
|
|
57
57
|
config: { perPageSizes: number[] };
|
|
58
58
|
empty?: ReactNode;
|
|
59
59
|
hasInitiallyLoaded?: boolean;
|
|
60
|
-
hasInfiniteScrollHandler: boolean;
|
|
61
60
|
itemListLabel?: string;
|
|
62
61
|
onReset?: ( () => void ) | false;
|
|
62
|
+
intersectionObserver?: IntersectionObserver | null;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
const DataViewsContext = createContext< DataViewsContextType< any > >( {
|
|
@@ -86,10 +86,10 @@ const DataViewsContext = createContext< DataViewsContextType< any > >( {
|
|
|
86
86
|
isShowingFilter: false,
|
|
87
87
|
setIsShowingFilter: () => {},
|
|
88
88
|
hasInitiallyLoaded: false,
|
|
89
|
-
hasInfiniteScrollHandler: false,
|
|
90
89
|
config: {
|
|
91
90
|
perPageSizes: [],
|
|
92
91
|
},
|
|
92
|
+
intersectionObserver: null,
|
|
93
93
|
} );
|
|
94
94
|
|
|
95
95
|
DataViewsContext.displayName = 'DataViewsContext';
|
|
@@ -31,14 +31,9 @@ export default function DataViewsFooter() {
|
|
|
31
31
|
actions = EMPTY_ARRAY,
|
|
32
32
|
isLoading,
|
|
33
33
|
hasInitiallyLoaded,
|
|
34
|
-
hasInfiniteScrollHandler,
|
|
35
34
|
} = useContext( DataViewsContext );
|
|
36
35
|
|
|
37
|
-
const isRefreshing =
|
|
38
|
-
!! isLoading &&
|
|
39
|
-
hasInitiallyLoaded &&
|
|
40
|
-
! hasInfiniteScrollHandler &&
|
|
41
|
-
!! data?.length;
|
|
36
|
+
const isRefreshing = !! isLoading && hasInitiallyLoaded && !! data?.length;
|
|
42
37
|
|
|
43
38
|
const isDelayedRefreshing = useDelayedLoading( !! isRefreshing );
|
|
44
39
|
|