Rob Koch
commited on
Commit
·
eb36ec6
1
Parent(s):
12e1c1a
basic context menu for folders
Browse files- app/components/workbench/FileTree.tsx +59 -16
- package.json +1 -0
app/components/workbench/FileTree.tsx
CHANGED
@@ -2,6 +2,7 @@ import { memo, useEffect, useMemo, useState, type ReactNode } from 'react';
|
|
2 |
import type { FileMap } from '~/lib/stores/files';
|
3 |
import { classNames } from '~/utils/classNames';
|
4 |
import { createScopedLogger, renderLogger } from '~/utils/logger';
|
|
|
5 |
|
6 |
const logger = createScopedLogger('FileTree');
|
7 |
|
@@ -159,23 +160,65 @@ interface FolderProps {
|
|
159 |
onClick: () => void;
|
160 |
}
|
161 |
|
162 |
-
|
|
|
|
|
|
|
|
|
163 |
return (
|
164 |
-
<
|
165 |
-
className=
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
}
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
);
|
180 |
}
|
181 |
|
|
|
2 |
import type { FileMap } from '~/lib/stores/files';
|
3 |
import { classNames } from '~/utils/classNames';
|
4 |
import { createScopedLogger, renderLogger } from '~/utils/logger';
|
5 |
+
import * as ContextMenu from '@radix-ui/react-context-menu';
|
6 |
|
7 |
const logger = createScopedLogger('FileTree');
|
8 |
|
|
|
160 |
onClick: () => void;
|
161 |
}
|
162 |
|
163 |
+
interface FolderContextMenuProps {
|
164 |
+
children: ReactNode;
|
165 |
+
}
|
166 |
+
|
167 |
+
function ContextMenuItem({ children }: { children: ReactNode }) {
|
168 |
return (
|
169 |
+
<ContextMenu.Item className="flex items-center gap-2 px-2 py-1.5 outline-0 text-sm text-bolt-elements-textPrimary cursor-pointer ws-nowrap text-bolt-elements-item-contentDefault hover:text-bolt-elements-item-contentActive hover:bg-bolt-elements-item-backgroundActive rounded-md">
|
170 |
+
<span className="size-4 shrink-0"></span>
|
171 |
+
<span>{children}</span>
|
172 |
+
</ContextMenu.Item>
|
173 |
+
);
|
174 |
+
}
|
175 |
+
|
176 |
+
function FolderContextMenu({ children }: FolderContextMenuProps) {
|
177 |
+
return (
|
178 |
+
<ContextMenu.Root>
|
179 |
+
<ContextMenu.Trigger>{children}</ContextMenu.Trigger>
|
180 |
+
<ContextMenu.Portal>
|
181 |
+
<ContextMenu.Content
|
182 |
+
style={{ zIndex: 998 }}
|
183 |
+
className="border border-bolt-elements-borderColor rounded-md z-context-menu bg-bolt-elements-background-depth-1 dark:bg-bolt-elements-background-depth-2 data-[state=open]:animate-in animate-duration-100 data-[state=open]:fade-in-0 data-[state=open]:zoom-in-98 w-56"
|
184 |
+
>
|
185 |
+
<ContextMenu.Group className="p-1 border-b-px border-solid border-bolt-elements-borderColor">
|
186 |
+
<ContextMenuItem>New file...</ContextMenuItem>
|
187 |
+
<ContextMenuItem>New folder...</ContextMenuItem>
|
188 |
+
</ContextMenu.Group>
|
189 |
+
<ContextMenu.Group className="p-1 border-b-px border-solid border-bolt-elements-borderColor">
|
190 |
+
<ContextMenuItem>Copy path</ContextMenuItem>
|
191 |
+
<ContextMenuItem>Copy relative path</ContextMenuItem>
|
192 |
+
</ContextMenu.Group>
|
193 |
+
<ContextMenu.Group className="p-1 border-b-px border-solid border-bolt-elements-borderColor">
|
194 |
+
<ContextMenuItem>Rename...</ContextMenuItem>
|
195 |
+
<ContextMenuItem>Delete</ContextMenuItem>
|
196 |
+
</ContextMenu.Group>
|
197 |
+
</ContextMenu.Content>
|
198 |
+
</ContextMenu.Portal>
|
199 |
+
</ContextMenu.Root>
|
200 |
+
);
|
201 |
+
}
|
202 |
+
|
203 |
+
function Folder({ folder, collapsed, selected = false, onClick }: FolderProps) {
|
204 |
+
return (
|
205 |
+
<FolderContextMenu>
|
206 |
+
<NodeButton
|
207 |
+
className={classNames('group', {
|
208 |
+
'bg-transparent text-bolt-elements-item-contentDefault hover:text-bolt-elements-item-contentActive hover:bg-bolt-elements-item-backgroundActive':
|
209 |
+
!selected,
|
210 |
+
'bg-bolt-elements-item-backgroundAccent text-bolt-elements-item-contentAccent': selected,
|
211 |
+
})}
|
212 |
+
depth={folder.depth}
|
213 |
+
iconClasses={classNames({
|
214 |
+
'i-ph:caret-right scale-98': collapsed,
|
215 |
+
'i-ph:caret-down scale-98': !collapsed,
|
216 |
+
})}
|
217 |
+
onClick={onClick}
|
218 |
+
>
|
219 |
+
{folder.name}
|
220 |
+
</NodeButton>
|
221 |
+
</FolderContextMenu>
|
222 |
);
|
223 |
}
|
224 |
|
package.json
CHANGED
@@ -57,6 +57,7 @@
|
|
57 |
"@octokit/rest": "^21.0.2",
|
58 |
"@octokit/types": "^13.6.2",
|
59 |
"@openrouter/ai-sdk-provider": "^0.0.5",
|
|
|
60 |
"@radix-ui/react-dialog": "^1.1.2",
|
61 |
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
62 |
"@radix-ui/react-separator": "^1.1.0",
|
|
|
57 |
"@octokit/rest": "^21.0.2",
|
58 |
"@octokit/types": "^13.6.2",
|
59 |
"@openrouter/ai-sdk-provider": "^0.0.5",
|
60 |
+
"@radix-ui/react-context-menu": "^2.2.2",
|
61 |
"@radix-ui/react-dialog": "^1.1.2",
|
62 |
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
63 |
"@radix-ui/react-separator": "^1.1.0",
|