S
SolidJS3mo ago
J

Expose a Function Outside of Component

I'm working on improvements to @solid-primitives/virtual, namely support for dynamic item sizes and fixes to broken reactivity. I implemented a scrollToItem utility function that is now returned from createVirtualList. This works perfectly fine if you are just using the headless virtual list. However, there is a VirtualList component that abstracts away the HTML boilerplate required for createVirtualList to function. For convenience, I would like to expose the scrollToItem function for use outside of VirtualList. Problem is, I have yet to find an idiomatic way to accomplish this after searching around for a bit. Here's an extremely hacky solution I came up with that I'm not so proud of and would like to replace before I submit the PR for review: Internals:
type VirtualListProps<T extends readonly any[], U extends JSX.Element> = {
// ...
setScrollToItem: (scrollToItem: (itemIndex: number) => void) => void;
};

// Inside `VirtualList`
let scrollContainer!: HTMLDivElement; // Attached Ref
props.setScrollToItem((itemIndex: number) => scrollToItem(itemIndex, scrollContainer));
type VirtualListProps<T extends readonly any[], U extends JSX.Element> = {
// ...
setScrollToItem: (scrollToItem: (itemIndex: number) => void) => void;
};

// Inside `VirtualList`
let scrollContainer!: HTMLDivElement; // Attached Ref
props.setScrollToItem((itemIndex: number) => scrollToItem(itemIndex, scrollContainer));
In Use:
let scrollToItem!: (itemIndex: number) => void;
// ...
<VirtualList
// ...
setScrollToItem={fn => (scrollToItem = fn)}
// ...
>
{/* ... */}
</VirtualList>
let scrollToItem!: (itemIndex: number) => void;
// ...
<VirtualList
// ...
setScrollToItem={fn => (scrollToItem = fn)}
// ...
>
{/* ... */}
</VirtualList>
I would really appreciate if anyone could help me replace this with something idiomatic, thanks!
GitHub
virtual Improvements (Dynamic Item Sizes, Fix Broken Reactivity) ...
This adds support for dynamic item sizes in the virtual package. This is accomplished by adding | (row: T[number], index: number) =&amp;gt; number) to the rowHeight parameter, and type-checking for...
2 Replies
Madaxen86
Madaxen863mo ago
What about instead of exporting the component itself include it in the / make its own primitive, e.g.
funtion MyCompt() {
const [VirtualList,{scrollToItem,scrollToLastItem,scrollToFirstItem}] = createVirtualList();

return <>
<button onClick={()=>scrollToItem(5)}>To 5</button>
<VirtualList
{/* ... */ }
/>
</>
}
funtion MyCompt() {
const [VirtualList,{scrollToItem,scrollToLastItem,scrollToFirstItem}] = createVirtualList();

return <>
<button onClick={()=>scrollToItem(5)}>To 5</button>
<VirtualList
{/* ... */ }
/>
</>
}
thetarnav
thetarnav3mo ago
there is also this pattern
let virtual!: VirtualInstance
<Virtual ref={virtual} />
virtual.scroll()
let virtual!: VirtualInstance
<Virtual ref={virtual} />
virtual.scroll()

Did you find this page helpful?