@wordpress/dataviews 4.8.0 → 4.9.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.
Files changed (189) hide show
  1. package/CHANGELOG.md +7 -2
  2. package/README.md +206 -17
  3. package/build/components/dataform/index.js +20 -8
  4. package/build/components/dataform/index.js.map +1 -1
  5. package/build/components/dataform-context/index.js +33 -0
  6. package/build/components/dataform-context/index.js.map +1 -0
  7. package/build/components/dataviews/index.js +3 -7
  8. package/build/components/dataviews/index.js.map +1 -1
  9. package/build/components/dataviews-context/index.js +1 -2
  10. package/build/components/dataviews-context/index.js.map +1 -1
  11. package/build/components/dataviews-filters/index.js +49 -31
  12. package/build/components/dataviews-filters/index.js.map +1 -1
  13. package/build/components/dataviews-item-actions/index.js +46 -20
  14. package/build/components/dataviews-item-actions/index.js.map +1 -1
  15. package/build/components/dataviews-layout/index.js +1 -3
  16. package/build/components/dataviews-layout/index.js.map +1 -1
  17. package/build/components/dataviews-view-config/index.js +4 -15
  18. package/build/components/dataviews-view-config/index.js.map +1 -1
  19. package/build/dataforms-layouts/data-form-layout.js +59 -0
  20. package/build/dataforms-layouts/data-form-layout.js.map +1 -0
  21. package/build/dataforms-layouts/index.js +4 -4
  22. package/build/dataforms-layouts/index.js.map +1 -1
  23. package/build/dataforms-layouts/is-combined-field.js +14 -0
  24. package/build/dataforms-layouts/is-combined-field.js.map +1 -0
  25. package/build/dataforms-layouts/panel/index.js +157 -72
  26. package/build/dataforms-layouts/panel/index.js.map +1 -1
  27. package/build/dataforms-layouts/regular/index.js +85 -19
  28. package/build/dataforms-layouts/regular/index.js.map +1 -1
  29. package/build/dataviews-layouts/grid/index.js +9 -9
  30. package/build/dataviews-layouts/grid/index.js.map +1 -1
  31. package/build/dataviews-layouts/grid/{density-picker.js → preview-size-picker.js} +40 -24
  32. package/build/dataviews-layouts/grid/preview-size-picker.js.map +1 -0
  33. package/build/dataviews-layouts/index.js +6 -2
  34. package/build/dataviews-layouts/index.js.map +1 -1
  35. package/build/dataviews-layouts/list/index.js +3 -2
  36. package/build/dataviews-layouts/list/index.js.map +1 -1
  37. package/build/dataviews-layouts/table/density-picker.js +51 -0
  38. package/build/dataviews-layouts/table/density-picker.js.map +1 -0
  39. package/build/dataviews-layouts/table/index.js +4 -1
  40. package/build/dataviews-layouts/table/index.js.map +1 -1
  41. package/build/normalize-fields.js +0 -21
  42. package/build/normalize-fields.js.map +1 -1
  43. package/build/normalize-form-fields.js +36 -0
  44. package/build/normalize-form-fields.js.map +1 -0
  45. package/build/types.js.map +1 -1
  46. package/build/validation.js.map +1 -1
  47. package/build-module/components/dataform/index.js +20 -8
  48. package/build-module/components/dataform/index.js.map +1 -1
  49. package/build-module/components/dataform-context/index.js +25 -0
  50. package/build-module/components/dataform-context/index.js.map +1 -0
  51. package/build-module/components/dataviews/index.js +4 -8
  52. package/build-module/components/dataviews/index.js.map +1 -1
  53. package/build-module/components/dataviews-context/index.js +1 -2
  54. package/build-module/components/dataviews-context/index.js.map +1 -1
  55. package/build-module/components/dataviews-filters/index.js +50 -32
  56. package/build-module/components/dataviews-filters/index.js.map +1 -1
  57. package/build-module/components/dataviews-item-actions/index.js +46 -20
  58. package/build-module/components/dataviews-item-actions/index.js.map +1 -1
  59. package/build-module/components/dataviews-layout/index.js +1 -3
  60. package/build-module/components/dataviews-layout/index.js.map +1 -1
  61. package/build-module/components/dataviews-view-config/index.js +5 -16
  62. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  63. package/build-module/dataforms-layouts/data-form-layout.js +52 -0
  64. package/build-module/dataforms-layouts/data-form-layout.js.map +1 -0
  65. package/build-module/dataforms-layouts/index.js +7 -7
  66. package/build-module/dataforms-layouts/index.js.map +1 -1
  67. package/build-module/dataforms-layouts/is-combined-field.js +8 -0
  68. package/build-module/dataforms-layouts/is-combined-field.js.map +1 -0
  69. package/build-module/dataforms-layouts/panel/index.js +157 -71
  70. package/build-module/dataforms-layouts/panel/index.js.map +1 -1
  71. package/build-module/dataforms-layouts/regular/index.js +87 -20
  72. package/build-module/dataforms-layouts/regular/index.js.map +1 -1
  73. package/build-module/dataviews-layouts/grid/index.js +9 -9
  74. package/build-module/dataviews-layouts/grid/index.js.map +1 -1
  75. package/build-module/dataviews-layouts/grid/{density-picker.js → preview-size-picker.js} +38 -24
  76. package/build-module/dataviews-layouts/grid/preview-size-picker.js.map +1 -0
  77. package/build-module/dataviews-layouts/index.js +6 -2
  78. package/build-module/dataviews-layouts/index.js.map +1 -1
  79. package/build-module/dataviews-layouts/list/index.js +3 -2
  80. package/build-module/dataviews-layouts/list/index.js.map +1 -1
  81. package/build-module/dataviews-layouts/table/density-picker.js +43 -0
  82. package/build-module/dataviews-layouts/table/density-picker.js.map +1 -0
  83. package/build-module/dataviews-layouts/table/index.js +4 -1
  84. package/build-module/dataviews-layouts/table/index.js.map +1 -1
  85. package/build-module/normalize-fields.js +0 -20
  86. package/build-module/normalize-fields.js.map +1 -1
  87. package/build-module/normalize-form-fields.js +30 -0
  88. package/build-module/normalize-form-fields.js.map +1 -0
  89. package/build-module/types.js.map +1 -1
  90. package/build-module/validation.js.map +1 -1
  91. package/build-style/style-rtl.css +54 -13
  92. package/build-style/style.css +54 -13
  93. package/build-types/components/dataform/index.d.ts +1 -1
  94. package/build-types/components/dataform/index.d.ts.map +1 -1
  95. package/build-types/components/dataform/stories/index.story.d.ts +18 -7
  96. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  97. package/build-types/components/dataform-context/index.d.ts +13 -0
  98. package/build-types/components/dataform-context/index.d.ts.map +1 -0
  99. package/build-types/components/dataviews/index.d.ts.map +1 -1
  100. package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
  101. package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
  102. package/build-types/components/dataviews-context/index.d.ts +0 -1
  103. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  104. package/build-types/components/dataviews-filters/index.d.ts +1 -1
  105. package/build-types/components/dataviews-filters/index.d.ts.map +1 -1
  106. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  107. package/build-types/components/dataviews-layout/index.d.ts.map +1 -1
  108. package/build-types/components/dataviews-view-config/index.d.ts +1 -3
  109. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  110. package/build-types/dataforms-layouts/data-form-layout.d.ts +16 -0
  111. package/build-types/dataforms-layouts/data-form-layout.d.ts.map +1 -0
  112. package/build-types/dataforms-layouts/index.d.ts +3 -3
  113. package/build-types/dataforms-layouts/index.d.ts.map +1 -1
  114. package/build-types/dataforms-layouts/is-combined-field.d.ts +6 -0
  115. package/build-types/dataforms-layouts/is-combined-field.d.ts.map +1 -0
  116. package/build-types/dataforms-layouts/panel/index.d.ts +5 -2
  117. package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
  118. package/build-types/dataforms-layouts/regular/index.d.ts +5 -2
  119. package/build-types/dataforms-layouts/regular/index.d.ts.map +1 -1
  120. package/build-types/dataviews-layouts/grid/index.d.ts +1 -1
  121. package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -1
  122. package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts +3 -0
  123. package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts.map +1 -0
  124. package/build-types/dataviews-layouts/index.d.ts +5 -0
  125. package/build-types/dataviews-layouts/index.d.ts.map +1 -1
  126. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
  127. package/build-types/dataviews-layouts/table/density-picker.d.ts +2 -0
  128. package/build-types/dataviews-layouts/table/density-picker.d.ts.map +1 -0
  129. package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
  130. package/build-types/normalize-fields.d.ts +1 -9
  131. package/build-types/normalize-fields.d.ts.map +1 -1
  132. package/build-types/normalize-form-fields.d.ts +12 -0
  133. package/build-types/normalize-form-fields.d.ts.map +1 -0
  134. package/build-types/types.d.ts +31 -22
  135. package/build-types/types.d.ts.map +1 -1
  136. package/build-types/validation.d.ts +1 -1
  137. package/build-types/validation.d.ts.map +1 -1
  138. package/package.json +2 -2
  139. package/src/components/dataform/index.tsx +22 -5
  140. package/src/components/dataform/stories/index.story.tsx +88 -49
  141. package/src/components/dataform-context/index.tsx +30 -0
  142. package/src/components/dataviews/index.tsx +2 -6
  143. package/src/components/dataviews/stories/fixtures.tsx +1 -0
  144. package/src/components/dataviews/stories/index.story.tsx +16 -3
  145. package/src/components/dataviews-context/index.ts +0 -2
  146. package/src/components/dataviews-filters/index.tsx +73 -38
  147. package/src/components/dataviews-item-actions/index.tsx +73 -25
  148. package/src/components/dataviews-layout/index.tsx +0 -2
  149. package/src/components/dataviews-view-config/index.tsx +7 -23
  150. package/src/dataforms-layouts/data-form-layout.tsx +87 -0
  151. package/src/dataforms-layouts/index.tsx +7 -7
  152. package/src/dataforms-layouts/is-combined-field.ts +10 -0
  153. package/src/dataforms-layouts/panel/index.tsx +192 -101
  154. package/src/dataforms-layouts/panel/style.scss +4 -0
  155. package/src/dataforms-layouts/regular/index.tsx +101 -37
  156. package/src/dataforms-layouts/regular/style.scss +30 -0
  157. package/src/dataviews-layouts/grid/index.tsx +10 -8
  158. package/src/dataviews-layouts/grid/{density-picker.tsx → preview-size-picker.tsx} +39 -26
  159. package/src/dataviews-layouts/grid/style.scss +3 -1
  160. package/src/dataviews-layouts/index.ts +4 -0
  161. package/src/dataviews-layouts/list/index.tsx +31 -27
  162. package/src/dataviews-layouts/table/density-picker.tsx +57 -0
  163. package/src/dataviews-layouts/table/index.tsx +12 -2
  164. package/src/dataviews-layouts/table/style.scss +32 -0
  165. package/src/normalize-fields.ts +1 -33
  166. package/src/normalize-form-fields.ts +42 -0
  167. package/src/style.scss +1 -1
  168. package/src/types.ts +36 -21
  169. package/src/validation.ts +1 -1
  170. package/tsconfig.tsbuildinfo +1 -1
  171. package/build/components/dataform-combined-edit/index.js +0 -73
  172. package/build/components/dataform-combined-edit/index.js.map +0 -1
  173. package/build/dataforms-layouts/get-visible-fields.js +0 -21
  174. package/build/dataforms-layouts/get-visible-fields.js.map +0 -1
  175. package/build/dataviews-layouts/grid/density-picker.js.map +0 -1
  176. package/build-module/components/dataform-combined-edit/index.js +0 -66
  177. package/build-module/components/dataform-combined-edit/index.js.map +0 -1
  178. package/build-module/dataforms-layouts/get-visible-fields.js +0 -14
  179. package/build-module/dataforms-layouts/get-visible-fields.js.map +0 -1
  180. package/build-module/dataviews-layouts/grid/density-picker.js.map +0 -1
  181. package/build-types/components/dataform-combined-edit/index.d.ts +0 -7
  182. package/build-types/components/dataform-combined-edit/index.d.ts.map +0 -1
  183. package/build-types/dataforms-layouts/get-visible-fields.d.ts +0 -3
  184. package/build-types/dataforms-layouts/get-visible-fields.d.ts.map +0 -1
  185. package/build-types/dataviews-layouts/grid/density-picker.d.ts +0 -5
  186. package/build-types/dataviews-layouts/grid/density-picker.d.ts.map +0 -1
  187. package/src/components/dataform-combined-edit/index.tsx +0 -69
  188. package/src/components/dataform-combined-edit/style.scss +0 -16
  189. package/src/dataforms-layouts/get-visible-fields.ts +0 -29
