From 6b462b9a29ab25dced1133f2d1384ba875805c40 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 30 Apr 2024 14:25:13 +0100 Subject: [PATCH 1/4] DataViews: Type the ViewList component --- .../src/{lock-unlock.js => lock-unlock.ts} | 0 packages/dataviews/src/types.ts | 28 +++++++++- .../src/{view-list.js => view-list.tsx} | 55 ++++++++++++++----- 3 files changed, 67 insertions(+), 16 deletions(-) rename packages/dataviews/src/{lock-unlock.js => lock-unlock.ts} (100%) rename packages/dataviews/src/{view-list.js => view-list.tsx} (83%) diff --git a/packages/dataviews/src/lock-unlock.js b/packages/dataviews/src/lock-unlock.ts similarity index 100% rename from packages/dataviews/src/lock-unlock.js rename to packages/dataviews/src/lock-unlock.ts diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index ef6b0773a2138..8244992a1f5f8 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -3,8 +3,6 @@ */ import type { ReactNode } from 'react'; -type Item = Record< string, any >; - interface Option { value: any; label: string; @@ -17,6 +15,8 @@ interface filterByConfig { type Operator = 'is' | 'isNot' | 'isAny' | 'isNone' | 'isAll' | 'isNotAll'; +export type Item = Record< string, any >; + export interface Field { /** * The unique identifier of the field. @@ -101,7 +101,7 @@ export interface Filter { value: any; } -export interface View { +interface ViewBase { /** * The layout of the view. */ @@ -141,4 +141,26 @@ export interface View { * The number of items per page */ perPage?: number; + + /** + * The hidden fields. + */ + hiddenFields: string[]; +} +export interface ViewList extends ViewBase { + type: 'list'; + + layout: { + /** + * The field to use as the primary field. + */ + primaryField: string; + + /** + * The field to use as the media field. + */ + mediaField: string; + }; } + +export type View = ViewList | ViewBase; diff --git a/packages/dataviews/src/view-list.js b/packages/dataviews/src/view-list.tsx similarity index 83% rename from packages/dataviews/src/view-list.js rename to packages/dataviews/src/view-list.tsx index 14799a9b94167..3241ddf40641c 100644 --- a/packages/dataviews/src/view-list.js +++ b/packages/dataviews/src/view-list.tsx @@ -21,6 +21,33 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import { unlock } from './lock-unlock'; +import type { + Data, + Item, + NormalizedField, + ViewList as ViewListType, +} from './types'; + +type ListViewProps = { + view: ViewListType; + fields: NormalizedField[]; + data: Data; + isLoading: boolean; + getItemId: ( item: Item ) => string; + onSelectionChange: ( selection: Item[] ) => void; + selection: Item[]; + id: string; +}; + +type ListViewItemProps = { + id: string; + item: Item; + isSelected: boolean; + onSelect: ( item: Item ) => void; + mediaField?: NormalizedField; + primaryField?: NormalizedField; + visibleFields: NormalizedField[]; +}; const { useCompositeStoreV2: useCompositeStore, @@ -37,13 +64,14 @@ function ListItem( { mediaField, primaryField, visibleFields, -} ) { +}: ListViewItemProps ) { const itemRef = useRef( null ); const labelId = `${ id }-label`; const descriptionId = `${ id }-description`; useEffect( () => { if ( isSelected ) { + // @ts-ignore itemRef.current?.scrollIntoView( { behavior: 'auto', block: 'nearest', @@ -120,16 +148,17 @@ function ListItem( { ); } -export default function ViewList( { - view, - fields, - data, - isLoading, - getItemId, - onSelectionChange, - selection, - id: preferredId, -} ) { +export default function ViewList( props: ListViewProps ) { + const { + view, + fields, + data, + isLoading, + getItemId, + onSelectionChange, + selection, + id: preferredId, + } = props; const baseId = useInstanceId( ViewList, 'view-list', preferredId ); const selectedItem = data?.findLast( ( item ) => selection.includes( item.id ) @@ -150,12 +179,12 @@ export default function ViewList( { ); const onSelect = useCallback( - ( item ) => onSelectionChange( [ item ] ), + ( item: Item ) => onSelectionChange( [ item ] ), [ onSelectionChange ] ); const getItemDomId = useCallback( - ( item ) => ( item ? `${ baseId }-${ getItemId( item ) }` : undefined ), + ( item?: Item ) => ( item ? `${ baseId }-${ getItemId( item ) }` : '' ), [ baseId, getItemId ] ); From bbe98798e04a470a0b7c37d368746fdc68dea9c5 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 1 May 2024 10:57:30 +0100 Subject: [PATCH 2/4] Update tsconfig --- packages/dataviews/tsconfig.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/dataviews/tsconfig.json b/packages/dataviews/tsconfig.json index 119035ffe7be3..60122ee152c80 100644 --- a/packages/dataviews/tsconfig.json +++ b/packages/dataviews/tsconfig.json @@ -3,7 +3,9 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "rootDir": "src", - "declarationDir": "build-types" + "declarationDir": "build-types", + "skipLibCheck": true, + "checkJs": false }, "references": [ { "path": "../a11y" }, @@ -16,5 +18,5 @@ { "path": "../primitives" }, { "path": "../private-apis" } ], - "include": [ "src/**/*.ts", "src/**/*.tsx" ] + "include": [ "src" ] } From 538017b5e688d9cb43ccb6288ffaeb64b3744dbc Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 6 May 2024 10:09:12 +0100 Subject: [PATCH 3/4] Avoid ts-ignore --- packages/dataviews/src/view-list.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/dataviews/src/view-list.tsx b/packages/dataviews/src/view-list.tsx index 3241ddf40641c..fb2955728944f 100644 --- a/packages/dataviews/src/view-list.tsx +++ b/packages/dataviews/src/view-list.tsx @@ -65,13 +65,12 @@ function ListItem( { primaryField, visibleFields, }: ListViewItemProps ) { - const itemRef = useRef( null ); + const itemRef = useRef< HTMLElement >( null ); const labelId = `${ id }-label`; const descriptionId = `${ id }-description`; useEffect( () => { if ( isSelected ) { - // @ts-ignore itemRef.current?.scrollIntoView( { behavior: 'auto', block: 'nearest', From e9f311e24f225a2cdf88661781a0a09545bb6278 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 6 May 2024 10:12:15 +0100 Subject: [PATCH 4/4] Prefer interface over type --- packages/dataviews/src/view-list.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dataviews/src/view-list.tsx b/packages/dataviews/src/view-list.tsx index fb2955728944f..d88f11de59eed 100644 --- a/packages/dataviews/src/view-list.tsx +++ b/packages/dataviews/src/view-list.tsx @@ -28,7 +28,7 @@ import type { ViewList as ViewListType, } from './types'; -type ListViewProps = { +interface ListViewProps { view: ViewListType; fields: NormalizedField[]; data: Data; @@ -37,9 +37,9 @@ type ListViewProps = { onSelectionChange: ( selection: Item[] ) => void; selection: Item[]; id: string; -}; +} -type ListViewItemProps = { +interface ListViewItemProps { id: string; item: Item; isSelected: boolean; @@ -47,7 +47,7 @@ type ListViewItemProps = { mediaField?: NormalizedField; primaryField?: NormalizedField; visibleFields: NormalizedField[]; -}; +} const { useCompositeStoreV2: useCompositeStore,