@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
@@ -0,0 +1,421 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+ // Import CompositeStore type, which is not exported from @wordpress/components.
6
+ // eslint-disable-next-line no-restricted-imports
7
+ import type { CompositeStore } from '@ariakit/react';
8
+
9
+ /**
10
+ * WordPress dependencies
11
+ */
12
+ import { useInstanceId } from '@wordpress/compose';
13
+ import {
14
+ __experimentalHStack as HStack,
15
+ __experimentalVStack as VStack,
16
+ Button,
17
+ privateApis as componentsPrivateApis,
18
+ Spinner,
19
+ VisuallyHidden,
20
+ } from '@wordpress/components';
21
+ import {
22
+ useCallback,
23
+ useEffect,
24
+ useMemo,
25
+ useRef,
26
+ useState,
27
+ } from '@wordpress/element';
28
+ import { __ } from '@wordpress/i18n';
29
+ import { moreVertical } from '@wordpress/icons';
30
+
31
+ /**
32
+ * Internal dependencies
33
+ */
34
+ import { unlock } from './lock-unlock';
35
+ import type {
36
+ Action,
37
+ AnyItem,
38
+ NormalizedField,
39
+ ViewList as ViewListType,
40
+ } from './types';
41
+
42
+ import { ActionsDropdownMenuGroup, ActionModal } from './item-actions';
43
+
44
+ interface ListViewProps< Item extends AnyItem > {
45
+ actions: Action< Item >[];
46
+ data: Item[];
47
+ fields: NormalizedField< Item >[];
48
+ getItemId: ( item: Item ) => string;
49
+ id: string;
50
+ isLoading: boolean;
51
+ onSelectionChange: ( selection: Item[] ) => void;
52
+ selection: string[];
53
+ view: ViewListType;
54
+ }
55
+
56
+ interface ListViewItemProps< Item extends AnyItem > {
57
+ actions: Action< Item >[];
58
+ id?: string;
59
+ isSelected: boolean;
60
+ item: Item;
61
+ mediaField?: NormalizedField< Item >;
62
+ onSelect: ( item: Item ) => void;
63
+ primaryField?: NormalizedField< Item >;
64
+ store: CompositeStore;
65
+ visibleFields: NormalizedField< Item >[];
66
+ }
67
+
68
+ const {
69
+ useCompositeStoreV2: useCompositeStore,
70
+ CompositeV2: Composite,
71
+ CompositeItemV2: CompositeItem,
72
+ CompositeRowV2: CompositeRow,
73
+ DropdownMenuV2: DropdownMenu,
74
+ } = unlock( componentsPrivateApis );
75
+
76
+ function ListItem< Item extends AnyItem >( {
77
+ actions,
78
+ id,
79
+ isSelected,
80
+ item,
81
+ mediaField,
82
+ onSelect,
83
+ primaryField,
84
+ store,
85
+ visibleFields,
86
+ }: ListViewItemProps< Item > ) {
87
+ const itemRef = useRef< HTMLElement >( null );
88
+ const labelId = `${ id }-label`;
89
+ const descriptionId = `${ id }-description`;
90
+
91
+ const [ isHovered, setIsHovered ] = useState( false );
92
+ const handleMouseEnter = () => {
93
+ setIsHovered( true );
94
+ };
95
+ const handleMouseLeave = () => {
96
+ setIsHovered( false );
97
+ };
98
+
99
+ useEffect( () => {
100
+ if ( isSelected ) {
101
+ itemRef.current?.scrollIntoView( {
102
+ behavior: 'auto',
103
+ block: 'nearest',
104
+ inline: 'nearest',
105
+ } );
106
+ }
107
+ }, [ isSelected ] );
108
+
109
+ const { primaryAction, eligibleActions } = useMemo( () => {
110
+ // If an action is eligible for all items, doesn't need
111
+ // to provide the `isEligible` function.
112
+ const _eligibleActions = actions.filter(
113
+ ( action ) => ! action.isEligible || action.isEligible( item )
114
+ );
115
+ const _primaryActions = _eligibleActions.filter(
116
+ ( action ) => action.isPrimary && !! action.icon
117
+ );
118
+ return {
119
+ primaryAction: _primaryActions?.[ 0 ],
120
+ eligibleActions: _eligibleActions,
121
+ };
122
+ }, [ actions, item ] );
123
+
124
+ const [ isModalOpen, setIsModalOpen ] = useState( false );
125
+
126
+ return (
127
+ <CompositeRow
128
+ ref={ itemRef }
129
+ render={ <li /> }
130
+ role="row"
131
+ className={ clsx( {
132
+ 'is-selected': isSelected,
133
+ 'is-hovered': isHovered,
134
+ } ) }
135
+ onMouseEnter={ handleMouseEnter }
136
+ onMouseLeave={ handleMouseLeave }
137
+ >
138
+ <HStack
139
+ className="dataviews-view-list__item-wrapper"
140
+ alignment="top"
141
+ >
142
+ <div role="gridcell">
143
+ <CompositeItem
144
+ store={ store }
145
+ render={ <div /> }
146
+ role="button"
147
+ id={ id }
148
+ aria-pressed={ isSelected }
149
+ aria-labelledby={ labelId }
150
+ aria-describedby={ descriptionId }
151
+ className="dataviews-view-list__item"
152
+ onClick={ () => onSelect( item ) }
153
+ >
154
+ <HStack
155
+ spacing={ 3 }
156
+ justify="start"
157
+ alignment="flex-start"
158
+ >
159
+ <div className="dataviews-view-list__media-wrapper">
160
+ { mediaField?.render( { item } ) || (
161
+ <div className="dataviews-view-list__media-placeholder"></div>
162
+ ) }
163
+ </div>
164
+ <VStack spacing={ 1 }>
165
+ <span
166
+ className="dataviews-view-list__primary-field"
167
+ id={ labelId }
168
+ >
169
+ { primaryField?.render( { item } ) }
170
+ </span>
171
+ <div
172
+ className="dataviews-view-list__fields"
173
+ id={ descriptionId }
174
+ >
175
+ { visibleFields.map( ( field ) => (
176
+ <div
177
+ key={ field.id }
178
+ className="dataviews-view-list__field"
179
+ >
180
+ <VisuallyHidden
181
+ as="span"
182
+ className="dataviews-view-list__field-label"
183
+ >
184
+ { field.header }
185
+ </VisuallyHidden>
186
+ <span className="dataviews-view-list__field-value">
187
+ { field.render( { item } ) }
188
+ </span>
189
+ </div>
190
+ ) ) }
191
+ </div>
192
+ </VStack>
193
+ </HStack>
194
+ </CompositeItem>
195
+ </div>
196
+ { actions?.length > 0 && (
197
+ <HStack
198
+ spacing={ 1 }
199
+ justify="flex-end"
200
+ className="dataviews-view-list__item-actions"
201
+ style={ {
202
+ flexShrink: '0',
203
+ width: 'auto',
204
+ } }
205
+ >
206
+ { primaryAction && 'RenderModal' in primaryAction && (
207
+ <div role="gridcell">
208
+ <CompositeItem
209
+ store={ store }
210
+ render={
211
+ <Button
212
+ label={ primaryAction.label }
213
+ icon={ primaryAction.icon }
214
+ isDestructive={
215
+ primaryAction.isDestructive
216
+ }
217
+ size="compact"
218
+ onClick={ () =>
219
+ setIsModalOpen( true )
220
+ }
221
+ />
222
+ }
223
+ >
224
+ { isModalOpen && (
225
+ <ActionModal< Item >
226
+ action={ primaryAction }
227
+ items={ [ item ] }
228
+ closeModal={ () =>
229
+ setIsModalOpen( false )
230
+ }
231
+ />
232
+ ) }
233
+ </CompositeItem>
234
+ </div>
235
+ ) }
236
+ { primaryAction &&
237
+ ! ( 'RenderModal' in primaryAction ) && (
238
+ <div role="gridcell" key={ primaryAction.id }>
239
+ <CompositeItem
240
+ store={ store }
241
+ render={
242
+ <Button
243
+ label={ primaryAction.label }
244
+ icon={ primaryAction.icon }
245
+ isDestructive={
246
+ primaryAction.isDestructive
247
+ }
248
+ size="compact"
249
+ onClick={ () =>
250
+ primaryAction.callback( [
251
+ item,
252
+ ] )
253
+ }
254
+ />
255
+ }
256
+ />
257
+ </div>
258
+ ) }
259
+ <div role="gridcell">
260
+ <DropdownMenu
261
+ trigger={
262
+ <CompositeItem
263
+ store={ store }
264
+ render={
265
+ <Button
266
+ size="compact"
267
+ icon={ moreVertical }
268
+ label={ __( 'Actions' ) }
269
+ disabled={ ! actions.length }
270
+ onKeyDown={ ( event: {
271
+ key: string;
272
+ preventDefault: () => void;
273
+ } ) => {
274
+ if (
275
+ event.key ===
276
+ 'ArrowDown'
277
+ ) {
278
+ // Prevent the default behaviour (open dropdown menu) and go down.
279
+ event.preventDefault();
280
+ store.move(
281
+ store.down()
282
+ );
283
+ }
284
+ if (
285
+ event.key === 'ArrowUp'
286
+ ) {
287
+ // Prevent the default behavior (open dropdown menu) and go up.
288
+ event.preventDefault();
289
+ store.move(
290
+ store.up()
291
+ );
292
+ }
293
+ } }
294
+ />
295
+ }
296
+ />
297
+ }
298
+ placement="bottom-end"
299
+ >
300
+ <ActionsDropdownMenuGroup
301
+ actions={ eligibleActions }
302
+ item={ item }
303
+ />
304
+ </DropdownMenu>
305
+ </div>
306
+ </HStack>
307
+ ) }
308
+ </HStack>
309
+ </CompositeRow>
310
+ );
311
+ }
312
+
313
+ export default function ViewList< Item extends AnyItem >(
314
+ props: ListViewProps< Item >
315
+ ) {
316
+ const {
317
+ actions,
318
+ data,
319
+ fields,
320
+ getItemId,
321
+ isLoading,
322
+ onSelectionChange,
323
+ selection,
324
+ view,
325
+ } = props;
326
+ const baseId = useInstanceId( ViewList, 'view-list' );
327
+ const selectedItem = data?.findLast( ( item ) =>
328
+ selection.includes( item.id )
329
+ );
330
+
331
+ const mediaField = fields.find(
332
+ ( field ) => field.id === view.layout.mediaField
333
+ );
334
+ const primaryField = fields.find(
335
+ ( field ) => field.id === view.layout.primaryField
336
+ );
337
+ const visibleFields = fields.filter(
338
+ ( field ) =>
339
+ ! view.hiddenFields.includes( field.id ) &&
340
+ ! [ view.layout.primaryField, view.layout.mediaField ].includes(
341
+ field.id
342
+ )
343
+ );
344
+
345
+ const onSelect = useCallback(
346
+ ( item: Item ) => onSelectionChange( [ item ] ),
347
+ [ onSelectionChange ]
348
+ );
349
+
350
+ const getItemDomId = useCallback(
351
+ ( item?: Item ) =>
352
+ item ? `${ baseId }-${ getItemId( item ) }` : undefined,
353
+ [ baseId, getItemId ]
354
+ );
355
+
356
+ const store = useCompositeStore( {
357
+ defaultActiveId: getItemDomId( selectedItem ),
358
+ } );
359
+
360
+ // Manage focused item, when the active one is removed from the list.
361
+ const isActiveIdInList = store.useState(
362
+ ( state: { items: any[]; activeId: any } ) =>
363
+ state.items.some(
364
+ ( item: { id: any } ) => item.id === state.activeId
365
+ )
366
+ );
367
+ useEffect( () => {
368
+ if ( ! isActiveIdInList ) {
369
+ // Prefer going down, except if there is no item below (last item), then go up (last item in list).
370
+ if ( store.down() ) {
371
+ store.move( store.down() );
372
+ } else if ( store.up() ) {
373
+ store.move( store.up() );
374
+ }
375
+ }
376
+ }, [ isActiveIdInList ] );
377
+
378
+ const hasData = data?.length;
379
+ if ( ! hasData ) {
380
+ return (
381
+ <div
382
+ className={ clsx( {
383
+ 'dataviews-loading': isLoading,
384
+ 'dataviews-no-results': ! hasData && ! isLoading,
385
+ } ) }
386
+ >
387
+ { ! hasData && (
388
+ <p>{ isLoading ? <Spinner /> : __( 'No results' ) }</p>
389
+ ) }
390
+ </div>
391
+ );
392
+ }
393
+
394
+ return (
395
+ <Composite
396
+ id={ baseId }
397
+ render={ <ul /> }
398
+ className="dataviews-view-list"
399
+ role="grid"
400
+ store={ store }
401
+ >
402
+ { data.map( ( item ) => {
403
+ const id = getItemDomId( item );
404
+ return (
405
+ <ListItem
406
+ key={ id }
407
+ id={ id }
408
+ actions={ actions }
409
+ item={ item }
410
+ isSelected={ item === selectedItem }
411
+ onSelect={ onSelect }
412
+ mediaField={ mediaField }
413
+ primaryField={ primaryField }
414
+ store={ store }
415
+ visibleFields={ visibleFields }
416
+ />
417
+ );
418
+ } ) }
419
+ </Composite>
420
+ );
421
+ }
package/src/view-table.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import classnames from 'classnames';
4
+ import clsx from 'clsx';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -257,7 +257,7 @@ function TableRow( {
257
257
 
258
258
  return (
259
259
  <tr
260
- className={ classnames( 'dataviews-view-table__row', {
260
+ className={ clsx( 'dataviews-view-table__row', {
261
261
  'is-selected': hasPossibleBulkAction && isSelected,
262
262
  'is-hovered': isHovered,
263
263
  'has-bulk-actions': hasPossibleBulkAction,
@@ -327,7 +327,7 @@ function TableRow( {
327
327
  } }
328
328
  >
329
329
  <div
330
- className={ classnames(
330
+ className={ clsx(
331
331
  'dataviews-view-table__cell-content-wrapper',
332
332
  {
333
333
  'dataviews-view-table__primary-field':
@@ -362,16 +362,16 @@ function TableRow( {
362
362
  }
363
363
 
364
364
  function ViewTable( {
365
- view,
366
- onChangeView,
367
- fields,
368
365
  actions,
369
366
  data,
367
+ fields,
370
368
  getItemId,
371
369
  isLoading = false,
372
- selection,
370
+ onChangeView,
373
371
  onSelectionChange,
372
+ selection,
374
373
  setOpenedFilter,
374
+ view,
375
375
  } ) {
376
376
  const headerMenuRefs = useRef( new Map() );
377
377
  const headerMenuToFocusRef = useRef();
@@ -516,7 +516,7 @@ function ViewTable( {
516
516
  </tbody>
517
517
  </table>
518
518
  <div
519
- className={ classnames( {
519
+ className={ clsx( {
520
520
  'dataviews-loading': isLoading,
521
521
  'dataviews-no-results': ! hasData && ! isLoading,
522
522
  } ) }
package/tsconfig.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig.json",
3
+ "extends": "../../tsconfig.base.json",
4
+ "compilerOptions": {
5
+ "rootDir": "src",
6
+ "declarationDir": "build-types",
7
+ "skipLibCheck": true,
8
+ "checkJs": false
9
+ },
10
+ "references": [
11
+ { "path": "../a11y" },
12
+ { "path": "../components" },
13
+ { "path": "../compose" },
14
+ { "path": "../element" },
15
+ { "path": "../i18n" },
16
+ { "path": "../icons" },
17
+ { "path": "../keycodes" },
18
+ { "path": "../primitives" },
19
+ { "path": "../private-apis" }
20
+ ],
21
+ "include": [ "src" ]
22
+ }