Skip to content

Commit fa14da3

Browse files
committed
Added context menu
1 parent 3ec441b commit fa14da3

9 files changed

Lines changed: 89 additions & 18 deletions

File tree

src/ContextMenu/ContextMenu.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.context-menu {
2+
position: fixed;
3+
}

src/ContextMenu/ContextMenu.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { useRef } from "react";
2+
import MenuItems, { MenuItemProps } from "../components/MenuItems";
3+
import "./ContextMenu.scss";
4+
import useDetectClickOutside from "../hooks/useDetectClickOutside";
5+
6+
interface ContextMenuProps {
7+
items: Array<MenuItemProps>;
8+
position: { x: number; y: number };
9+
close: () => void;
10+
}
11+
12+
function ContextMenu({ items, position, close }: ContextMenuProps) {
13+
const elementRef = useRef<HTMLDivElement>(null);
14+
15+
useDetectClickOutside({ elementRef, onClick: close });
16+
17+
return (
18+
<div
19+
className="context-menu"
20+
ref={elementRef}
21+
style={{
22+
left: position.x,
23+
top: position.y,
24+
}}
25+
>
26+
<MenuItems
27+
items={items}
28+
position={{ x: 0, y: 0 }}
29+
positionType="relative"
30+
/>
31+
</div>
32+
);
33+
}
34+
35+
export default ContextMenu;

src/ContextMenu/indext.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import ContextMenu from "./ContextMenu";
2+
3+
export default ContextMenu;

src/components/BorderedApp/BorderedApp.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@ import useWindowManagerStore, {
33
BaseProps,
44
} from "../../stores/windowManagerStore";
55
import { Dimensions } from "../../hooks/useDragToResize";
6-
import BorderedAppMenu, {
7-
BorderedAppMenuItemProps,
8-
} from "./BorderedAppMenu/BorderedAppMenu";
6+
import BorderedAppMenu from "./BorderedAppMenu/BorderedAppMenu";
97
import usePositionableElement from "../../hooks/usePositionableElement";
108

119
import "./BorderedApp.scss";
1210
import useSystemSettings from "../../stores/systemSettingsStore";
11+
import { MenuItemProps } from "../MenuItems";
1312
interface BorderedAppProps extends BaseProps {
1413
title: string;
1514
type: string;
1615
id: string;
1716
initialDimensions: Dimensions;
1817
maxDimensions?: Dimensions;
1918
minDimensions?: Dimensions;
20-
menus?: Array<BorderedAppMenuItemProps>;
19+
menus?: Array<MenuItemProps>;
2120
}
2221

2322
function BorderedApp({

src/components/BorderedApp/BorderedAppMenu/BorderedAppMenu.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,13 @@ function BorderedAppMenu({ title, items }: BorderedAppMenuProps) {
2929
onClick={() => setOpen(!open)}
3030
>
3131
<span className="bordered-app-menu__title">{title}</span>
32-
{open && <MenuItems items={items} position={{ ...position.current }} />}
32+
{open && (
33+
<MenuItems
34+
items={items}
35+
position={{ ...position.current }}
36+
positionType="absolute"
37+
/>
38+
)}
3339
</div>
3440
);
3541
}

src/components/MenuItems/MenuItems.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
.menu {
22
&-items {
33
width: auto;
4-
position: absolute;
54
white-space: nowrap;
65
box-sizing: border-box;
76
box-shadow: 0 0 2px rgb(0, 0, 0, 0.5);

src/components/MenuItems/MenuItems.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import "./MenuItems.scss";
55
export interface MenuItemsProps {
66
items: Array<MenuItemProps>;
77
position: { x: number; y: number };
8+
positionType: "relative" | "absolute";
89
}
910

1011
export interface MenuItemProps {
@@ -13,7 +14,7 @@ export interface MenuItemProps {
1314
items?: Array<MenuItemProps>;
1415
}
1516

16-
function MenuItems({ items, position }: MenuItemsProps) {
17+
function MenuItems({ items, position, positionType }: MenuItemsProps) {
1718
const settings = useSystemSettings();
1819
return (
1920
<div
@@ -22,6 +23,7 @@ function MenuItems({ items, position }: MenuItemsProps) {
2223
left: position.x,
2324
top: position.y,
2425
backgroundColor: settings.mainColor,
26+
position: positionType,
2527
}}
2628
>
2729
<div className="menu-items__content">
@@ -129,7 +131,11 @@ function MenuItem({
129131
{title}
130132
</span>
131133
{items && open && (
132-
<MenuItems items={items} position={{ ...elementPosition.current }} />
134+
<MenuItems
135+
items={items}
136+
position={{ ...elementPosition.current }}
137+
positionType="absolute"
138+
/>
133139
)}
134140
</div>
135141
);

src/programs/FileBrowser/FileBrowser.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
import React, { useEffect, useState } from "react";
1+
import React, { useEffect, useRef, useState } from "react";
22
import { ReactComponent as FolderIcon } from "../../assets/icons/folder-icon.svg";
33

4-
import useLocalFS, {
5-
FSDirectory,
6-
FSObject,
7-
isFSDirectory,
8-
} from "../../stores/localFS";
4+
import { FSDirectory, FSObject, isFSDirectory } from "../../stores/localFS";
95
import useLocalFSWithHistory from "../../hooks/useLocalFSWithHistory";
106

117
import "./FileBrowser.scss";
128
import AppSideBar from "../../components/AppSideBar";
13-
import useCompression from "../../hooks/useCompression";
9+
import ContextMenu from "../../ContextMenu/ContextMenu";
10+
import { getMainContentContextItems } from "./contextMenus";
1411
const defaultPath = "/home/user";
1512

1613
interface FileBrowserProps {
@@ -64,20 +61,28 @@ interface MainContentProps {
6461

6562
function MainContent({ currentDirectory, openFSObject }: MainContentProps) {
6663
const [selected, setSelected] = useState<string>("");
67-
const fs = useLocalFS();
68-
const { compress } = useCompression();
64+
const clickPosition = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
65+
const [open, setOpen] = useState(false);
6966

7067
function handleRightClick(e: React.MouseEvent) {
68+
clickPosition.current = { x: e.clientX, y: e.clientY };
7169
e.stopPropagation();
7270
e.preventDefault();
73-
//fs.createFile("test-create-file.txt", currentDirectory, compress("Hello world!"));
71+
setOpen(true);
7472
}
7573

7674
return (
7775
<div
7876
className="file-browser__main-content"
7977
onContextMenu={handleRightClick}
8078
>
79+
{open && (
80+
<ContextMenu
81+
position={clickPosition.current}
82+
items={getMainContentContextItems()}
83+
close={() => setOpen(!open)}
84+
/>
85+
)}
8186
{Object.values<FSObject>(currentDirectory.contents).map((fsObject) => (
8287
<DirectoryOrFile
8388
fsObject={fsObject}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { MenuItemProps } from "../../components/MenuItems";
2+
3+
export function getMainContentContextItems(): Array<MenuItemProps> {
4+
return [
5+
{
6+
title: "Create Directory",
7+
},
8+
{
9+
title: "Create File",
10+
},
11+
{
12+
title: "Open in Terminal",
13+
},
14+
];
15+
}

0 commit comments

Comments
 (0)