@wordpress/dataviews 6.0.0 → 7.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 +25 -1
- package/README.md +42 -14
- package/build/components/dataviews/index.js +38 -6
- package/build/components/dataviews/index.js.map +1 -1
- package/build/components/dataviews-context/index.js +4 -1
- package/build/components/dataviews-context/index.js.map +1 -1
- package/build/components/dataviews-item-actions/index.js +1 -10
- package/build/components/dataviews-item-actions/index.js.map +1 -1
- package/build/components/dataviews-pagination/index.js +1 -1
- package/build/components/dataviews-pagination/index.js.map +1 -1
- package/build/components/dataviews-view-config/index.js +8 -5
- package/build/components/dataviews-view-config/index.js.map +1 -1
- package/build/components/dataviews-view-config/infinite-scroll-toggle.js +47 -0
- package/build/components/dataviews-view-config/infinite-scroll-toggle.js.map +1 -0
- package/build/dataform-controls/array.js +70 -0
- package/build/dataform-controls/array.js.map +1 -0
- package/build/dataform-controls/boolean.js +15 -7
- package/build/dataform-controls/boolean.js.map +1 -1
- package/build/dataform-controls/email.js +14 -7
- package/build/dataform-controls/email.js.map +1 -1
- package/build/dataform-controls/index.js +3 -1
- package/build/dataform-controls/index.js.map +1 -1
- package/build/dataform-controls/integer.js +14 -7
- package/build/dataform-controls/integer.js.map +1 -1
- package/build/dataform-controls/text.js +14 -7
- package/build/dataform-controls/text.js.map +1 -1
- package/build/dataforms-layouts/card/index.js +137 -0
- package/build/dataforms-layouts/card/index.js.map +1 -0
- package/build/dataforms-layouts/data-form-layout.js +2 -2
- package/build/dataforms-layouts/data-form-layout.js.map +1 -1
- package/build/dataforms-layouts/index.js +4 -0
- package/build/dataforms-layouts/index.js.map +1 -1
- package/build/dataforms-layouts/panel/dropdown.js +124 -0
- package/build/dataforms-layouts/panel/dropdown.js.map +1 -0
- package/build/dataforms-layouts/panel/index.js +34 -149
- package/build/dataforms-layouts/panel/index.js.map +1 -1
- package/build/dataforms-layouts/panel/modal.js +125 -0
- package/build/dataforms-layouts/panel/modal.js.map +1 -0
- package/build/dataforms-layouts/regular/index.js +10 -21
- package/build/dataforms-layouts/regular/index.js.map +1 -1
- package/build/dataviews-layouts/grid/index.js +24 -7
- package/build/dataviews-layouts/grid/index.js.map +1 -1
- package/build/dataviews-layouts/grid/preview-size-picker.js +11 -11
- package/build/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
- package/build/dataviews-layouts/list/index.js +45 -27
- package/build/dataviews-layouts/list/index.js.map +1 -1
- package/build/dataviews-layouts/table/column-header-menu.js +3 -0
- package/build/dataviews-layouts/table/column-header-menu.js.map +1 -1
- package/build/dataviews-layouts/table/index.js +23 -8
- package/build/dataviews-layouts/table/index.js.map +1 -1
- package/build/field-types/array.js +2 -2
- package/build/field-types/array.js.map +1 -1
- package/build/normalize-form-fields.js +52 -13
- package/build/normalize-form-fields.js.map +1 -1
- package/build/types.js.map +1 -1
- package/build-module/components/dataviews/index.js +40 -8
- package/build-module/components/dataviews/index.js.map +1 -1
- package/build-module/components/dataviews-context/index.js +4 -1
- package/build-module/components/dataviews-context/index.js.map +1 -1
- package/build-module/components/dataviews-item-actions/index.js +1 -10
- package/build-module/components/dataviews-item-actions/index.js.map +1 -1
- package/build-module/components/dataviews-pagination/index.js +1 -1
- package/build-module/components/dataviews-pagination/index.js.map +1 -1
- package/build-module/components/dataviews-view-config/index.js +8 -5
- package/build-module/components/dataviews-view-config/index.js.map +1 -1
- package/build-module/components/dataviews-view-config/infinite-scroll-toggle.js +39 -0
- package/build-module/components/dataviews-view-config/infinite-scroll-toggle.js.map +1 -0
- package/build-module/dataform-controls/array.js +63 -0
- package/build-module/dataform-controls/array.js.map +1 -0
- package/build-module/dataform-controls/boolean.js +15 -7
- package/build-module/dataform-controls/boolean.js.map +1 -1
- package/build-module/dataform-controls/email.js +15 -8
- package/build-module/dataform-controls/email.js.map +1 -1
- package/build-module/dataform-controls/index.js +3 -1
- package/build-module/dataform-controls/index.js.map +1 -1
- package/build-module/dataform-controls/integer.js +15 -8
- package/build-module/dataform-controls/integer.js.map +1 -1
- package/build-module/dataform-controls/text.js +15 -8
- package/build-module/dataform-controls/text.js.map +1 -1
- package/build-module/dataforms-layouts/card/index.js +128 -0
- package/build-module/dataforms-layouts/card/index.js.map +1 -0
- package/build-module/dataforms-layouts/data-form-layout.js +2 -2
- package/build-module/dataforms-layouts/data-form-layout.js.map +1 -1
- package/build-module/dataforms-layouts/index.js +4 -0
- package/build-module/dataforms-layouts/index.js.map +1 -1
- package/build-module/dataforms-layouts/panel/dropdown.js +118 -0
- package/build-module/dataforms-layouts/panel/dropdown.js.map +1 -0
- package/build-module/dataforms-layouts/panel/index.js +37 -152
- package/build-module/dataforms-layouts/panel/index.js.map +1 -1
- package/build-module/dataforms-layouts/panel/modal.js +119 -0
- package/build-module/dataforms-layouts/panel/modal.js.map +1 -0
- package/build-module/dataforms-layouts/regular/index.js +10 -21
- package/build-module/dataforms-layouts/regular/index.js.map +1 -1
- package/build-module/dataviews-layouts/grid/index.js +25 -8
- package/build-module/dataviews-layouts/grid/index.js.map +1 -1
- package/build-module/dataviews-layouts/grid/preview-size-picker.js +11 -11
- package/build-module/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
- package/build-module/dataviews-layouts/list/index.js +47 -29
- package/build-module/dataviews-layouts/list/index.js.map +1 -1
- package/build-module/dataviews-layouts/table/column-header-menu.js +3 -0
- package/build-module/dataviews-layouts/table/column-header-menu.js.map +1 -1
- package/build-module/dataviews-layouts/table/index.js +23 -8
- package/build-module/dataviews-layouts/table/index.js.map +1 -1
- package/build-module/field-types/array.js +2 -2
- package/build-module/field-types/array.js.map +1 -1
- package/build-module/normalize-form-fields.js +50 -13
- package/build-module/normalize-form-fields.js.map +1 -1
- package/build-module/types.js.map +1 -1
- package/build-style/style-rtl.css +53 -16
- package/build-style/style.css +53 -16
- package/build-types/components/dataform/stories/index.story.d.ts +41 -17
- package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
- package/build-types/components/dataviews/index.d.ts +5 -2
- package/build-types/components/dataviews/index.d.ts.map +1 -1
- package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
- package/build-types/components/dataviews/stories/index.story.d.ts +2 -1
- package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
- package/build-types/components/dataviews-context/index.d.ts +4 -1
- package/build-types/components/dataviews-context/index.d.ts.map +1 -1
- package/build-types/components/dataviews-item-actions/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 +2 -0
- package/build-types/components/dataviews-view-config/infinite-scroll-toggle.d.ts.map +1 -0
- package/build-types/dataform-controls/array.d.ts +6 -0
- package/build-types/dataform-controls/array.d.ts.map +1 -0
- package/build-types/dataform-controls/boolean.d.ts.map +1 -1
- package/build-types/dataform-controls/email.d.ts.map +1 -1
- package/build-types/dataform-controls/index.d.ts.map +1 -1
- package/build-types/dataform-controls/integer.d.ts.map +1 -1
- package/build-types/dataform-controls/text.d.ts.map +1 -1
- package/build-types/dataforms-layouts/card/index.d.ts +13 -0
- package/build-types/dataforms-layouts/card/index.d.ts.map +1 -0
- package/build-types/dataforms-layouts/index.d.ts.map +1 -1
- package/build-types/dataforms-layouts/panel/dropdown.d.ts +14 -0
- package/build-types/dataforms-layouts/panel/dropdown.d.ts.map +1 -0
- package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
- package/build-types/dataforms-layouts/panel/modal.d.ts +13 -0
- package/build-types/dataforms-layouts/panel/modal.d.ts.map +1 -0
- package/build-types/dataforms-layouts/regular/index.d.ts.map +1 -1
- package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -1
- package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts +1 -1
- package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts.map +1 -1
- package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
- package/build-types/dataviews-layouts/table/column-header-menu.d.ts.map +1 -1
- package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
- package/build-types/field-types/boolean.d.ts +1 -1
- package/build-types/normalize-form-fields.d.ts +10 -3
- package/build-types/normalize-form-fields.d.ts.map +1 -1
- package/build-types/test/normalize-form-fields.d.ts +2 -0
- package/build-types/test/normalize-form-fields.d.ts.map +1 -0
- package/build-types/types.d.ts +54 -6
- package/build-types/types.d.ts.map +1 -1
- package/build-wp/index.js +3062 -1147
- package/package.json +15 -15
- package/src/components/dataform/stories/index.story.tsx +478 -91
- package/src/components/dataviews/index.tsx +50 -14
- package/src/components/dataviews/stories/fixtures.tsx +98 -7
- package/src/components/dataviews/stories/index.story.tsx +137 -4
- package/src/components/dataviews/style.scss +4 -0
- package/src/components/dataviews-context/index.ts +6 -2
- package/src/components/dataviews-item-actions/index.tsx +7 -16
- package/src/components/dataviews-pagination/index.tsx +1 -1
- package/src/components/dataviews-view-config/index.tsx +13 -5
- package/src/components/dataviews-view-config/infinite-scroll-toggle.tsx +39 -0
- package/src/dataform-controls/array.tsx +85 -0
- package/src/dataform-controls/boolean.tsx +24 -10
- package/src/dataform-controls/email.tsx +24 -11
- package/src/dataform-controls/index.tsx +3 -1
- package/src/dataform-controls/integer.tsx +27 -13
- package/src/dataform-controls/text.tsx +24 -11
- package/src/dataforms-layouts/card/index.tsx +154 -0
- package/src/dataforms-layouts/card/style.scss +3 -0
- package/src/dataforms-layouts/data-form-layout.tsx +2 -2
- package/src/dataforms-layouts/index.tsx +5 -0
- package/src/dataforms-layouts/panel/dropdown.tsx +160 -0
- package/src/dataforms-layouts/panel/index.tsx +49 -189
- package/src/dataforms-layouts/panel/modal.tsx +165 -0
- package/src/dataforms-layouts/panel/style.scss +4 -0
- package/src/dataforms-layouts/regular/index.tsx +20 -23
- package/src/dataviews-layouts/grid/index.tsx +32 -5
- package/src/dataviews-layouts/grid/preview-size-picker.tsx +15 -13
- package/src/dataviews-layouts/grid/style.scss +3 -1
- package/src/dataviews-layouts/list/index.tsx +65 -31
- package/src/dataviews-layouts/list/style.scss +7 -3
- package/src/dataviews-layouts/table/column-header-menu.tsx +4 -0
- package/src/dataviews-layouts/table/index.tsx +27 -1
- package/src/field-types/array.tsx +1 -1
- package/src/normalize-form-fields.ts +63 -17
- package/src/test/dataform.tsx +181 -3
- package/src/test/dataviews.tsx +38 -0
- package/src/test/filter-and-sort-data-view.js +123 -64
- package/src/test/normalize-form-fields.ts +247 -0
- package/src/types.ts +72 -6
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -9,173 +9,22 @@ import clsx from 'clsx';
|
|
|
9
9
|
import {
|
|
10
10
|
__experimentalVStack as VStack,
|
|
11
11
|
__experimentalHStack as HStack,
|
|
12
|
-
__experimentalHeading as Heading,
|
|
13
|
-
__experimentalSpacer as Spacer,
|
|
14
|
-
Dropdown,
|
|
15
|
-
Button,
|
|
16
12
|
} from '@wordpress/components';
|
|
17
|
-
import {
|
|
18
|
-
import { useState, useMemo, useContext } from '@wordpress/element';
|
|
19
|
-
import { closeSmall } from '@wordpress/icons';
|
|
13
|
+
import { useState, useContext } from '@wordpress/element';
|
|
20
14
|
|
|
21
15
|
/**
|
|
22
16
|
* Internal dependencies
|
|
23
17
|
*/
|
|
24
18
|
import type {
|
|
25
|
-
Form,
|
|
26
|
-
FormField,
|
|
27
19
|
FieldLayoutProps,
|
|
28
|
-
|
|
20
|
+
NormalizedPanelLayout,
|
|
29
21
|
SimpleFormField,
|
|
30
22
|
} from '../../types';
|
|
31
23
|
import DataFormContext from '../../components/dataform-context';
|
|
32
|
-
import { DataFormLayout } from '../data-form-layout';
|
|
33
24
|
import { isCombinedField } from '../is-combined-field';
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
onClose,
|
|
38
|
-
}: {
|
|
39
|
-
title?: string;
|
|
40
|
-
onClose: () => void;
|
|
41
|
-
} ) {
|
|
42
|
-
return (
|
|
43
|
-
<VStack
|
|
44
|
-
className="dataforms-layouts-panel__dropdown-header"
|
|
45
|
-
spacing={ 4 }
|
|
46
|
-
>
|
|
47
|
-
<HStack alignment="center">
|
|
48
|
-
{ title && (
|
|
49
|
-
<Heading level={ 2 } size={ 13 }>
|
|
50
|
-
{ title }
|
|
51
|
-
</Heading>
|
|
52
|
-
) }
|
|
53
|
-
<Spacer />
|
|
54
|
-
{ onClose && (
|
|
55
|
-
<Button
|
|
56
|
-
label={ __( 'Close' ) }
|
|
57
|
-
icon={ closeSmall }
|
|
58
|
-
onClick={ onClose }
|
|
59
|
-
size="small"
|
|
60
|
-
/>
|
|
61
|
-
) }
|
|
62
|
-
</HStack>
|
|
63
|
-
</VStack>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function PanelDropdown< Item >( {
|
|
68
|
-
fieldDefinition,
|
|
69
|
-
popoverAnchor,
|
|
70
|
-
labelPosition = 'side',
|
|
71
|
-
data,
|
|
72
|
-
onChange,
|
|
73
|
-
field,
|
|
74
|
-
}: {
|
|
75
|
-
fieldDefinition: NormalizedField< Item >;
|
|
76
|
-
popoverAnchor: HTMLElement | null;
|
|
77
|
-
labelPosition: 'side' | 'top' | 'none';
|
|
78
|
-
data: Item;
|
|
79
|
-
onChange: ( value: any ) => void;
|
|
80
|
-
field: FormField;
|
|
81
|
-
} ) {
|
|
82
|
-
const fieldLabel = isCombinedField( field )
|
|
83
|
-
? field.label
|
|
84
|
-
: fieldDefinition?.label;
|
|
85
|
-
const form = useMemo( () => {
|
|
86
|
-
if ( isCombinedField( field ) ) {
|
|
87
|
-
return {
|
|
88
|
-
type: 'regular' as const,
|
|
89
|
-
fields: field.children.map( ( child ) => {
|
|
90
|
-
if ( typeof child === 'string' ) {
|
|
91
|
-
return {
|
|
92
|
-
id: child,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
return child;
|
|
96
|
-
} ),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
// If not explicit children return the field id itself.
|
|
100
|
-
return {
|
|
101
|
-
type: 'regular' as const,
|
|
102
|
-
fields: [ { id: field.id } ],
|
|
103
|
-
};
|
|
104
|
-
}, [ field ] );
|
|
105
|
-
|
|
106
|
-
// Memoize popoverProps to avoid returning a new object every time.
|
|
107
|
-
const popoverProps = useMemo(
|
|
108
|
-
() => ( {
|
|
109
|
-
// Anchor the popover to the middle of the entire row so that it doesn't
|
|
110
|
-
// move around when the label changes.
|
|
111
|
-
anchor: popoverAnchor,
|
|
112
|
-
placement: 'left-start',
|
|
113
|
-
offset: 36,
|
|
114
|
-
shift: true,
|
|
115
|
-
} ),
|
|
116
|
-
[ popoverAnchor ]
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
return (
|
|
120
|
-
<Dropdown
|
|
121
|
-
contentClassName="dataforms-layouts-panel__field-dropdown"
|
|
122
|
-
popoverProps={ popoverProps }
|
|
123
|
-
focusOnMount
|
|
124
|
-
toggleProps={ {
|
|
125
|
-
size: 'compact',
|
|
126
|
-
variant: 'tertiary',
|
|
127
|
-
tooltipPosition: 'middle left',
|
|
128
|
-
} }
|
|
129
|
-
renderToggle={ ( { isOpen, onToggle } ) => (
|
|
130
|
-
<Button
|
|
131
|
-
className="dataforms-layouts-panel__field-control"
|
|
132
|
-
size="compact"
|
|
133
|
-
variant={
|
|
134
|
-
[ 'none', 'top' ].includes( labelPosition )
|
|
135
|
-
? 'link'
|
|
136
|
-
: 'tertiary'
|
|
137
|
-
}
|
|
138
|
-
aria-expanded={ isOpen }
|
|
139
|
-
aria-label={ sprintf(
|
|
140
|
-
// translators: %s: Field name.
|
|
141
|
-
_x( 'Edit %s', 'field' ),
|
|
142
|
-
fieldLabel || ''
|
|
143
|
-
) }
|
|
144
|
-
onClick={ onToggle }
|
|
145
|
-
disabled={ fieldDefinition.readOnly === true }
|
|
146
|
-
accessibleWhenDisabled
|
|
147
|
-
>
|
|
148
|
-
<fieldDefinition.render
|
|
149
|
-
item={ data }
|
|
150
|
-
field={ fieldDefinition }
|
|
151
|
-
/>
|
|
152
|
-
</Button>
|
|
153
|
-
) }
|
|
154
|
-
renderContent={ ( { onClose } ) => (
|
|
155
|
-
<>
|
|
156
|
-
<DropdownHeader title={ fieldLabel } onClose={ onClose } />
|
|
157
|
-
<DataFormLayout
|
|
158
|
-
data={ data }
|
|
159
|
-
form={ form as Form }
|
|
160
|
-
onChange={ onChange }
|
|
161
|
-
>
|
|
162
|
-
{ ( FieldLayout, nestedField ) => (
|
|
163
|
-
<FieldLayout
|
|
164
|
-
key={ nestedField.id }
|
|
165
|
-
data={ data }
|
|
166
|
-
field={ nestedField }
|
|
167
|
-
onChange={ onChange }
|
|
168
|
-
hideLabelFromVision={
|
|
169
|
-
( form?.fields ?? [] ).length < 2
|
|
170
|
-
}
|
|
171
|
-
/>
|
|
172
|
-
) }
|
|
173
|
-
</DataFormLayout>
|
|
174
|
-
</>
|
|
175
|
-
) }
|
|
176
|
-
/>
|
|
177
|
-
);
|
|
178
|
-
}
|
|
25
|
+
import { normalizeLayout } from '../../normalize-form-fields';
|
|
26
|
+
import PanelDropdown from './dropdown';
|
|
27
|
+
import PanelModal from './modal';
|
|
179
28
|
|
|
180
29
|
export default function FormPanelField< Item >( {
|
|
181
30
|
data,
|
|
@@ -183,20 +32,27 @@ export default function FormPanelField< Item >( {
|
|
|
183
32
|
onChange,
|
|
184
33
|
}: FieldLayoutProps< Item > ) {
|
|
185
34
|
const { fields } = useContext( DataFormContext );
|
|
186
|
-
const fieldDefinition = fields.find( (
|
|
187
|
-
// Default to the first child if it is a combined field.
|
|
35
|
+
const fieldDefinition = fields.find( ( _field ) => {
|
|
36
|
+
// Default to the first simple child if it is a combined field.
|
|
188
37
|
if ( isCombinedField( field ) ) {
|
|
189
|
-
const
|
|
38
|
+
const simpleChildren = field.children.filter(
|
|
190
39
|
( child ): child is string | SimpleFormField =>
|
|
191
40
|
typeof child === 'string' || ! isCombinedField( child )
|
|
192
41
|
);
|
|
42
|
+
|
|
43
|
+
if ( simpleChildren.length === 0 ) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
193
47
|
const firstChildFieldId =
|
|
194
|
-
typeof
|
|
195
|
-
?
|
|
196
|
-
:
|
|
197
|
-
|
|
48
|
+
typeof simpleChildren[ 0 ] === 'string'
|
|
49
|
+
? simpleChildren[ 0 ]
|
|
50
|
+
: simpleChildren[ 0 ].id;
|
|
51
|
+
|
|
52
|
+
return _field.id === firstChildFieldId;
|
|
198
53
|
}
|
|
199
|
-
|
|
54
|
+
|
|
55
|
+
return _field.id === field.id;
|
|
200
56
|
} );
|
|
201
57
|
|
|
202
58
|
// Use internal state instead of a ref to make sure that the component
|
|
@@ -209,7 +65,12 @@ export default function FormPanelField< Item >( {
|
|
|
209
65
|
return null;
|
|
210
66
|
}
|
|
211
67
|
|
|
212
|
-
const
|
|
68
|
+
const layout: NormalizedPanelLayout = normalizeLayout( {
|
|
69
|
+
...field.layout,
|
|
70
|
+
type: 'panel',
|
|
71
|
+
} ) as NormalizedPanelLayout;
|
|
72
|
+
|
|
73
|
+
const labelPosition = layout.labelPosition;
|
|
213
74
|
const labelClassName = clsx(
|
|
214
75
|
'dataforms-layouts-panel__field-label',
|
|
215
76
|
`dataforms-layouts-panel__field-label--label-position-${ labelPosition }`
|
|
@@ -218,6 +79,26 @@ export default function FormPanelField< Item >( {
|
|
|
218
79
|
? field.label
|
|
219
80
|
: fieldDefinition?.label;
|
|
220
81
|
|
|
82
|
+
const renderedControl =
|
|
83
|
+
layout.openAs === 'modal' ? (
|
|
84
|
+
<PanelModal
|
|
85
|
+
field={ field }
|
|
86
|
+
fieldDefinition={ fieldDefinition }
|
|
87
|
+
data={ data }
|
|
88
|
+
onChange={ onChange }
|
|
89
|
+
labelPosition={ labelPosition }
|
|
90
|
+
/>
|
|
91
|
+
) : (
|
|
92
|
+
<PanelDropdown
|
|
93
|
+
field={ field }
|
|
94
|
+
popoverAnchor={ popoverAnchor }
|
|
95
|
+
fieldDefinition={ fieldDefinition }
|
|
96
|
+
data={ data }
|
|
97
|
+
onChange={ onChange }
|
|
98
|
+
labelPosition={ labelPosition }
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
|
|
221
102
|
if ( labelPosition === 'top' ) {
|
|
222
103
|
return (
|
|
223
104
|
<VStack className="dataforms-layouts-panel__field" spacing={ 0 }>
|
|
@@ -228,14 +109,7 @@ export default function FormPanelField< Item >( {
|
|
|
228
109
|
{ fieldLabel }
|
|
229
110
|
</div>
|
|
230
111
|
<div className="dataforms-layouts-panel__field-control">
|
|
231
|
-
|
|
232
|
-
field={ field }
|
|
233
|
-
popoverAnchor={ popoverAnchor }
|
|
234
|
-
fieldDefinition={ fieldDefinition }
|
|
235
|
-
data={ data }
|
|
236
|
-
onChange={ onChange }
|
|
237
|
-
labelPosition={ labelPosition }
|
|
238
|
-
/>
|
|
112
|
+
{ renderedControl }
|
|
239
113
|
</div>
|
|
240
114
|
</VStack>
|
|
241
115
|
);
|
|
@@ -244,14 +118,7 @@ export default function FormPanelField< Item >( {
|
|
|
244
118
|
if ( labelPosition === 'none' ) {
|
|
245
119
|
return (
|
|
246
120
|
<div className="dataforms-layouts-panel__field">
|
|
247
|
-
|
|
248
|
-
field={ field }
|
|
249
|
-
popoverAnchor={ popoverAnchor }
|
|
250
|
-
fieldDefinition={ fieldDefinition }
|
|
251
|
-
data={ data }
|
|
252
|
-
onChange={ onChange }
|
|
253
|
-
labelPosition={ labelPosition }
|
|
254
|
-
/>
|
|
121
|
+
{ renderedControl }
|
|
255
122
|
</div>
|
|
256
123
|
);
|
|
257
124
|
}
|
|
@@ -264,14 +131,7 @@ export default function FormPanelField< Item >( {
|
|
|
264
131
|
>
|
|
265
132
|
<div className={ labelClassName }>{ fieldLabel }</div>
|
|
266
133
|
<div className="dataforms-layouts-panel__field-control">
|
|
267
|
-
|
|
268
|
-
field={ field }
|
|
269
|
-
popoverAnchor={ popoverAnchor }
|
|
270
|
-
fieldDefinition={ fieldDefinition }
|
|
271
|
-
data={ data }
|
|
272
|
-
onChange={ onChange }
|
|
273
|
-
labelPosition={ labelPosition }
|
|
274
|
-
/>
|
|
134
|
+
{ renderedControl }
|
|
275
135
|
</div>
|
|
276
136
|
</HStack>
|
|
277
137
|
);
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
__experimentalHStack as HStack,
|
|
6
|
+
__experimentalSpacer as Spacer,
|
|
7
|
+
Button,
|
|
8
|
+
Modal,
|
|
9
|
+
} from '@wordpress/components';
|
|
10
|
+
import { __, sprintf, _x } from '@wordpress/i18n';
|
|
11
|
+
import { useState, useMemo } from '@wordpress/element';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Internal dependencies
|
|
15
|
+
*/
|
|
16
|
+
import type { Form, FormField, NormalizedField } from '../../types';
|
|
17
|
+
import { DataFormLayout } from '../data-form-layout';
|
|
18
|
+
import { isCombinedField } from '../is-combined-field';
|
|
19
|
+
import { DEFAULT_LAYOUT } from '../../normalize-form-fields';
|
|
20
|
+
|
|
21
|
+
function ModalContent< Item >( {
|
|
22
|
+
data,
|
|
23
|
+
form,
|
|
24
|
+
fieldLabel,
|
|
25
|
+
onChange,
|
|
26
|
+
onClose,
|
|
27
|
+
}: {
|
|
28
|
+
data: Item;
|
|
29
|
+
form: Form;
|
|
30
|
+
fieldLabel: string;
|
|
31
|
+
onChange: ( data: Partial< Item > ) => void;
|
|
32
|
+
onClose: () => void;
|
|
33
|
+
} ) {
|
|
34
|
+
const [ changes, setChanges ] = useState< Partial< Item > >( {} );
|
|
35
|
+
|
|
36
|
+
const onApply = () => {
|
|
37
|
+
onChange( changes );
|
|
38
|
+
onClose();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleOnChange = ( value: Partial< Item > ) => {
|
|
42
|
+
setChanges( ( prev ) => ( { ...prev, ...value } ) );
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Merge original data with local changes for display
|
|
46
|
+
const displayData = { ...data, ...changes };
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Modal
|
|
50
|
+
className="dataforms-layouts-panel__modal"
|
|
51
|
+
onRequestClose={ onClose }
|
|
52
|
+
isFullScreen={ false }
|
|
53
|
+
title={ fieldLabel }
|
|
54
|
+
size="medium"
|
|
55
|
+
>
|
|
56
|
+
<DataFormLayout
|
|
57
|
+
data={ displayData }
|
|
58
|
+
form={ form }
|
|
59
|
+
onChange={ handleOnChange }
|
|
60
|
+
>
|
|
61
|
+
{ ( FieldLayout, nestedField ) => (
|
|
62
|
+
<FieldLayout
|
|
63
|
+
key={ nestedField.id }
|
|
64
|
+
data={ displayData }
|
|
65
|
+
field={ nestedField }
|
|
66
|
+
onChange={ handleOnChange }
|
|
67
|
+
hideLabelFromVision={
|
|
68
|
+
( form?.fields ?? [] ).length < 2
|
|
69
|
+
}
|
|
70
|
+
/>
|
|
71
|
+
) }
|
|
72
|
+
</DataFormLayout>
|
|
73
|
+
<HStack
|
|
74
|
+
className="dataforms-layouts-panel__modal-footer"
|
|
75
|
+
spacing={ 3 }
|
|
76
|
+
>
|
|
77
|
+
<Spacer />
|
|
78
|
+
<Button
|
|
79
|
+
variant="tertiary"
|
|
80
|
+
onClick={ onClose }
|
|
81
|
+
__next40pxDefaultSize
|
|
82
|
+
>
|
|
83
|
+
{ __( 'Cancel' ) }
|
|
84
|
+
</Button>
|
|
85
|
+
<Button
|
|
86
|
+
variant="primary"
|
|
87
|
+
onClick={ onApply }
|
|
88
|
+
__next40pxDefaultSize
|
|
89
|
+
>
|
|
90
|
+
{ __( 'Apply' ) }
|
|
91
|
+
</Button>
|
|
92
|
+
</HStack>
|
|
93
|
+
</Modal>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function PanelModal< Item >( {
|
|
98
|
+
fieldDefinition,
|
|
99
|
+
labelPosition,
|
|
100
|
+
data,
|
|
101
|
+
onChange,
|
|
102
|
+
field,
|
|
103
|
+
}: {
|
|
104
|
+
fieldDefinition: NormalizedField< Item >;
|
|
105
|
+
labelPosition: 'side' | 'top' | 'none';
|
|
106
|
+
data: Item;
|
|
107
|
+
onChange: ( value: any ) => void;
|
|
108
|
+
field: FormField;
|
|
109
|
+
} ) {
|
|
110
|
+
const [ isOpen, setIsOpen ] = useState( false );
|
|
111
|
+
|
|
112
|
+
const fieldLabel = isCombinedField( field )
|
|
113
|
+
? field.label
|
|
114
|
+
: fieldDefinition?.label;
|
|
115
|
+
|
|
116
|
+
const form: Form = useMemo(
|
|
117
|
+
(): Form => ( {
|
|
118
|
+
layout: DEFAULT_LAYOUT,
|
|
119
|
+
fields: isCombinedField( field )
|
|
120
|
+
? field.children
|
|
121
|
+
: // If not explicit children return the field id itself.
|
|
122
|
+
[ { id: field.id } ],
|
|
123
|
+
} ),
|
|
124
|
+
[ field ]
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<>
|
|
129
|
+
<Button
|
|
130
|
+
className="dataforms-layouts-modal__field-control"
|
|
131
|
+
size="compact"
|
|
132
|
+
variant={
|
|
133
|
+
[ 'none', 'top' ].includes( labelPosition )
|
|
134
|
+
? 'link'
|
|
135
|
+
: 'tertiary'
|
|
136
|
+
}
|
|
137
|
+
aria-expanded={ isOpen }
|
|
138
|
+
aria-label={ sprintf(
|
|
139
|
+
// translators: %s: Field name.
|
|
140
|
+
_x( 'Edit %s', 'field' ),
|
|
141
|
+
fieldLabel || ''
|
|
142
|
+
) }
|
|
143
|
+
onClick={ () => setIsOpen( true ) }
|
|
144
|
+
disabled={ fieldDefinition.readOnly === true }
|
|
145
|
+
accessibleWhenDisabled
|
|
146
|
+
>
|
|
147
|
+
<fieldDefinition.render
|
|
148
|
+
item={ data }
|
|
149
|
+
field={ fieldDefinition }
|
|
150
|
+
/>
|
|
151
|
+
</Button>
|
|
152
|
+
{ isOpen && (
|
|
153
|
+
<ModalContent
|
|
154
|
+
data={ data }
|
|
155
|
+
form={ form as Form }
|
|
156
|
+
fieldLabel={ fieldLabel ?? '' }
|
|
157
|
+
onChange={ onChange }
|
|
158
|
+
onClose={ () => setIsOpen( false ) }
|
|
159
|
+
/>
|
|
160
|
+
) }
|
|
161
|
+
</>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export default PanelModal;
|
|
@@ -52,6 +52,10 @@
|
|
|
52
52
|
margin-bottom: $grid-unit-20;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
.dataforms-layouts-panel__modal-footer {
|
|
56
|
+
margin-top: $grid-unit-20;
|
|
57
|
+
}
|
|
58
|
+
|
|
55
59
|
.components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown {
|
|
56
60
|
z-index: z-index(".components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown");
|
|
57
61
|
}
|
|
@@ -17,10 +17,15 @@ import {
|
|
|
17
17
|
/**
|
|
18
18
|
* Internal dependencies
|
|
19
19
|
*/
|
|
20
|
-
import type {
|
|
20
|
+
import type {
|
|
21
|
+
Form,
|
|
22
|
+
FieldLayoutProps,
|
|
23
|
+
NormalizedRegularLayout,
|
|
24
|
+
} from '../../types';
|
|
21
25
|
import DataFormContext from '../../components/dataform-context';
|
|
22
26
|
import { DataFormLayout } from '../data-form-layout';
|
|
23
27
|
import { isCombinedField } from '../is-combined-field';
|
|
28
|
+
import { DEFAULT_LAYOUT, normalizeLayout } from '../../normalize-form-fields';
|
|
24
29
|
|
|
25
30
|
function Header( { title }: { title: string } ) {
|
|
26
31
|
return (
|
|
@@ -43,26 +48,13 @@ export default function FormRegularField< Item >( {
|
|
|
43
48
|
}: FieldLayoutProps< Item > ) {
|
|
44
49
|
const { fields } = useContext( DataFormContext );
|
|
45
50
|
|
|
46
|
-
const form = useMemo(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
return child;
|
|
56
|
-
} ),
|
|
57
|
-
type: 'regular' as const,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
type: 'regular' as const,
|
|
63
|
-
fields: [],
|
|
64
|
-
};
|
|
65
|
-
}, [ field ] );
|
|
51
|
+
const form: Form = useMemo(
|
|
52
|
+
(): Form => ( {
|
|
53
|
+
layout: DEFAULT_LAYOUT,
|
|
54
|
+
fields: isCombinedField( field ) ? field.children : [],
|
|
55
|
+
} ),
|
|
56
|
+
[ field ]
|
|
57
|
+
);
|
|
66
58
|
|
|
67
59
|
if ( isCombinedField( field ) ) {
|
|
68
60
|
return (
|
|
@@ -72,14 +64,19 @@ export default function FormRegularField< Item >( {
|
|
|
72
64
|
) }
|
|
73
65
|
<DataFormLayout
|
|
74
66
|
data={ data }
|
|
75
|
-
form={ form
|
|
67
|
+
form={ form }
|
|
76
68
|
onChange={ onChange }
|
|
77
69
|
/>
|
|
78
70
|
</>
|
|
79
71
|
);
|
|
80
72
|
}
|
|
81
73
|
|
|
82
|
-
const
|
|
74
|
+
const layout: NormalizedRegularLayout = normalizeLayout( {
|
|
75
|
+
...field.layout,
|
|
76
|
+
type: 'regular',
|
|
77
|
+
} ) as NormalizedRegularLayout;
|
|
78
|
+
|
|
79
|
+
const labelPosition = layout.labelPosition;
|
|
83
80
|
const fieldDefinition = fields.find(
|
|
84
81
|
( fieldDef ) => fieldDef.id === field.id
|
|
85
82
|
);
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
Spinner,
|
|
14
14
|
Flex,
|
|
15
15
|
FlexItem,
|
|
16
|
+
Tooltip,
|
|
16
17
|
privateApis as componentsPrivateApis,
|
|
17
18
|
} from '@wordpress/components';
|
|
18
19
|
import { __, sprintf } from '@wordpress/i18n';
|
|
@@ -64,6 +65,7 @@ interface GridItemProps< Item > {
|
|
|
64
65
|
config: {
|
|
65
66
|
sizes: string;
|
|
66
67
|
};
|
|
68
|
+
posinset?: number;
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
function GridItem< Item >( {
|
|
@@ -83,8 +85,14 @@ function GridItem< Item >( {
|
|
|
83
85
|
badgeFields,
|
|
84
86
|
hasBulkActions,
|
|
85
87
|
config,
|
|
88
|
+
posinset,
|
|
86
89
|
}: GridItemProps< Item > ) {
|
|
87
|
-
const {
|
|
90
|
+
const {
|
|
91
|
+
showTitle = true,
|
|
92
|
+
showMedia = true,
|
|
93
|
+
showDescription = true,
|
|
94
|
+
infiniteScrollEnabled,
|
|
95
|
+
} = view;
|
|
88
96
|
const hasBulkAction = useHasAPossibleBulkAction( actions, item );
|
|
89
97
|
const id = getItemId( item );
|
|
90
98
|
const instanceId = useInstanceId( GridItem );
|
|
@@ -117,6 +125,7 @@ function GridItem< Item >( {
|
|
|
117
125
|
};
|
|
118
126
|
}
|
|
119
127
|
}
|
|
128
|
+
const { paginationInfo } = useContext( DataViewsContext );
|
|
120
129
|
|
|
121
130
|
return (
|
|
122
131
|
<VStack
|
|
@@ -139,6 +148,11 @@ function GridItem< Item >( {
|
|
|
139
148
|
);
|
|
140
149
|
}
|
|
141
150
|
} }
|
|
151
|
+
role={ infiniteScrollEnabled ? 'article' : undefined }
|
|
152
|
+
aria-setsize={
|
|
153
|
+
infiniteScrollEnabled ? paginationInfo.totalItems : undefined
|
|
154
|
+
}
|
|
155
|
+
aria-posinset={ posinset }
|
|
142
156
|
>
|
|
143
157
|
{ showMedia && renderedMediaField && (
|
|
144
158
|
<ItemClickWrapper
|
|
@@ -227,9 +241,11 @@ function GridItem< Item >( {
|
|
|
227
241
|
direction="row"
|
|
228
242
|
>
|
|
229
243
|
<>
|
|
230
|
-
<
|
|
231
|
-
|
|
232
|
-
|
|
244
|
+
<Tooltip text={ field.label }>
|
|
245
|
+
<FlexItem className="dataviews-view-grid__field-name">
|
|
246
|
+
{ field.header }
|
|
247
|
+
</FlexItem>
|
|
248
|
+
</Tooltip>
|
|
233
249
|
<FlexItem
|
|
234
250
|
className="dataviews-view-grid__field-value"
|
|
235
251
|
style={ { maxHeight: 'none' } }
|
|
@@ -322,6 +338,8 @@ function ViewGrid< Item >( {
|
|
|
322
338
|
}, new Map< string, typeof data >() )
|
|
323
339
|
: null;
|
|
324
340
|
|
|
341
|
+
const isInfiniteScroll = view.infiniteScrollEnabled && ! dataByGroup;
|
|
342
|
+
|
|
325
343
|
return (
|
|
326
344
|
<>
|
|
327
345
|
{
|
|
@@ -409,8 +427,9 @@ function ViewGrid< Item >( {
|
|
|
409
427
|
} }
|
|
410
428
|
aria-busy={ isLoading }
|
|
411
429
|
ref={ resizeObserverRef }
|
|
430
|
+
role={ isInfiniteScroll ? 'feed' : undefined }
|
|
412
431
|
>
|
|
413
|
-
{ data.map( ( item ) => {
|
|
432
|
+
{ data.map( ( item, index ) => {
|
|
414
433
|
return (
|
|
415
434
|
<GridItem
|
|
416
435
|
key={ getItemId( item ) }
|
|
@@ -432,6 +451,9 @@ function ViewGrid< Item >( {
|
|
|
432
451
|
config={ {
|
|
433
452
|
sizes: size,
|
|
434
453
|
} }
|
|
454
|
+
posinset={
|
|
455
|
+
isInfiniteScroll ? index + 1 : undefined
|
|
456
|
+
}
|
|
435
457
|
/>
|
|
436
458
|
);
|
|
437
459
|
} ) }
|
|
@@ -451,6 +473,11 @@ function ViewGrid< Item >( {
|
|
|
451
473
|
</div>
|
|
452
474
|
)
|
|
453
475
|
}
|
|
476
|
+
{ hasData && isLoading && (
|
|
477
|
+
<p className="dataviews-loading-more">
|
|
478
|
+
<Spinner />
|
|
479
|
+
</p>
|
|
480
|
+
) }
|
|
454
481
|
</>
|
|
455
482
|
);
|
|
456
483
|
}
|
|
@@ -12,6 +12,14 @@ import DataViewsContext from '../../components/dataviews-context';
|
|
|
12
12
|
import type { ViewGrid } from '../../types';
|
|
13
13
|
|
|
14
14
|
const imageSizes = [
|
|
15
|
+
{
|
|
16
|
+
value: 120,
|
|
17
|
+
breakpoint: 1,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
value: 170,
|
|
21
|
+
breakpoint: 1,
|
|
22
|
+
},
|
|
15
23
|
{
|
|
16
24
|
value: 230,
|
|
17
25
|
breakpoint: 1,
|
|
@@ -34,24 +42,18 @@ export default function PreviewSizePicker() {
|
|
|
34
42
|
const context = useContext( DataViewsContext );
|
|
35
43
|
const view = context.view as ViewGrid;
|
|
36
44
|
|
|
37
|
-
if ( context.containerWidth < 588 ) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
45
|
const breakValues = imageSizes.filter( ( size ) => {
|
|
42
46
|
return context.containerWidth >= size.breakpoint;
|
|
43
47
|
} );
|
|
44
48
|
|
|
49
|
+
const layoutPreviewSize = view.layout?.previewSize ?? 230; // Default to the third smallest size if no preview size is set.
|
|
45
50
|
// If the container has resized and the set preview size is no longer available,
|
|
46
|
-
// we reset it to the next smallest size.
|
|
47
|
-
const previewSizeToUse =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
)
|
|
53
|
-
.sort( ( a, b ) => b.value - a.value )[ 0 ].index
|
|
54
|
-
: 0;
|
|
51
|
+
// we reset it to the next smallest size, or the smallest available size.
|
|
52
|
+
const previewSizeToUse =
|
|
53
|
+
breakValues
|
|
54
|
+
.map( ( size, index ) => ( { ...size, index } ) )
|
|
55
|
+
.filter( ( size ) => size.value <= layoutPreviewSize )
|
|
56
|
+
.sort( ( a, b ) => b.value - a.value )[ 0 ]?.index ?? 0;
|
|
55
57
|
|
|
56
58
|
const marks = breakValues.map( ( size, index ) => {
|
|
57
59
|
return {
|