@wordpress/dataviews 13.1.1-next.v.202603102151.0 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/README.md +19 -3
  3. package/build/components/dataform-controls/datetime.cjs +8 -4
  4. package/build/components/dataform-controls/datetime.cjs.map +2 -2
  5. package/build/components/dataform-layouts/card/index.cjs +132 -128
  6. package/build/components/dataform-layouts/card/index.cjs.map +3 -3
  7. package/build/components/dataviews-bulk-actions/index.cjs +28 -5
  8. package/build/components/dataviews-bulk-actions/index.cjs.map +2 -2
  9. package/build/components/dataviews-context/index.cjs +2 -2
  10. package/build/components/dataviews-context/index.cjs.map +2 -2
  11. package/build/components/dataviews-footer/index.cjs +2 -3
  12. package/build/components/dataviews-footer/index.cjs.map +2 -2
  13. package/build/components/dataviews-layout/index.cjs +12 -3
  14. package/build/components/dataviews-layout/index.cjs.map +2 -2
  15. package/build/components/dataviews-layouts/grid/composite-grid.cjs +378 -245
  16. package/build/components/dataviews-layouts/grid/composite-grid.cjs.map +2 -2
  17. package/build/components/dataviews-layouts/index.cjs +3 -3
  18. package/build/components/dataviews-layouts/index.cjs.map +3 -3
  19. package/build/components/dataviews-layouts/picker-grid/index.cjs +76 -32
  20. package/build/components/dataviews-layouts/picker-grid/index.cjs.map +2 -2
  21. package/build/components/dataviews-layouts/picker-table/index.cjs +34 -22
  22. package/build/components/dataviews-layouts/picker-table/index.cjs.map +2 -2
  23. package/build/components/dataviews-layouts/table/index.cjs +97 -88
  24. package/build/components/dataviews-layouts/table/index.cjs.map +2 -2
  25. package/build/components/dataviews-layouts/table/{use-is-horizontal-scroll-end.cjs → use-scroll-state.cjs} +29 -33
  26. package/build/components/dataviews-layouts/table/use-scroll-state.cjs.map +7 -0
  27. package/build/components/dataviews-layouts/utils/density-picker.cjs.map +2 -2
  28. package/build/components/dataviews-layouts/utils/grid-config-options.cjs +45 -0
  29. package/build/components/dataviews-layouts/utils/grid-config-options.cjs.map +7 -0
  30. package/build/components/dataviews-layouts/utils/use-infinite-scroll.cjs +62 -0
  31. package/build/components/dataviews-layouts/utils/use-infinite-scroll.cjs.map +7 -0
  32. package/build/components/dataviews-picker-footer/index.cjs +23 -4
  33. package/build/components/dataviews-picker-footer/index.cjs.map +2 -2
  34. package/build/components/dataviews-search/index.cjs +2 -1
  35. package/build/components/dataviews-search/index.cjs.map +2 -2
  36. package/build/components/dataviews-selection-checkbox/index.cjs +3 -2
  37. package/build/components/dataviews-selection-checkbox/index.cjs.map +2 -2
  38. package/build/components/dataviews-view-config/index.cjs +0 -2
  39. package/build/components/dataviews-view-config/index.cjs.map +3 -3
  40. package/build/components/dataviews-view-config/infinite-scroll-toggle.cjs +0 -3
  41. package/build/components/dataviews-view-config/infinite-scroll-toggle.cjs.map +2 -2
  42. package/build/dataviews/index.cjs +38 -34
  43. package/build/dataviews/index.cjs.map +3 -3
  44. package/build/dataviews-picker/index.cjs +26 -25
  45. package/build/dataviews-picker/index.cjs.map +3 -3
  46. package/build/hooks/index.cjs +11 -2
  47. package/build/hooks/index.cjs.map +2 -2
  48. package/build/hooks/use-data.cjs +146 -9
  49. package/build/hooks/use-data.cjs.map +2 -2
  50. package/build/hooks/use-infinite-scroll.cjs +208 -0
  51. package/build/hooks/use-infinite-scroll.cjs.map +7 -0
  52. package/build/hooks/use-selected-items.cjs +57 -0
  53. package/build/hooks/use-selected-items.cjs.map +7 -0
  54. package/build/types/dataviews.cjs.map +1 -1
  55. package/build/types/field-api.cjs.map +1 -1
  56. package/build/utils/filter-sort-and-paginate.cjs +5 -1
  57. package/build/utils/filter-sort-and-paginate.cjs.map +2 -2
  58. package/build/utils/get-footer-message.cjs +8 -8
  59. package/build/utils/get-footer-message.cjs.map +2 -2
  60. package/build-module/components/dataform-controls/datetime.mjs +8 -4
  61. package/build-module/components/dataform-controls/datetime.mjs.map +2 -2
  62. package/build-module/components/dataform-layouts/card/index.mjs +132 -133
  63. package/build-module/components/dataform-layouts/card/index.mjs.map +2 -2
  64. package/build-module/components/dataviews-bulk-actions/index.mjs +28 -5
  65. package/build-module/components/dataviews-bulk-actions/index.mjs.map +2 -2
  66. package/build-module/components/dataviews-context/index.mjs +2 -2
  67. package/build-module/components/dataviews-context/index.mjs.map +2 -2
  68. package/build-module/components/dataviews-footer/index.mjs +2 -3
  69. package/build-module/components/dataviews-footer/index.mjs.map +2 -2
  70. package/build-module/components/dataviews-layout/index.mjs +12 -3
  71. package/build-module/components/dataviews-layout/index.mjs.map +2 -2
  72. package/build-module/components/dataviews-layouts/grid/composite-grid.mjs +387 -246
  73. package/build-module/components/dataviews-layouts/grid/composite-grid.mjs.map +2 -2
  74. package/build-module/components/dataviews-layouts/index.mjs +3 -3
  75. package/build-module/components/dataviews-layouts/index.mjs.map +2 -2
  76. package/build-module/components/dataviews-layouts/picker-grid/index.mjs +80 -33
  77. package/build-module/components/dataviews-layouts/picker-grid/index.mjs.map +2 -2
  78. package/build-module/components/dataviews-layouts/picker-table/index.mjs +34 -22
  79. package/build-module/components/dataviews-layouts/picker-table/index.mjs.map +2 -2
  80. package/build-module/components/dataviews-layouts/table/index.mjs +97 -88
  81. package/build-module/components/dataviews-layouts/table/index.mjs.map +2 -2
  82. package/build-module/components/dataviews-layouts/table/use-scroll-state.mjs +46 -0
  83. package/build-module/components/dataviews-layouts/table/use-scroll-state.mjs.map +7 -0
  84. package/build-module/components/dataviews-layouts/utils/density-picker.mjs.map +2 -2
  85. package/build-module/components/dataviews-layouts/utils/grid-config-options.mjs +14 -0
  86. package/build-module/components/dataviews-layouts/utils/grid-config-options.mjs.map +7 -0
  87. package/build-module/components/dataviews-layouts/utils/use-infinite-scroll.mjs +26 -0
  88. package/build-module/components/dataviews-layouts/utils/use-infinite-scroll.mjs.map +7 -0
  89. package/build-module/components/dataviews-picker-footer/index.mjs +23 -4
  90. package/build-module/components/dataviews-picker-footer/index.mjs.map +2 -2
  91. package/build-module/components/dataviews-search/index.mjs +2 -1
  92. package/build-module/components/dataviews-search/index.mjs.map +2 -2
  93. package/build-module/components/dataviews-selection-checkbox/index.mjs +3 -2
  94. package/build-module/components/dataviews-selection-checkbox/index.mjs.map +2 -2
  95. package/build-module/components/dataviews-view-config/index.mjs +0 -2
  96. package/build-module/components/dataviews-view-config/index.mjs.map +2 -2
  97. package/build-module/components/dataviews-view-config/infinite-scroll-toggle.mjs +0 -3
  98. package/build-module/components/dataviews-view-config/infinite-scroll-toggle.mjs.map +2 -2
  99. package/build-module/dataviews/index.mjs +46 -36
  100. package/build-module/dataviews/index.mjs.map +2 -2
  101. package/build-module/dataviews-picker/index.mjs +34 -27
  102. package/build-module/dataviews-picker/index.mjs.map +2 -2
  103. package/build-module/hooks/index.mjs +7 -1
  104. package/build-module/hooks/index.mjs.map +2 -2
  105. package/build-module/hooks/use-data.mjs +147 -10
  106. package/build-module/hooks/use-data.mjs.map +2 -2
  107. package/build-module/hooks/use-infinite-scroll.mjs +188 -0
  108. package/build-module/hooks/use-infinite-scroll.mjs.map +7 -0
  109. package/build-module/hooks/use-selected-items.mjs +36 -0
  110. package/build-module/hooks/use-selected-items.mjs.map +7 -0
  111. package/build-module/utils/filter-sort-and-paginate.mjs +5 -1
  112. package/build-module/utils/filter-sort-and-paginate.mjs.map +2 -2
  113. package/build-module/utils/get-footer-message.mjs +8 -8
  114. package/build-module/utils/get-footer-message.mjs.map +2 -2
  115. package/build-style/style-rtl.css +107 -41
  116. package/build-style/style.css +107 -41
  117. package/build-types/components/dataform-controls/datetime.d.ts +1 -1
  118. package/build-types/components/dataform-controls/datetime.d.ts.map +1 -1
  119. package/build-types/components/dataform-layouts/card/index.d.ts.map +1 -1
  120. package/build-types/components/dataviews-bulk-actions/index.d.ts +2 -1
  121. package/build-types/components/dataviews-bulk-actions/index.d.ts.map +1 -1
  122. package/build-types/components/dataviews-context/index.d.ts +1 -1
  123. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  124. package/build-types/components/dataviews-footer/index.d.ts.map +1 -1
  125. package/build-types/components/dataviews-layout/index.d.ts.map +1 -1
  126. package/build-types/components/dataviews-layouts/grid/composite-grid.d.ts.map +1 -1
  127. package/build-types/components/dataviews-layouts/index.d.ts +3 -3
  128. package/build-types/components/dataviews-layouts/index.d.ts.map +1 -1
  129. package/build-types/components/dataviews-layouts/picker-grid/index.d.ts.map +1 -1
  130. package/build-types/components/dataviews-layouts/picker-table/index.d.ts.map +1 -1
  131. package/build-types/components/dataviews-layouts/table/index.d.ts.map +1 -1
  132. package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts +25 -0
  133. package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts.map +1 -0
  134. package/build-types/components/dataviews-layouts/utils/density-picker.d.ts.map +1 -1
  135. package/build-types/components/dataviews-layouts/utils/grid-config-options.d.ts +2 -0
  136. package/build-types/components/dataviews-layouts/utils/grid-config-options.d.ts.map +1 -0
  137. package/build-types/components/dataviews-layouts/utils/use-infinite-scroll.d.ts +22 -0
  138. package/build-types/components/dataviews-layouts/utils/use-infinite-scroll.d.ts.map +1 -0
  139. package/build-types/components/dataviews-picker-footer/index.d.ts.map +1 -1
  140. package/build-types/components/dataviews-search/index.d.ts.map +1 -1
  141. package/build-types/components/dataviews-selection-checkbox/index.d.ts.map +1 -1
  142. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  143. package/build-types/components/dataviews-view-config/infinite-scroll-toggle.d.ts +1 -1
  144. package/build-types/components/dataviews-view-config/infinite-scroll-toggle.d.ts.map +1 -1
  145. package/build-types/dataviews/index.d.ts +0 -1
  146. package/build-types/dataviews/index.d.ts.map +1 -1
  147. package/build-types/dataviews/stories/empty.d.ts +1 -2
  148. package/build-types/dataviews/stories/empty.d.ts.map +1 -1
  149. package/build-types/dataviews/stories/fixtures.d.ts.map +1 -1
  150. package/build-types/dataviews/stories/free-composition.d.ts.map +1 -1
  151. package/build-types/dataviews/stories/index.story.d.ts +18 -10
  152. package/build-types/dataviews/stories/index.story.d.ts.map +1 -1
  153. package/build-types/dataviews/stories/infinite-scroll.d.ts.map +1 -1
  154. package/build-types/dataviews/stories/layout-activity.d.ts.map +1 -1
  155. package/build-types/dataviews/stories/layout-custom.d.ts +3 -1
  156. package/build-types/dataviews/stories/layout-custom.d.ts.map +1 -1
  157. package/build-types/dataviews/stories/layout-grid.d.ts.map +1 -1
  158. package/build-types/dataviews/stories/layout-list.d.ts.map +1 -1
  159. package/build-types/dataviews/stories/layout-table.d.ts.map +1 -1
  160. package/build-types/dataviews/stories/with-card.d.ts +3 -1
  161. package/build-types/dataviews/stories/with-card.d.ts.map +1 -1
  162. package/build-types/dataviews-picker/index.d.ts +0 -1
  163. package/build-types/dataviews-picker/index.d.ts.map +1 -1
  164. package/build-types/dataviews-picker/stories/fixtures.d.ts.map +1 -1
  165. package/build-types/dataviews-picker/stories/index.story.d.ts.map +1 -1
  166. package/build-types/field-types/stories/index.story.d.ts.map +1 -1
  167. package/build-types/hooks/index.d.ts +3 -0
  168. package/build-types/hooks/index.d.ts.map +1 -1
  169. package/build-types/hooks/test/use-data.d.ts +2 -0
  170. package/build-types/hooks/test/use-data.d.ts.map +1 -0
  171. package/build-types/hooks/use-data.d.ts +41 -3
  172. package/build-types/hooks/use-data.d.ts.map +1 -1
  173. package/build-types/hooks/use-infinite-scroll.d.ts +21 -0
  174. package/build-types/hooks/use-infinite-scroll.d.ts.map +1 -0
  175. package/build-types/hooks/use-selected-items.d.ts +19 -0
  176. package/build-types/hooks/use-selected-items.d.ts.map +1 -0
  177. package/build-types/types/dataviews.d.ts +15 -1
  178. package/build-types/types/dataviews.d.ts.map +1 -1
  179. package/build-types/types/field-api.d.ts +15 -4
  180. package/build-types/types/field-api.d.ts.map +1 -1
  181. package/build-types/utils/filter-sort-and-paginate.d.ts.map +1 -1
  182. package/build-types/utils/get-footer-message.d.ts +3 -2
  183. package/build-types/utils/get-footer-message.d.ts.map +1 -1
  184. package/build-wp/index.js +3202 -2761
  185. package/package.json +19 -19
  186. package/src/components/dataform-controls/datetime.tsx +19 -11
  187. package/src/components/dataform-layouts/card/index.tsx +171 -146
  188. package/src/components/dataform-layouts/card/style.scss +8 -5
  189. package/src/components/dataviews-bulk-actions/index.tsx +28 -1
  190. package/src/components/dataviews-context/index.ts +2 -2
  191. package/src/components/dataviews-footer/index.tsx +1 -6
  192. package/src/components/dataviews-layout/index.tsx +41 -19
  193. package/src/components/dataviews-layout/style.scss +8 -0
  194. package/src/components/dataviews-layouts/grid/composite-grid.tsx +433 -278
  195. package/src/components/dataviews-layouts/grid/style.scss +22 -2
  196. package/src/components/dataviews-layouts/index.ts +3 -3
  197. package/src/components/dataviews-layouts/picker-grid/index.tsx +70 -17
  198. package/src/components/dataviews-layouts/picker-grid/style.scss +10 -0
  199. package/src/components/dataviews-layouts/picker-table/index.tsx +42 -22
  200. package/src/components/dataviews-layouts/table/index.tsx +10 -4
  201. package/src/components/dataviews-layouts/table/style.scss +13 -0
  202. package/src/components/dataviews-layouts/table/use-scroll-state.ts +79 -0
  203. package/src/components/dataviews-layouts/utils/density-picker.tsx +12 -2
  204. package/src/components/dataviews-layouts/utils/grid-config-options.tsx +14 -0
  205. package/src/components/dataviews-layouts/utils/grid-items.scss +9 -1
  206. package/src/components/dataviews-layouts/utils/use-infinite-scroll.ts +64 -0
  207. package/src/components/dataviews-picker-footer/index.tsx +21 -1
  208. package/src/components/dataviews-search/index.tsx +2 -1
  209. package/src/components/dataviews-selection-checkbox/index.tsx +4 -2
  210. package/src/components/dataviews-view-config/index.tsx +0 -2
  211. package/src/components/dataviews-view-config/infinite-scroll-toggle.tsx +0 -5
  212. package/src/dataviews/index.tsx +58 -45
  213. package/src/dataviews/stories/empty.tsx +1 -3
  214. package/src/dataviews/stories/fixtures.tsx +288 -0
  215. package/src/dataviews/stories/free-composition.tsx +44 -45
  216. package/src/dataviews/stories/index.story.tsx +31 -8
  217. package/src/dataviews/stories/infinite-scroll.tsx +7 -93
  218. package/src/dataviews/stories/layout-activity.tsx +1 -0
  219. package/src/dataviews/stories/layout-custom.tsx +7 -3
  220. package/src/dataviews/stories/layout-grid.tsx +1 -0
  221. package/src/dataviews/stories/layout-list.tsx +1 -0
  222. package/src/dataviews/stories/layout-table.tsx +1 -0
  223. package/src/dataviews/stories/style.css +0 -5
  224. package/src/dataviews/stories/with-card.tsx +35 -24
  225. package/src/dataviews/style.scss +5 -8
  226. package/src/dataviews/test/dataviews.tsx +54 -1
  227. package/src/dataviews-picker/index.tsx +41 -35
  228. package/src/dataviews-picker/stories/fixtures.tsx +270 -0
  229. package/src/dataviews-picker/stories/index.story.tsx +62 -129
  230. package/src/field-types/stories/index.story.tsx +12 -0
  231. package/src/hooks/index.ts +3 -0
  232. package/src/hooks/test/use-data.ts +791 -0
  233. package/src/hooks/use-data.ts +288 -21
  234. package/src/hooks/use-infinite-scroll.ts +304 -0
  235. package/src/hooks/use-selected-items.ts +72 -0
  236. package/src/style.scss +1 -0
  237. package/src/types/dataviews.ts +18 -1
  238. package/src/types/field-api.ts +16 -3
  239. package/src/utils/filter-sort-and-paginate.ts +13 -1
  240. package/src/utils/get-footer-message.ts +12 -9
  241. package/src/utils/test/filter-sort-and-paginate.js +78 -54
  242. package/build/components/dataviews-layouts/table/use-is-horizontal-scroll-end.cjs.map +0 -7
  243. package/build-module/components/dataviews-layouts/table/use-is-horizontal-scroll-end.mjs +0 -50
  244. package/build-module/components/dataviews-layouts/table/use-is-horizontal-scroll-end.mjs.map +0 -7
  245. package/build-types/components/dataviews-layouts/table/use-is-horizontal-scroll-end.d.ts +0 -19
  246. package/build-types/components/dataviews-layouts/table/use-is-horizontal-scroll-end.d.ts.map +0 -1
  247. package/src/components/dataviews-layouts/table/use-is-horizontal-scroll-end.ts +0 -82
