@wordpress/dataviews 15.0.0 → 16.0.1

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 (67) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/build/components/dataform-controls/datetime.cjs.map +2 -2
  3. package/build/components/dataviews-context/index.cjs.map +2 -2
  4. package/build/components/dataviews-layouts/index.cjs +9 -0
  5. package/build/components/dataviews-layouts/index.cjs.map +3 -3
  6. package/build/components/dataviews-layouts/picker-activity/index.cjs +304 -0
  7. package/build/components/dataviews-layouts/picker-activity/index.cjs.map +7 -0
  8. package/build/components/dataviews-layouts/table/use-scroll-state.cjs.map +1 -1
  9. package/build/components/dataviews-layouts/utils/item-click-wrapper.cjs.map +2 -2
  10. package/build/components/dataviews-view-config/index.cjs +1 -0
  11. package/build/components/dataviews-view-config/index.cjs.map +2 -2
  12. package/build/constants.cjs +3 -0
  13. package/build/constants.cjs.map +2 -2
  14. package/build/hooks/use-form-validity.cjs.map +1 -1
  15. package/build/types/dataviews.cjs.map +1 -1
  16. package/build-module/components/dataform-controls/datetime.mjs.map +2 -2
  17. package/build-module/components/dataviews-context/index.mjs.map +2 -2
  18. package/build-module/components/dataviews-layouts/index.mjs +11 -1
  19. package/build-module/components/dataviews-layouts/index.mjs.map +2 -2
  20. package/build-module/components/dataviews-layouts/picker-activity/index.mjs +273 -0
  21. package/build-module/components/dataviews-layouts/picker-activity/index.mjs.map +7 -0
  22. package/build-module/components/dataviews-layouts/table/use-scroll-state.mjs.map +1 -1
  23. package/build-module/components/dataviews-layouts/utils/item-click-wrapper.mjs.map +2 -2
  24. package/build-module/components/dataviews-view-config/index.mjs +1 -0
  25. package/build-module/components/dataviews-view-config/index.mjs.map +2 -2
  26. package/build-module/constants.mjs +2 -0
  27. package/build-module/constants.mjs.map +2 -2
  28. package/build-module/hooks/use-form-validity.mjs.map +1 -1
  29. package/build-style/style-rtl.css +199 -13
  30. package/build-style/style.css +199 -13
  31. package/build-types/components/dataviews-context/index.d.ts +2 -2
  32. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  33. package/build-types/components/dataviews-layouts/index.d.ts +8 -0
  34. package/build-types/components/dataviews-layouts/index.d.ts.map +1 -1
  35. package/build-types/components/dataviews-layouts/picker-activity/index.d.ts +3 -0
  36. package/build-types/components/dataviews-layouts/picker-activity/index.d.ts.map +1 -0
  37. package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts +5 -9
  38. package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts.map +1 -1
  39. package/build-types/components/dataviews-layouts/utils/item-click-wrapper.d.ts.map +1 -1
  40. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  41. package/build-types/constants.d.ts +1 -0
  42. package/build-types/constants.d.ts.map +1 -1
  43. package/build-types/dataform/stories/index.story.d.ts +1 -0
  44. package/build-types/dataform/stories/index.story.d.ts.map +1 -1
  45. package/build-types/dataviews/stories/index.story.d.ts.map +1 -1
  46. package/build-types/dataviews-picker/stories/index.story.d.ts.map +1 -1
  47. package/build-types/types/dataviews.d.ts +16 -2
  48. package/build-types/types/dataviews.d.ts.map +1 -1
  49. package/build-wp/index.js +1088 -820
  50. package/package.json +24 -21
  51. package/src/components/dataform-controls/datetime.tsx +1 -1
  52. package/src/components/dataviews-context/index.ts +4 -2
  53. package/src/components/dataviews-layouts/index.ts +10 -0
  54. package/src/components/dataviews-layouts/picker-activity/index.tsx +359 -0
  55. package/src/components/dataviews-layouts/picker-activity/style.scss +227 -0
  56. package/src/components/dataviews-layouts/table/use-scroll-state.ts +6 -6
  57. package/src/components/dataviews-layouts/utils/item-click-wrapper.tsx +1 -3
  58. package/src/components/dataviews-view-config/index.tsx +1 -0
  59. package/src/constants.ts +1 -0
  60. package/src/dataform/stories/content.story.tsx +1 -1
  61. package/src/dataform/stories/index.story.tsx +1 -0
  62. package/src/dataviews/stories/index.story.tsx +1 -0
  63. package/src/dataviews-picker/stories/index.story.tsx +6 -0
  64. package/src/dataviews-picker/test/dataviews-picker.tsx +5 -0
  65. package/src/hooks/use-form-validity.ts +2 -2
  66. package/src/style.scss +1 -0
  67. package/src/types/dataviews.ts +21 -1
