Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add containerProps and itemProps to Virtualizer #435

Closed
AdamConleyDSI opened this issue Apr 26, 2024 · 1 comment
Closed

Add containerProps and itemProps to Virtualizer #435

AdamConleyDSI opened this issue Apr 26, 2024 · 1 comment

Comments

@AdamConleyDSI
Copy link

Is your feature request related to a problem? Please describe.
I have a standard table component that I'd like to use as the container for Virtualizer, something like <Virtualizer as={MyTableThing}>...</Virtualizer>. However, I need to be able to pass in the column definitions, as this container component would build the header row, and the children would be rows to be virtualized.

Describe the solution you'd like
I'd like a couple of new props added to Virtualizer:

containerProps - this would be an object which would be passed with/inside the CustomContainerComponentProps to the container component.
itemProps - something similar that would be passed to custom items (not really necessary for my use case, but could be useful)

along with the same additions to CustomContainerComponentProps and CustomItemComponentProps.

This would allow for something like:

// This component would be in a separate file...
export const MyTableThing = forwardRef<HTMLTableElement, CustomContainerComponentProps>(
  ({children, style, containerProps}, ref) => {
    return (
        <table ref={ref}>
          <thead>
            <tr>
              {containerProps.columns.map((c, i) => (
                <th key={i}>{c.name}</th>
              ))}
            </tr>
          </thead>
        <tbody>
          {children}
        </tbody>
      </table>
    );
  }
);

// And in another component, I'd use it like this:
<Virtualizer as={MyTableThing} 
    containerProps={{ columns: [{name: "col1", width: "100"},{name: "col2", width: 150}], headerHeight: 30}}
    item="tr">
    ...
</Virtualizer>

Describe alternatives you've considered
I'll admit that maybe I'm not a React expert, so I may be missing a really simple solution to this, but I don't think there are any alternatives besides not having a re-usable component for the table.

@inokawa
Copy link
Owner

inokawa commented Apr 28, 2024

Hi, you could do the same thing with React's context like this:

import { createContext, useContext } from 'react';

const ColumnContext = createContext([])
const MyTableThing = forwardRef<HTMLTableElement, CustomContainerComponentProps>(
  ({children, style }, ref) => {
    const columns = useContext(ColumnContext);
    return (
        <table ref={ref}>
          <thead>
            <tr>
              {columns.map((c, i) => (
                <th key={i}>{c.name}</th>
              ))}
            </tr>
          </thead>
        <tbody>
          {children}
        </tbody>
      </table>
    );
  }
);

const TableWithHeader = ({ columns, ...tableProps }: TableWithHeaderProps) => {
  return (
    <ColumnContext.Provider value={columns}>
      <Virtualizer as={MyTableThing} item="tr" {...tableProps} />
    </ColumnContext.Provider>
  );
};

For now I don't think I'd like to add the containerProps prop because it's substitutable with the way I mentioned. And I'm also not satisfied with the current table support in virtua, so I may add a new component or props in #312 for easier table virtualization.

@inokawa inokawa closed this as completed May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants