@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
@@ -0,0 +1,36 @@
1
+ // packages/dataviews/src/hooks/use-selected-items.ts
2
+ import { useMemo, useRef } from "@wordpress/element";
3
+ function useSelectedItems(view, data, selection, getItemId, filterFn) {
4
+ const selectedItemsCacheRef = useRef(/* @__PURE__ */ new Map());
5
+ return useMemo(() => {
6
+ const selectionSet = new Set(selection);
7
+ if (view.infiniteScrollEnabled) {
8
+ data.forEach((item) => {
9
+ const id = getItemId(item);
10
+ if (selectionSet.has(id)) {
11
+ const passesFilter = filterFn ? filterFn(item) : true;
12
+ if (passesFilter) {
13
+ selectedItemsCacheRef.current.set(id, item);
14
+ }
15
+ }
16
+ });
17
+ selectedItemsCacheRef.current.forEach((_, id) => {
18
+ if (!selectionSet.has(id)) {
19
+ selectedItemsCacheRef.current.delete(id);
20
+ }
21
+ });
22
+ return Array.from(selectedItemsCacheRef.current.values());
23
+ }
24
+ return data.filter((item) => {
25
+ const id = getItemId(item);
26
+ if (!selectionSet.has(id)) {
27
+ return false;
28
+ }
29
+ return filterFn ? filterFn(item) : true;
30
+ });
31
+ }, [view.infiniteScrollEnabled, selection, getItemId, data, filterFn]);
32
+ }
33
+ export {
34
+ useSelectedItems as default
35
+ };
36
+ //# sourceMappingURL=use-selected-items.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/hooks/use-selected-items.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useMemo, useRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport type { View } from '../types';\n\n/**\n * Hook to get selected items, with support for infinite scroll.\n *\n * When infinite scroll is enabled, items that scroll out of view are cached\n * so they remain available for bulk actions even when not in the current data set.\n *\n * @param view The current view configuration.\n * @param data The current page of data items.\n * @param selection Array of selected item IDs.\n * @param getItemId Function to get the ID of an item.\n * @param filterFn Optional filter function to apply to selected items (e.g., for selectability).\n * @return Array of selected items.\n */\nexport default function useSelectedItems< Item >(\n\tview: View,\n\tdata: Item[],\n\tselection: string[],\n\tgetItemId: ( item: Item ) => string,\n\tfilterFn?: ( item: Item ) => boolean\n): Item[] {\n\t// With infinite scroll enabled items scroll out of view, but we want to keep the selection unaltered,\n\t// unlike page-based navigation where we might clear selection upon navigating to a different page.\n\tconst selectedItemsCacheRef = useRef< Map< string, Item > >( new Map() );\n\n\treturn useMemo( () => {\n\t\tconst selectionSet = new Set( selection );\n\n\t\tif ( view.infiniteScrollEnabled ) {\n\t\t\t// Selection array contains selected item IDs\n\t\t\t// Cache selected items so they remain available when scrolled out of view\n\t\t\tdata.forEach( ( item ) => {\n\t\t\t\tconst id = getItemId( item );\n\t\t\t\tif ( selectionSet.has( id ) ) {\n\t\t\t\t\tconst passesFilter = filterFn ? filterFn( item ) : true;\n\t\t\t\t\tif ( passesFilter ) {\n\t\t\t\t\t\tselectedItemsCacheRef.current.set( id, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Remove items from cache that are no longer selected\n\t\t\tselectedItemsCacheRef.current.forEach( ( _, id ) => {\n\t\t\t\tif ( ! selectionSet.has( id ) ) {\n\t\t\t\t\tselectedItemsCacheRef.current.delete( id );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Return all cached selected items\n\t\t\treturn Array.from( selectedItemsCacheRef.current.values() );\n\t\t}\n\n\t\t// Non-infinite scroll mode\n\t\treturn data.filter( ( item ) => {\n\t\t\tconst id = getItemId( item );\n\t\t\tif ( ! selectionSet.has( id ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Apply optional filter (e.g., selectability check for bulk actions)\n\t\t\treturn filterFn ? filterFn( item ) : true;\n\t\t} );\n\t}, [ view.infiniteScrollEnabled, selection, getItemId, data, filterFn ] );\n}\n"],
5
+ "mappings": ";AAGA,SAAS,SAAS,cAAc;AAoBjB,SAAR,iBACN,MACA,MACA,WACA,WACA,UACS;AAGT,QAAM,wBAAwB,OAA+B,oBAAI,IAAI,CAAE;AAEvE,SAAO,QAAS,MAAM;AACrB,UAAM,eAAe,IAAI,IAAK,SAAU;AAExC,QAAK,KAAK,uBAAwB;AAGjC,WAAK,QAAS,CAAE,SAAU;AACzB,cAAM,KAAK,UAAW,IAAK;AAC3B,YAAK,aAAa,IAAK,EAAG,GAAI;AAC7B,gBAAM,eAAe,WAAW,SAAU,IAAK,IAAI;AACnD,cAAK,cAAe;AACnB,kCAAsB,QAAQ,IAAK,IAAI,IAAK;AAAA,UAC7C;AAAA,QACD;AAAA,MACD,CAAE;AAGF,4BAAsB,QAAQ,QAAS,CAAE,GAAG,OAAQ;AACnD,YAAK,CAAE,aAAa,IAAK,EAAG,GAAI;AAC/B,gCAAsB,QAAQ,OAAQ,EAAG;AAAA,QAC1C;AAAA,MACD,CAAE;AAGF,aAAO,MAAM,KAAM,sBAAsB,QAAQ,OAAO,CAAE;AAAA,IAC3D;AAGA,WAAO,KAAK,OAAQ,CAAE,SAAU;AAC/B,YAAM,KAAK,UAAW,IAAK;AAC3B,UAAK,CAAE,aAAa,IAAK,EAAG,GAAI;AAC/B,eAAO;AAAA,MACR;AAEA,aAAO,WAAW,SAAU,IAAK,IAAI;AAAA,IACtC,CAAE;AAAA,EACH,GAAG,CAAE,KAAK,uBAAuB,WAAW,WAAW,MAAM,QAAS,CAAE;AACzE;",
6
+ "names": []
7
+ }
@@ -77,7 +77,11 @@ function filterSortAndPaginate(data, view, fields) {
77
77
  }
