Как автоматически разместить все содержимое на странице при монтировании компонента?

#javascript #reactjs

Вопрос:

Редактировать

Я пока оставляю этот вопрос открытым, но вот как я его решил.

ностальгический-хилл-efkbm

Вы можете изменить значение numberOfBoxes , чтобы увидеть изменения.

 import * as React from "react";
import styled from "@emotion/styled";

const numberOfBoxes = 20;
const totalMarginPerBox = 2;
const containerHeight = window.innerHeight - 100;

const Component = React.memo(() => {
  const boxHeight = (containerHeight - 2 * numberOfBoxes) / numberOfBoxes;

  return (
    <Container>
      {boxHeight}px
      {Array.from({ length: numberOfBoxes }, (_, index) => (
        <Box height={boxHeight}>box {index   1}</Box>
      ))}
    </Container>
  );
});

export default Component;

const Container = styled.div`
  width: 100%;
  height: ${containerHeight}px;

  display: flex;
  flex-direction: column;
  align-items: center;
`;

const Box = styled.div<{ height: number }>`
  ${({ height }) => `
    width: 10rem;
    height: ${height}px;
    border: 1px solid black;
    margin: ${
      totalMarginPerBox /
      // top margin = 1px ; bottom margin = 1px
      2
    }px 0;
    max-height: ${height}px;
    overflow: hidden;

    amp;:first-child {
      background-color: lightgreen;
    }

    amp;:last-child {
      background-color: tomato;
    }
  `}
`;
 

Я использую react-xarrows для рисования диаграммы и react-zoom-pan-pinch, чтобы иметь дополнительную функциональность для увеличения и уменьшения масштаба диаграммы.

Проблема, с которой я сталкиваюсь, заключается в том, что если на диаграмме много содержимого, то оно переполняет страницу, и пользователь вынужден прокручивать ее, чтобы увидеть.

Diagram Компонент выглядит так:

голодный-http-2u6dv

 import React from "react";
import Xarrow, { Xwrapper } from "react-xarrows";
import styled from "@emotion/styled";

const BOX_WIDTH = 362;

const QuestionAndOptionContainer = styled.div`
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: flex-start;
  z-index: 10000;
`;

const Node = styled.div`
  amp;amp;amp; {
    background: "#e3e";
    border: 1px solid #dcdcdc;
    box-sizing: border-box;
    border-radius: 8px;
    padding: 20px 24px;
    width: ${BOX_WIDTH}px;
    display: flex;
    margin: 1rem;
  }
`;

const diagram = {
  nodes: [
    {
      id: "1",
      questionNumber: "1",
      title: "This is node number 1",
      connectionsConfig: [
        {
          id: "2"
        }
      ]
    },
    {
      id: "2",
      questionNumber: "2",
      title: "This is node number 2",
      connectionsConfig: [
        {
          id: "3"
        }
      ]
    },
    {
      id: "3",
      questionNumber: "3",
      title: "This is node number 3",
      connectionsConfig: [
        {
          id: "4"
        }
      ]
    },
    {
      id: "4",
      questionNumber: "4",
      title: "This is node number 4",
      connectionsConfig: [
        {
          id: "5"
        }
      ]
    },
    {
      id: "5",
      questionNumber: "5",
      title: "This is node number 5"
    }
  ]
};

const Diagram = React.memo(() => {
  const handleRenderQuestionsTree = React.useCallback(
    ({ id, title, connectionsConfig }) => {
      return (
        <QuestionAndOptionContainer>
          <Node id={id}>
            <div>{title}</div>
          </Node>
          {!!connectionsConfig?.length amp;amp; (
            <>
              {connectionsConfig.map(({ id: nextNodeId }) => (
                <Xarrow
                  color={"#000000"}
                  headSize={7}
                  tailSize={2}
                  strokeWidth={1}
                  lineColor={"#000000"}
                  start={id}
                  end={nextNodeId}
                />
              ))}
            </>
          )}
        </QuestionAndOptionContainer>
      );
    },
    []
  );

  return <Xwrapper>{diagram.nodes.map(handleRenderQuestionsTree)}</Xwrapper>;
});

export default Diagram;
 

Now imagine, that diagram.nodes is much larger:

 const diagram = {
  nodes: [
    {
      id: "1",
      questionNumber: "1",
      title: "This is node number 1",
      connectionsConfig: [
        {
          id: "2"
        }
      ]
    },
    {
      id: "2",
      questionNumber: "2",
      title: "This is node number 2",
      connectionsConfig: [
        {
          id: "3"
        }
      ]
    },
    {
      id: "3",
      questionNumber: "3",
      title: "This is node number 3",
      connectionsConfig: [
        {
          id: "4"
        }
      ]
    },
    {
      id: "4",
      questionNumber: "4",
      title: "This is node number 4",
      connectionsConfig: [
        {
          id: "5"
        }
      ]
    },
    {
      id: "5",
      questionNumber: "5",
      title: "This is node number 5",
      connectionsConfig: [
        {
          id: "6"
        }
      ]
    },
    {
      id: "6",
      questionNumber: "6",
      title: "This is node number 6",
      connectionsConfig: [
        {
          id: "7"
        }
      ]
    },
    {
      id: "7",
      questionNumber: "7",
      title: "This is node number 7",
      connectionsConfig: [
        {
          id: "8"
        }
      ]
    },
    {
      id: "8",
      questionNumber: "8",
      title: "This is node number 8",
      connectionsConfig: [
        {
          id: "9"
        }
      ]
    },
    {
      id: "9",
      questionNumber: "9",
      title: "This is node number 9",
      connectionsConfig: [
        {
          id: "10"
        }
      ]
    },
    {
      id: "10",
      questionNumber: "10",
      title: "This is node number 10",
      connectionsConfig: [
        {
          id: "11"
        }
      ]
    },
    {
      id: "11",
      questionNumber: "11",
      title: "This is node number 11"
    }
  ]
};
 

The content overflows off the page and I’m unable to see it all.

I’m looking for a dynamic way to make sure that the content fits the page, and, if the user wants, they can zoom into it all they want.

The only thing that came to mind was calculating the BOX_WIDTH (and height) of all elements in a useEffect , which would count the number of nodes available and compare it to the windows size, something like height: window.innerHeight / diagram.nodes.length}px; , but that didn’t work out too well.

What can I do here?