@wordpress/dataviews 1.0.0 → 1.2.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 (153) hide show
  1. package/CHANGELOG.md +13 -5
  2. package/build/bulk-actions-toolbar.js +182 -0
  3. package/build/bulk-actions-toolbar.js.map +1 -0
  4. package/build/bulk-actions.js +8 -8
  5. package/build/bulk-actions.js.map +1 -1
  6. package/build/constants.js +1 -26
  7. package/build/constants.js.map +1 -1
  8. package/build/dataviews.js +13 -5
  9. package/build/dataviews.js.map +1 -1
  10. package/build/filter-and-sort-data-view.js +72 -65
  11. package/build/filter-and-sort-data-view.js.map +1 -1
  12. package/build/filter-summary.js +3 -3
  13. package/build/filter-summary.js.map +1 -1
  14. package/build/index.js +2 -2
  15. package/build/index.js.map +1 -1
  16. package/build/item-actions.js +41 -22
  17. package/build/item-actions.js.map +1 -1
  18. package/build/layouts.js +38 -0
  19. package/build/layouts.js.map +1 -0
  20. package/build/lock-unlock.js.map +1 -1
  21. package/build/normalize-fields.js +7 -2
  22. package/build/normalize-fields.js.map +1 -1
  23. package/build/pagination.js +13 -7
  24. package/build/pagination.js.map +1 -1
  25. package/build/single-selection-checkbox.js +4 -0
  26. package/build/single-selection-checkbox.js.map +1 -1
  27. package/build/types.js +6 -0
  28. package/build/types.js.map +1 -0
  29. package/build/view-actions.js +2 -1
  30. package/build/view-actions.js.map +1 -1
  31. package/build/view-grid.js +9 -10
  32. package/build/view-grid.js.map +1 -1
  33. package/build/view-list.js +134 -21
  34. package/build/view-list.js.map +1 -1
  35. package/build/view-table.js +9 -9
  36. package/build/view-table.js.map +1 -1
  37. package/build-module/bulk-actions-toolbar.js +175 -0
  38. package/build-module/bulk-actions-toolbar.js.map +1 -0
  39. package/build-module/bulk-actions.js +8 -8
  40. package/build-module/bulk-actions.js.map +1 -1
  41. package/build-module/constants.js +1 -25
  42. package/build-module/constants.js.map +1 -1
  43. package/build-module/dataviews.js +13 -5
  44. package/build-module/dataviews.js.map +1 -1
  45. package/build-module/filter-and-sort-data-view.js +72 -65
  46. package/build-module/filter-and-sort-data-view.js.map +1 -1
  47. package/build-module/filter-summary.js +3 -3
  48. package/build-module/filter-summary.js.map +1 -1
  49. package/build-module/index.js +1 -1
  50. package/build-module/index.js.map +1 -1
  51. package/build-module/item-actions.js +40 -24
  52. package/build-module/item-actions.js.map +1 -1
  53. package/build-module/layouts.js +30 -0
  54. package/build-module/layouts.js.map +1 -0
  55. package/build-module/lock-unlock.js.map +1 -1
  56. package/build-module/normalize-fields.js +7 -2
  57. package/build-module/normalize-fields.js.map +1 -1
  58. package/build-module/pagination.js +14 -7
  59. package/build-module/pagination.js.map +1 -1
  60. package/build-module/single-selection-checkbox.js +5 -0
  61. package/build-module/single-selection-checkbox.js.map +1 -1
  62. package/build-module/types.js +2 -0
  63. package/build-module/types.js.map +1 -0
  64. package/build-module/view-actions.js +2 -1
  65. package/build-module/view-actions.js.map +1 -1
  66. package/build-module/view-grid.js +9 -10
  67. package/build-module/view-grid.js.map +1 -1
  68. package/build-module/view-list.js +135 -23
  69. package/build-module/view-list.js.map +1 -1
  70. package/build-module/view-table.js +9 -9
  71. package/build-module/view-table.js.map +1 -1
  72. package/build-style/style-rtl.css +82 -44
  73. package/build-style/style.css +82 -44
  74. package/build-types/add-filter.d.ts +8 -0
  75. package/build-types/add-filter.d.ts.map +1 -0
  76. package/build-types/bulk-actions-toolbar.d.ts +8 -0
  77. package/build-types/bulk-actions-toolbar.d.ts.map +1 -0
  78. package/build-types/bulk-actions.d.ts +14 -0
  79. package/build-types/bulk-actions.d.ts.map +1 -0
  80. package/build-types/constants.d.ts +45 -0
  81. package/build-types/constants.d.ts.map +1 -0
  82. package/build-types/dataviews.d.ts +15 -0
  83. package/build-types/dataviews.d.ts.map +1 -0
  84. package/build-types/dropdown-menu-helper.d.ts +6 -0
  85. package/build-types/dropdown-menu-helper.d.ts.map +1 -0
  86. package/build-types/filter-and-sort-data-view.d.ts +18 -0
  87. package/build-types/filter-and-sort-data-view.d.ts.map +1 -0
  88. package/build-types/filter-summary.d.ts +6 -0
  89. package/build-types/filter-summary.d.ts.map +1 -0
  90. package/build-types/filters.d.ts +3 -0
  91. package/build-types/filters.d.ts.map +1 -0
  92. package/build-types/index.d.ts +4 -0
  93. package/build-types/index.d.ts.map +1 -0
  94. package/build-types/item-actions.d.ts +37 -0
  95. package/build-types/item-actions.d.ts.map +1 -0
  96. package/build-types/layouts.d.ts +20 -0
  97. package/build-types/layouts.d.ts.map +1 -0
  98. package/build-types/lock-unlock.d.ts +2 -0
  99. package/build-types/lock-unlock.d.ts.map +1 -0
  100. package/build-types/normalize-fields.d.ts +12 -0
  101. package/build-types/normalize-fields.d.ts.map +1 -0
  102. package/build-types/pagination.d.ts +16 -0
  103. package/build-types/pagination.d.ts.map +1 -0
  104. package/build-types/reset-filters.d.ts +6 -0
  105. package/build-types/reset-filters.d.ts.map +1 -0
  106. package/build-types/search-widget.d.ts +2 -0
  107. package/build-types/search-widget.d.ts.map +1 -0
  108. package/build-types/search.d.ts +3 -0
  109. package/build-types/search.d.ts.map +1 -0
  110. package/build-types/single-selection-checkbox.d.ts +17 -0
  111. package/build-types/single-selection-checkbox.d.ts.map +1 -0
  112. package/build-types/stories/fixtures.d.ts +114 -0
  113. package/build-types/stories/fixtures.d.ts.map +1 -0
  114. package/build-types/stories/index.story.d.ts +15 -0
  115. package/build-types/stories/index.story.d.ts.map +1 -0
  116. package/build-types/types.d.ts +254 -0
  117. package/build-types/types.d.ts.map +1 -0
  118. package/build-types/utils.d.ts +2 -0
  119. package/build-types/utils.d.ts.map +1 -0
  120. package/build-types/view-actions.d.ts +3 -0
  121. package/build-types/view-actions.d.ts.map +1 -0
  122. package/build-types/view-grid.d.ts +15 -0
  123. package/build-types/view-grid.d.ts.map +1 -0
  124. package/build-types/view-list.d.ts +16 -0
  125. package/build-types/view-list.d.ts.map +1 -0
  126. package/build-types/view-table.d.ts +14 -0
  127. package/build-types/view-table.d.ts.map +1 -0
  128. package/package.json +12 -12
  129. package/src/bulk-actions-toolbar.js +244 -0
  130. package/src/{bulk-actions.js → bulk-actions.tsx} +73 -17
  131. package/src/{constants.js → constants.ts} +1 -35
  132. package/src/dataviews.js +16 -4
  133. package/src/filter-and-sort-data-view.ts +169 -0
  134. package/src/filter-summary.js +3 -3
  135. package/src/index.js +1 -1
  136. package/src/{item-actions.js → item-actions.tsx} +112 -28
  137. package/src/layouts.js +39 -0
  138. package/src/normalize-fields.ts +25 -0
  139. package/src/{pagination.js → pagination.tsx} +28 -7
  140. package/src/{single-selection-checkbox.js → single-selection-checkbox.tsx} +17 -2
  141. package/src/stories/fixtures.js +0 -2
  142. package/src/style.scss +100 -44
  143. package/src/types.ts +314 -0
  144. package/src/view-actions.js +2 -1
  145. package/src/{view-grid.js → view-grid.tsx} +45 -16
  146. package/src/view-list.tsx +421 -0
  147. package/src/view-table.js +8 -8
  148. package/tsconfig.json +22 -0
  149. package/tsconfig.tsbuildinfo +1 -0
  150. package/src/filter-and-sort-data-view.js +0 -154
  151. package/src/normalize-fields.js +0 -17
  152. package/src/view-list.js +0 -207
  153. /package/src/{lock-unlock.js → lock-unlock.ts} +0 -0