@@ -7,14 +7,15 @@ import {
7
7
  createInterpolateElement,
8
8
  } from '@wordpress/element';
9
9
  import {
10
- Card,
11
- CardBody,
12
10
  __experimentalHeading as Heading,
13
11
  __experimentalText as Text,
14
12
  Button,
15
13
  } from '@wordpress/components';
16
14
  import { __, _n } from '@wordpress/i18n';
17
- import { Stack } from '@wordpress/ui';
15
+ // TODO: enable in the ESlint rule once we complete
16
+ // https://github.com/WordPress/gutenberg/issues/76135.
17
+ // eslint-disable-next-line @wordpress/use-recommended-components
18
+ import { Card, Stack } from '@wordpress/ui';
18
19
 
19
20
  /**
20
21
  * Internal dependencies
@@ -52,8 +53,8 @@ function PlanetOverview( { planets }: { planets: SpaceObject[] } ) {
52
53
  </Stack>
53
54
  </Stack>
54
55
  <DataViews.FiltersToggled />
55
- <Card variant="secondary">
56
- <CardBody>
56
+ <Card.Root>
57
+ <Card.Content>
57
58
  <Stack direction="column" gap="sm">
58
59
  <Text size={ 18 } as="p">
59
60
  { createInterpolateElement(
@@ -87,10 +88,10 @@ function PlanetOverview( { planets }: { planets: SpaceObject[] } ) {
87
88
  ) }
88
89
  </Text>
89
90
  </Stack>
90
- </CardBody>
91
- </Card>
92
- <Card style={ { width: '100%' } }>
93
- <CardBody>
91
+ </Card.Content>
92
+ </Card.Root>
93
+ <Card.Root style={ { width: '100%' } }>
94
+ <Card.Content>
94
95
  <Stack
95
96
  direction="row"
96
97
  justify="space-between"
@@ -100,11 +101,11 @@ function PlanetOverview( { planets }: { planets: SpaceObject[] } ) {
100
101
  <DataViews.BulkActionToolbar />
101
102
  <DataViews.Pagination />
102
103
  </Stack>
103
- </CardBody>
104
- </Card>
105
- <DataViews.Layout className="free-composition-dataviews-layout" />
104
+ </Card.Content>
105
+ </Card.Root>
106
106
  </Stack>
107
107
  </div>
108
+ <DataViews.Layout className="free-composition-dataviews-layout" />
108
109
  </>
109
110
  );
110
111
  }
@@ -132,7 +133,7 @@ export const FreeCompositionComponent = () => {
132
133
  type: LAYOUT_TABLE,
133
134
  search: '',
134
135
  page: 1,
135
- perPage: 10,
136
+ perPage: 20,
136
137
  layout: {
137
138
  enableMoving: false,
138
139
  },
@@ -152,38 +153,36 @@ export const FreeCompositionComponent = () => {
152
153
  );
153
154
 
154
155
  return (
155
- <div className="free-composition">
156
- <DataViews
157
- getItemId={ ( item ) => item.id.toString() }
158
- paginationInfo={ paginationInfo }
159
- data={ processedData }
160
- view={ view }
161
- fields={ fields }
162
- actions={ actions }
163
- onChangeView={ setView }
164
- defaultLayouts={ {
165
- table: {},
166
- grid: {},
167
- } }
168
- empty={
169
- <Stack
170
- direction="column"
171
- gap="sm"
172
- justify="space-around"
173
- align="center"
174
- className="free-composition-dataviews-empty"
175
- >
176
- <Text size={ 18 } as="p">
177
- No planets
178
- </Text>
179
- <Text variant="muted">{ `Try a different search because “${ view.search }” returned no results.` }</Text>
180
- <Button variant="secondary">Create new planet</Button>
181
- </Stack>
182
- }
183
- >
184
- <PlanetOverview planets={ planets } />
185
- </DataViews>
186
- </div>
156
+ <DataViews
157
+ getItemId={ ( item ) => item.id.toString() }
158
+ paginationInfo={ paginationInfo }
159
+ data={ processedData }
160
+ view={ view }
161
+ fields={ fields }
162
+ actions={ actions }
163
+ onChangeView={ setView }
164
+ defaultLayouts={ {
165
+ table: {},
166
+ grid: {},
167
+ } }
168
+ empty={
169
+ <Stack
170
+ direction="column"
171
+ gap="sm"
172
+ justify="space-around"
173
+ align="center"
174
+ className="free-composition-dataviews-empty"
175
+ >
176
+ <Text size={ 18 } as="p">
177
+ No planets
178
+ </Text>
179
+ <Text variant="muted">{ `Try a different search because “${ view.search }” returned no results.` }</Text>
180
+ <Button variant="secondary">Create new planet</Button>
181
+ </Stack>
182
+ }
183
+ >
184
+ <PlanetOverview planets={ planets } />
185
+ </DataViews>
187
186
  );
188
187
  };
189
188
 
@@ -23,6 +23,16 @@ import './style.css';
23
23
  const meta = {
24
24
  title: 'DataViews/DataViews',
25
25
  component: DataViews,
26
+ args: {
27
+ containerHeight: 'auto',
28
+ },
29
+ argTypes: {
30
+ containerHeight: {
31
+ control: 'select',
32
+ options: [ 'auto', '600px', '80vh' ],
33
+ description: 'Height of the container',
34
+ },
35
+ },
26
36
  // Use fullscreen layout and a wrapper div with padding to resolve conflicts
27
37
  // between Ariakit's Dialog (usePreventBodyScroll) and Storybook's body padding
28
38
  // (sb-main-padding class). This ensures consistent layout in DataViews stories
@@ -31,9 +41,17 @@ const meta = {
31
41
  layout: 'fullscreen',
32
42
  },
33
43
  decorators: [
34
- ( Story ) => (
44
+ ( Story, { args, parameters }: { args: any; parameters: any } ) => (
35
45
  <div style={ { padding: '1rem' } }>
36
- <Story />
46
+ <div
47
+ style={ {
48
+ height:
49
+ parameters.containerHeight ?? args.containerHeight,
50
+ minHeight: 0,
51
+ } }
52
+ >
53
+ <Story containerHeight={ args.containerHeight } />
54
+ </div>
37
55
  </div>
38
56
  ),
39
57
  ],
@@ -212,7 +230,6 @@ export const Empty = {
212
230
  render: EmptyComponent,
213
231
  args: {
214
232
  customEmpty: false,
215
- containerHeight: '50vh',
216
233
  isLoading: false,
217
234
  },
218
235
  argTypes: {
@@ -220,11 +237,6 @@ export const Empty = {
220
237
  control: 'boolean',
221
238
  description: 'Use custom empty state with planet illustration',
222
239
  },
223
- containerHeight: {
224
- control: 'select',
225
- options: [ 'auto', '50vh', '100vh' ],
226
- description: 'Height of the container',
227
- },
228
240
  isLoading: {
229
241
  control: 'boolean',
230
242
  description: 'Show loading state',
@@ -253,4 +265,15 @@ export const WithCard = {
253
265
 
254
266
  export const InfiniteScroll = {
255
267
  render: InfiniteScrollComponent,
268
+ parameters: {
269
+ containerHeight: '600px',
270
+ },
271
+ argTypes: {
272
+ containerHeight: {
273
+ control: false,
274
+ table: {
275
+ disable: true,
276
+ },
277
+ },
278
+ },
256
279
  };
@@ -1,9 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useState, useMemo, useCallback, useEffect } from '@wordpress/element';
5
- import { __experimentalText as Text } from '@wordpress/components';
6
- import { __ } from '@wordpress/i18n';
4
+ import { useState, useMemo } from '@wordpress/element';
7
5
 
8
6
  /**
9
7
  * Internal dependencies
@@ -17,14 +15,14 @@ import {
17
15
  } from '../../constants';
18
16
  import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
19
17
  import type { View } from '../../types';
20
- import { actions, data, fields, type SpaceObject } from './fixtures';
18
+ import { actions, data, fields } from './fixtures';
21
19
 
22
20
  const InfiniteScroll = () => {
23
21
  const [ view, setView ] = useState< View >( {
24
22
  type: LAYOUT_GRID,
25
23
  search: '',
26
- page: 1,
27
- perPage: 6, // Start with a small number to demonstrate pagination
24
+ startPosition: 1,
25
+ perPage: 15, // Start with a small number to demonstrate pagination
28
26
  filters: [],
29
27
  fields: [ 'satellites' ],
30
28
  titleField: 'title',
@@ -32,109 +30,25 @@ const InfiniteScroll = () => {
32
30
  mediaField: 'image',
33
31
  infiniteScrollEnabled: true, // Enable infinite scroll by default
34
32
  } );
35
- const { data: shownData } = useMemo( () => {
33
+ const { data: shownData, paginationInfo } = useMemo( () => {
36
34
  return filterSortAndPaginate( data, view, fields );
37
35
  }, [ view ] );
38
-
39
- // Custom pagination handler that simulates server-side pagination
40
- const [ allLoadedRecords, setAllLoadedRecords ] = useState< SpaceObject[] >(
41
- []
42
- );
43
- const [ isLoadingMore, setIsLoadingMore ] = useState( false );
44
-
45
- const totalItems = data.length;
46
- const totalPages = Math.ceil( totalItems / 6 ); // perPage is 6.
47
- const currentPage = view.page || 1;
48
- const hasMoreData = currentPage < totalPages;
49
- const getItemId = ( item: {
50
- id: any;
51
- title?: string;
52
- description?: string;
53
- image?: string;
54
- type?: string;
55
- isPlanet?: boolean;
56
- categories?: string[];
57
- satellites?: number;
58
- date?: string;
59
- datetime?: string;
60
- email?: string;
61
- } ) => item.id.toString();
62
-
63
- const infiniteScrollHandler = useCallback( () => {
64
- if ( isLoadingMore || currentPage >= totalPages ) {
65
- return;
66
- }
67
-
68
- setIsLoadingMore( true );
69
-
70
- setView( {
71
- ...view,
72
- page: currentPage + 1,
73
- } );
74
- }, [ isLoadingMore, currentPage, totalPages, view ] );
75
-
76
- // Initialize data on first load or when view changes significantly
77
- useEffect( () => {
78
- if ( currentPage === 1 || ! view.infiniteScrollEnabled ) {
79
- // First page - replace all data
80
- setAllLoadedRecords( shownData );
81
- } else {
82
- // Subsequent pages - append to existing data
83
- setAllLoadedRecords( ( prev ) => {
84
- const existingIds = new Set( prev.map( getItemId ) );
85
- const newRecords = shownData.filter(
86
- ( record ) => ! existingIds.has( getItemId( record ) )
87
- );
88
- return [ ...prev, ...newRecords ];
89
- } );
90
- }
91
- setIsLoadingMore( false );
92
- }, [
93
- shownData,
94
- view.search,
95
- view.filters,
96
- view.perPage,
97
- currentPage,
98
- view.infiniteScrollEnabled,
99
- ] );
100
-
101
- const paginationInfo = {
102
- totalItems,
103
- totalPages,
104
- infiniteScrollHandler,
105
- };
106
-
107
36
  return (
108
37
  <>
109
38
  <style>{ `
110
39
  .dataviews-wrapper {
111
- height: 600px;
40
+ height: 750px;
112
41
  overflow: auto;
113
42
  }
114
43
  ` }</style>
115
- <Text
116
- style={ {
117
- marginBottom: '16px',
118
- padding: '8px',
119
- background: '#f0f0f0',
120
- borderRadius: '4px',
121
- display: 'block',
122
- } }
123
- >
124
- { __( 'Infinite Scroll Demo' ) }: { allLoadedRecords.length } of{ ' ' }
125
- { totalItems } items loaded.
126
- { isLoadingMore && __( 'Loading more…' ) }
127
- { ! hasMoreData && __( 'All items loaded!' ) }
128
- </Text>
129
44
  <DataViews
130
45
  getItemId={ ( item ) => item.id.toString() }
131
46
  paginationInfo={ paginationInfo }
132
- data={ allLoadedRecords }
47
+ data={ shownData }
133
48
  view={ view }
134
49
  fields={ fields }
135
50
  onChangeView={ setView }
136
51
  actions={ actions }
137
- isLoading={ isLoadingMore }
138
52
  defaultLayouts={ {
139
53
  [ LAYOUT_TABLE ]: {},
140
54
  [ LAYOUT_GRID ]: {},
@@ -642,6 +642,7 @@ const LayoutActivityComponent = ( {
642
642
  <div
643
643
  style={
644
644
  {
645
+ height: '100%',
645
646
  maxWidth: fullWidth ? undefined : '400px',
646
647
  '--wp-dataviews-color-background': backgroundColor,
647
648
  } as React.CSSProperties
@@ -104,7 +104,11 @@ function PosterGrid( { items }: { items: typeof data } ) {
104
104
  * - Render a completely custom layout (poster grid) instead of `<DataViews.Layout />`
105
105
  * - Still leverage DataViews sub-components for search and pagination
106
106
  */