@@ -1,52 +1,116 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { __experimentalVStack as VStack } from '@wordpress/components';
5
- import { useMemo } from '@wordpress/element';
4
+ import { useContext, useMemo } from '@wordpress/element';
5
+ import {
6
+ __experimentalHStack as HStack,
7
+ __experimentalVStack as VStack,
8
+ __experimentalHeading as Heading,
9
+ __experimentalSpacer as Spacer,
10
+ } from '@wordpress/components';
6
11
 
7
12
  /**
8
13
  * Internal dependencies
9
14
  */
10
- import { normalizeFields } from '../../normalize-fields';
11
- import { getVisibleFields } from '../get-visible-fields';
12
- import type { DataFormProps } from '../../types';
13
- import FormFieldVisibility from '../../components/form-field-visibility';
15
+ import type { Form, FieldLayoutProps } from '../../types';
16
+ import DataFormContext from '../../components/dataform-context';
17
+ import { DataFormLayout } from '../data-form-layout';
18
+ import { isCombinedField } from '../is-combined-field';
14
19
 
15
- export default function FormRegular< Item >( {
20
+ function Header( { title }: { title: string } ) {
21
+ return (
22
+ <VStack className="dataforms-layouts-regular__header" spacing={ 4 }>
23
+ <HStack alignment="center">
24
+ <Heading level={ 2 } size={ 13 }>
25
+ { title }
26
+ </Heading>
27
+ <Spacer />
28
+ </HStack>
29
+ </VStack>
30
+ );
31
+ }
32
+
33
+ export default function FormRegularField< Item >( {
16
34
  data,
17
- fields,
18
- form,
35
+ field,
19
36
  onChange,
20
- }: DataFormProps< Item > ) {
21
- const visibleFields = useMemo(
22
- () =>
23
- normalizeFields(
24
- getVisibleFields< Item >(
25
- fields,
26
- form.fields,
27
- form.combinedFields
28
- )
29
- ),
30
- [ fields, form.fields, form.combinedFields ]
37
+ hideLabelFromVision,
38
+ }: FieldLayoutProps< Item > ) {
39
+ const { fields } = useContext( DataFormContext );
40
+
41
+ const form = useMemo( () => {
42
+ if ( isCombinedField( field ) ) {
43
+ return {
44
+ fields: field.children.map( ( child ) => {
45
+ if ( typeof child === 'string' ) {
46
+ return {
47
+ id: child,
48
+ };
49
+ }
50
+ return child;
51
+ } ),
52
+ type: 'regular' as const,
53
+ };
54
+ }
55
+
56
+ return {
57
+ type: 'regular' as const,
58
+ fields: [],
59
+ };
60
+ }, [ field ] );
61
+
62
+ if ( isCombinedField( field ) ) {
63
+ return (
64
+ <>
65
+ { ! hideLabelFromVision && field.label && (
66
+ <Header title={ field.label } />
67
+ ) }
68
+ <DataFormLayout
69
+ data={ data }
70
+ form={ form as Form }
71
+ onChange={ onChange }
72
+ />
73
+ </>
74
+ );
75
+ }
76
+
77
+ const labelPosition = field.labelPosition ?? 'top';
78
+ const fieldDefinition = fields.find(
79
+ ( fieldDef ) => fieldDef.id === field.id
31
80
  );
32
81
 
33
- return (
34
- <VStack spacing={ 4 }>
35
- { visibleFields.map( ( field ) => {
36
- return (
37
- <FormFieldVisibility
38
- key={ field.id }
82
+ if ( ! fieldDefinition ) {
83
+ return null;
84
+ }
85
+ if ( labelPosition === 'side' ) {
86
+ return (
87
+ <HStack className="dataforms-layouts-regular__field">
88
+ <div className="dataforms-layouts-regular__field-label">
89
+ { fieldDefinition.label }
90
+ </div>
91
+ <div className="dataforms-layouts-regular__field-control">
92
+ <fieldDefinition.Edit
93
+ key={ fieldDefinition.id }
39
94
  data={ data }
40
- field={ field }
41
- >
42
- <field.Edit
43
- data={ data }
44
- field={ field }
45
- onChange={ onChange }
46
- />
47
- </FormFieldVisibility>
48
- );
49
- } ) }
50
- </VStack>
95
+ field={ fieldDefinition }
96
+ onChange={ onChange }
97
+ hideLabelFromVision
98
+ />
99
+ </div>
100
+ </HStack>
101
+ );
102
+ }
103
+
104
+ return (
105
+ <div className="dataforms-layouts-regular__field">
106
+ <fieldDefinition.Edit
107
+ data={ data }
108
+ field={ fieldDefinition }
109
+ onChange={ onChange }
110
+ hideLabelFromVision={
111
+ labelPosition === 'none' ? true : hideLabelFromVision
112
+ }
113
+ />
114
+ </div>
51
115
  );
52
116
  }
@@ -0,0 +1,30 @@
1
+ .dataforms-layouts-regular__field {
2
+ width: 100%;
3
+ min-height: $grid-unit-40;
4
+ justify-content: flex-start !important;
5
+ align-items: flex-start !important;
6
+ }
7
+
8
+ .dataforms-layouts-regular__field .components-base-control__label {
9
+ font-size: inherit;
10
+ font-weight: normal;
11
+ text-transform: none;
12
+ }
13
+
14
+ .dataforms-layouts-regular__field-label {
15
+ width: 38%;
16
+ flex-shrink: 0;
17
+ min-height: $grid-unit-40;
18
+ display: flex;
19
+ align-items: center;
20
+ padding: 6px 0; // Matches button to ensure alignment
21
+ line-height: $grid-unit-05 * 5;
22
+ hyphens: auto;
23
+ }
24
+
25
+ .dataforms-layouts-regular__field-control {
26
+ flex-grow: 1;
27
+ min-height: $grid-unit-40;
28
+ display: flex;
29
+ align-items: center;
30
+ }
@@ -25,6 +25,7 @@ import { useHasAPossibleBulkAction } from '../../components/dataviews-bulk-actio
25
25
  import type { Action, NormalizedField, ViewGridProps } from '../../types';
26
26
  import type { SetSelection } from '../../private-types';
27
27
  import getClickableItemProps from '../utils/get-clickable-item-props';
28
+ import { useUpdatedPreviewSizeOnViewportChange } from './preview-size-picker';
28
29
 
29
30
  interface GridItemProps< Item > {
30
31
  selection: string[];
@@ -114,11 +115,9 @@ function GridItem< Item >( {
114
115
  justify="space-between"
115
116
  className="dataviews-view-grid__title-actions"
116
117
  >
117
- <HStack>
118
- <div { ...clickablePrimaryItemProps }>
119
- { renderedPrimaryField }
120
- </div>
121
- </HStack>
118
+ <div { ...clickablePrimaryItemProps }>
119
+ { renderedPrimaryField }
120
+ </div>
122
121
  <ItemActions item={ item } actions={ actions } isCompact />
123
122
  </HStack>
124
123
  { !! badgeFields?.length && (
@@ -194,7 +193,6 @@ export default function ViewGrid< Item >( {
194
193
  isItemClickable,
195
194
  selection,
196
195
  view,
197
- density,
198
196
  }: ViewGridProps< Item > ) {
199
197
  const mediaField = fields.find(
200
198
  ( field ) => field.id === view.layout?.mediaField
@@ -225,8 +223,12 @@ export default function ViewGrid< Item >( {
225
223
  { visibleFields: [], badgeFields: [] }
226
224
  );
227
225
  const hasData = !! data?.length;
228
- const gridStyle = density
229
- ? { gridTemplateColumns: `repeat(${ density }, minmax(0, 1fr))` }
226
+ const updatedPreviewSize = useUpdatedPreviewSizeOnViewportChange();
227
+ const usedPreviewSize = updatedPreviewSize || view.layout?.previewSize;
228
+ const gridStyle = usedPreviewSize
229
+ ? {
230
+ gridTemplateColumns: `repeat(${ usedPreviewSize }, minmax(0, 1fr))`,
231
+ }
230
232
  : {};
231
233
  return (
232
234
  <>
@@ -4,7 +4,13 @@
4
4
  import { RangeControl } from '@wordpress/components';
5
5
  import { __ } from '@wordpress/i18n';
6
6
  import { useViewportMatch } from '@wordpress/compose';
7
- import { useEffect, useMemo } from '@wordpress/element';
7
+ import { useMemo, useContext } from '@wordpress/element';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import DataViewsContext from '../../components/dataviews-context';
13
+ import type { ViewGrid } from '../../types';
8
14
 
9
15
  const viewportBreaks = {
10
16
  xhuge: { min: 3, max: 6, default: 5 },
@@ -39,31 +45,32 @@ function useViewPortBreakpoint() {
39
45
  return null;
40
46
  }
41
47
 
42
- export default function DensityPicker( {
43
- density,
44
- setDensity,
45
- }: {
46
- density: number;
47
- setDensity: React.Dispatch< React.SetStateAction< number > >;
48
- } ) {
48
+ export function useUpdatedPreviewSizeOnViewportChange() {
49
+ const viewport = useViewPortBreakpoint();
50
+ const view = useContext( DataViewsContext ).view as ViewGrid;
51
+ return useMemo( () => {
52
+ const previewSize = view.layout?.previewSize;
53
+ let newPreviewSize;
54
+ if ( ! viewport || ! previewSize ) {
55
+ return;
56
+ }
57
+ const breakValues = viewportBreaks[ viewport ];
58
+ if ( previewSize < breakValues.min ) {
59
+ newPreviewSize = breakValues.min;
60
+ }
61
+ if ( previewSize > breakValues.max ) {
62
+ newPreviewSize = breakValues.max;
63
+ }
64
+ return newPreviewSize;
65
+ }, [ viewport, view ] );
66
+ }
67
+
68
+ export default function PreviewSizePicker() {
49
69
  const viewport = useViewPortBreakpoint();
50
- useEffect( () => {
51
- setDensity( ( _density ) => {
52
- if ( ! viewport || ! _density ) {
53
- return 0;
54
- }
55
- const breakValues = viewportBreaks[ viewport ];
56
- if ( _density < breakValues.min ) {
57
- return breakValues.min;
58
- }
59
- if ( _density > breakValues.max ) {
60
- return breakValues.max;
61
- }
62
- return _density;
63
- } );
64
- }, [ setDensity, viewport ] );
70
+ const context = useContext( DataViewsContext );
71
+ const view = context.view as ViewGrid;
65
72
  const breakValues = viewportBreaks[ viewport || 'mobile' ];
66
- const densityToUse = density || breakValues.default;
73
+ const previewSizeToUse = view.layout?.previewSize || breakValues.default;
67
74
 
68
75
  const marks = useMemo(
69
76
  () =>
@@ -88,13 +95,19 @@ export default function DensityPicker( {
88
95
  __next40pxDefaultSize
89
96
  showTooltip={ false }
90
97
  label={ __( 'Preview size' ) }
91
- value={ breakValues.max + breakValues.min - densityToUse }
98
+ value={ breakValues.max + breakValues.min - previewSizeToUse }
92
99
  marks={ marks }
93
100
  min={ breakValues.min }
94
101
  max={ breakValues.max }
95
102
  withInputField={ false }
96
103
  onChange={ ( value = 0 ) => {
97
- setDensity( breakValues.max + breakValues.min - value );
104
+ context.onChangeView( {
105
+ ...view,
106
+ layout: {
107
+ ...view.layout,
108
+ previewSize: breakValues.max + breakValues.min - value,
109
+ },
110
+ } );
98
111
  } }
99
112
  step={ 1 }
100
113
  />
@@ -16,7 +16,9 @@
16
16
  }
17
17
 
18
18
  .dataviews-view-grid__primary-field {
19
- min-height: $grid-unit-40; // Preserve layout when there is no ellipsis button
19
+ min-height: $grid-unit-30; // Preserve layout when there is no ellipsis button
20
+ display: flex;
21
+ align-items: center;
20
22
 
21
23
  &--clickable {
22
24
  width: fit-content;
@@ -17,6 +17,8 @@ import ViewGrid from './grid';
17
17
  import ViewList from './list';
18
18
  import { LAYOUT_GRID, LAYOUT_LIST, LAYOUT_TABLE } from '../constants';
19
19
  import type { View, Field } from '../types';
20
+ import PreviewSizePicker from './grid/preview-size-picker';
21
+ import DensityPicker from './table/density-picker';
20
22
 
21
23
  export const VIEW_LAYOUTS = [
22
24
  {
@@ -24,12 +26,14 @@ export const VIEW_LAYOUTS = [
24
26
  label: __( 'Table' ),
25
27
  component: ViewTable,
26
28
  icon: blockTable,
29
+ viewConfigOptions: DensityPicker,
27
30
  },
28
31
  {
29
32
  type: LAYOUT_GRID,
30
33
  label: __( 'Grid' ),
31
34
  component: ViewGrid,
32
35
  icon: category,
36
+ viewConfigOptions: PreviewSizePicker,
33
37
  },
34
38
  {
35
39
  type: LAYOUT_LIST,
@@ -170,11 +170,13 @@ function ListItem< Item >( {
170
170
  ( action ) => action.isPrimary && !! action.icon
171
171
  );
172
172
  return {
173
- primaryAction: _primaryActions?.[ 0 ],
173
+ primaryAction: _primaryActions[ 0 ],
174
174
  eligibleActions: _eligibleActions,
175
175
  };
176
176
  }, [ actions, item ] );
177
177
 
178
+ const hasOnlyOnePrimaryAction = primaryAction && actions.length === 1;
179
+
178
180
  const renderedMediaField = mediaField?.render ? (
179
181
  <div className="dataviews-view-list__media-wrapper">
180
182
  <mediaField.render item={ item } />
@@ -194,33 +196,35 @@ function ListItem< Item >( {
194
196
  item={ item }
195
197
  />
196
198
  ) }
197
- <div role="gridcell">
198
- <Menu
199
- trigger={
200
- <Composite.Item
201
- id={ generateDropdownTriggerCompositeId(
202
- idPrefix
203
- ) }
204
- render={
205
- <Button
206
- size="small"
207
- icon={ moreVertical }
208
- label={ __( 'Actions' ) }
209
- accessibleWhenDisabled
210
- disabled={ ! actions.length }
211
- onKeyDown={ onDropdownTriggerKeyDown }
212
- />
213
- }
199
+ { ! hasOnlyOnePrimaryAction && (
200
+ <div role="gridcell">
201
+ <Menu
202
+ trigger={
203
+ <Composite.Item
204
+ id={ generateDropdownTriggerCompositeId(
205
+ idPrefix
206
+ ) }
207
+ render={
208
+ <Button
209
+ size="small"
210
+ icon={ moreVertical }
211
+ label={ __( 'Actions' ) }
212
+ accessibleWhenDisabled
213
+ disabled={ ! actions.length }
214
+ onKeyDown={ onDropdownTriggerKeyDown }
215
+ />
216
+ }
217
+ />
218
+ }
219
+ placement="bottom-end"
220
+ >
221
+ <ActionsMenuGroup
222
+ actions={ eligibleActions }
223
+ item={ item }
214
224
  />
215
- }
216
- placement="bottom-end"
217
- >
218
- <ActionsMenuGroup
219
- actions={ eligibleActions }
220
- item={ item }
221
- />
222
- </Menu>
223
- </div>
225
+ </Menu>
226
+ </div>
227
+ ) }
224
228
  </HStack>
225
229
  );
226
230
 
@@ -0,0 +1,57 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ __experimentalToggleGroupControl as ToggleGroupControl,
6
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
7
+ } from '@wordpress/components';
8
+ import { __, _x } from '@wordpress/i18n';
9
+ import { useContext } from '@wordpress/element';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import DataViewsContext from '../../components/dataviews-context';
15
+ import type { ViewTable, Density } from '../../types';
16
+
17
+ export default function DensityPicker() {
18
+ const context = useContext( DataViewsContext );
19
+ const view = context.view as ViewTable;
20
+ return (
21
+ <ToggleGroupControl
22
+ __nextHasNoMarginBottom
23
+ size="__unstable-large"
24
+ label={ __( 'Density' ) }
25
+ value={ view.layout?.density || 'balanced' }
26
+ onChange={ ( value ) => {
27
+ context.onChangeView( {
28
+ ...view,
29
+ layout: {
30
+ ...view.layout,
31
+ density: value as Density,
32
+ },
33
+ } );
34
+ } }
35
+ isBlock
36
+ >
37
+ <ToggleGroupControlOption
38
+ key="comfortable"
39
+ value="comfortable"
40
+ label={ _x(
41
+ 'Comfortable',
42
+ 'Density option for DataView layout'
43
+ ) }
44
+ />
45
+ <ToggleGroupControlOption
46
+ key="balanced"
47
+ value="balanced"
48
+ label={ _x( 'Balanced', 'Density option for DataView layout' ) }
49
+ />
50
+ <ToggleGroupControlOption
51
+ key="compact"
52
+ value="compact"
53
+ label={ _x( 'Compact', 'Density option for DataView layout' ) }
54
+ />
55
+ </ToggleGroupControl>
56
+ );
57
+ }
@@ -147,7 +147,11 @@ function TableColumnCombined< Item >( {
147
147
  ) );
148
148
 
149
149
  if ( field.direction === 'horizontal' ) {
150
- return <HStack spacing={ 3 }>{ children }</HStack>;
150
+ return (
151
+ <HStack spacing={ 3 } justify="flex-start">
152
+ { children }
153
+ </HStack>
154
+ );
151
155
  }
152
156
  return <VStack spacing={ 0 }>{ children }</VStack>;
153
157
  }
@@ -328,7 +332,13 @@ function ViewTable< Item >( {
328
332
  return (
329
333
  <>
330
334
  <table
331
- className="dataviews-view-table"
335
+ className={ clsx( 'dataviews-view-table', {
336
+ [ `has-${ view.layout?.density }-density` ]:
337
+ view.layout?.density &&
338
+ [ 'compact', 'comfortable' ].includes(
339
+ view.layout.density
340
+ ),
341
+ } ) }
332
342
  aria-busy={ isLoading }
333
343
  aria-describedby={ tableNoticeId }
334
344
  >
@@ -169,6 +169,38 @@
169
169
  opacity: 1;
170
170
  }
171
171
  }
172
+
173
+ // Density style overrides.
174
+ &.has-compact-density {
175
+ thead {
176
+ th {
177
+ &:has(.dataviews-view-table-header-button):not(:first-child) {
178
+ padding-left: 0;
179
+ }
180
+ }
181
+ }
182
+ td,
183
+ th {
184
+ padding: $grid-unit-05 $grid-unit-10;
185
+ }
186
+ }
187
+
188
+ &.has-comfortable-density {
189
+ td,
190
+ th {
191
+ padding: $grid-unit-20 $grid-unit-15;
192
+ }
193
+ }
194
+
195
+ &.has-compact-density,
196
+ &.has-comfortable-density {
197
+ td,
198
+ th {
199
+ &.dataviews-view-table__checkbox-column {
200
+ padding-right: 0;
201
+ }
202
+ }
203
+ }
172
204
  }
173
205
 
174
206
  /* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */
@@ -2,14 +2,8 @@
2
2
  * Internal dependencies
3
3
  */
4
4
  import getFieldTypeDefinition from './field-types';
5
- import type {
6
- CombinedFormField,
7
- Field,
8
- NormalizedField,
9
- NormalizedCombinedFormField,
10
- } from './types';
5
+ import type { Field, NormalizedField } from './types';
11
6
  import { getControl } from './dataform-controls';
12
- import DataFormCombinedEdit from './components/dataform-combined-edit';
13
7
 
14
8
  const getValueFromId =
15
9
  ( id: string ) =>
@@ -87,29 +81,3 @@ export function normalizeFields< Item >(
87
81
  };
88
82
  } );
89
83
  }
90
-
91
- /**
92
- * Apply default values and normalize the fields config.
93
- *
94
- * @param combinedFields combined field list.
95
- * @param fields Fields config.
96
- * @return Normalized fields config.
97
- */
98
- export function normalizeCombinedFields< Item >(
99
- combinedFields: CombinedFormField< Item >[],
100
- fields: Field< Item >[]
101
- ): NormalizedCombinedFormField< Item >[] {
102
- return combinedFields.map( ( combinedField ) => {
103
- return {
104
- ...combinedField,
105
- Edit: DataFormCombinedEdit,
106
- fields: normalizeFields(
107
- combinedField.children
108
- .map( ( fieldId ) =>
109
- fields.find( ( { id } ) => id === fieldId )
110
- )
111
- .filter( ( field ): field is Field< Item > => !! field )
112
- ),
113
- };
114
- } );
115
- }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import type { Form } from './types';
5
+
6
+ interface NormalizedFormField {
7
+ id: string;
8
+ layout: 'regular' | 'panel';
9
+ labelPosition: 'side' | 'top' | 'none';
10
+ }
11
+
12
+ export default function normalizeFormFields(
13
+ form: Form
14
+ ): NormalizedFormField[] {
15
+ let layout: 'regular' | 'panel' = 'regular';
16
+ if ( [ 'regular', 'panel' ].includes( form.type ?? '' ) ) {
17
+ layout = form.type as 'regular' | 'panel';
18
+ }
19
+
20
+ const labelPosition =
21
+ form.labelPosition ?? ( layout === 'regular' ? 'top' : 'side' );
22
+
23
+ return ( form.fields ?? [] ).map( ( field ) => {
24
+ if ( typeof field === 'string' ) {
25
+ return {
26
+ id: field,
27
+ layout,
28
+ labelPosition,
29
+ };
30
+ }
31
+
32
+ const fieldLayout = field.layout ?? layout;
33
+ const fieldLabelPosition =
34
+ field.labelPosition ??
35
+ ( fieldLayout === 'regular' ? 'top' : 'side' );
36
+ return {
37
+ ...field,
38
+ layout: fieldLayout,
39
+ labelPosition: fieldLabelPosition,
40
+ };
41
+ } );
42
+ }
package/src/style.scss CHANGED
@@ -6,7 +6,6 @@
6
6
  @import "./components/dataviews-item-actions/style.scss";
7
7
  @import "./components/dataviews-selection-checkbox/style.scss";
8
8
  @import "./components/dataviews-view-config/style.scss";
9
- @import "./components/dataform-combined-edit/style.scss";
10
9
 
11
10
  @import "./dataviews-layouts/grid/style.scss";
12
11
  @import "./dataviews-layouts/list/style.scss";
@@ -14,3 +13,4 @@
14
13
 
15
14
  @import "./dataform-controls/style.scss";
16
15
  @import "./dataforms-layouts/panel/style.scss";
16
+ @import "./dataforms-layouts/regular/style.scss";