@wordpress/dataviews 13.0.0 → 13.1.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 +25 -0
- package/README.md +2 -1
- package/build/components/dataform-controls/date.cjs +11 -1
- package/build/components/dataform-controls/date.cjs.map +2 -2
- package/build/components/dataform-controls/datetime.cjs +23 -32
- package/build/components/dataform-controls/datetime.cjs.map +2 -2
- package/build/components/dataform-controls/utils/relative-date-control.cjs +2 -1
- package/build/components/dataform-controls/utils/relative-date-control.cjs.map +2 -2
- package/build/components/dataform-layouts/normalize-form.cjs +19 -1
- package/build/components/dataform-layouts/normalize-form.cjs.map +2 -2
- package/build/components/dataform-layouts/panel/index.cjs +1 -1
- package/build/components/dataform-layouts/panel/index.cjs.map +2 -2
- package/build/components/dataform-layouts/panel/modal.cjs +4 -3
- package/build/components/dataform-layouts/panel/modal.cjs.map +2 -2
- package/build/components/dataviews-layout/index.cjs +12 -3
- package/build/components/dataviews-layout/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/grid/composite-grid.cjs +5 -1
- package/build/components/dataviews-layouts/grid/composite-grid.cjs.map +2 -2
- package/build/components/dataviews-layouts/index.cjs +3 -3
- package/build/components/dataviews-layouts/index.cjs.map +3 -3
- package/build/components/dataviews-layouts/picker-grid/index.cjs +13 -2
- package/build/components/dataviews-layouts/picker-grid/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/table/index.cjs +98 -89
- package/build/components/dataviews-layouts/table/index.cjs.map +2 -2
- package/build/components/dataviews-layouts/table/{use-is-horizontal-scroll-end.cjs → use-scroll-state.cjs} +29 -33
- package/build/components/dataviews-layouts/table/use-scroll-state.cjs.map +7 -0
- package/build/components/dataviews-layouts/utils/density-picker.cjs.map +2 -2
- package/build/components/dataviews-layouts/utils/grid-config-options.cjs +45 -0
- package/build/components/dataviews-layouts/utils/grid-config-options.cjs.map +7 -0
- package/build/dataviews/index.cjs +12 -8
- package/build/dataviews/index.cjs.map +2 -2
- package/build/dataviews-picker/index.cjs +1 -1
- package/build/dataviews-picker/index.cjs.map +2 -2
- package/build/types/dataform.cjs.map +1 -1
- package/build/types/dataviews.cjs.map +1 -1
- package/build-module/components/dataform-controls/date.mjs +11 -1
- package/build-module/components/dataform-controls/date.mjs.map +2 -2
- package/build-module/components/dataform-controls/datetime.mjs +24 -33
- package/build-module/components/dataform-controls/datetime.mjs.map +2 -2
- package/build-module/components/dataform-controls/utils/relative-date-control.mjs +2 -1
- package/build-module/components/dataform-controls/utils/relative-date-control.mjs.map +2 -2
- package/build-module/components/dataform-layouts/normalize-form.mjs +19 -1
- package/build-module/components/dataform-layouts/normalize-form.mjs.map +2 -2
- package/build-module/components/dataform-layouts/panel/index.mjs +1 -1
- package/build-module/components/dataform-layouts/panel/index.mjs.map +2 -2
- package/build-module/components/dataform-layouts/panel/modal.mjs +4 -3
- package/build-module/components/dataform-layouts/panel/modal.mjs.map +2 -2
- package/build-module/components/dataviews-layout/index.mjs +12 -3
- package/build-module/components/dataviews-layout/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/grid/composite-grid.mjs +5 -1
- package/build-module/components/dataviews-layouts/grid/composite-grid.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/index.mjs +3 -3
- package/build-module/components/dataviews-layouts/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/picker-grid/index.mjs +13 -2
- package/build-module/components/dataviews-layouts/picker-grid/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/table/index.mjs +98 -89
- package/build-module/components/dataviews-layouts/table/index.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/table/use-scroll-state.mjs +46 -0
- package/build-module/components/dataviews-layouts/table/use-scroll-state.mjs.map +7 -0
- package/build-module/components/dataviews-layouts/utils/density-picker.mjs.map +2 -2
- package/build-module/components/dataviews-layouts/utils/grid-config-options.mjs +14 -0
- package/build-module/components/dataviews-layouts/utils/grid-config-options.mjs.map +7 -0
- package/build-module/dataviews/index.mjs +12 -8
- package/build-module/dataviews/index.mjs.map +2 -2
- package/build-module/dataviews-picker/index.mjs +1 -1
- package/build-module/dataviews-picker/index.mjs.map +2 -2
- package/build-style/style-rtl.css +47 -5
- package/build-style/style.css +47 -5
- 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/relative-date-control.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/normalize-form.d.ts.map +1 -1
- package/build-types/components/dataform-layouts/panel/modal.d.ts.map +1 -1
- package/build-types/components/dataviews-layout/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/index.d.ts +3 -3
- package/build-types/components/dataviews-layouts/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/table/index.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts +25 -0
- package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts.map +1 -0
- package/build-types/components/dataviews-layouts/utils/density-picker.d.ts.map +1 -1
- package/build-types/components/dataviews-layouts/utils/grid-config-options.d.ts +2 -0
- package/build-types/components/dataviews-layouts/utils/grid-config-options.d.ts.map +1 -0
- package/build-types/dataform/stories/index.story.d.ts +26 -1
- package/build-types/dataform/stories/index.story.d.ts.map +1 -1
- package/build-types/dataform/stories/layout-panel.d.ts +3 -1
- package/build-types/dataform/stories/layout-panel.d.ts.map +1 -1
- package/build-types/dataviews/index.d.ts.map +1 -1
- package/build-types/dataviews/stories/empty.d.ts +1 -2
- package/build-types/dataviews/stories/empty.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 +18 -10
- 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/layout-activity.d.ts.map +1 -1
- package/build-types/dataviews/stories/layout-custom.d.ts +3 -1
- package/build-types/dataviews/stories/layout-custom.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 +3 -1
- package/build-types/dataviews/stories/with-card.d.ts.map +1 -1
- package/build-types/types/dataform.d.ts +17 -2
- package/build-types/types/dataform.d.ts.map +1 -1
- package/build-types/types/dataviews.d.ts +8 -0
- package/build-types/types/dataviews.d.ts.map +1 -1
- package/build-wp/index.js +883 -866
- package/package.json +19 -19
- package/src/components/dataform-controls/date.tsx +11 -1
- package/src/components/dataform-controls/datetime.tsx +28 -44
- package/src/components/dataform-controls/utils/relative-date-control.tsx +2 -1
- package/src/components/dataform-layouts/normalize-form.ts +24 -1
- package/src/components/dataform-layouts/panel/index.tsx +1 -1
- package/src/components/dataform-layouts/panel/modal.tsx +7 -3
- package/src/components/dataform-layouts/panel/style.scss +1 -1
- package/src/components/dataform-layouts/test/normalize-form.ts +98 -5
- package/src/components/dataviews-layout/index.tsx +41 -19
- package/src/components/dataviews-layout/style.scss +8 -0
- package/src/components/dataviews-layouts/grid/composite-grid.tsx +7 -1
- package/src/components/dataviews-layouts/grid/style.scss +18 -2
- package/src/components/dataviews-layouts/index.ts +3 -3
- package/src/components/dataviews-layouts/picker-grid/index.tsx +17 -2
- package/src/components/dataviews-layouts/picker-grid/style.scss +10 -0
- package/src/components/dataviews-layouts/table/index.tsx +11 -5
- package/src/components/dataviews-layouts/table/style.scss +13 -0
- package/src/components/dataviews-layouts/table/use-scroll-state.ts +79 -0
- package/src/components/dataviews-layouts/utils/density-picker.tsx +12 -2
- package/src/components/dataviews-layouts/utils/grid-config-options.tsx +14 -0
- package/src/components/dataviews-layouts/utils/grid-items.scss +9 -1
- package/src/dataform/stories/index.story.tsx +15 -0
- package/src/dataform/stories/layout-panel.tsx +19 -4
- package/src/dataviews/index.tsx +17 -9
- package/src/dataviews/stories/empty.tsx +1 -3
- package/src/dataviews/stories/free-composition.tsx +32 -34
- package/src/dataviews/stories/index.story.tsx +31 -8
- package/src/dataviews/stories/infinite-scroll.tsx +0 -6
- package/src/dataviews/stories/layout-activity.tsx +1 -0
- package/src/dataviews/stories/layout-custom.tsx +7 -3
- package/src/dataviews/stories/layout-grid.tsx +1 -0
- package/src/dataviews/stories/layout-list.tsx +1 -0
- package/src/dataviews/stories/layout-table.tsx +1 -0
- package/src/dataviews/stories/style.css +0 -5
- package/src/dataviews/stories/with-card.tsx +6 -2
- package/src/dataviews/style.scss +0 -1
- package/src/dataviews/test/dataviews.tsx +42 -1
- package/src/dataviews-picker/index.tsx +1 -1
- package/src/style.scss +1 -0
- package/src/types/dataform.ts +15 -2
- package/src/types/dataviews.ts +10 -0
- package/build/components/dataviews-layouts/table/use-is-horizontal-scroll-end.cjs.map +0 -7
- package/build-module/components/dataviews-layouts/table/use-is-horizontal-scroll-end.mjs +0 -50
- package/build-module/components/dataviews-layouts/table/use-is-horizontal-scroll-end.mjs.map +0 -7
- package/build-types/components/dataviews-layouts/table/use-is-horizontal-scroll-end.d.ts +0 -19
- package/build-types/components/dataviews-layouts/table/use-is-horizontal-scroll-end.d.ts.map +0 -1
- package/src/components/dataviews-layouts/table/use-is-horizontal-scroll-end.ts +0 -82
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/dataviews",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.1.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": "^
|
|
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.18.0",
|
|
57
|
+
"@wordpress/components": "^32.4.0",
|
|
58
|
+
"@wordpress/compose": "^7.42.0",
|
|
59
|
+
"@wordpress/data": "^10.42.0",
|
|
60
|
+
"@wordpress/date": "^5.42.0",
|
|
61
|
+
"@wordpress/deprecated": "^4.42.0",
|
|
62
|
+
"@wordpress/element": "^6.42.0",
|
|
63
|
+
"@wordpress/i18n": "^6.15.0",
|
|
64
|
+
"@wordpress/icons": "^12.0.0",
|
|
65
|
+
"@wordpress/keycodes": "^4.42.0",
|
|
66
|
+
"@wordpress/primitives": "^4.42.0",
|
|
67
|
+
"@wordpress/private-apis": "^1.42.0",
|
|
68
|
+
"@wordpress/ui": "^0.9.0",
|
|
69
|
+
"@wordpress/warning": "^3.42.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": "c20787b1778ae64c2db65643b1c236309d68e6ba"
|
|
96
96
|
}
|
|
@@ -293,6 +293,7 @@ function CalendarDateControl< Item >( {
|
|
|
293
293
|
const {
|
|
294
294
|
id,
|
|
295
295
|
label,
|
|
296
|
+
description,
|
|
296
297
|
setValue,
|
|
297
298
|
getValue,
|
|
298
299
|
isValid,
|
|
@@ -385,6 +386,7 @@ function CalendarDateControl< Item >( {
|
|
|
385
386
|
id={ id }
|
|
386
387
|
className="dataviews-controls__date"
|
|
387
388
|
label={ displayLabel }
|
|
389
|
+
help={ description }
|
|
388
390
|
hideLabelFromVision={ hideLabelFromVision }
|
|
389
391
|
>
|
|
390
392
|
<Stack direction="column" gap="lg">
|
|
@@ -462,7 +464,14 @@ function CalendarDateRangeControl< Item >( {
|
|
|
462
464
|
markWhenOptional,
|
|
463
465
|
validity,
|
|
464
466
|
}: DataFormControlProps< Item > ) {
|
|
465
|
-
const {
|
|
467
|
+
const {
|
|
468
|
+
id,
|
|
469
|
+
label,
|
|
470
|
+
description,
|
|
471
|
+
getValue,
|
|
472
|
+
setValue,
|
|
473
|
+
format: fieldFormat,
|
|
474
|
+
} = field;
|
|
466
475
|
let value: DateRange;
|
|
467
476
|
const fieldValue = getValue( { item: data } );
|
|
468
477
|
if (
|
|
@@ -597,6 +606,7 @@ function CalendarDateRangeControl< Item >( {
|
|
|
597
606
|
id={ id }
|
|
598
607
|
className="dataviews-controls__date"
|
|
599
608
|
label={ displayLabel }
|
|
609
|
+
help={ description }
|
|
600
610
|
hideLabelFromVision={ hideLabelFromVision }
|
|
601
611
|
>
|
|
602
612
|
<Stack direction="column" gap="lg">
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { format } from 'date-fns';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* WordPress dependencies
|
|
8
3
|
*/
|
|
@@ -12,7 +7,7 @@ import {
|
|
|
12
7
|
} from '@wordpress/components';
|
|
13
8
|
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
|
|
14
9
|
import { __ } from '@wordpress/i18n';
|
|
15
|
-
import { getSettings } from '@wordpress/date';
|
|
10
|
+
import { dateI18n, getDate, getSettings } from '@wordpress/date';
|
|
16
11
|
import { Stack } from '@wordpress/ui';
|
|
17
12
|
|
|
18
13
|
/**
|
|
@@ -27,15 +22,12 @@ import { unlock } from '../../lock-unlock';
|
|
|
27
22
|
|
|
28
23
|
const { DateCalendar, ValidatedInputControl } = unlock( componentsPrivateApis );
|
|
29
24
|
|
|
30
|
-
const formatDateTime = (
|
|
31
|
-
if ( !
|
|
25
|
+
const formatDateTime = ( value?: string ): string => {
|
|
26
|
+
if ( ! value ) {
|
|
32
27
|
return '';
|
|
33
28
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
// Format as datetime-local input expects: YYYY-MM-DDTHH:mm
|
|
38
|
-
return format( date, "yyyy-MM-dd'T'HH:mm" );
|
|
29
|
+
// Format in WordPress timezone for datetime-local input: YYYY-MM-DDTHH:mm
|
|
30
|
+
return dateI18n( 'Y-m-d\\TH:i', getDate( value ) );
|
|
39
31
|
};
|
|
40
32
|
|
|
41
33
|
function CalendarDateTimeControl< Item >( {
|
|
@@ -79,21 +71,19 @@ function CalendarDateTimeControl< Item >( {
|
|
|
79
71
|
( newDate: Date | undefined | null ) => {
|
|
80
72
|
let dateTimeValue: string | undefined;
|
|
81
73
|
if ( newDate ) {
|
|
82
|
-
//
|
|
83
|
-
|
|
74
|
+
// Extract the date part in WP timezone from the calendar selection
|
|
75
|
+
const wpDate = dateI18n( 'Y-m-d', newDate );
|
|
84
76
|
|
|
77
|
+
// Preserve time if it exists in current value, otherwise use current time
|
|
78
|
+
let wpTime: string;
|
|
85
79
|
if ( value ) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
finalDateTime = new Date( newDate );
|
|
90
|
-
finalDateTime.setHours( currentDateTime.getHours() );
|
|
91
|
-
finalDateTime.setMinutes(
|
|
92
|
-
currentDateTime.getMinutes()
|
|
93
|
-
);
|
|
94
|
-
}
|
|
80
|
+
wpTime = dateI18n( 'H:i', getDate( value ) );
|
|
81
|
+
} else {
|
|
82
|
+
wpTime = dateI18n( 'H:i', newDate );
|
|
95
83
|
}
|
|
96
84
|
|
|
85
|
+
// Combine date and time in WP timezone and convert to ISO
|
|
86
|
+
const finalDateTime = getDate( `${ wpDate }T${ wpTime }` );
|
|
97
87
|
dateTimeValue = finalDateTime.toISOString();
|
|
98
88
|
onChangeCallback( dateTimeValue );
|
|
99
89
|
|
|
@@ -133,8 +123,8 @@ function CalendarDateTimeControl< Item >( {
|
|
|
133
123
|
const handleManualDateTimeChange = useCallback(
|
|
134
124
|
( newValue?: string ) => {
|
|
135
125
|
if ( newValue ) {
|
|
136
|
-
//
|
|
137
|
-
const dateTime =
|
|
126
|
+
// Interpret the datetime-local value in WordPress timezone
|
|
127
|
+
const dateTime = getDate( newValue );
|
|
138
128
|
onChangeCallback( dateTime.toISOString() );
|
|
139
129
|
|
|
140
130
|
// Update calendar month to match
|
|
@@ -176,6 +166,18 @@ function CalendarDateTimeControl< Item >( {
|
|
|
176
166
|
hideLabelFromVision={ hideLabelFromVision }
|
|
177
167
|
>
|
|
178
168
|
<Stack direction="column" gap="lg">
|
|
169
|
+
{ /* Manual datetime input */ }
|
|
170
|
+
<ValidatedInputControl
|
|
171
|
+
ref={ inputControlRef }
|
|
172
|
+
__next40pxDefaultSize
|
|
173
|
+
required={ !! isValid?.required }
|
|
174
|
+
customValidity={ getCustomValidity( isValid, validity ) }
|
|
175
|
+
type="datetime-local"
|
|
176
|
+
label={ __( 'Date time' ) }
|
|
177
|
+
hideLabelFromVision
|
|
178
|
+
value={ formatDateTime( value ) }
|
|
179
|
+
onChange={ handleManualDateTimeChange }
|
|
180
|
+
/>
|
|
179
181
|
{ /* Calendar widget */ }
|
|
180
182
|
<DateCalendar
|
|
181
183
|
style={ { width: '100%' } }
|
|
@@ -188,24 +190,6 @@ function CalendarDateTimeControl< Item >( {
|
|
|
188
190
|
timeZone={ timezoneString || undefined }
|
|
189
191
|
weekStartsOn={ weekStartsOn }
|
|
190
192
|
/>
|
|
191
|
-
{ /* Manual datetime input */ }
|
|
192
|
-
<ValidatedInputControl
|
|
193
|
-
ref={ inputControlRef }
|
|
194
|
-
__next40pxDefaultSize
|
|
195
|
-
required={ !! isValid?.required }
|
|
196
|
-
customValidity={ getCustomValidity( isValid, validity ) }
|
|
197
|
-
type="datetime-local"
|
|
198
|
-
label={ __( 'Date time' ) }
|
|
199
|
-
hideLabelFromVision
|
|
200
|
-
value={
|
|
201
|
-
value
|
|
202
|
-
? formatDateTime(
|
|
203
|
-
parseDateTime( value ) || undefined
|
|
204
|
-
)
|
|
205
|
-
: ''
|
|
206
|
-
}
|
|
207
|
-
onChange={ handleManualDateTimeChange }
|
|
208
|
-
/>
|
|
209
193
|
</Stack>
|
|
210
194
|
</BaseControl>
|
|
211
195
|
);
|
|
@@ -58,7 +58,7 @@ export default function RelativeDateControl< Item >( {
|
|
|
58
58
|
operator === OPERATOR_IN_THE_PAST ? 'inThePast' : 'over'
|
|
59
59
|
];
|
|
60
60
|
|
|
61
|
-
const { id, label, getValue, setValue } = field;
|
|
61
|
+
const { id, label, description, getValue, setValue } = field;
|
|
62
62
|
const fieldValue = getValue( { item: data } );
|
|
63
63
|
const { value: relValue = '', unit = options[ 0 ].value } =
|
|
64
64
|
fieldValue && typeof fieldValue === 'object' ? fieldValue : {};
|
|
@@ -91,6 +91,7 @@ export default function RelativeDateControl< Item >( {
|
|
|
91
91
|
className={ clsx( className, 'dataviews-controls__relative-date' ) }
|
|
92
92
|
label={ label }
|
|
93
93
|
hideLabelFromVision={ hideLabelFromVision }
|
|
94
|
+
help={ description }
|
|
94
95
|
>
|
|
95
96
|
<Stack direction="row" gap="sm">
|
|
96
97
|
<NumberControl
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Internal dependencies
|
|
3
8
|
*/
|
|
@@ -55,10 +60,28 @@ function normalizeLayout( layout?: Layout ): NormalizedLayout {
|
|
|
55
60
|
? summary
|
|
56
61
|
: [ summary ];
|
|
57
62
|
|
|
63
|
+
const openAs = layout?.openAs;
|
|
64
|
+
let normalizedOpenAs: NormalizedPanelLayout[ 'openAs' ];
|
|
65
|
+
if ( typeof openAs === 'object' && openAs.type === 'modal' ) {
|
|
66
|
+
normalizedOpenAs = {
|
|
67
|
+
type: 'modal',
|
|
68
|
+
applyLabel: openAs.applyLabel?.trim() || __( 'Apply' ),
|
|
69
|
+
cancelLabel: openAs.cancelLabel?.trim() || __( 'Cancel' ),
|
|
70
|
+
};
|
|
71
|
+
} else if ( openAs === 'modal' ) {
|
|
72
|
+
normalizedOpenAs = {
|
|
73
|
+
type: 'modal',
|
|
74
|
+
applyLabel: __( 'Apply' ),
|
|
75
|
+
cancelLabel: __( 'Cancel' ),
|
|
76
|
+
};
|
|
77
|
+
} else {
|
|
78
|
+
normalizedOpenAs = { type: 'dropdown' };
|
|
79
|
+
}
|
|
80
|
+
|
|
58
81
|
normalizedLayout = {
|
|
59
82
|
type: 'panel',
|
|
60
83
|
labelPosition: layout?.labelPosition ?? 'side',
|
|
61
|
-
openAs:
|
|
84
|
+
openAs: normalizedOpenAs,
|
|
62
85
|
summary: normalizedSummary,
|
|
63
86
|
editVisibility: layout?.editVisibility ?? 'on-hover',
|
|
64
87
|
} satisfies NormalizedPanelLayout;
|
|
@@ -13,7 +13,7 @@ export default function FormPanelField< Item >( {
|
|
|
13
13
|
}: FieldLayoutProps< Item > ) {
|
|
14
14
|
const layout = field.layout as NormalizedPanelLayout;
|
|
15
15
|
|
|
16
|
-
if ( layout.openAs === 'modal' ) {
|
|
16
|
+
if ( layout.openAs.type === 'modal' ) {
|
|
17
17
|
return (
|
|
18
18
|
<PanelModal
|
|
19
19
|
data={ data }
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
Button,
|
|
12
12
|
Modal,
|
|
13
13
|
} from '@wordpress/components';
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
import { useContext, useMemo, useRef, useState } from '@wordpress/element';
|
|
16
16
|
import { useFocusOnMount, useMergeRefs } from '@wordpress/compose';
|
|
17
17
|
import { Stack } from '@wordpress/ui';
|
|
@@ -23,6 +23,8 @@ import type {
|
|
|
23
23
|
Field,
|
|
24
24
|
NormalizedForm,
|
|
25
25
|
NormalizedFormField,
|
|
26
|
+
NormalizedPanelLayout,
|
|
27
|
+
PanelOpenAsModal,
|
|
26
28
|
FieldLayoutProps,
|
|
27
29
|
} from '../../../types';
|
|
28
30
|
import { DataFormLayout } from '../data-form-layout';
|
|
@@ -48,6 +50,8 @@ function ModalContent< Item >( {
|
|
|
48
50
|
fieldLabel: string;
|
|
49
51
|
touched: boolean;
|
|
50
52
|
} ) {
|
|
53
|
+
const { openAs } = field.layout as NormalizedPanelLayout;
|
|
54
|
+
const { applyLabel, cancelLabel } = openAs as PanelOpenAsModal;
|
|
51
55
|
const { fields } = useContext( DataFormContext );
|
|
52
56
|
const [ changes, setChanges ] = useState< Partial< Item > >( {} );
|
|
53
57
|
const modalData = useMemo( () => {
|
|
@@ -147,14 +151,14 @@ function ModalContent< Item >( {
|
|
|
147
151
|
onClick={ onClose }
|
|
148
152
|
__next40pxDefaultSize
|
|
149
153
|
>
|
|
150
|
-
{
|
|
154
|
+
{ cancelLabel }
|
|
151
155
|
</Button>
|
|
152
156
|
<Button
|
|
153
157
|
variant="primary"
|
|
154
158
|
onClick={ onApply }
|
|
155
159
|
__next40pxDefaultSize
|
|
156
160
|
>
|
|
157
|
-
{
|
|
161
|
+
{ applyLabel }
|
|
158
162
|
</Button>
|
|
159
163
|
</Stack>
|
|
160
164
|
</Modal>
|
|
@@ -137,7 +137,7 @@ describe( 'normalizeFormFields', () => {
|
|
|
137
137
|
layout: {
|
|
138
138
|
labelPosition: 'side',
|
|
139
139
|
type: 'panel',
|
|
140
|
-
openAs: 'dropdown',
|
|
140
|
+
openAs: { type: 'dropdown' },
|
|
141
141
|
summary: [],
|
|
142
142
|
editVisibility: 'on-hover',
|
|
143
143
|
},
|
|
@@ -147,7 +147,7 @@ describe( 'normalizeFormFields', () => {
|
|
|
147
147
|
layout: {
|
|
148
148
|
type: 'panel',
|
|
149
149
|
labelPosition: 'side',
|
|
150
|
-
openAs: 'dropdown',
|
|
150
|
+
openAs: { type: 'dropdown' },
|
|
151
151
|
summary: [],
|
|
152
152
|
editVisibility: 'on-hover',
|
|
153
153
|
},
|
|
@@ -166,7 +166,7 @@ describe( 'normalizeFormFields', () => {
|
|
|
166
166
|
layout: {
|
|
167
167
|
labelPosition: 'top',
|
|
168
168
|
type: 'panel',
|
|
169
|
-
openAs: 'dropdown',
|
|
169
|
+
openAs: { type: 'dropdown' },
|
|
170
170
|
summary: [],
|
|
171
171
|
editVisibility: 'on-hover',
|
|
172
172
|
},
|
|
@@ -176,7 +176,7 @@ describe( 'normalizeFormFields', () => {
|
|
|
176
176
|
layout: {
|
|
177
177
|
type: 'panel',
|
|
178
178
|
labelPosition: 'top',
|
|
179
|
-
openAs: 'dropdown',
|
|
179
|
+
openAs: { type: 'dropdown' },
|
|
180
180
|
summary: [],
|
|
181
181
|
editVisibility: 'on-hover',
|
|
182
182
|
},
|
|
@@ -185,6 +185,99 @@ describe( 'normalizeFormFields', () => {
|
|
|
185
185
|
} );
|
|
186
186
|
} );
|
|
187
187
|
|
|
188
|
+
it( 'panel: openAs string "modal" normalizes to object with defaults', () => {
|
|
189
|
+
const form: Form = {
|
|
190
|
+
layout: { type: 'panel', openAs: 'modal' },
|
|
191
|
+
fields: [ 'field1' ],
|
|
192
|
+
};
|
|
193
|
+
const result = normalizeForm( form );
|
|
194
|
+
expect( result.layout ).toEqual( {
|
|
195
|
+
type: 'panel',
|
|
196
|
+
labelPosition: 'side',
|
|
197
|
+
openAs: {
|
|
198
|
+
type: 'modal',
|
|
199
|
+
applyLabel: 'Apply',
|
|
200
|
+
cancelLabel: 'Cancel',
|
|
201
|
+
},
|
|
202
|
+
summary: [],
|
|
203
|
+
editVisibility: 'on-hover',
|
|
204
|
+
} );
|
|
205
|
+
} );
|
|
206
|
+
|
|
207
|
+
it( 'panel: openAs object preserves labels', () => {
|
|
208
|
+
const form: Form = {
|
|
209
|
+
layout: {
|
|
210
|
+
type: 'panel',
|
|
211
|
+
openAs: {
|
|
212
|
+
type: 'modal',
|
|
213
|
+
applyLabel: 'Save',
|
|
214
|
+
cancelLabel: 'Dismiss',
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
fields: [ 'field1' ],
|
|
218
|
+
};
|
|
219
|
+
const result = normalizeForm( form );
|
|
220
|
+
expect( result.layout ).toEqual( {
|
|
221
|
+
type: 'panel',
|
|
222
|
+
labelPosition: 'side',
|
|
223
|
+
openAs: {
|
|
224
|
+
type: 'modal',
|
|
225
|
+
applyLabel: 'Save',
|
|
226
|
+
cancelLabel: 'Dismiss',
|
|
227
|
+
},
|
|
228
|
+
summary: [],
|
|
229
|
+
editVisibility: 'on-hover',
|
|
230
|
+
} );
|
|
231
|
+
} );
|
|
232
|
+
|
|
233
|
+
it( 'panel: openAs object without labels gets defaults', () => {
|
|
234
|
+
const form: Form = {
|
|
235
|
+
layout: {
|
|
236
|
+
type: 'panel',
|
|
237
|
+
openAs: { type: 'modal' },
|
|
238
|
+
},
|
|
239
|
+
fields: [ 'field1' ],
|
|
240
|
+
};
|
|
241
|
+
const result = normalizeForm( form );
|
|
242
|
+
expect( result.layout ).toEqual( {
|
|
243
|
+
type: 'panel',
|
|
244
|
+
labelPosition: 'side',
|
|
245
|
+
openAs: {
|
|
246
|
+
type: 'modal',
|
|
247
|
+
applyLabel: 'Apply',
|
|
248
|
+
cancelLabel: 'Cancel',
|
|
249
|
+
},
|
|
250
|
+
summary: [],
|
|
251
|
+
editVisibility: 'on-hover',
|
|
252
|
+
} );
|
|
253
|
+
} );
|
|
254
|
+
|
|
255
|
+
it( 'panel: openAs object trims whitespace and falls back to defaults', () => {
|
|
256
|
+
const form: Form = {
|
|
257
|
+
layout: {
|
|
258
|
+
type: 'panel',
|
|
259
|
+
openAs: {
|
|
260
|
+
type: 'modal',
|
|
261
|
+
applyLabel: ' ',
|
|
262
|
+
cancelLabel: '',
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
fields: [ 'field1' ],
|
|
266
|
+
};
|
|
267
|
+
const result = normalizeForm( form );
|
|
268
|
+
expect( result.layout ).toEqual( {
|
|
269
|
+
type: 'panel',
|
|
270
|
+
labelPosition: 'side',
|
|
271
|
+
openAs: {
|
|
272
|
+
type: 'modal',
|
|
273
|
+
applyLabel: 'Apply',
|
|
274
|
+
cancelLabel: 'Cancel',
|
|
275
|
+
},
|
|
276
|
+
summary: [],
|
|
277
|
+
editVisibility: 'on-hover',
|
|
278
|
+
} );
|
|
279
|
+
} );
|
|
280
|
+
|
|
188
281
|
it( 'card: with default layout options', () => {
|
|
189
282
|
const form: Form = {
|
|
190
283
|
layout: { type: 'card' },
|
|
@@ -360,7 +453,7 @@ describe( 'normalizeFormFields', () => {
|
|
|
360
453
|
layout: {
|
|
361
454
|
type: 'panel',
|
|
362
455
|
labelPosition: 'side',
|
|
363
|
-
openAs: 'dropdown',
|
|
456
|
+
openAs: { type: 'dropdown' },
|
|
364
457
|
summary: [],
|
|
365
458
|
editVisibility: 'on-hover',
|
|
366
459
|
},
|
|
@@ -7,6 +7,7 @@ import type { ComponentType } from 'react';
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { useContext } from '@wordpress/element';
|
|
10
|
+
import { Spinner } from '@wordpress/components';
|
|
10
11
|
import { __ } from '@wordpress/i18n';
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -14,6 +15,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
14
15
|
*/
|
|
15
16
|
import DataViewsContext from '../dataviews-context';
|
|
16
17
|
import { VIEW_LAYOUTS } from '../dataviews-layouts';
|
|
18
|
+
import { useDelayedLoading } from '../../hooks/use-delayed-loading';
|
|
17
19
|
import type { ViewBaseProps } from '../../types';
|
|
18
20
|
|
|
19
21
|
type DataViewsLayoutProps = {
|
|
@@ -38,11 +40,29 @@ export default function DataViewsLayout( { className }: DataViewsLayoutProps ) {
|
|
|
38
40
|
isItemClickable,
|
|
39
41
|
renderItemLink,
|
|
40
42
|
defaultLayouts,
|
|
43
|
+
containerRef,
|
|
41
44
|
empty = <p>{ __( 'No results' ) }</p>,
|
|
42
45
|
} = useContext( DataViewsContext );
|
|
43
46
|
|
|
47
|
+
const isDelayedInitialLoading = useDelayedLoading( ! hasInitiallyLoaded, {
|
|
48
|
+
delay: 200,
|
|
49
|
+
} );
|
|
50
|
+
// Until the initial data load completes, show a spinner (or nothing if fast).
|
|
51
|
+
// After that, render the layout component which preserves previous data
|
|
52
|
+
// while loading subsequent requests.
|
|
44
53
|
if ( ! hasInitiallyLoaded ) {
|
|
45
|
-
|
|
54
|
+
// If the initial data load is fast, don't show the loading state at all.
|
|
55
|
+
if ( ! isDelayedInitialLoading ) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
// If the initial data load takes more than 200ms, show the loading state.
|
|
59
|
+
return (
|
|
60
|
+
<div className="dataviews-loading">
|
|
61
|
+
<p>
|
|
62
|
+
<Spinner />
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
46
66
|
}
|
|
47
67
|
|
|
48
68
|
const ViewComponent = VIEW_LAYOUTS.find(
|
|
@@ -50,23 +70,25 @@ export default function DataViewsLayout( { className }: DataViewsLayoutProps ) {
|
|
|
50
70
|
)?.component as ComponentType< ViewBaseProps< any > >;
|
|
51
71
|
|
|
52
72
|
return (
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
<div className="dataviews-layout__container" ref={ containerRef }>
|
|
74
|
+
<ViewComponent
|
|
75
|
+
className={ className }
|
|
76
|
+
actions={ actions }
|
|
77
|
+
data={ data }
|
|
78
|
+
fields={ fields }
|
|
79
|
+
getItemId={ getItemId }
|
|
80
|
+
getItemLevel={ getItemLevel }
|
|
81
|
+
isLoading={ isLoading }
|
|
82
|
+
onChangeView={ onChangeView }
|
|
83
|
+
onChangeSelection={ onChangeSelection }
|
|
84
|
+
selection={ selection }
|
|
85
|
+
setOpenedFilter={ setOpenedFilter }
|
|
86
|
+
onClickItem={ onClickItem }
|
|
87
|
+
renderItemLink={ renderItemLink }
|
|
88
|
+
isItemClickable={ isItemClickable }
|
|
89
|
+
view={ view }
|
|
90
|
+
empty={ empty }
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
71
93
|
);
|
|
72
94
|
}
|
|
@@ -372,7 +372,13 @@ export default function CompositeGrid< Item >( {
|
|
|
372
372
|
return (
|
|
373
373
|
<Composite
|
|
374
374
|
role={ isInfiniteScroll ? 'feed' : 'grid' }
|
|
375
|
-
className={ clsx( 'dataviews-view-grid', className
|
|
375
|
+
className={ clsx( 'dataviews-view-grid', className, {
|
|
376
|
+
[ `has-${ view.layout?.density }-density` ]:
|
|
377
|
+
view.layout?.density &&
|
|
378
|
+
[ 'compact', 'comfortable' ].includes(
|
|
379
|
+
view.layout.density
|
|
380
|
+
),
|
|
381
|
+
} ) }
|
|
376
382
|
focusWrap
|
|
377
383
|
aria-busy={ isLoading }
|
|
378
384
|
aria-rowcount={ isInfiniteScroll ? undefined : totalRows }
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
padding: 0 $grid-unit-30 $grid-unit-30;
|
|
10
10
|
display: flex;
|
|
11
11
|
flex-direction: column;
|
|
12
|
-
gap: $grid-unit-
|
|
12
|
+
gap: $grid-unit-30;
|
|
13
13
|
container-type: inline-size;
|
|
14
14
|
margin-bottom: auto;
|
|
15
15
|
|
|
@@ -17,9 +17,25 @@
|
|
|
17
17
|
transition: padding ease-out 0.1s;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
&.has-compact-density {
|
|
21
|
+
gap: $grid-unit-20;
|
|
22
|
+
|
|
23
|
+
.dataviews-view-grid__row {
|
|
24
|
+
gap: $grid-unit-20;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&.has-comfortable-density {
|
|
29
|
+
gap: $grid-unit-40;
|
|
30
|
+
|
|
31
|
+
.dataviews-view-grid__row {
|
|
32
|
+
gap: $grid-unit-40;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
.dataviews-view-grid__row {
|
|
21
37
|
display: grid;
|
|
22
|
-
gap: $grid-unit-
|
|
38
|
+
gap: $grid-unit-30;
|
|
23
39
|
|
|
24
40
|
.dataviews-view-grid__row__gridcell {
|
|
25
41
|
border-radius: $radius-medium;
|
|
@@ -27,8 +27,8 @@ import {
|
|
|
27
27
|
LAYOUT_PICKER_GRID,
|
|
28
28
|
LAYOUT_PICKER_TABLE,
|
|
29
29
|
} from '../../constants';
|
|
30
|
-
import PreviewSizePicker from './utils/preview-size-picker';
|
|
31
30
|
import DensityPicker from './utils/density-picker';
|
|
31
|
+
import GridConfigOptions from './utils/grid-config-options';
|
|
32
32
|
|
|
33
33
|
export const VIEW_LAYOUTS = [
|
|
34
34
|
{
|
|
@@ -43,7 +43,7 @@ export const VIEW_LAYOUTS = [
|
|
|
43
43
|
label: __( 'Grid' ),
|
|
44
44
|
component: ViewGrid,
|
|
45
45
|
icon: category,
|
|
46
|
-
viewConfigOptions:
|
|
46
|
+
viewConfigOptions: GridConfigOptions,
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
type: LAYOUT_LIST,
|
|
@@ -64,7 +64,7 @@ export const VIEW_LAYOUTS = [
|
|
|
64
64
|
label: __( 'Grid' ),
|
|
65
65
|
component: ViewPickerGrid,
|
|
66
66
|
icon: category,
|
|
67
|
-
viewConfigOptions:
|
|
67
|
+
viewConfigOptions: GridConfigOptions,
|
|
68
68
|
isPicker: true,
|
|
69
69
|
},
|
|
70
70
|
{
|