Reputation: 1356
I am using React Virtuoso to create a virtual list. By default, React Virtuoso renders its list as a <div>
with <div>
elements. I would like to instead render a <ul>
with <li>
elements and add some styling like so:
const Item = React.forwardRef<HTMLLIElement, { children: React.ReactNode }>(
(props, ref) => {
return (
<li className="border-r border-neutral-20" {...props} ref={ref}>
{props.children}
</li>
);
}
);
const List = React.forwardRef<HTMLUListElement, { children: React.ReactNode }>(
(props, ref) => {
return (
<ul className="list-none divide-y divide-neutral-20" {...props} ref={ref}>
{props.children}
</ul>
);
}
);
const MyListComponent: React.FC = () => {
return (
<Virtuoso
...
components={{ List, Item }}
itemContent={(index: number) => {
...
It works but I am getting a TypeScript error saying that List and Item is of the wrong types. In the examples on their site they are using styled elements from emotion but I have no clue what types these have.
Does anyone know how to do this properly?
Here is the type-error if it is of any use:
Type 'ForwardRefExoticComponent<{ children: ReactNode; } & RefAttributes<HTMLUListElement>>' is not assignable to type 'ComponentType<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }> | undefined'.
Type 'ForwardRefExoticComponent<{ children: ReactNode; } & RefAttributes<HTMLUListElement>>' is not assignable to type 'FunctionComponent<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }>'.
Types of property 'propTypes' are incompatible.
Type 'WeakValidationMap<{ children: ReactNode; } & RefAttributes<HTMLUListElement>> | undefined' is not assignable to type 'WeakValidationMap<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }> | undefined'.
Type 'WeakValidationMap<{ children: ReactNode; } & RefAttributes<HTMLUListElement>>' is not assignable to type 'WeakValidationMap<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }>'.
Types of property 'ref' are incompatible.
Type 'Validator<Ref<HTMLUListElement> | undefined> | undefined' is not assignable to type 'Validator<((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined> | undefined'.
Type 'Validator<Ref<HTMLUListElement> | undefined>' is not assignable to type 'Validator<((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined>'.
Type 'Ref<HTMLUListElement> | undefined' is not assignable to type '((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
Type '(instance: HTMLUListElement | null) => void' is not assignable to type '((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
Type '(instance: HTMLUListElement | null) => void' is not assignable to type '(instance: HTMLDivElement | null) => void'.
Types of parameters 'instance' and 'instance' are incompatible.
Type 'HTMLDivElement | null' is not assignable to type 'HTMLUListElement | null'.
Type 'HTMLDivElement' is missing the following properties from type 'HTMLUListElement': compact, typets(2322)
Upvotes: 3
Views: 2245
Reputation: 1356
I was unable to ge the List
element to accept a HTMLUListElement as ref-type so I went for regular divs instead. Item
worked with HTMLLiElement though which was nice.
So my solution ended up like this:
const Item = React.forwardRef<
HTMLDivElement,
ItemProps & { context?: Context<unknown> }
>((props, ref) => {
return (
<div className="border-r border-neutral-20" {...props} ref={ref}>
{props.children}
</div>
);
});
const List = React.forwardRef<
HTMLDivElement,
ListProps & { context?: Context<unknown> }
>((props, ref) => {
return (
<div className="divide-y divide-neutral-20" {...props} ref={ref}>
{props.children}
</div>
);
});
Upvotes: 3