78
78
  let totalItems = filteredData.length;
79
79
  let totalPages = 1;
80
- if (view.page !== void 0 && view.perPage !== void 0) {
80
+ if (view.infiniteScrollEnabled && view.startPosition !== void 0 && view.perPage !== void 0) {
81
+ const start = view.startPosition - 1;
82
+ const end = Math.min(start + view.perPage, totalItems);
83
+ filteredData = filteredData?.slice(start, end);
84
+ } else if (view.page !== void 0 && view.perPage !== void 0) {
81
85
  const start = (view.page - 1) * view.perPage;
82
86
  totalItems = filteredData?.length || 0;
83
87
  totalPages = Math.ceil(totalItems / view.perPage);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/filter-sort-and-paginate.ts"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport removeAccents from 'remove-accents';\n\n/**\n * WordPress dependencies\n */\nimport deprecated from '@wordpress/deprecated';\n\n/**\n * Internal dependencies\n */\nimport { OPERATOR_IS_NOT_ALL } from '../constants';\nimport normalizeFields from '../field-types';\nimport type { Field, Operator, View } from '../types';\n\nfunction normalizeSearchInput( input = '' ) {\n\treturn removeAccents( input.trim().toLowerCase() );\n}\n\nconst EMPTY_ARRAY: [] = [];\n\n/**\n * Applies the filtering, sorting and pagination to the raw data based on the view configuration.\n *\n * @param data Raw data.\n * @param view View config.\n * @param fields Fields config.\n *\n * @return Filtered, sorted and paginated data.\n */\nexport default function filterSortAndPaginate< Item >(\n\tdata: Item[],\n\tview: View,\n\tfields: Field< Item >[]\n): {\n\tdata: Item[];\n\tpaginationInfo: { totalItems: number; totalPages: number };\n} {\n\tif ( ! data ) {\n\t\treturn {\n\t\t\tdata: EMPTY_ARRAY,\n\t\t\tpaginationInfo: { totalItems: 0, totalPages: 0 },\n\t\t};\n\t}\n\tconst _fields = normalizeFields( fields );\n\tlet filteredData = [ ...data ];\n\t// Handle global search.\n\tif ( view.search ) {\n\t\tconst normalizedSearch = normalizeSearchInput( view.search );\n\t\tfilteredData = filteredData.filter( ( item ) => {\n\t\t\treturn _fields\n\t\t\t\t.filter( ( field ) => field.enableGlobalSearch )\n\t\t\t\t.some( ( field ) => {\n\t\t\t\t\tconst fieldValue = field.getValue( { item } );\n\t\t\t\t\tconst values = Array.isArray( fieldValue )\n\t\t\t\t\t\t? fieldValue\n\t\t\t\t\t\t: [ fieldValue ];\n\t\t\t\t\treturn values.some( ( value ) =>\n\t\t\t\t\t\tnormalizeSearchInput( String( value ) ).includes(\n\t\t\t\t\t\t\tnormalizedSearch\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} );\n\t\t} );\n\t}\n\n\tif ( view.filters && view.filters?.length > 0 ) {\n\t\tview.filters.forEach( ( filter ) => {\n\t\t\tconst field = _fields.find(\n\t\t\t\t( _field ) => _field.id === filter.field\n\t\t\t);\n\t\t\tif ( field ) {\n\t\t\t\t// Show deprecation warning for `isNotAll` operator.\n\t\t\t\t// We still handle this by mapping it to `isNone` in `getFilter`.\n\t\t\t\tif ( filter.operator === OPERATOR_IS_NOT_ALL ) {\n\t\t\t\t\tdeprecated( \"The 'isNotAll' filter operator\", {\n\t\t\t\t\t\tsince: '7.0',\n\t\t\t\t\t\talternative: \"'isNone'\",\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tconst handler = field.filter[ filter.operator as Operator ];\n\t\t\t\tif ( handler ) {\n\t\t\t\t\tfilteredData = filteredData.filter( ( item ) =>\n\t\t\t\t\t\thandler( item, field, filter.value )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t// Handle sorting.\n\tconst sortByField = view.sort?.field\n\t\t? _fields.find( ( field ) => {\n\t\t\t\treturn (\n\t\t\t\t\tfield.enableSorting !== false &&\n\t\t\t\t\tfield.id === view.sort?.field\n\t\t\t\t);\n\t\t } )\n\t\t: null;\n\tconst groupByField = view.groupBy?.field\n\t\t? _fields.find( ( field ) => {\n\t\t\t\treturn (\n\t\t\t\t\tfield.enableSorting !== false &&\n\t\t\t\t\tfield.id === view.groupBy?.field\n\t\t\t\t);\n\t\t } )\n\t\t: null;\n\tif ( sortByField || groupByField ) {\n\t\tfilteredData.sort( ( a, b ) => {\n\t\t\tif ( groupByField ) {\n\t\t\t\tconst groupCompare = groupByField.sort(\n\t\t\t\t\ta,\n\t\t\t\t\tb,\n\t\t\t\t\tview.groupBy?.direction ?? 'asc'\n\t\t\t\t);\n\n\t\t\t\t// If items are in different groups, return the group comparison result.\n\t\t\t\t// Otherwise, fall back to sorting by the sort field.\n\t\t\t\tif ( groupCompare !== 0 ) {\n\t\t\t\t\treturn groupCompare;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( sortByField ) {\n\t\t\t\treturn sortByField.sort( a, b, view.sort?.direction ?? 'desc' );\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t} );\n\t}\n\n\t// Handle pagination.\n\tlet totalItems = filteredData.length;\n\tlet totalPages = 1;\n\tif ( view.page !== undefined && view.perPage !== undefined ) {\n\t\tconst start = ( view.page - 1 ) * view.perPage;\n\t\ttotalItems = filteredData?.length || 0;\n\t\ttotalPages = Math.ceil( totalItems / view.perPage );\n\t\tfilteredData = filteredData?.slice( start, start + view.perPage );\n\t}\n\n\treturn {\n\t\tdata: filteredData,\n\t\tpaginationInfo: {\n\t\t\ttotalItems,\n\t\t\ttotalPages,\n\t\t},\n\t};\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport removeAccents from 'remove-accents';\n\n/**\n * WordPress dependencies\n */\nimport deprecated from '@wordpress/deprecated';\n\n/**\n * Internal dependencies\n */\nimport { OPERATOR_IS_NOT_ALL } from '../constants';\nimport normalizeFields from '../field-types';\nimport type { Field, Operator, View } from '../types';\n\nfunction normalizeSearchInput( input = '' ) {\n\treturn removeAccents( input.trim().toLowerCase() );\n}\n\nconst EMPTY_ARRAY: [] = [];\n\n/**\n * Applies the filtering, sorting and pagination to the raw data based on the view configuration.\n *\n * @param data Raw data.\n * @param view View config.\n * @param fields Fields config.\n *\n * @return Filtered, sorted and paginated data.\n */\nexport default function filterSortAndPaginate< Item >(\n\tdata: Item[],\n\tview: View,\n\tfields: Field< Item >[]\n): {\n\tdata: Item[];\n\tpaginationInfo: { totalItems: number; totalPages: number };\n} {\n\tif ( ! data ) {\n\t\treturn {\n\t\t\tdata: EMPTY_ARRAY,\n\t\t\tpaginationInfo: { totalItems: 0, totalPages: 0 },\n\t\t};\n\t}\n\tconst _fields = normalizeFields( fields );\n\tlet filteredData = [ ...data ];\n\t// Handle global search.\n\tif ( view.search ) {\n\t\tconst normalizedSearch = normalizeSearchInput( view.search );\n\t\tfilteredData = filteredData.filter( ( item ) => {\n\t\t\treturn _fields\n\t\t\t\t.filter( ( field ) => field.enableGlobalSearch )\n\t\t\t\t.some( ( field ) => {\n\t\t\t\t\tconst fieldValue = field.getValue( { item } );\n\t\t\t\t\tconst values = Array.isArray( fieldValue )\n\t\t\t\t\t\t? fieldValue\n\t\t\t\t\t\t: [ fieldValue ];\n\t\t\t\t\treturn values.some( ( value ) =>\n\t\t\t\t\t\tnormalizeSearchInput( String( value ) ).includes(\n\t\t\t\t\t\t\tnormalizedSearch\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} );\n\t\t} );\n\t}\n\n\tif ( view.filters && view.filters?.length > 0 ) {\n\t\tview.filters.forEach( ( filter ) => {\n\t\t\tconst field = _fields.find(\n\t\t\t\t( _field ) => _field.id === filter.field\n\t\t\t);\n\t\t\tif ( field ) {\n\t\t\t\t// Show deprecation warning for `isNotAll` operator.\n\t\t\t\t// We still handle this by mapping it to `isNone` in `getFilter`.\n\t\t\t\tif ( filter.operator === OPERATOR_IS_NOT_ALL ) {\n\t\t\t\t\tdeprecated( \"The 'isNotAll' filter operator\", {\n\t\t\t\t\t\tsince: '7.0',\n\t\t\t\t\t\talternative: \"'isNone'\",\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tconst handler = field.filter[ filter.operator as Operator ];\n\t\t\t\tif ( handler ) {\n\t\t\t\t\tfilteredData = filteredData.filter( ( item ) =>\n\t\t\t\t\t\thandler( item, field, filter.value )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t// Handle sorting.\n\tconst sortByField = view.sort?.field\n\t\t? _fields.find( ( field ) => {\n\t\t\t\treturn (\n\t\t\t\t\tfield.enableSorting !== false &&\n\t\t\t\t\tfield.id === view.sort?.field\n\t\t\t\t);\n\t\t } )\n\t\t: null;\n\tconst groupByField = view.groupBy?.field\n\t\t? _fields.find( ( field ) => {\n\t\t\t\treturn (\n\t\t\t\t\tfield.enableSorting !== false &&\n\t\t\t\t\tfield.id === view.groupBy?.field\n\t\t\t\t);\n\t\t } )\n\t\t: null;\n\tif ( sortByField || groupByField ) {\n\t\tfilteredData.sort( ( a, b ) => {\n\t\t\tif ( groupByField ) {\n\t\t\t\tconst groupCompare = groupByField.sort(\n\t\t\t\t\ta,\n\t\t\t\t\tb,\n\t\t\t\t\tview.groupBy?.direction ?? 'asc'\n\t\t\t\t);\n\n\t\t\t\t// If items are in different groups, return the group comparison result.\n\t\t\t\t// Otherwise, fall back to sorting by the sort field.\n\t\t\t\tif ( groupCompare !== 0 ) {\n\t\t\t\t\treturn groupCompare;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( sortByField ) {\n\t\t\t\treturn sortByField.sort( a, b, view.sort?.direction ?? 'desc' );\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t} );\n\t}\n\n\t// Handle pagination.\n\tlet totalItems = filteredData.length;\n\tlet totalPages = 1;\n\n\t// Use position-based pagination for infinite scroll\n\tif (\n\t\tview.infiniteScrollEnabled &&\n\t\tview.startPosition !== undefined &&\n\t\tview.perPage !== undefined\n\t) {\n\t\t// Convert 1-indexed positions to 0-indexed array indices\n\t\tconst start = view.startPosition - 1;\n\t\tconst end = Math.min( start + view.perPage, totalItems );\n\t\tfilteredData = filteredData?.slice( start, end );\n\t} else if ( view.page !== undefined && view.perPage !== undefined ) {\n\t\t// Use traditional page-based pagination\n\t\tconst start = ( view.page - 1 ) * view.perPage;\n\t\ttotalItems = filteredData?.length || 0;\n\t\ttotalPages = Math.ceil( totalItems / view.perPage );\n\t\tfilteredData = filteredData?.slice( start, start + view.perPage );\n\t}\n\n\treturn {\n\t\tdata: filteredData,\n\t\tpaginationInfo: {\n\t\t\ttotalItems,\n\t\t\ttotalPages,\n\t\t},\n\t};\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  // packages/dataviews/src/utils/get-footer-message.ts
2
2
  import { _n, sprintf } from "@wordpress/i18n";
3
- function getFooterMessage(selectionCount, itemsCount, totalItems) {
3
+ function getFooterMessage(selectionCount, itemsCount, totalItems, onlyTotalCount = false) {
4
4
  if (selectionCount > 0) {
5
5
  return sprintf(
6
6
  /* translators: %d: number of items. */
@@ -8,18 +8,18 @@ function getFooterMessage(selectionCount, itemsCount, totalItems) {
8
8
  selectionCount
9
9
  );
10
10
  }
11
- if (totalItems > itemsCount) {
11
+ if (onlyTotalCount || totalItems <= itemsCount) {
12
12
  return sprintf(
13
- /* translators: %1$d: number of items. %2$d: total number of items. */
14
- _n("%1$d of %2$d Item", "%1$d of %2$d Items", totalItems),
15
- itemsCount,
13
+ /* translators: %d: number of items. */
14
+ _n("%d Item", "%d Items", totalItems),
16
15
  totalItems
17
16
  );
18
17
  }
19
18
  return sprintf(
20
- /* translators: %d: number of items. */
21
- _n("%d Item", "%d Items", itemsCount),
22
- itemsCount
19
+ /* translators: %1$d: number of items. %2$d: total number of items. */
20
+ _n("%1$d of %2$d Item", "%1$d of %2$d Items", totalItems),
21
+ itemsCount,
22
+ totalItems
23
23
  );
24
24
  }
25
25
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/get-footer-message.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { _n, sprintf } from '@wordpress/i18n';\n\n/**\n * Get the footer message for the DataViews footer.\n *\n * @param selectionCount - The number of items selected.\n * @param itemsCount - The number of items in the current page.\n * @param totalItems - The total number of items.\n * @return - The footer message.\n */\nexport default function getFooterMessage(\n\tselectionCount: number,\n\titemsCount: number,\n\ttotalItems: number\n): string {\n\tif ( selectionCount > 0 ) {\n\t\treturn sprintf(\n\t\t\t/* translators: %d: number of items. */\n\t\t\t_n( '%d Item selected', '%d Items selected', selectionCount ),\n\t\t\tselectionCount\n\t\t);\n\t}\n\n\tif ( totalItems > itemsCount ) {\n\t\treturn sprintf(\n\t\t\t/* translators: %1$d: number of items. %2$d: total number of items. */\n\t\t\t_n( '%1$d of %2$d Item', '%1$d of %2$d Items', totalItems ),\n\t\t\titemsCount,\n\t\t\ttotalItems\n\t\t);\n\t}\n\n\treturn sprintf(\n\t\t/* translators: %d: number of items. */\n\t\t_n( '%d Item', '%d Items', itemsCount ),\n\t\titemsCount\n\t);\n}\n"],
5
- "mappings": ";AAGA,SAAS,IAAI,eAAe;AAUb,SAAR,iBACN,gBACA,YACA,YACS;AACT,MAAK,iBAAiB,GAAI;AACzB,WAAO;AAAA;AAAA,MAEN,GAAI,oBAAoB,qBAAqB,cAAe;AAAA,MAC5D;AAAA,IACD;AAAA,EACD;AAEA,MAAK,aAAa,YAAa;AAC9B,WAAO;AAAA;AAAA,MAEN,GAAI,qBAAqB,sBAAsB,UAAW;AAAA,MAC1D;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AAAA;AAAA,IAEN,GAAI,WAAW,YAAY,UAAW;AAAA,IACtC;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { _n, sprintf } from '@wordpress/i18n';\n\n/**\n * Get the footer message for the DataViews footer.\n *\n * @param selectionCount - The number of selected items.\n * @param itemsCount - The number of items in the current page.\n * @param totalItems - The total number of items.\n * @param onlyTotalCount - Whether to only show the total count (used with infinite scroll).\n * @return - The footer message.\n */\nexport default function getFooterMessage(\n\tselectionCount: number,\n\titemsCount: number,\n\ttotalItems: number,\n\tonlyTotalCount = false\n): string {\n\tif ( selectionCount > 0 ) {\n\t\treturn sprintf(\n\t\t\t/* translators: %d: number of items. */\n\t\t\t_n( '%d Item selected', '%d Items selected', selectionCount ),\n\t\t\tselectionCount\n\t\t);\n\t}\n\n\t// No selection - show item count\n\tif ( onlyTotalCount || totalItems <= itemsCount ) {\n\t\treturn sprintf(\n\t\t\t/* translators: %d: number of items. */\n\t\t\t_n( '%d Item', '%d Items', totalItems ),\n\t\t\ttotalItems\n\t\t);\n\t}\n\n\treturn sprintf(\n\t\t/* translators: %1$d: number of items. %2$d: total number of items. */\n\t\t_n( '%1$d of %2$d Item', '%1$d of %2$d Items', totalItems ),\n\t\titemsCount,\n\t\ttotalItems\n\t);\n}\n"],
5
+ "mappings": ";AAGA,SAAS,IAAI,eAAe;AAWb,SAAR,iBACN,gBACA,YACA,YACA,iBAAiB,OACR;AACT,MAAK,iBAAiB,GAAI;AACzB,WAAO;AAAA;AAAA,MAEN,GAAI,oBAAoB,qBAAqB,cAAe;AAAA,MAC5D;AAAA,IACD;AAAA,EACD;AAGA,MAAK,kBAAkB,cAAc,YAAa;AACjD,WAAO;AAAA;AAAA,MAEN,GAAI,WAAW,YAAY,UAAW;AAAA,MACtC;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AAAA;AAAA,IAEN,GAAI,qBAAqB,sBAAsB,UAAW;AAAA,IAC1D;AAAA,IACA;AAAA,EACD;AACD;",
6
6
  "names": []
7
7
  }
@@ -90,7 +90,6 @@
90
90
  .dataviews-wrapper,
91
91
  .dataviews-picker-wrapper {
92
92
  height: 100%;
93
- overflow: auto;
94
93
  box-sizing: border-box;
95
94
  scroll-padding-bottom: 64px;
96
95
  /* stylelint-disable-next-line property-no-unknown -- '@container' not globally permitted */
@@ -214,13 +213,11 @@
214
213
  border-radius: 2px;
215
214
  }
216
215
 
217
- /**
218
- * When DataViews are placed within cards, apply a consistent top padding.
219
- */
220
- .components-card__body:has(> .dataviews-wrapper),
221
- .components-card__body:has(> .dataviews-picker-wrapper) {
222
- padding: 8px 0 0;
223
- overflow: hidden;
216
+ .dataviews__view-actions--infinite-scroll {
217
+ position: sticky;
218
+ top: 0;
219
+ z-index: 2;
220
+ background-color: #fff;
224
221
  }
225
222
 
226
223
  .dataviews-bulk-actions-footer__item-count {
@@ -232,6 +229,15 @@
232
229
  min-height: 32px;
233
230
  }
234
231
 
232
+ .dataviews-layout__container {
233
+ flex: 1;
234
+ min-height: 0;
235
+ overflow: auto;
236
+ display: flex;
237
+ flex-direction: column;
238
+ background-color: inherit;
239
+ }
240
+
235
241
  .dataviews-filters__button {
236
242
  position: relative;
237
243
  }
@@ -905,7 +911,7 @@
905
911
  .dataviews-view-grid-items {
906
912
  margin-bottom: auto;
907
913
  display: grid;
908
- gap: 32px;
914
+ gap: 24px;
909
915
  grid-template-rows: max-content;
910
916
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
911
917
  padding: 0 24px 24px;
@@ -916,12 +922,18 @@
916
922
  transition: padding ease-out 0.1s;
917
923
  }
918
924
  }
925
+ .dataviews-view-grid-items.has-compact-density {
926
+ gap: 16px;
927
+ }
928
+ .dataviews-view-grid-items.has-comfortable-density {
929
+ gap: 32px;
930
+ }
919
931
 
920
932
  .dataviews-view-grid {
921
933
  padding: 0 24px 24px;
922
934
  display: flex;
923
935
  flex-direction: column;
924
- gap: 32px;
936
+ gap: 24px;
925
937
  container-type: inline-size;
926
938
  margin-bottom: auto;
927
939
  }
@@ -930,9 +942,21 @@
930
942
  transition: padding ease-out 0.1s;
931
943
  }
932
944
  }
945
+ .dataviews-view-grid.has-compact-density {
946
+ gap: 16px;
947
+ }
948
+ .dataviews-view-grid.has-compact-density .dataviews-view-grid__row {
949
+ gap: 16px;
950
+ }
951
+ .dataviews-view-grid.has-comfortable-density {
952
+ gap: 32px;
953
+ }
954
+ .dataviews-view-grid.has-comfortable-density .dataviews-view-grid__row {
955
+ gap: 32px;
956
+ }
933
957
  .dataviews-view-grid .dataviews-view-grid__row {
934
958
  display: grid;
935
- gap: 32px;
959
+ gap: 24px;
936
960
  }
937
961
  .dataviews-view-grid .dataviews-view-grid__row .dataviews-view-grid__row__gridcell {
938
962
  border-radius: 4px;
@@ -950,37 +974,48 @@
950
974
  pointer-events: none;
951
975
  outline: 2px solid transparent;
952
976
  }
953
- .dataviews-view-grid .dataviews-view-grid__card {
977
+
978
+ .dataviews-view-grid .dataviews-view-grid__card,
979
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card {
954
980
  height: 100%;
955
981
  justify-content: flex-start;
956
982
  position: relative;
957
983
  }
958
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title {
984
+ .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title,
985
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card .dataviews-view-grid__title {
959
986
  padding: 8px 0 4px;
960
987
  }
961
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field {
988
+ .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field,
989
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card .dataviews-view-grid__title-field {
962
990
  min-height: 24px;
963
991
  overflow: hidden;
964
992
  align-content: center;
965
993
  text-align: start;
966
994
  }
967
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable {
995
+ .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable,
996
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable {
968
997
  width: fit-content;
969
998
  }
970
- .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
999
+ .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value,
1000
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
971
1001
  color: #1e1e1e;
972
1002
  }
973
1003
  .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media::after,
974
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus::after {
1004
+ .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus::after,
1005
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card.is-selected .dataviews-view-grid__media::after,
1006
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card .dataviews-view-grid__media:focus::after {
975
1007
  background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
976
1008
  }
977
- .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media::after {
1009
+ .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media::after,
1010
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card.is-selected .dataviews-view-grid__media::after {
978
1011
  box-shadow: inset 0 0 0 1px var(--wp-admin-theme-color);
979
1012
  }
980
- .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus::after {
1013
+ .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus::after,
1014
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__card .dataviews-view-grid__media:focus::after {
981
1015
  box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
982
1016
  }
983
- .dataviews-view-grid .dataviews-view-grid__media {
1017
+ .dataviews-view-grid .dataviews-view-grid__media,
1018
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__media {
984
1019
  width: 100%;
985
1020
  aspect-ratio: 1/1;
986
1021
  background-color: #fff;
@@ -988,15 +1023,18 @@
988
1023
  overflow: hidden;
989
1024
  position: relative;
990
1025
  }
991
- .dataviews-view-grid .dataviews-view-grid__media.dataviews-view-grid__media--placeholder {
1026
+ .dataviews-view-grid .dataviews-view-grid__media.dataviews-view-grid__media--placeholder,
1027
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__media.dataviews-view-grid__media--placeholder {
992
1028
  aspect-ratio: 3/1;
993
1029
  }
994
- .dataviews-view-grid .dataviews-view-grid__media img {
1030
+ .dataviews-view-grid .dataviews-view-grid__media img,
1031
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__media img {
995
1032
  object-fit: cover;
996
1033
  width: 100%;
997
1034
  height: 100%;
998
1035
  }
999
- .dataviews-view-grid .dataviews-view-grid__media::after {
1036
+ .dataviews-view-grid .dataviews-view-grid__media::after,
1037
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__media::after {
1000
1038
  content: "";
1001
1039
  position: absolute;
1002
1040
  top: 0;
@@ -1007,7 +1045,8 @@
1007
1045
  border-radius: 4px;
1008
1046
  pointer-events: none;
1009
1047
  }
1010
- .dataviews-view-grid .dataviews-view-grid__media .dataviews-view-grid__media-placeholder {
1048
+ .dataviews-view-grid .dataviews-view-grid__media .dataviews-view-grid__media-placeholder,
1049
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__media .dataviews-view-grid__media-placeholder {
1011
1050
  width: 100%;
1012
1051
  height: 100%;
1013
1052
  display: block;
@@ -1015,48 +1054,58 @@
1015
1054
  box-shadow: none;
1016
1055
  background: #f0f0f0;
1017
1056
  }
1018
- .dataviews-view-grid .dataviews-view-grid__fields {
1057
+ .dataviews-view-grid .dataviews-view-grid__fields,
1058
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__fields {
1019
1059
  position: relative;
1020
1060
  font-size: 12px;
1021
1061
  line-height: 16px;
1022
1062
  }
1023
- .dataviews-view-grid .dataviews-view-grid__fields:not(:empty) {
1063
+ .dataviews-view-grid .dataviews-view-grid__fields:not(:empty),
1064
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__fields:not(:empty) {
1024
1065
  padding: 0 0 12px;
1025
1066
  }
1026
- .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty) {
1067
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty),
1068
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty) {
1027
1069
  min-height: 24px;
1028
1070
  line-height: 20px;
1029
1071
  padding-top: 2px;
1030
1072
  }
1031
- .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field {
1073
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field,
1074
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__fields .dataviews-view-grid__field {
1032
1075
  min-height: 24px;
1033
1076
  align-items: center;
1034
1077
  }
1035
- .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name {
1078
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name,
1079
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name {
1036
1080
  width: 35%;
1037
1081
  color: #757575;
1038
1082
  overflow: hidden;
1039
1083
  text-overflow: ellipsis;
1040
1084
  white-space: nowrap;
1041
1085
  }
1042
- .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
1086
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value,
1087
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
1043
1088
  width: 65%;
1044
1089
  overflow: hidden;
1045
1090
  text-overflow: ellipsis;
1046
1091
  white-space: nowrap;
1047
1092
  }
1048
- .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))) {
1093
+ .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))),
1094
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))) {
1049
1095
  display: none;
1050
1096
  }
1051
- .dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty) {
1097
+ .dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty),
1098
+ .dataviews-view-grid-infinite-scroll .dataviews-view-grid__badge-fields:not(:empty) {
1052
1099
  padding-bottom: 12px;
1053
1100
  }
1054
- .dataviews-view-grid.is-refreshing {
1101
+ .dataviews-view-grid.is-refreshing,
1102
+ .dataviews-view-grid-infinite-scroll.is-refreshing {
1055
1103
  opacity: 0.5;
1056
1104
  pointer-events: none;
1057
1105
  }
1058
1106
  @media not (prefers-reduced-motion) {
1059
- .dataviews-view-grid.is-refreshing {
1107
+ .dataviews-view-grid.is-refreshing,
1108
+ .dataviews-view-grid-infinite-scroll.is-refreshing {
1060
1109
  opacity: 1;
1061
1110
  animation: dataviews-pulse 1s ease-in-out infinite;
1062
1111
  }
@@ -1483,6 +1532,16 @@ div.dataviews-view-list {
1483
1532
  z-index: 1;
1484
1533
  background-color: inherit;
1485
1534
  }
1535
+ .dataviews-view-table thead.dataviews-view-table__thead--stuck::after {
1536
+ display: block;
1537
+ content: "";
1538
+ position: absolute;
1539
+ bottom: 0;
1540
+ right: 0;
1541
+ left: 0;
1542
+ height: 1px;
1543
+ background-color: #f0f0f0;
1544
+ }
1486
1545
  .dataviews-view-table thead tr {
1487
1546
  border: 0;
1488
1547
  }
@@ -1631,6 +1690,12 @@ div.dataviews-view-list {
1631
1690
  }
1632
1691
  }
1633
1692
 
1693
+ .dataviews-view-picker-grid.has-compact-density .dataviews-view-grid-items {
1694
+ gap: 16px;
1695
+ }
1696
+ .dataviews-view-picker-grid.has-comfortable-density .dataviews-view-grid-items {
1697
+ gap: 32px;
1698
+ }
1634
1699
  .dataviews-view-picker-grid .dataviews-view-picker-grid__card {
1635
1700
  height: 100%;
1636
1701
  justify-content: flex-start;
@@ -2191,17 +2256,18 @@ div.dataviews-view-list {
2191
2256
  align-items: center;
2192
2257
  }
2193
2258
 
2194
- .dataforms-layouts-card__field-header-label {
2195
- font-family: -apple-system, "system-ui", "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
2196
- font-weight: 499;
2197
- font-size: 15px;
2198
- line-height: 20px;
2199
- }
2200
-
2201
2259
  .dataforms-layouts-card__field {
2202
2260
  width: 100%;
2203
2261
  }
2204
2262
 
2263
+ .dataforms-layouts-card__field-header-content {
2264
+ min-height: 24px;
2265
+ }
2266
+
2267
+ .dataforms-layouts-card__field-header-content-description {
2268
+ display: contents;
2269
+ }
2270
+
2205
2271
  .dataforms-layouts-card__field-description {
2206
2272
  color: #757575;
2207
2273
  display: block;