@@ -1,154 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import removeAccents from 'remove-accents';
5
-
6
- /**
7
- * Internal dependencies
8
- */
9
- import {
10
- OPERATOR_IS,
11
- OPERATOR_IS_NOT,
12
- OPERATOR_IS_NONE,
13
- OPERATOR_IS_ANY,
14
- OPERATOR_IS_ALL,
15
- OPERATOR_IS_NOT_ALL,
16
- } from './constants';
17
- import { normalizeFields } from './normalize-fields';
18
-
19
- function normalizeSearchInput( input = '' ) {
20
- return removeAccents( input.trim().toLowerCase() );
21
- }
22
-
23
- const EMPTY_ARRAY = [];
24
-
25
- /**
26
- * Applies the filtering, sorting and pagination to the raw data based on the view configuration.
27
- *
28
- * @param {any[]} data Raw data.
29
- * @param {Object} view View config.
30
- * @param {Object[]} fields Fields config.
31
- *
32
- * @return {Object} { data: any[], paginationInfo: { totalItems: number, totalPages: number } }
33
- */
34
- export function filterSortAndPaginate( data, view, fields ) {
35
- if ( ! data ) {
36
- return {
37
- data: EMPTY_ARRAY,
38
- paginationInfo: { totalItems: 0, totalPages: 0 },
39
- };
40
- }
41
- const _fields = normalizeFields( fields );
42
- let filteredData = [ ...data ];
43
- // Handle global search.
44
- if ( view.search ) {
45
- const normalizedSearch = normalizeSearchInput( view.search );
46
- filteredData = filteredData.filter( ( item ) => {
47
- return _fields
48
- .filter( ( field ) => field.enableGlobalSearch )
49
- .map( ( field ) => {
50
- return normalizeSearchInput( field.getValue( { item } ) );
51
- } )
52
- .some( ( field ) => field.includes( normalizedSearch ) );
53
- } );
54
- }
55
-
56
- if ( view.filters.length > 0 ) {
57
- view.filters.forEach( ( filter ) => {
58
- const field = _fields.find(
59
- ( _field ) => _field.id === filter.field
60
- );
61
- if (
62
- filter.operator === OPERATOR_IS_ANY &&
63
- filter?.value?.length > 0
64
- ) {
65
- filteredData = filteredData.filter( ( item ) => {
66
- const fieldValue = field.getValue( { item } );
67
- if ( Array.isArray( fieldValue ) ) {
68
- return filter.value.some( ( filterValue ) =>
69
- fieldValue.includes( filterValue )
70
- );
71
- } else if ( typeof fieldValue === 'string' ) {
72
- return filter.value.includes( fieldValue );
73
- }
74
- return false;
75
- } );
76
- } else if (
77
- filter.operator === OPERATOR_IS_NONE &&
78
- filter?.value?.length > 0
79
- ) {
80
- filteredData = filteredData.filter( ( item ) => {
81
- const fieldValue = field.getValue( { item } );
82
- if ( Array.isArray( fieldValue ) ) {
83
- return ! filter.value.some( ( filterValue ) =>
84
- fieldValue.includes( filterValue )
85
- );
86
- } else if ( typeof fieldValue === 'string' ) {
87
- return ! filter.value.includes( fieldValue );
88
- }
89
- return false;
90
- } );
91
- } else if (
92
- filter.operator === OPERATOR_IS_ALL &&
93
- filter?.value?.length > 0
94
- ) {
95
- filteredData = filteredData.filter( ( item ) => {
96
- return filter.value.every( ( value ) => {
97
- return field.getValue( { item } ).includes( value );
98
- } );
99
- } );
100
- } else if (
101
- filter.operator === OPERATOR_IS_NOT_ALL &&
102
- filter?.value?.length > 0
103
- ) {
104
- filteredData = filteredData.filter( ( item ) => {
105
- return filter.value.every( ( value ) => {
106
- return ! field.getValue( { item } ).includes( value );
107
- } );
108
- } );
109
- } else if ( filter.operator === OPERATOR_IS ) {
110
- filteredData = filteredData.filter( ( item ) => {
111
- return filter.value === field.getValue( { item } );
112
- } );
113
- } else if ( filter.operator === OPERATOR_IS_NOT ) {
114
- filteredData = filteredData.filter( ( item ) => {
115
- return filter.value !== field.getValue( { item } );
116
- } );
117
- }
118
- } );
119
- }
120
-
121
- // Handle sorting.
122
- if ( view.sort ) {
123
- const fieldId = view.sort.field;
124
- const fieldToSort = _fields.find( ( field ) => {
125
- return field.id === fieldId;
126
- } );
127
- filteredData.sort( ( a, b ) => {
128
- const valueA = fieldToSort.getValue( { item: a } ) ?? '';
129
- const valueB = fieldToSort.getValue( { item: b } ) ?? '';
130
- return view.sort.direction === 'asc'
131
- ? valueA.localeCompare( valueB )
132
- : valueB.localeCompare( valueA );
133
- } );
134
- }
135
-
136
- // Handle pagination.
137
- const hasPagination = view.page && view.perPage;
138
- const start = hasPagination ? ( view.page - 1 ) * view.perPage : 0;
139
- const totalItems = filteredData?.length || 0;
140
- const totalPages = hasPagination
141
- ? Math.ceil( totalItems / view.perPage )
142
- : 1;
143
- filteredData = hasPagination
144
- ? filteredData?.slice( start, start + view.perPage )
145
- : filteredData;
146
-
147
- return {
148
- data: filteredData,
149
- paginationInfo: {
150
- totalItems,
151
- totalPages,
152
- },
153
- };
154
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Apply default values and normalize the fields config.
3
- *
4
- * @param {Object[]} fields Raw Fields.
5
- * @return {Object[]} Normalized fields.
6
- */
7
- export function normalizeFields( fields ) {
8
- return fields.map( ( field ) => {
9
- const getValue = field.getValue || ( ( { item } ) => item[ field.id ] );
10
-
11
- return {
12
- ...field,
13
- getValue,
14
- render: field.render || getValue,
15
- };
16
- } );
17
- }
package/src/view-list.js DELETED
@@ -1,207 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import classNames from 'classnames';
5
-
6
- /**
7
- * WordPress dependencies
8
- */
9
- import { useInstanceId } from '@wordpress/compose';
10
- import {
11
- __experimentalHStack as HStack,
12
- __experimentalVStack as VStack,
13
- privateApis as componentsPrivateApis,
14
- Spinner,
15
- VisuallyHidden,
16
- } from '@wordpress/components';
17
- import { useCallback, useEffect, useRef } from '@wordpress/element';
18
- import { __ } from '@wordpress/i18n';
19
-
20
- /**
21
- * Internal dependencies
22
- */
23
- import { unlock } from './lock-unlock';
24
-
25
- const {
26
- useCompositeStoreV2: useCompositeStore,
27
- CompositeV2: Composite,
28
- CompositeItemV2: CompositeItem,
29
- CompositeRowV2: CompositeRow,
30
- } = unlock( componentsPrivateApis );
31
-
32
- function ListItem( {
33
- id,
34
- item,
35
- isSelected,
36
- onSelect,
37
- mediaField,
38
- primaryField,
39
- visibleFields,
40
- } ) {
41
- const itemRef = useRef( null );
42
- const labelId = `${ id }-label`;
43
- const descriptionId = `${ id }-description`;
44
-
45
- useEffect( () => {
46
- if ( isSelected ) {
47
- itemRef.current?.scrollIntoView( {
48
- behavior: 'auto',
49
- block: 'nearest',
50
- inline: 'nearest',
51
- } );
52
- }
53
- }, [ isSelected ] );
54
-
55
- return (
56
- <CompositeRow
57
- ref={ itemRef }
58
- render={ <li /> }
59
- role="row"
60
- className={ classNames( {
61
- 'is-selected': isSelected,
62
- } ) }
63
- >
64
- <HStack className="dataviews-view-list__item-wrapper">
65
- <div role="gridcell">
66
- <CompositeItem
67
- render={ <div /> }
68
- role="button"
69
- id={ id }
70
- aria-pressed={ isSelected }
71
- aria-labelledby={ labelId }
72
- aria-describedby={ descriptionId }
73
- className="dataviews-view-list__item"
74
- onClick={ () => onSelect( item ) }
75
- >
76
- <HStack
77
- spacing={ 3 }
78
- justify="start"
79
- alignment="flex-start"
80
- >
81
- <div className="dataviews-view-list__media-wrapper">
82
- { mediaField?.render( { item } ) || (
83
- <div className="dataviews-view-list__media-placeholder"></div>
84
- ) }
85
- </div>
86
- <VStack spacing={ 1 }>
87
- <span
88
- className="dataviews-view-list__primary-field"
89
- id={ labelId }
90
- >
91
- { primaryField?.render( { item } ) }
92
- </span>
93
- <div
94
- className="dataviews-view-list__fields"
95
- id={ descriptionId }
96
- >
97
- { visibleFields.map( ( field ) => (
98
- <div
99
- key={ field.id }
100
- className="dataviews-view-list__field"
101
- >
102
- <VisuallyHidden
103
- as="span"
104
- className="dataviews-view-list__field-label"
105
- >
106
- { field.header }
107
- </VisuallyHidden>
108
- <span className="dataviews-view-list__field-value">
109
- { field.render( { item } ) }
110
- </span>
111
- </div>
112
- ) ) }
113
- </div>
114
- </VStack>
115
- </HStack>
116
- </CompositeItem>
117
- </div>
118
- </HStack>
119
- </CompositeRow>
120
- );
121
- }
122
-
123
- export default function ViewList( {
124
- view,
125
- fields,
126
- data,
127
- isLoading,
128
- getItemId,
129
- onSelectionChange,
130
- selection,
131
- id: preferredId,
132
- } ) {
133
- const baseId = useInstanceId( ViewList, 'view-list', preferredId );
134
- const selectedItem = data?.findLast( ( item ) =>
135
- selection.includes( item.id )
136
- );
137
-
138
- const mediaField = fields.find(
139
- ( field ) => field.id === view.layout.mediaField
140
- );
141
- const primaryField = fields.find(
142
- ( field ) => field.id === view.layout.primaryField
143
- );
144
- const visibleFields = fields.filter(
145
- ( field ) =>
146
- ! view.hiddenFields.includes( field.id ) &&
147
- ! [ view.layout.primaryField, view.layout.mediaField ].includes(
148
- field.id
149
- )
150
- );
151
-
152
- const onSelect = useCallback(
153
- ( item ) => onSelectionChange( [ item ] ),
154
- [ onSelectionChange ]
155
- );
156
-
157
- const getItemDomId = useCallback(
158
- ( item ) => ( item ? `${ baseId }-${ getItemId( item ) }` : undefined ),
159
- [ baseId, getItemId ]
160
- );
161
-
162
- const store = useCompositeStore( {
163
- defaultActiveId: getItemDomId( selectedItem ),
164
- } );
165
-
166
- const hasData = data?.length;
167
- if ( ! hasData ) {
168
- return (
169
- <div
170
- className={ classNames( {
171
- 'dataviews-loading': isLoading,
172
- 'dataviews-no-results': ! hasData && ! isLoading,
173
- } ) }
174
- >
175
- { ! hasData && (
176
- <p>{ isLoading ? <Spinner /> : __( 'No results' ) }</p>
177
- ) }
178
- </div>
179
- );
180
- }
181
-
182
- return (
183
- <Composite
184
- id={ baseId }
185
- render={ <ul /> }
186
- className="dataviews-view-list"
187
- role="grid"
188
- store={ store }
189
- >
190
- { data.map( ( item ) => {
191
- const id = getItemDomId( item );
192
- return (
193
- <ListItem
194
- key={ id }
195
- id={ id }
196
- item={ item }
197
- isSelected={ item === selectedItem }
198
- onSelect={ onSelect }
199
- mediaField={ mediaField }
200
- primaryField={ primaryField }
201
- visibleFields={ visibleFields }
202
- />
203
- );
204
- } ) }
205
- </Composite>
206
- );
207
- }
File without changes