diff --git a/libs/remix-ui/file-explorer/src/lib/css/file-explorer-context-menu.css b/libs/remix-ui/file-explorer/src/lib/css/file-explorer-context-menu.css
new file mode 100644
index 0000000000..f88c8825a8
--- /dev/null
+++ b/libs/remix-ui/file-explorer/src/lib/css/file-explorer-context-menu.css
@@ -0,0 +1,28 @@
+.remixui_contextContainer
+{
+ display: block;
+ position: fixed;
+ border-radius: 2px;
+ z-index: 1000;
+ box-shadow: 0 0 4px var(--dark);
+}
+.remixui_contextContainer:focus {
+ outline: none;
+}
+.remixui_liitem
+{
+ padding: 2px;
+ padding-left: 6px;
+ cursor: pointer;
+ color: var(--text-dark);
+ background-color: var(--light);
+}
+.remixui_liitem:hover
+{
+ background-color: var(--secondary);
+}
+#remixui_menuitems
+{
+ list-style: none;
+ margin: 0px;
+}
\ No newline at end of file
diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx
new file mode 100644
index 0000000000..6ea088ab44
--- /dev/null
+++ b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx
@@ -0,0 +1,55 @@
+import React, { useRef, useEffect } from 'react' // eslint-disable-line
+import { FileExplorerContextMenuProps } from './types'
+
+import './css/file-explorer-context-menu.css'
+
+export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => {
+ const { actions, createNewFile, hideContextMenu, pageX, pageY, ...otherProps } = props
+ const contextMenuRef = useRef(null)
+
+ useEffect(() => {
+ contextMenuRef.current.focus()
+ }, [])
+
+ useEffect(() => {
+ const menuItemsContainer = contextMenuRef.current
+ const boundary = menuItemsContainer.getBoundingClientRect()
+
+ if (boundary.bottom > (window.innerHeight || document.documentElement.clientHeight)) {
+ menuItemsContainer.style.position = 'absolute'
+ menuItemsContainer.style.bottom = '10px'
+ menuItemsContainer.style.top = null
+ }
+ }, [pageX, pageY])
+
+ const menu = () => {
+ return actions.map((item, index) => {
+ return
+ })
+ }
+
+ return (
+
+ )
+}
+
+export default FileExplorerContextMenu
diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
index ce956c59ea..8a2e629e37 100644
--- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
+++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
@@ -2,6 +2,7 @@ import React, { useEffect, useState, useRef } from 'react' // eslint-disable-lin
import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd' // eslint-disable-line
import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line
+import { FileExplorerContextMenu } from './file-explorer-context-menu'
import { FileExplorerProps, File } from './types'
import * as helper from '../../../../../apps/remix-ide/src/lib/helper'
@@ -10,9 +11,11 @@ import './css/file-explorer.css'
export const FileExplorer = (props: FileExplorerProps) => {
const { files, name, registry, plugin } = props
const containerRef = useRef(null)
- const contextMenuRef = useRef({})
const [state, setState] = useState({
- focusElement: [],
+ focusElement: [{
+ key: name,
+ type: 'folder'
+ }],
focusPath: null,
files: [],
fileManager: null,
@@ -116,13 +119,15 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const extractParentFromKey = (key: string):string => {
+ if (!key) return
const keyPath = key.split('/')
+ keyPath.pop()
- return keyPath.pop()
+ return keyPath.join('/')
}
const createNewFile = (parentFolder?: string) => {
- if (!parentFolder) parentFolder = extractParentFromKey(state.focusElement[0])
+ if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name
// const self = this
// modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => {
// if (!input) input = 'New file'
@@ -154,14 +159,14 @@ export const FileExplorer = (props: FileExplorerProps) => {
name: extractNameFromKey(newFileName),
isDirectory: false
}],
- focusElement: [newFileName]
+ focusElement: [{ key: newFileName, type: 'file' }]
}
})
} else {
const updatedFiles = await resolveDirectory(parentFolder, state.files)
setState(prevState => {
- return { ...prevState, files: updatedFiles, focusElement: [newFileName] }
+ return { ...prevState, files: [...updatedFiles], focusElement: [{ key: newFileName, type: 'file' }] }
})
}
if (newFileName.includes('_test.sol')) {
@@ -250,33 +255,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
)
}
- const contextMenu = (actions: { name: string, type: string[] }[], index: number) => {
- const menu = actions.map((item) => {
- return
- })
-
- return (
-
- )
- }
-
const onDragEnd = result => {
}
@@ -284,39 +262,40 @@ export const FileExplorer = (props: FileExplorerProps) => {
const handleClickFile = (path) => {
state.fileManager.open(path)
setState(prevState => {
- return { ...prevState, focusElement: [path] }
+ return { ...prevState, focusElement: [{ key: path, type: 'file' }] }
})
}
const handleClickFolder = async (path) => {
if (state.ctrlKey) {
- if (state.focusElement.findIndex(item => item === path) !== -1) {
+ if (state.focusElement.findIndex(item => item.key === path) !== -1) {
setState(prevState => {
- return { ...prevState, focusElement: [...prevState.focusElement.filter(item => item !== path)] }
+ return { ...prevState, focusElement: [...prevState.focusElement.filter(item => item.key !== path)] }
})
} else {
setState(prevState => {
- return { ...prevState, focusElement: [...prevState.focusElement, path] }
+ return { ...prevState, focusElement: [...prevState.focusElement, { key: path, type: 'folder' }] }
})
}
} else {
const files = await resolveDirectory(path, state.files)
setState(prevState => {
- return { ...prevState, focusElement: [path], files }
+ return { ...prevState, focusElement: [{ key: path, type: 'folder' }], files }
})
}
}
- const handleContextMenuFile = (pageX, pageY, label) => {
- const menuItemsContainer = contextMenuRef.current
- const boundary = menuItemsContainer.getBoundingClientRect()
+ const handleContextMenuFile = (pageX: number, pageY: number, path: string) => {
+ setState(prevState => {
+ return { ...prevState, focusContext: { element: path, x: pageX, y: pageY } }
+ })
+ }
- if (boundary.bottom > (window.innerHeight || document.documentElement.clientHeight)) {
- menuItemsContainer.style.position = 'absolute'
- menuItemsContainer.style.bottom = '10px'
- menuItemsContainer.style.top = null
- }
+ const hideContextMenu = () => {
+ setState(prevState => {
+ return { ...prevState, focusContext: { element: null, x: 0, y: 0 } }
+ })
}
const renderFiles = (file: File, index: number) => {
@@ -336,7 +315,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
e.stopPropagation()
handleClickFolder(file.path)
}}
- labelClass={ state.focusElement.findIndex(item => item === file.path) !== -1 ? 'bg-secondary' : '' }
+ labelClass={ state.focusElement.findIndex(item => item.key === file.path) !== -1 ? 'bg-secondary' : '' }
controlBehaviour={ state.ctrlKey }
onContextMenu={(e) => {
e.preventDefault()
@@ -373,12 +352,20 @@ export const FileExplorer = (props: FileExplorerProps) => {
}}
onContextMenu={(e) => {
e.preventDefault()
- handleContextMenuFile()
+ handleContextMenuFile(e.pageX, e.pageY, file.path)
}}
icon='fa fa-file'
- labelClass={ state.focusElement.findIndex(item => item === file.path) !== -1 ? 'bg-secondary' : '' }
+ labelClass={ state.focusElement.findIndex(item => item.key === file.path) !== -1 ? 'bg-secondary' : '' }
/>
- { contextMenu(state.actions.filter(item => item.type.findIndex(name => name === 'file') !== -1), index) }
+ { (state.focusContext.element === file.path) &&
+ item.type.findIndex(name => name === 'file') !== -1) }
+ hideContextMenu={hideContextMenu}
+ createNewFile={createNewFile}
+ pageX={state.focusContext.x}
+ pageY={state.focusContext.y}
+ />
+ }
>
)}
diff --git a/libs/remix-ui/file-explorer/src/lib/types/index.ts b/libs/remix-ui/file-explorer/src/lib/types/index.ts
index 581d0acbf5..ac28a26570 100644
--- a/libs/remix-ui/file-explorer/src/lib/types/index.ts
+++ b/libs/remix-ui/file-explorer/src/lib/types/index.ts
@@ -19,7 +19,15 @@ export interface FileExplorerMenuProps {
menuItems: string[],
fileManager: any,
addFile: (parent: string, fileName: string) => void,
- createNewFile: () => void,
+ createNewFile: (parentFolder?: string) => void,
files: any,
accessToken: string
}
+
+export interface FileExplorerContextMenuProps {
+ actions: { name: string, type: string[] }[],
+ createNewFile: (parentFolder?: string) => void
+ hideContextMenu: () => void,
+ pageX: number,
+ pageY: number
+}