React File Manager를 만들어 봅시다. Chapter X: 활성 사이드바 노드

이제 파일 관리자에서 활성 노드를 가져와 SidebarNode의 현재 노드와 비교해 보겠습니다. 동일한 경우 활성 노드가 됩니다.

// SidebarNode.tsx
...
import useFileManager from "../../../hooks/useFileManager";

export default function SidebarNode({ icon, node }: SidebarNodeProps) {
  const fileManager = useFileManager();

  const [isActiveNode, setIsActiveNode] = useState(
    node === fileManager.currentDirectoryNode,
  );

  useEffect(() => {
    setIsActiveNode(node === fileManager.currentDirectoryNode);
  }, [fileManager.currentDirectoryNode, node]);

...
}


이제 파일 관리자의 현재 디렉토리 노드와 일치하는 경우 현재 노드가 활성 노드인 경우 이제 할 수 있습니다.

이제 노드가 동일한 경우 노드를 강조 표시하겠습니다. NavLink에는 active prop이 있으므로 이를 사용하여 노드를 강조 표시할 수 있지만 먼저 사이드바 노드 내부로 이동해야 합니다.

// SidebarNode.tsx
import { NavLink } from "@mantine/core";
import { IconFolder } from "@tabler/icons";
import { useEffect, useState } from "react";
import useFileManager from "../../../hooks/useFileManager";
import { Node } from "../../../types/FileManager.types";
import { IconWrapper } from "./SidebarNode.styles";

export type SidebarNodeProps = {
  node: Node;
  icon?: React.ReactNode;
};

export default function SidebarNode({ icon, node }: SidebarNodeProps) {
  const fileManager = useFileManager();

  const [isActiveNode, setIsActiveNode] = useState(
    node === fileManager.currentDirectoryNode,
  );

  useEffect(() => {
    setIsActiveNode(node === fileManager.currentDirectoryNode);
  }, [fileManager.currentDirectoryNode, node]);

  return (
    <>
      <NavLink
        label={
          <>
            <IconWrapper>{icon}</IconWrapper>
            <span>{node.name}</span>
          </>
        }
      />
    </>
  );
}

SidebarNode.defaultProps = {
  icon: <IconFolder fill="#31caf9" />,
};


이제 Sidebar 구성 요소를 업데이트하고 탐색 링크를 제거해 보겠습니다.

// Sidebar.tsx
...

  return (
    <>
      <Card shadow="sm">
        <SidebarNode
          node={rootDirectory}
          icon={<IconHome2 size={16} color="#78a136" />}
        />
        {rootChildren?.map(child => (
          <SidebarNode
            key={child.path}
            icon={<IconFolder size={16} fill="#31caf9" />}
            node={child}
          />
        ))}
      </Card>
    </>
  );


그러나 스타일링을 위해 NavLink에 더 많은 사용자 정의가 필요하므로 모든 navProps 소품을 허용하도록 NavLink 소품을 생성하겠습니다.

// SidebarNode.tsx
import { NavLink, NavLinkProps } from "@mantine/core";
import { IconFolder } from "@tabler/icons";
import { useEffect, useState } from "react";
import useFileManager from "../../../hooks/useFileManager";
import { Node } from "../../../types/FileManager.types";
import { IconWrapper } from "./SidebarNode.styles";

export type SidebarNodeProps = {
  node: Node;
  icon?: React.ReactNode;
  navProps?: Partial<NavLinkProps>;
};

export default function SidebarNode({
  icon,
  node,
  navProps = {},
}: SidebarNodeProps) {
  const fileManager = useFileManager();

  const [isActiveNode, setIsActiveNode] = useState(
    node === fileManager.currentDirectoryNode,
  );

  useEffect(() => {
    setIsActiveNode(node === fileManager.currentDirectoryNode);
  }, [fileManager.currentDirectoryNode, node]);

  return (
    <>
      <NavLink
        {...navProps}
        label={
          <>
            <IconWrapper>{icon}</IconWrapper>
            <span>{node.name}</span>
          </>
        }
      />
    </>
  );
}

SidebarNode.defaultProps = {
  icon: <IconFolder fill="#31caf9" />,
};


이제 우리는 패딩을 위해 루트와 자식에 대해 동일한 소품을 설정할 수 있습니다.

// Sidebar.tsx
...

  return (
    <>
      <Card shadow="sm">
        <SidebarNode
          node={rootDirectory}
          navProps={{
            p: 0,
          }}
          icon={<IconHome2 size={16} color="#78a136" />}
        />
        {rootChildren?.map(child => (
          <SidebarNode
            navProps={{
              p: 0,
              pl: 10,
            }}
            key={child.path}
            icon={<IconFolder size={16} fill="#31caf9" />}
            node={child}
          />
        ))}
      </Card>
    </>
  );


이제 동일한 노드인 경우 탐색 링크를 활성으로 표시해 보겠습니다.

// SidebarNode.tsx

import { NavLink, NavLinkProps } from "@mantine/core";
import { IconFolder } from "@tabler/icons";
import { useEffect, useState } from "react";
import useFileManager from "../../../hooks/useFileManager";
import { Node } from "../../../types/FileManager.types";
import { IconWrapper } from "./SidebarNode.styles";

export type SidebarNodeProps = {
  node: Node;
  icon?: React.ReactNode;
  navProps?: Partial<NavLinkProps>;
};

export default function SidebarNode({
  icon,
  node,
  navProps = {},
}: SidebarNodeProps) {
  const fileManager = useFileManager();

  const [isActiveNode, setIsActiveNode] = useState(
    node === fileManager.currentDirectoryNode,
  );

  useEffect(() => {
    setIsActiveNode(node === fileManager.currentDirectoryNode);
  }, [fileManager.currentDirectoryNode, node]);

  return (
    <>
      <NavLink
        {...navProps}
        active={isActiveNode}
        label={
          <>
            <IconWrapper>{icon}</IconWrapper>
            <span>{node.name}</span>
          </>
        }
      />
    </>
  );
}
...


이제 우리는 다음과 같은 것을 볼 수 있습니다:



다음 부분에서는 디렉토리 사이를 탐색하는 기능을 추가할 것입니다.

기사 저장소



Github Repository에서 챕터 파일을 볼 수 있습니다.

Don't forget the main branch has the latest updated code.



지금 어디 있는지 말해줘



이 시리즈를 저와 함께 후속 조치하는 경우 현재 위치와 어려움을 겪고 있는 부분을 알려주시면 최대한 도와드리겠습니다.

살람.

좋은 웹페이지 즐겨찾기