@@ -0,0 +1,227 @@
1
+ .dataviews-view-picker-activity {
2
+ margin: 0;
3
+ padding: 0;
4
+ // Fill the wrapper height so the footer sits at the bottom.
5
+ flex-grow: 1;
6
+
7
+ &:focus-visible {
8
+ &[aria-activedescendant] {
9
+ outline: none;
10
+ }
11
+
12
+ .dataviews-view-picker-activity__item[data-active-item="true"] {
13
+ outline: 2px solid var(--wpds-color-stroke-focus-brand);
14
+ outline-offset: -2px;
15
+ }
16
+ }
17
+
18
+ .dataviews-view-picker-activity__item {
19
+ cursor: var(--wpds-cursor-control);
20
+ border-radius: var(--wpds-border-radius-sm);
21
+ // Inset content to the toolbar/footer padding so the timeline aligns with the chrome.
22
+ padding-inline: var(--wpds-dimension-padding-2xl);
23
+ transition: background-color 0.1s ease;
24
+
25
+ // Selected and hovered rows share the same tint (like the table picker),
26
+ // keeping selection legible even for bullet-only items.
27
+ &.is-selected,
28
+ &:hover {
29
+ background-color: var(--wpds-color-bg-interactive-brand-weak-active);
30
+ }
31
+
32
+ // Selection outline only renders in Windows High Contrast mode.
33
+ &.is-selected {
34
+ outline: 3px solid transparent;
35
+ outline-offset: -2px;
36
+ }
37
+
38
+ &.is-compact {
39
+ .dataviews-view-picker-activity__item-type {
40
+ width: var(--wpds-dimension-padding-md);
41
+
42
+ &::before {
43
+ height: calc(var(--wpds-dimension-base) * 3);
44
+ }
45
+ }
46
+ .dataviews-view-picker-activity__item-type-icon {
47
+ width: calc(var(--wpds-dimension-base) * 3 - 1px);
48
+ height: calc(var(--wpds-dimension-base) * 3 - 1px);
49
+ }
50
+ .dataviews-view-picker-activity__item-content {
51
+ margin: var(--wpds-dimension-gap-md) 0;
52
+ }
53
+ }
54
+
55
+ &.is-balanced {
56
+ .dataviews-view-picker-activity__item-type {
57
+ width: calc(var(--wpds-dimension-base) * 6); // TODO: use size token when available
58
+
59
+ &::before {
60
+ height: calc(var(--wpds-dimension-base) * 3);
61
+ }
62
+ }
63
+ .dataviews-view-picker-activity__item-type-icon {
64
+ width: calc(var(--wpds-dimension-base) * 6 + 1px);
65
+ height: calc(var(--wpds-dimension-base) * 6 + 1px);
66
+ }
67
+ .dataviews-view-picker-activity__item-content {
68
+ margin: var(--wpds-dimension-gap-md) 0;
69
+ padding-top: var(--wpds-dimension-padding-sm);
70
+ }
71
+ }
72
+
73
+ &.is-comfortable {
74
+ .dataviews-view-picker-activity__item-type {
75
+ width: calc(var(--wpds-dimension-base) * 8); // TODO: use size token when available
76
+
77
+ &::before {
78
+ height: calc(var(--wpds-dimension-base) * 2);
79
+ }
80
+ }
81
+ .dataviews-view-picker-activity__item-type-icon {
82
+ width: calc(var(--wpds-dimension-base) * 8 + 1px);
83
+ height: calc(var(--wpds-dimension-base) * 8 + 1px);
84
+ }
85
+ .dataviews-view-picker-activity__item-content {
86
+ margin: var(--wpds-dimension-gap-sm) 0 var(--wpds-dimension-gap-lg);
87
+ padding-top: var(--wpds-dimension-padding-md);
88
+ }
89
+ }
90
+
91
+ &.is-comfortable,
92
+ &.is-balanced {
93
+ .dataviews-view-picker-activity__item-bullet {
94
+ width: calc(var(--wpds-dimension-base) * 2 + 1px);
95
+ height: calc(var(--wpds-dimension-base) * 2 + 1px);
96
+ position: relative;
97
+ top: 50%;
98
+ transform: translateY(-50%);
99
+ }
100
+ }
101
+ }
102
+
103
+ .dataviews-view-picker-activity__item-content {
104
+ flex-grow: 1;
105
+
106
+ .dataviews-view-picker-activity__item-title,
107
+ .dataviews-view-picker-activity__item-description,
108
+ .dataviews-view-picker-activity__item-fields {
109
+ min-height: calc(var(--wpds-dimension-base) * 4); // TODO: use size token when available
110
+ }
111
+
112
+ .dataviews-view-picker-activity__item-title {
113
+ position: relative;
114
+ display: flex;
115
+ align-items: center;
116
+ flex: 1;
117
+ overflow: hidden;
118
+ }
119
+
120
+ .dataviews-view-picker-activity__item-description {
121
+ &:empty {
122
+ display: none;
123
+ }
124
+ }
125
+
126
+ .dataviews-view-picker-activity__item-fields {
127
+ color: var(--wpds-color-fg-content-neutral-weak);
128
+ display: flex;
129
+ gap: var(--wpds-dimension-gap-md);
130
+ row-gap: var(--wpds-dimension-gap-xs);
131
+ flex-wrap: wrap;
132
+
133
+ &:empty {
134
+ display: none;
135
+ }
136
+
137
+ .dataviews-view-picker-activity__item-field {
138
+ &:has(.dataviews-view-picker-activity__item-field-value:empty) {
139
+ display: none;
140
+ }
141
+ }
142
+
143
+ .dataviews-view-picker-activity__item-field-value {
144
+ display: flex;
145
+ align-items: center;
146
+ }
147
+ }
148
+ }
149
+
150
+ // Timeline connector line
151
+ .dataviews-view-picker-activity__item-type {
152
+ align-self: stretch;
153
+ flex-shrink: 0;
154
+
155
+ &::after {
156
+ content: "";
157
+ flex: 1 1 auto;
158
+ width: 1px;
159
+ margin: 0 auto;
160
+ background-color: var(--wpds-color-stroke-surface-neutral);
161
+ }
162
+
163
+ &::before {
164
+ content: "";
165
+ flex: 0 0 auto;
166
+ width: 1px;
167
+ margin: 0 auto;
168
+ background-color: var(--wpds-color-stroke-surface-neutral);
169
+ }
170
+ }
171
+
172
+ // First and last item timeline lines
173
+ .dataviews-view-picker-activity__item:first-child {
174
+ .dataviews-view-picker-activity__item-type {
175
+ &::before {
176
+ visibility: hidden;
177
+ }
178
+ }
179
+ }
180
+
181
+ .dataviews-view-picker-activity-group:last-of-type > .dataviews-view-picker-activity__item:last-of-type,
182
+ & > .dataviews-view-picker-activity__item:last-child {
183
+ .dataviews-view-picker-activity__item-type {
184
+ &::after {
185
+ background: linear-gradient(to bottom, var(--wpds-color-stroke-surface-neutral) 0%, color-mix(in srgb, var(--wpds-color-stroke-surface-neutral) 20%, transparent) 60%, transparent 100%);
186
+ }
187
+ }
188
+ }
189
+
190
+ .dataviews-view-picker-activity-group__header {
191
+ font-size: var(--wpds-typography-font-size-lg);
192
+ font-weight: var(--wpds-typography-font-weight-medium);
193
+ color: var(--wpds-color-fg-content-neutral-weak);
194
+ margin: 0 0 var(--wpds-dimension-gap-sm) 0;
195
+ padding: 0;
196
+ padding-inline-start: var(--wpds-dimension-padding-2xl);
197
+ }
198
+
199
+ // Bullet/icon styling
200
+ .dataviews-view-picker-activity__item-type-icon {
201
+ overflow: hidden;
202
+ flex-shrink: 0;
203
+ // Transparent so the row tint shows through the corners around the round media.
204
+ background-color: transparent;
205
+
206
+ img,
207
+ svg,
208
+ .dataviews-view-picker-activity__item-bullet {
209
+ display: block;
210
+ width: 100%;
211
+ height: 100%;
212
+ margin: 0 auto;
213
+ object-fit: cover;
214
+ border-radius: 50%;
215
+ box-sizing: border-box;
216
+ box-shadow: inset 0 0 0 var(--wpds-border-width-xs) var(--wpds-color-stroke-surface-neutral);
217
+ }
218
+
219
+ svg {
220
+ padding: var(--wpds-dimension-padding-xs);
221
+ }
222
+
223
+ .dataviews-view-picker-activity__item-bullet {
224
+ background-color: var(--wpds-color-stroke-surface-neutral);
225
+ }
226
+ }
227
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import type { RefObject } from 'react';
4
+ import type { MutableRefObject } from 'react';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -30,16 +30,16 @@ const isScrolledToEnd = ( element: Element ) => {
30
30
  *
31
31
  * See https://github.com/Automattic/wp-calypso/pull/103005#discussion_r2077567912.
32
32
  *
33
- * @param params The parameters for the hook.
34
- * @param params.scrollContainerRef The ref to the scroll container element.
35
- * @param [params.enabledHorizontal=false] Whether to track horizontal scroll end.
36
- * @return The scroll state.
33
+ * @param {Object} params The parameters for the hook.
34
+ * @param {MutableRefObject<HTMLDivElement | null>} params.scrollContainerRef The ref to the scroll container element.
35
+ * @param {boolean} [params.enabledHorizontal=false] Whether to track horizontal scroll end.
36
+ * @return {{ isHorizontalScrollEnd: boolean, isVerticallyScrolled: boolean }} The scroll state.
37
37
  */
38
38
  export function useScrollState( {
39
39
  scrollContainerRef,
40
40
  enabledHorizontal = false,
41
41
  }: {
42
- scrollContainerRef: RefObject< HTMLDivElement | null >;
42
+ scrollContainerRef: React.MutableRefObject< HTMLDivElement | null >;
43
43
  enabledHorizontal?: boolean;
44
44
  } ): { isHorizontalScrollEnd: boolean; isVerticallyScrolled: boolean } {
45
45
  const [ isHorizontalScrollEnd, setIsHorizontalScrollEnd ] =
@@ -86,9 +86,7 @@ export function ItemClickWrapper< Item >( {
86
86
  className: `${ className } ${ className }--clickable`,
87
87
  ...extraProps,
88
88
  children,
89
- } ) as ReactElement<
90
- Pick< React.DOMAttributes< Element >, 'onClick' | 'onKeyDown' >
91
- >;
89
+ } );
92
90
 
93
91
  // Clone the element and enhance onClick to stop propagation
94
92
  return cloneElement( renderedElement, {
@@ -85,6 +85,7 @@ export function ViewTypeMenu() {
85
85
  case 'table':
86
86
  case 'pickerGrid':
87
87
  case 'pickerTable':
88
+ case 'pickerActivity':
88
89
  case 'activity':
89
90
  const viewWithoutLayout = { ...view };
90
91
  if ( 'layout' in viewWithoutLayout ) {
package/src/constants.ts CHANGED
@@ -54,5 +54,6 @@ export const LAYOUT_ACTIVITY = 'activity';
54
54
  // Picker view layouts.
55
55
  export const LAYOUT_PICKER_GRID = 'pickerGrid';
56
56
  export const LAYOUT_PICKER_TABLE = 'pickerTable';
57
+ export const LAYOUT_PICKER_ACTIVITY = 'pickerActivity';
57
58
 
58
59
  export const DAYS_OF_WEEK: DayNumber[] = [ 0, 1, 2, 3, 4, 5, 6 ];
@@ -18,7 +18,7 @@ const meta: Meta< typeof DataForm > = {
18
18
  parameters: {
19
19
  controls: { disable: true },
20
20
  },
21
- tags: [ '!dev' /* Hide individual story pages from sidebar */ ],
21
+ tags: [ '!dev' /* Hide individual story pages from sidebar */, 'manifest' ],
22
22
  };
23
23
  export default meta;
24
24
 
@@ -13,6 +13,7 @@ import ValidationComponent from './validation';
13
13
  import VisibilityComponent from './visibility';
14
14
 
15
15
  const meta = {
16
+ tags: [ 'manifest' ],
16
17
  title: 'DataViews/DataForm',
17
18
  component: DataForm,
18
19
  };
@@ -21,6 +21,7 @@ import EmptyComponent from './empty';
21
21
  import './style.css';
22
22
 
23
23
  const meta = {
24
+ tags: [ 'manifest' ],
24
25
  title: 'DataViews/DataViews',
25
26
  component: DataViews,
26
27
  args: {
@@ -20,6 +20,7 @@ import type { ActionButton, View } from '../../types';
20
20
  import { data, fields, type SpaceObject } from './fixtures';
21
21
 
22
22
  const meta = {
23
+ tags: [ 'manifest' ],
23
24
  title: 'DataViews/DataViewsPicker',
24
25
  component: DataViewsPicker,
25
26
  } as Meta< typeof DataViewsPicker >;
@@ -186,6 +187,11 @@ const DataViewsPickerContent = ( {
186
187
  fields={ fields }
187
188
  onChangeView={ setView }
188
189
  config={ { perPageSizes } }
190
+ defaultLayouts={ {
191
+ pickerGrid: true,
192
+ pickerTable: true,
193
+ pickerActivity: true,
194
+ } }
189
195
  itemListLabel="Galactic Bodies"
190
196
  />
191
197
  </>
@@ -543,6 +543,11 @@ describe( 'DataViews Picker', () => {
543
543
  screen.getByRole( 'menuitemradio', { name: 'Table' } )
544
544
  ).toBeInTheDocument();
545
545
 
546
+ // The Activity layout is opt-in and must not appear by default.
547
+ expect(
548
+ screen.queryByRole( 'menuitemradio', { name: 'Activity' } )
549
+ ).not.toBeInTheDocument();
550
+
546
551
  // The grid layout is active by default.
547
552
  expect(
548
553
  screen.getByRole( 'menuitemradio', { name: 'Grid' } )
@@ -392,8 +392,8 @@ function handleCustomValidationAsync< Item >(
392
392
  }
393
393
 
394
394
  type PromiseHandler< Item > = {
395
- customCounterRef: React.RefObject< Record< string, number > >;
396
- elementsCounterRef: React.RefObject< Record< string, number > >;
395
+ customCounterRef: React.MutableRefObject< Record< string, number > >;
396
+ elementsCounterRef: React.MutableRefObject< Record< string, number > >;
397
397
  setFormValidity: React.Dispatch< React.SetStateAction< FormValidity > >;
398
398
  path: string[];
399
399
  item: Item;
package/src/style.scss CHANGED
@@ -13,6 +13,7 @@
13
13
  @use "./components/dataviews-layouts/picker-grid/style.scss" as *;
14
14
  @use "./components/dataviews-layouts/picker-table/style.scss" as *;
15
15
  @use "./components/dataviews-layouts/activity/style.scss" as *;
16
+ @use "./components/dataviews-layouts/picker-activity/style.scss" as *;
16
17
  @use "./components/dataviews-picker-footer/style.scss" as *;
17
18
 
18
19
  @use "./components/dataform-controls/style.scss" as *;
@@ -342,12 +342,24 @@ export interface ViewPickerTable extends ViewBase {
342
342
  };
343
343
  }
344
344
 
345
+ export interface ViewPickerActivity extends ViewBase {
346
+ type: 'pickerActivity';
347
+
348
+ layout?: {
349
+ /**
350
+ * The density of the view.
351
+ */
352
+ density?: Density;
353
+ };
354
+ }
355
+
345
356
  export type View =
346
357
  | ViewList
347
358
  | ViewGrid
348
359
  | ViewTable
349
360
  | ViewPickerGrid
350
361
  | ViewPickerTable
362
+ | ViewPickerActivity
351
363
  | ViewActivity;
352
364
 
353
365
  interface ActionBase< Item > {
@@ -516,6 +528,11 @@ export interface ViewPickerTableProps< Item >
516
528
  view: ViewPickerTable;
517
529
  }
518
530
 
531
+ export interface ViewPickerActivityProps< Item >
532
+ extends Omit< ViewPickerBaseProps< Item >, 'view' > {
533
+ view: ViewPickerActivity;
534
+ }
535
+
519
536
  export type ViewProps< Item > =
520
537
  | ViewTableProps< Item >
521
538
  | ViewGridProps< Item >
@@ -524,7 +541,8 @@ export type ViewProps< Item > =
524
541
 
525
542
  export type ViewPickerProps< Item > =
526
543
  | ViewPickerGridProps< Item >
527
- | ViewPickerTableProps< Item >;
544
+ | ViewPickerTableProps< Item >
545
+ | ViewPickerActivityProps< Item >;
528
546
 
529
547
  export interface SupportedLayouts {
530
548
  list?: Omit< ViewList, 'type' > | true;
@@ -533,6 +551,7 @@ export interface SupportedLayouts {
533
551
  activity?: Omit< ViewActivity, 'type' > | true;
534
552
  pickerGrid?: Omit< ViewPickerGrid, 'type' > | true;
535
553
  pickerTable?: Omit< ViewPickerTable, 'type' > | true;
554
+ pickerActivity?: Omit< ViewPickerActivity, 'type' > | true;
536
555
  }
537
556
 
538
557
  export interface NormalizedSupportedLayouts {
@@ -542,4 +561,5 @@ export interface NormalizedSupportedLayouts {
542
561
  activity?: Omit< ViewActivity, 'type' >;
543
562
  pickerGrid?: Omit< ViewPickerGrid, 'type' >;
544
563
  pickerTable?: Omit< ViewPickerTable, 'type' >;
564
+ pickerActivity?: Omit< ViewPickerActivity, 'type' >;
545
565
  }