diff --git a/packages/interface/src/components/explorer/ExplorerContextMenu.tsx b/packages/interface/src/components/explorer/ExplorerContextMenu.tsx index a76c1c163..ff6c08cf9 100644 --- a/packages/interface/src/components/explorer/ExplorerContextMenu.tsx +++ b/packages/interface/src/components/explorer/ExplorerContextMenu.tsx @@ -1,182 +1,122 @@ import { explorerStore, useLibraryMutation, useLibraryQuery } from '@sd/client'; -import { ExplorerData } from '@sd/core'; import { - ArrowBendUpRight, - LockSimple, - Package, - Plus, - Share, - TagSimple, - Trash, - TrashSimple + ArrowBendUpRight, + FilePlus, + FileX, + LockSimple, + Package, + Plus, + Share, + TagSimple, + Trash, + TrashSimple, } from 'phosphor-react'; import React from 'react'; import { useSnapshot } from 'valtio'; -import { WithContextMenu } from '../layout/MenuOverlay'; +import { NewContextMenu as CM } from "@sd/ui" + +const AssignTagMenuItems = (props: { objectId: number }) => { + const tags = useLibraryQuery(['tags.getAll'], { suspense: true }); + const tagsForFile = useLibraryQuery(['tags.getForFile', props.objectId], { suspense: true }); + + const { mutate: assignTag } = useLibraryMutation('tags.assign'); + + return ( + <> + {tags.data?.map(tag => { + const active = !!tagsForFile.data?.find(t => t.id === tag.id) + + return { + e.preventDefault(); + if (props.objectId === null) return; + + assignTag({ + tag_id: tag.id, + file_id: props.objectId, + unassign: active + }); + }} + > +
+

{tag.name}

+ + })} + + ); +} interface Props { - children: React.ReactNode; + children: React.ReactNode; } export default function ExplorerContextMenu(props: Props) { - const store = useSnapshot(explorerStore); + const store = useSnapshot(explorerStore); - const { data: tags } = useLibraryQuery(['tags.getAll'], {}); + return ( +
+ + + - const { mutate: assignTag } = useLibraryMutation('tags.assign'); + - const { data: tagsForFile } = useLibraryQuery([ - 'tags.getForFile', - store.contextMenuObjectId || -1 - ]); - return ( -
- { - const active = !!tagsForFile?.find((t) => t.id === tag.id); - return { - label: tag.name || '', + + - // leftItem: t.id === tag.id)} />, - leftItem: ( -
-
-
- ), - onClick(e) { - e.preventDefault(); - if (store.contextMenuObjectId != null) - assignTag({ - tag_id: tag.id, - file_id: store.contextMenuObjectId, - unassign: active - }); - } - }; - }) || [] - ] - } - ], - [ - { - label: 'More actions...', - icon: Plus, + - children: [ - // [ - // { - // label: 'Move to library', - // icon: FilePlus, - // children: [libraries?.map((library) => ({ label: library.config.name })) || []] - // }, - // { - // label: 'Remove from library', - // icon: FileX - // } - // ], - [ - { - label: 'Encrypt', - icon: LockSimple - }, - { - label: 'Compress', - icon: Package - }, - { - label: 'Convert to', - icon: ArrowBendUpRight, + + - children: [ - [ - { - label: 'PNG' - }, - { - label: 'WebP' - } - ] - ] - } - // { - // label: 'Mint NFT', - // icon: TrashIcon - // } - ], - [ - { - label: 'Secure delete', - icon: TrashSimple - } - ] - ] - } - ], - [ - { - label: 'Delete', - icon: Trash, - danger: true - } - ] - ]} - > - {props.children} - -
- ); + + + { + e.preventDefault(); + + navigator.share?.({ + title: 'Spacedrive', + text: 'Check out this cool app', + url: 'https://spacedrive.com' + }); + }} /> + + + + {store.contextMenuObjectId && + + } + + + {/* {libraries.map(library => )} */} + + + + + + + + + + + + + + + + +
+ ); } diff --git a/packages/ui/package.json b/packages/ui/package.json index 1c32f3fba..cc0279996 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -21,11 +21,13 @@ "@heroicons/react": "^2.0.10", "@radix-ui/react-context-menu": "^1.0.0", "@tailwindcss/forms": "^0.5.2", + "class-variance-authority": "^0.2.3", "clsx": "^1.2.1", "phosphor-react": "^1.4.1", "postcss": "^8.4.14", "react": "^18.2.0", "react-dom": "^18.2.0", + "storybook": "^6.5.10", "tailwindcss": "^3.1.6" }, "devDependencies": { diff --git a/packages/ui/src/ContextMenu/index.tsx b/packages/ui/src/ContextMenu/index.tsx new file mode 100644 index 000000000..06b1e26da --- /dev/null +++ b/packages/ui/src/ContextMenu/index.tsx @@ -0,0 +1,107 @@ +import * as RadixCM from "@radix-ui/react-context-menu" +import clsx from "clsx"; +import { CaretRight, Icon } from "phosphor-react"; +import { HTMLAttributes, PropsWithChildren, Suspense, } from "react" +import React from 'react' +import { cva, VariantProps } from "class-variance-authority"; + +interface Props extends RadixCM.MenuContentProps { + trigger: React.ReactNode, +} + +const MENU_CLASSES = ` + flex flex-col + min-w-[11rem] p-2 space-y-1 + text-left text-sm dark:text-gray-100 text-gray-800 + bg-gray-50 border-gray-200 dark:bg-gray-950 + shadow-md shadow-gray-300 dark:shadow-gray-750 + select-none cursor-default rounded-lg +`; + +export const ContextMenu = ({ trigger, children, className, ...props }: PropsWithChildren) => { + return ( + + {trigger} + + + {children} + + + + ) +} + +export const Separator = () => + + +export const SubMenu = ({ label, icon, className, ...props }: RadixCM.MenuSubContentProps & ItemProps) => { + return ( + + + + + + + + + + + ) +} + +const ITEM_CLASSES = ` + flex flex-row items-center justify-start flex-1 + px-2 py-1 space-x-2 + cursor-default rounded + focus:outline-none +`; + +const itemStyles = cva([ITEM_CLASSES], { + variants: { + variant: { + default: 'hover:bg-primary focus:bg-primary', + danger: ` + text-red-600 dark:text-red-400 + hover:text-white focus:text-white + hover:bg-red-500 focus:bg-red-500 + ` + } + }, + defaultVariants: { + variant: 'default' + } +}) + +interface ItemProps extends VariantProps { + icon?: Icon, + rightArrow?: boolean, + label?: string, +} + +export const Item = ({ icon, label, rightArrow, children, variant, ...props }: ItemProps & RadixCM.MenuItemProps) => ( + + {children ? children : } + +) + +const DivItem = ({ variant, ...props }: ItemProps) => ( +
+ +
+) + + +const ItemInternals = ({ icon, label, rightArrow }: ItemProps) => { + const ItemIcon = icon; + return ( + <> + {ItemIcon && } + {label &&

{label}

} + + {rightArrow && <> +
+ + } + + ) +} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index a305cff1c..ca98bd6fb 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,4 +1,5 @@ export * from './Button'; export * from './Dropdown'; export * from './ContextMenu'; +export * as NewContextMenu from "./ContextMenu/index" export * from './Input'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e66a95e5b..81a2ed2f5 100644 Binary files a/pnpm-lock.yaml and b/pnpm-lock.yaml differ