From e415ee1e2e31a6bd99c494362db1318e4e4b6296 Mon Sep 17 00:00:00 2001 From: Tristan Yang Date: Tue, 13 Jun 2023 21:21:34 +0800 Subject: [PATCH] feat: sub menu --- public/locales/en/member.json | 1 + public/locales/zh/member.json | 1 + src/assets/icons/arrow.right.svg | 8 +++ src/components/ContextMenu.tsx | 95 ++++++++++++++++++++++++++++- src/components/User/ContextMenu.tsx | 16 ++++- 5 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 src/assets/icons/arrow.right.svg diff --git a/public/locales/en/member.json b/public/locales/en/member.json index c937db75..ba5959fd 100644 --- a/public/locales/en/member.json +++ b/public/locales/en/member.json @@ -25,6 +25,7 @@ "remove_account": "Remove account", "remove_account_desc": "Are you sure remove this account?", "remove_from_channel": "Remove from channel", + "roles": "Roles", "set_admin": "Set as admin", "set_normal": "Set as normal user", diff --git a/public/locales/zh/member.json b/public/locales/zh/member.json index 7adc8960..d0bd633a 100644 --- a/public/locales/zh/member.json +++ b/public/locales/zh/member.json @@ -24,6 +24,7 @@ "remove_account": "注销账号", "remove_account_desc": "确定永久注销该账号?", "remove_from_channel": "从频道移除", + "roles": "设置角色", "set_admin": "设置为管理员", "set_normal": "设置为普通用户", diff --git a/src/assets/icons/arrow.right.svg b/src/assets/icons/arrow.right.svg new file mode 100644 index 00000000..5812cb75 --- /dev/null +++ b/src/assets/icons/arrow.right.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx index 4c683be2..0a953b9f 100644 --- a/src/components/ContextMenu.tsx +++ b/src/components/ContextMenu.tsx @@ -1,18 +1,82 @@ import { FC, ReactElement } from "react"; +import Tippy from "@tippyjs/react"; + +import IconArrow from "@/assets/icons/arrow.right.svg"; +import IconChecked from "@/assets/icons/check.sign.svg"; export interface Item { title: string; icon?: string | ReactElement; - handler: (param: any) => void; + handler?: (param: any) => void; underline?: boolean; danger?: boolean; + checked?: boolean; + subs?: Item[]; } interface Props { items: Item[]; hideMenu?: () => void; } - +const WrapWithSubmenu = ({ + items, + hideMenu, + child +}: { + items: Item[]; + hideMenu: () => void | null; + child: ReactElement; +}) => { + return ( + + {items.map((sub) => { + const { + title, + icon = null, + handler = (evt) => { + evt.preventDefault(); + if (hideMenu) { + hideMenu(); + } + }, + underline = false, + danger = false, + checked = false + } = sub; + return ( +
  • { + evt.stopPropagation(); + evt.preventDefault(); + if (checked) return; + handler(evt); + if (hideMenu) { + hideMenu(); + } + }} + > + {icon} + {title} + {checked && ( + + )} +
  • + ); + })} + + } + > + {child} +
    + ); +}; const ContextMenu: FC = ({ items = [], hideMenu = null }) => { return (