0

I'm working on a React project where I'm using the libraries react-window and react-window-infinite-loader to render a large list of project cards. Each project card contains an image, which is stored as a list of strings. I want to display these images in a element using

  • items within each project card.

    I have defined a component called Item to render each project card. Within Item, I'm trying to render the list of images using a and

  • structure. However, I'm facing some issues with the layout and positioning of the images within the project cards. Additionally, when the list is long, some list items go under the project cards.

    The issues I'm facing are:

    The images are not being rendered properly within the project cards. Some project names are overlapping with the images, and the buttons are not positioned correctly. When the list of projects is long, some list items go under the project cards, causing them to be partially hidden. I've already tried adjusting the CSS styles and using flexbox for layout, but the issues persist. I suspect there might be some conflict between the react-window and flexbox styles.

    Has anyone faced a similar issue while using react-window and react-window-infinite-loader to render a list with images as a list of strings? How can I properly render the images as a list within each project card and ensure the correct positioning of the buttons? Additionally, how can I prevent the list items from going under the project cards when the list is long?

    I would greatly appreciate any guidance or suggestions to resolve these issues.

    here is code-sandbox's sample example

    Here is React component code:

    {filteredProjects.length === 0 && isSearchMode ? (
            <div className="d-flex justify-content-center align-items-center">
              <h3>No projects found or project is still loading</h3>
            </div>
          ) : (
            <InfiniteLoader
              isItemLoaded={isItemLoaded}
              itemCount={itemCount}
              loadMoreItems={fetchNextProjects}
            >
              {({ onItemsRendered, ref }) => (
                <FixedSizeList
                  height={600}
                  itemCount={itemCount}
                  itemSize={150}
                  onItemsRendered={onItemsRendered}
                  ref={ref}
                  width={1400}
                >
                  {Item}
                </FixedSizeList>
              )}
            </InfiniteLoader>
          )}
    
    /// This is the Item:
      const Item = memo(
        ({ index, style }: { index: number; style: React.CSSProperties }) => {
          if (!isItemLoaded(index)) {
            return (
              <div style={style} className="loader">
                <Spinner animation="border" variant="primary" />
              </div>
            );
          }
    
          const project = projects[index];
          return (
            <div style={style} className="list-group-item">
              <div className="details">
                <div className="info">
                  <p className="number">{project.projectName + 1}</p>
                  <p className="project-name">
                    {highlightSearchTerm(project.projectName, searchTerm)}
                  </p>{" "}
                  {/* Added class for project name */}
                  <p>Use image:</p>
                  <ul>
                    {project.images.map((image: any, i: any) => (
                      <li key={i}>
                        <p className="image">
                          {highlightSearchTerm(image.image, searchTerm)}
                        </p>{" "}
                        {/* Added class for image */}
                      </li>
                    ))}
                  </ul>
                  <div className="buttons">
                    {" "}
                    {/* Added wrapper div for buttons */}
                    {visibleImages < project.images.length && (
                      <Button
                        variant="secondary"
                        onClick={handleLoadMore}
                        className="load-button"
                      >
                        Load More
                      </Button>
                    )}
                    <Button
                      variant="primary"
                      onClick={() => handleGitLabButtonClick(project.gitlabUrl)}
                      className="repo-button"
                    >
                      Repo
                    </Button>
                  </div>
                </div>
              </div>
            </div>
          );
        },
        areEqual
      );

    This is the css

    .title {
      display: flex;
      margin-bottom: 20px;
    }
    
    .title h1 {
      color: white;
      font-weight: normal;
      font-size: 24px;
      font-family: avenir next, avenir, sans-serif;
    }
    
    .list-container {
      border: 2px solid #bababa;
      border-radius: 10px;
    }
    
    .details {
      display: flex;
      justify-content: space-between;
      font-family: 'Nunito Sans', sans-serif;
      margin-top: 15px;
    }
    
    .info {
      display: flex;
      flex-direction: column;
    }
    
    .info p {
      margin: 0;
    }
    
    .list-group-item {
      border-bottom: 1px solid #fff;
      display: flex;
      margin-bottom: 10px;
      background-color: #b9e6b3;
      padding: 10px;
    }
    
    .list-group-item .number {
      color: #fff;
      font-size: 20px;
      font-weight: 700;
    }
    
    .list-group-item .avatar img {
      width: 60px;
      height: 60px;
      border-radius: 30px;
      border: 1px solid #f0f0f0;
    }
    
    .loader {
      margin-top: 40px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .project-name {
      margin-top: 10px;
      font-weight: bold;
    }
    
    .image {
      margin: 0;
    }
    
    .buttons {
      display: flex;
      justify-content: space-between; /* Adjust button alignment */
      align-items: center; /* Adjust button alignment */
      margin-top: 10px;
    }
    
    .load-button {
      margin-right: 0.5rem;
    }
  • Krisna
    • 2,854
    • 2
    • 24
    • 66

    1 Answers1

    1

    In your Item you need to put style within curly brackets when you're passing it to the style attribute. In the following manner:

    const Item = memo(
        ({ index, style }: { index: number; style: React.CSSProperties }) => {
          if (!isItemLoaded(index)) {
            return (
              <div style={{style}} className="loader">
                <Spinner animation="border" variant="primary" />
              </div>
            );
          } 
    

    Following is the edited codeSandbox: https://codesandbox.io/s/crazy-chihiro-c564m4 In any case, do let me know if the change worked if/when you make it. Good luck!

    Suryasish Paul
    • 399
    • 2
    • 12
    • Your solutions works! when I implement it, it does not work on my app I am sharing my real code. can you able to see whats the issue: https://codesandbox.io/s/boring-tom-dh4fx5?file=/index.js. – Krisna Jul 08 '23 at 13:22
    • That's great! But I checked the sandbox you just sent and it seems incomplete. You'll have to add the rest of the files and install the dependencies in the sandbox for the code to work. There seem to be values which are passed by other components or something. Can you resolve those issues and send the link again? – Suryasish Paul Jul 08 '23 at 13:32
    • I went outside. I will update it later . Thank you – Krisna Jul 08 '23 at 13:35
    • Here is real code: https://codesandbox.io/s/delicate-hill-lpcc64?file=/src/App.tsx – Krisna Jul 08 '23 at 16:07
    • 1
      Here is your edited sandbox: https://codesandbox.io/s/elastic-ben-kxqywc So, as it turns out in your actual code the solution I mentioned earlier wouldn’t work. I had to make changes in the height and itemSize props of . Let me know if that is what you needed after which I will edit my answer. – Suryasish Paul Jul 08 '23 at 16:35
    • Thank you...how can I make gap between cards. atleast 10px – Krisna Jul 08 '23 at 16:59
    • 1
      I believe this should work: https://codesandbox.io/s/elastic-ben-kxqywc?file=/src/styles.css Play around with the styles a little to get it perfect. Also, please let me know if it is what you needed, in which case, I shall update my answer. – Suryasish Paul Jul 08 '23 at 18:21