React 파일 관리자를 만들어 봅시다 19장: 파일 관리자 도구 모음의 개념
37209 단어 typescriptmongezjavascriptreact
파일 관리자 도구 모음의 개념
그렇다면 파일 관리자 도구 모음의 기본 개념은 무엇입니까? 음, 간단합니다. 버튼 목록이 있고, 각 버튼에는 액션이 있고, 각 액션에는 핸들러가 있습니다. 그게 다예요❕
이제 여기에는
UI
AKA 버튼과 logic
AKA 작업의 두 가지가 있습니다.// src/apps/front-office/file-manager/components/Toolbar/Toolbar.tsx
import { Card } from "@mantine/core";
const buttons = [];
export default function Toolbar() {
return (
<>
<Card shadow="sm">
<div>Toolbar</div>
</Card>
</>
);
}
빈 버튼을 제외하고 여기에 새로운 것을 추가하지 않았습니다. 홈 디렉토리로 이동하는 버튼을 추가해 보겠습니다.
// Toolbar.tsx
import { Card } from "@mantine/core";
const buttons = [
HomeDirectoryButton,
];
export default function Toolbar() {
return (
<>
<Card shadow="sm">
<div>Toolbar</div>
</Card>
</>
);
}
홈 디렉토리 버튼
이제
components/Toolbar/Buttons
디렉토리 아래의 툴바 안에 해당 버튼을 만들어 보겠습니다.// HomeDirectoryButton.tsx
export default function HomeDirectoryButton() {
return <div>HomeDirectoryButton</div>;
}
이제 가져와서 이 버튼을 렌더링해야 합니다. 그리드에서도 렌더링해 보겠습니다.
// Toolbar.tsx
import { Card, Grid } from "@mantine/core";
import HomeDirectoryButton from "./Buttons/HomeDirectoryButton";
const buttons = [
HomeDirectoryButton,
];
export default function Toolbar() {
return (
<>
<Card shadow="sm">
<Grid>
{buttons.map((Button, index) => (
<Button key={index} />
))}
</Grid>
</Card>
</>
);
}
다음과 같습니다.
이제 버튼으로 렌더링해 보겠습니다.
import { ActionIcon, ThemeIcon, useMantineTheme } from "@mantine/core";
import { IconHome2 } from "@tabler/icons";
export default function HomeDirectoryButton() {
const theme = useMantineTheme();
return (
<>
<ActionIcon variant="subtle">
<ThemeIcon variant="light" color={theme.colors.lime[1]}>
<IconHome2 size={16} color={theme.colors.lime[9]} />
</ThemeIcon>
</ActionIcon>
</>
);
}
버튼을 Action Icon Component so it does not make any paddings around it으로 래핑하고 사이드바에 동일한 아이콘을 추가했습니다.
이제 그것을 tooltip 로 감싸자.
// HomeDirectoryButton.tsx
import { ActionIcon, ThemeIcon, Tooltip, useMantineTheme } from "@mantine/core";
import { IconHome2 } from "@tabler/icons";
export default function HomeDirectoryButton() {
const theme = useMantineTheme();
return (
<>
<Tooltip label="Home" position="bottom" transition="slide-up">
<ActionIcon variant="subtle">
<ThemeIcon variant="light" color={theme.colors.lime[1]}>
<IconHome2 size={16} color={theme.colors.lime[9]} />
</ThemeIcon>
</ActionIcon>
</Tooltip>
</>
);
}
당신은 다음과 같은 것을 볼 수 있습니다
Mantine Cards은 기본적으로 내부의 모든 오버플로를 숨기기 때문에 표시되도록 해야 합니다.
Toolbar.styles.tsx
파일을 만들고 이 스타일을 추가해 보겠습니다.// Toolbar.styles.tsx
import styled from "@emotion/styled";
import { Card, CardProps } from "@mantine/core";
import { FC } from "react";
export const ToolbarWrapper = styled<FC<CardProps>>(Card)`
label: ToolbarWrapper;
overflow: visible; ;
`;
이제 가져와서
Card
구성 요소 대신 사용하겠습니다.// Toolbar.tsx
import { Grid } from "@mantine/core";
import HomeDirectoryButton from "./Buttons/HomeDirectoryButton";
import { ToolbarWrapper } from "./Toolbar.styles";
const buttons = [
HomeDirectoryButton,
];
export default function Toolbar() {
return (
<>
<ToolbarWrapper shadow="sm">
<Grid>
{buttons.map((Button, index) => (
<Button key={index} />
))}
</Grid>
</ToolbarWrapper>
</>
);
}
이제 잘 작동합니다
이제 버튼, 아이콘, 텍스트 및 래퍼 내부의 세 가지 요소에 대한 스타일을 만들어 봅시다.
// HomeDirectoryButton.tsx
import { ThemeIcon, Tooltip, useMantineTheme } from "@mantine/core";
import { IconHome2 } from "@tabler/icons";
import {
ToolbarButtonText,
ToolBarButtonWrapper,
ToolbarIcon,
} from "../Toolbar.styles";
export default function HomeDirectoryButton() {
const theme = useMantineTheme();
return (
<Tooltip label={"Home"} position="bottom" transition="slide-up">
<ToolBarButtonWrapper>
<ToolbarIcon variant="subtle">
<ThemeIcon variant="light" color={theme.colors.lime[1]}>
<IconHome2 size={16} color={theme.colors.lime[9]} />
</ThemeIcon>
</ToolbarIcon>
<ToolbarButtonText>Home</ToolbarButtonText>
</ToolBarButtonWrapper>
</Tooltip>
);
}
계속하기 전에 Mantine에 따라
definitions.d.ts
테마 매개변수를 재정의할 수 있도록 src 디렉토리에 styled
라는 파일을 만들어야 합니다.// definitions.d.ts
import "@emotion/react";
import type { MantineTheme } from "@mantine/core";
declare module "@emotion/react" {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Theme extends MantineTheme {}
}
테마에 아무것도 추가할 필요가 없기 때문에 eslint 오류를 비활성화했습니다.
이제 스타일링 섹션으로 이동합니다.
// Toolbar.styles.tsx
import styled from "@emotion/styled";
import { ActionIcon, ActionIconProps, Card, CardProps } from "@mantine/core";
import { FC } from "react";
// 👇🏻 We need to add FC<CardProps> to make it work with styled
export const ToolbarWrapper = styled<FC<CardProps>>(Card)`
label: ToolbarWrapper;
overflow: visible; ;
`;
// 👇🏻 the wrapper that will be used to wrap the icon and the text
export const ToolBarButtonWrapper = styled.div`
label: ToolBarButtonWrapper;
text-align: center;
margin: 0 0.5rem;
cursor: pointer;
`;
// 👇🏻 We need to add FC<ActionIconProps> to make it work with styled
export const ToolbarIcon = styled<FC<ActionIconProps>>(ActionIcon)`
label: ToolbarIcon;
width: 100%;
`;
// 👇🏻 the button text that will be displayed below the icon
export const ToolbarButtonText = styled.div`
label: ToolbarButtonText;
color: ${({ theme }) => theme.colors.gray[5]};
font-weight: bold;
font-size: 13px;
`;
이제 최종 모습은 이렇습니다
행위
지금은 간단한 작업 목록을 만들고
Kernel
로 이동하여 getteractions
속성을 추가해 보겠습니다.// Kernel.ts
...
/**
* Get kernel actions
*/
public get actions() {
return {
navigateTo: this.load.bind(this),
};
}
여기서 첫 번째 작업은 이미 커널에 내장되어 있으며
navigateTo
작업이며 load
메서드의 래퍼일 뿐입니다.이제
HomeDirectoryButton
구성 요소에서 사용해 보겠습니다.// HomeDirectoryButton.tsx
import { ThemeIcon, Tooltip, useMantineTheme } from "@mantine/core";
import { IconHome2 } from "@tabler/icons";
import { useKernel } from "app/file-manager/hooks";
import {
ToolbarButtonText,
ToolBarButtonWrapper,
ToolbarIcon,
} from "../Toolbar.styles";
export default function HomeDirectoryButton() {
const theme = useMantineTheme();
// we need to use the kernel to get the root path
const kernel = useKernel();
const actions = kernel.actions;
return (
<Tooltip label={"Home"} position="bottom" transition="slide-up">
<ToolBarButtonWrapper onClick={() => actions.navigateTo(kernel.rootPath)}>
<ToolbarIcon variant="subtle">
<ThemeIcon variant="light" color={theme.colors.lime[1]}>
<IconHome2 size={16} color={theme.colors.lime[9]} />
</ThemeIcon>
</ToolbarIcon>
<ToolbarButtonText>Home</ToolbarButtonText>
</ToolBarButtonWrapper>
</Tooltip>
);
}
지금까지는 좋았고 어려운 것도 쉬운 것도 없었습니다. 이제
create directory
버튼을 추가해 보겠습니다.그러나 먼저 파일 관리자
file-manager/actions
에서 작업 디렉토리를 만들고 createDirectory.ts
라는 파일을 만들고 다음 코드를 추가해야 합니다.// createDirectory.ts
import Kernel from "../Kernel";
export default function createDirectory(kernel: Kernel) {
return function create(directoryName: string) {
}
}
색인 파일을 만들고 여기에서 모든 작업을 내보냅니다.
// index.ts
export { default as createDirectory } from "./createDirectory";
여기서 우리가 한 것은 커널을 수신하고 콜백 함수를 반환하는 함수를 만드는 것입니다. 이 콜백은 커널 작업 목록에서 호출할 때 직접 사용됩니다
kernel.actions.createDirectory
.// Kernel.ts
// 👇🏻 import the createDirectory action
import { createDirectory } from "../actions";
...
/**
* Get kernel actions
*/
public get actions() {
return {
navigateTo: this.load.bind(this),
createDirectory: createDirectory(kernel);
};
}
이제 작업 목록을 업데이트하고 디렉터리 만들기 작업을 추가했습니다.
그러나 여기에 함정이 있습니다.
actions
getter를 호출할 때마다 새로운 createDirectory
함수가 생성되므로 한 번만 호출해야 합니다.// Kernel.ts
...
/**
* Get kernel actions
*/
public get actions() {
// we added the following line to disable the annoying eslint message
// as we can not use the this keyword in any getters i.e createDirectory.
// eslint-disable-next-line @typescript-eslint/no-this-alias
const kernel = this;
return {
navigateTo: this.load.bind(this),
get createDirectory() {
return createDirectory(kernel);
},
};
}
createDirectory
에서 getter Advantage를 다시 사용하면 사용해야 할 때만 호출하게 됩니다.다음 장
다음 장에서는
create directory
작업과 버튼에 대한 작업도 시작합니다.기사 저장소
Github Repository에서 챕터 파일을 볼 수 있습니다.
Don't forget the
main
branch has the latest updated code.
지금 어디 있는지 말해줘
이 시리즈를 저와 함께 후속 조치하는 경우 현재 위치와 어려움을 겪고 있는 부분을 알려주시면 최대한 도와드리겠습니다.
살람.
Reference
이 문제에 관하여(React 파일 관리자를 만들어 봅시다 19장: 파일 관리자 도구 모음의 개념), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hassanzohdy/lets-create-a-react-file-manager-chapter-xix-the-concept-behind-file-manager-toolbars-4bba텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)