export default function HomeExporer()

in website/src/components/explorer/index.tsx [217:344]


export default function HomeExporer({ children }: { children: ReactNode }) {
  const [userInput, setUserInput] = useQueryState("hex", "");
  const [userResolution, setUserResolution] = useQueryState<number>("res", -1);

  const { splitUserInput, showCellId, inputGeoJson, showResolutionInput } =
    useMemo(
      () => doSplitUserInput(userInput, userResolution),
      [userInput, userResolution],
    );
  const userValidHex = useMemo(
    () => splitUserInput.map(isValidCell).includes(true),
    [splitUserInput],
  );
  const constantResolution = useMemo(() => {
    const resAsSet = new Set(splitUserInput.map(getResolution));
    if (resAsSet.size === 1) {
      return [...resAsSet][0];
    } else {
      return undefined;
    }
  }, [splitUserInput]);

  const objectOnClick = useCallback(
    ({ hex }: { hex: string }) => {
      const asSet = new Set(splitUserInput);
      if (!asSet.delete(hex)) {
        asSet.add(hex);
      }
      setUserInput([...asSet].join(", "));
    },
    [splitUserInput, setUserInput],
  );
  const coordinateOnClick = useCallback(
    ({
      coordinate,
      zoom,
      resolution,
    }: {
      coordinate: [number, number];
      zoom: number;
      resolution?: number;
    }) => {
      if (constantResolution !== undefined) {
        const asSet = new Set(splitUserInput);
        asSet.add(
          latLngToCell(coordinate[1], coordinate[0], constantResolution),
        );
        setUserInput([...asSet].join(", "));
      } else if (splitUserInput.length === 0) {
        const detectedRes =
          resolution !== undefined ? resolution : zoomToResolution(zoom);
        setUserInput(
          `${latLngToCell(coordinate[1], coordinate[0], detectedRes)}`,
        );
      }
    },
    [splitUserInput, setUserInput, constantResolution],
  );

  // Note: The Layout "wrapper" component adds header and footer etc
  return (
    <>
      <Banner>
        <HeroExampleContainer>
          <DemoContainer>
            <ExplorerMap
              userInput={splitUserInput}
              inputGeoJson={inputGeoJson}
              userValidHex={userValidHex}
              objectOnClick={objectOnClick}
              coordinateOnClick={coordinateOnClick}
            />
          </DemoContainer>
        </HeroExampleContainer>
        <BannerContainer>
          <textarea
            value={userInput}
            onChange={(e) => {
              setUserInput(e.target.value);
            }}
            placeholder="Click on map or enter cell IDs"
            style={{
              marginRight: "0.5rem",
              height: "3em",
              minHeight: "2em",
              maxHeight: "10em",
              width: "100%",
              resize: "vertical",
            }}
          />
          {splitUserInput.length ? (
            <SelectedHexDetails
              splitUserInput={splitUserInput}
              showCellId={showCellId}
              setUserInput={setUserInput}
              showNavigation={false}
              showDetails={true}
            />
          ) : null}
          {showResolutionInput !== null ? (
            <div>
              <input
                type="number"
                min="0"
                max="15"
                placeholder="Resolution"
                value={`${userResolution}`}
                onChange={(e) => {
                  try {
                    const res = parseInt(e.target.value, 10);
                    if (!isNaN(res) && res >= 0 && res <= 15) {
                      setUserResolution(res);
                    }
                  } catch (err) {
                    // Ignore
                    console.error(err);
                  }
                }}
              />
            </div>
          ) : null}
        </BannerContainer>
        <WhereAmIButton setUserInput={setUserInput} />
      </Banner>
      {children}
    </>
  );
}