107
- export const LayoutCustomComponent = () => {
107
+ export const LayoutCustomComponent = ( {
108
+ containerHeight,
109
+ }: {
110
+ containerHeight: string;
111
+ } ) => {
108
112
  const [ view, setView ] = useState< View >( {
109
113
  type: LAYOUT_TABLE,
110
114
  search: '',
@@ -128,11 +132,11 @@ export const LayoutCustomComponent = () => {
128
132
  onChangeView={ setView }
129
133
  defaultLayouts={ { table: {} } }
130
134
  >
131
- <div style={ { padding: '2px' } }>
135
+ <div style={ { padding: '2px', height: containerHeight } }>
132
136
  <DataViews.Search />
133
137
  <PosterGrid items={ processedData } />
134
- <DataViews.Pagination />
135
138
  </div>
139
+ <DataViews.Pagination />
136
140
  </DataViews>
137
141
  );
138
142
  };
@@ -63,6 +63,7 @@ export const LayoutTableComponent = ( {
63
63
  <div
64
64
  style={
65
65
  {
66
+ height: '100%',
66
67
  '--wp-dataviews-color-background': backgroundColor,
67
68
  } as React.CSSProperties
68
69
  }
@@ -65,6 +65,7 @@ export const LayoutTableComponent = ( {
65
65
  <div
66
66
  style={
67
67
  {
68
+ height: '100%',
68
69
  maxWidth: fullWidth ? undefined : '400px',
69
70
  '--wp-dataviews-color-background': backgroundColor,
70
71
  } as React.CSSProperties
@@ -64,6 +64,7 @@ export const LayoutTableComponent = ( {
64
64
  <div
65
65
  style={
66
66
  {
67
+ height: '100%',
67
68
  '--wp-dataviews-color-background': backgroundColor,
68
69
  } as React.CSSProperties
69
70
  }
@@ -3,11 +3,6 @@
3
3
  text-wrap: pretty;
4
4
  }
5
5
 
6
- .free-composition {
7
- height: 600px;
8
- overflow: auto;
9
- }
10
-
11
6
  .free-composition-heading,
12
7
  .free-composition-header {
13
8
  padding: 16px 48px;
@@ -2,7 +2,10 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { useState, useMemo } from '@wordpress/element';
5
- import { Card, CardHeader, CardBody } from '@wordpress/components';
5
+ // TODO: enable in the ESlint rule once we complete
6
+ // https://github.com/WordPress/gutenberg/issues/76135.
7
+ // eslint-disable-next-line @wordpress/use-recommended-components
8
+ import { Card } from '@wordpress/ui';
6
9
 
7
10
  /**
8
11
  * Internal dependencies
@@ -18,7 +21,11 @@ import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
18
21
  import type { View } from '../../types';
19
22
  import { actions, data, fields } from './fixtures';
20
23
 
21
- const WithCardComponent = () => {
24
+ const WithCardComponent = ( {
25
+ containerHeight,
26
+ }: {
27
+ containerHeight: string;
28
+ } ) => {
22
29
  const [ view, setView ] = useState< View >( {
23
30
  type: LAYOUT_TABLE,
24
31
  search: '',
@@ -35,28 +42,32 @@ const WithCardComponent = () => {
35
42
  return filterSortAndPaginate( data, view, fields );
36
43
  }, [ view ] );
37
44
  return (
38
- <Card>
39
- <CardHeader>Header</CardHeader>
40
- <CardBody>
41
- <DataViews
42
- getItemId={ ( item ) => item.id.toString() }
43
- paginationInfo={ paginationInfo }
44
- data={ shownData }
45
- view={ view }
46
- fields={ fields }
47
- onChangeView={ setView }
48
- actions={ actions.filter(
49
- ( action ) => ! action.supportsBulk
50
- ) }
51
- defaultLayouts={ {
52
- [ LAYOUT_TABLE ]: {},
53
- [ LAYOUT_GRID ]: {},
54
- [ LAYOUT_LIST ]: {},
55
- [ LAYOUT_ACTIVITY ]: {},
56
- } }
57
- />
58
- </CardBody>
59
- </Card>
45
+ <Card.Root>
46
+ <Card.Header>
47
+ <Card.Title>Header</Card.Title>
48
+ </Card.Header>
49
+ <Card.Content style={ { height: containerHeight, minHeight: 0 } }>
50
+ <Card.FullBleed>
51
+ <DataViews
52
+ getItemId={ ( item ) => item.id.toString() }
53
+ paginationInfo={ paginationInfo }
54
+ data={ shownData }
55
+ view={ view }
56
+ fields={ fields }
57
+ onChangeView={ setView }
58
+ actions={ actions.filter(
59
+ ( action ) => ! action.supportsBulk
60
+ ) }
61
+ defaultLayouts={ {
62
+ [ LAYOUT_TABLE ]: {},
63
+ [ LAYOUT_GRID ]: {},
64
+ [ LAYOUT_LIST ]: {},
65
+ [ LAYOUT_ACTIVITY ]: {},
66
+ } }
67
+ />
68
+ </Card.FullBleed>
69
+ </Card.Content>
70
+ </Card.Root>
60
71
  );
61
72
  };
62
73
 
@@ -15,7 +15,6 @@
15
15
  .dataviews-wrapper,
16
16
  .dataviews-picker-wrapper {
17
17
  height: 100%;
18
- overflow: auto;
19
18
  box-sizing: border-box;
20
19
  scroll-padding-bottom: $grid-unit-80;
21
20
  /* stylelint-disable-next-line property-no-unknown -- '@container' not globally permitted */
@@ -127,11 +126,9 @@
127
126
  @include link-reset();
128
127
  }
129
128
 
130
- /**
131
- * When DataViews are placed within cards, apply a consistent top padding.
132
- */
133
- .components-card__body:has(> .dataviews-wrapper),
134
- .components-card__body:has(> .dataviews-picker-wrapper) {
135
- padding: $grid-unit-10 0 0;
136
- overflow: hidden; // Prevent cells with white backgrounds overflowing the card
129
+ .dataviews__view-actions--infinite-scroll {
130
+ position: sticky;
131
+ top: 0;
132
+ z-index: 2; // Ensure it appears above dataview items when scrolling.
133
+ background-color: #fff;
137
134
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { render, screen } from '@testing-library/react';
4
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
5
5
  import userEvent from '@testing-library/user-event';
6
6
 
7
7
  /**
@@ -240,6 +240,59 @@ describe( 'DataViews component', () => {
240
240
  expect( screen.getByText( 'TEST TITLE' ) ).toBeInTheDocument();
241
241
  } );
242
242
 
243
+ it( 'should trigger infinite scroll when the layout container scrolls', async () => {
244
+ const onChangeView = jest.fn();
245
+
246
+ if ( typeof global.IntersectionObserver === 'undefined' ) {
247
+ ( global as any ).IntersectionObserver = jest.fn( () => ( {
248
+ observe: jest.fn(),
249
+ unobserve: jest.fn(),
250
+ disconnect: jest.fn(),
251
+ } ) );
252
+ }
253
+
254
+ const { container } = render(
255
+ <DataViewWrapper
256
+ view={ {
257
+ type: LAYOUT_GRID,
258
+ infiniteScrollEnabled: true,
259
+ perPage: 1,
260
+ } }
261
+ onChangeView={ onChangeView }
262
+ />
263
+ );
264
+ // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
265
+ const layoutContainer = container.querySelector(
266
+ '.dataviews-layout__container'
267
+ ) as HTMLDivElement;
268
+
269
+ Object.defineProperties( layoutContainer, {
270
+ scrollTop: {
271
+ configurable: true,
272
+ value: 500,
273
+ },
274
+ scrollHeight: {
275
+ configurable: true,
276
+ value: 1000,
277
+ },
278
+ clientHeight: {
279
+ configurable: true,
280
+ value: 500,
281
+ },
282
+ } );
283
+
284
+ fireEvent.scroll( layoutContainer );
285
+
286
+ await waitFor( () => {
287
+ expect( onChangeView ).toHaveBeenCalledWith(
288
+ expect.objectContaining( {
289
+ infiniteScrollEnabled: true,
290
+ startPosition: 2,
291
+ } )
292
+ );
293
+ } );
294
+ } );
295
+
243
296
  describe( 'in table view', () => {
244
297
  it( 'should display columns for each field', () => {
245
298
  render( <DataViewWrapper /> );