bvaughn / react-window

React components for efficiently rendering large lists and tabular data
https://react-window.now.sh/
MIT License
15.48k stars 778 forks source link

Row size is fixed #767

Open askanDev opened 3 weeks ago

askanDev commented 3 weeks ago

I am using nested Accordion from flowbite-react. i want to do lazy loading for large data but when i am using VariableSizeList the hight is fixed . and also row has more gap in-between. first row affecting the second row. the sub-data is from first row it overlaps with second row also

Screenshot 2024-06-14 121326

My Code:

` import { VariableSizeList } from 'react-window'; import { Accordion, Checkbox } from "flowbite-react"; import { useEffect, useState } from "react"; import { local_dashboard_filtered, local_dashboard_subcat, local_dashboard_titles } from "../../Redux/Action/localAction"; import { useDispatch, useSelector } from "react-redux";

const CustomAccordion = (props: any) => {
const { data, allowCategoryCheck } = props;

const dispatch = useDispatch()
const [selectedSubCat, setSelectedSubCat] = useState<any>([])
const [filteredObjects, setFilteredObjects] = useState<any>([])
const [selectedTitles, setSelectedTitles] = useState<any>([])

useEffect(() => {
    setSelectedTitles([])
}, [allowCategoryCheck])

useEffect(() => {
    const filteredData = (data || []).map((obj: any) => ({
        ...obj,
        subCategoryList: obj.subCategoryList.filter((subObj: any) =>
            selectedSubCat.some((item: any) => subObj.gtcmCpvDetails === item)
        )
    })).filter((obj: any) => obj.subCategoryList.length > 0);
    setFilteredObjects(filteredData);
}, [selectedSubCat]);

useEffect(() => {
    dispatch(local_dashboard_titles(selectedTitles))
    dispatch(local_dashboard_subcat(selectedSubCat))
    dispatch(local_dashboard_filtered(filteredObjects))
}, [selectedSubCat, filteredObjects, selectedTitles])

const handleTitleClick = (accord: any) => {
    const isSelected = selectedTitles.some((tit: any) => tit.gtsmSectorName === accord.gtsmSectorName);
    if (isSelected) {
        setSelectedTitles(selectedTitles.filter((t: any) => t.gtsmSectorName !== accord.gtsmSectorName));
    } else {
        if (selectedTitles.length < allowCategoryCheck) {
            setSelectedTitles([...selectedTitles, accord]);
        }
    }
};

const handleSubCategory = (sub: any) => {
    if (selectedSubCat.includes(sub)) {
        setSelectedSubCat(selectedSubCat.filter((item: any) => item !== sub));
    } else {
        setSelectedSubCat([...selectedSubCat, sub]);
    }
}

const Row = ({ index, style }: { index: number, style: React.CSSProperties }) => {
    const accord = data[index];
    const isSelected = selectedTitles.some((tit: any) => tit.gtsmSectorName === accord.gtsmSectorName);
    const isDisabled = !isSelected && selectedTitles.length >= allowCategoryCheck;

    return (
        <div style={style} key={index}>
            <Accordion className="accordion" collapseAll>
                <Accordion.Panel>
                    <Accordion.Title style={{ padding: "6px", backgroundColor: "white" }}>
                        <div
                            style={{
                                padding: "0px",
                                backgroundColor: "white",
                                display: "flex",
                                flexDirection: "row",
                                gap: "6px",
                                alignItems: "center",
                                fontFamily: "Segoe-Bold",
                                fontSize: "12px",
                            }}
                        >
                            <Checkbox
                                className="leftpanelCustomCheckbox"
                                checked={isSelected}
                                disabled={isDisabled}
                                onChange={() => handleTitleClick(accord)}
                            />
                            <div>{accord.gtsmSectorName}</div>
                        </div>
                    </Accordion.Title>
                    <Accordion.Content style={{ padding: "0px 0px 0px 12px", border: "none" }}>
                        <div
                            style={{
                                padding: "0px 6px 6px 6px",
                                backgroundColor: "white",
                                display: "flex",
                                flexDirection: "column",
                                gap: "6px",
                            }}
                        >
                            {(accord.subCategoryList || []).map((accordChild: any) => (
                                <span
                                    key={accordChild.gccTendCpvMstPk}
                                    style={{
                                        display: "flex",
                                        flexDirection: "row",
                                        alignItems: "center",
                                        gap: "6px",
                                        fontSize: "12px",
                                    }}
                                >
                                    <Checkbox
                                        className="leftpanelCustomCheckbox"
                                        checked={isSelected ? undefined : false}
                                        onChange={() => handleSubCategory(accordChild.gtcmCpvDetails)}
                                    />
                                    {" "}
                                    {accordChild.gtcmCpvDetails}
                                </span>
                            ))}
                        </div>
                    </Accordion.Content>
                </Accordion.Panel>
            </Accordion>
        </div>
    );
};

// Function to determine row height dynamically
const rowHeight = (index: number) => {
    // Return different heights based on your logic or data
    return index; // Adjust as needed
};

return (
    <VariableSizeList
        height={400} // Adjust the height as needed
        itemCount={data.length}
        itemSize={rowHeight} // Use the function to determine row height dynamically
        width={"100%"}
    >
        {Row}
    </VariableSizeList>
);

};

export default CustomAccordion; `