From f0f1984405db795d5a60bd03d05bec524dc12db3 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 31 Jul 2023 17:15:53 +0800 Subject: ... --- FrontEnd/src/views/common/Icon.css | 3 + FrontEnd/src/views/common/Icon.tsx | 29 ++++++++++ FrontEnd/src/views/common/menu/Menu.css | 7 ++- FrontEnd/src/views/common/menu/Menu.tsx | 49 +++++++---------- FrontEnd/src/views/common/menu/PopupMenu.css | 2 +- FrontEnd/src/views/common/menu/PopupMenu.tsx | 82 +++++++++++++--------------- 6 files changed, 97 insertions(+), 75 deletions(-) create mode 100644 FrontEnd/src/views/common/Icon.css create mode 100644 FrontEnd/src/views/common/Icon.tsx (limited to 'FrontEnd/src/views') diff --git a/FrontEnd/src/views/common/Icon.css b/FrontEnd/src/views/common/Icon.css new file mode 100644 index 00000000..fe980d7b --- /dev/null +++ b/FrontEnd/src/views/common/Icon.css @@ -0,0 +1,3 @@ +.cru-icon { + font-size: 1.4rem; +} diff --git a/FrontEnd/src/views/common/Icon.tsx b/FrontEnd/src/views/common/Icon.tsx new file mode 100644 index 00000000..c91d514b --- /dev/null +++ b/FrontEnd/src/views/common/Icon.tsx @@ -0,0 +1,29 @@ +import { ComponentPropsWithoutRef } from "react"; +import classNames from "classnames"; + +import { ThemeColor } from "./common"; + +import "./Icon.css"; + +interface IconButtonProps extends ComponentPropsWithoutRef<"i"> { + icon: string; + color?: ThemeColor | "on-surface"; + size?: string | number; +} + +export default function Icon(props: IconButtonProps) { + const { icon, color, size, style, className, ...otherProps } = props; + + const colorName = color === "on-surface" ? "surface-on" : color ?? "primary"; + + return ( + + ); +} diff --git a/FrontEnd/src/views/common/menu/Menu.css b/FrontEnd/src/views/common/menu/Menu.css index 93c229f0..db0b7432 100644 --- a/FrontEnd/src/views/common/menu/Menu.css +++ b/FrontEnd/src/views/common/menu/Menu.css @@ -11,7 +11,7 @@ } .cru-menu-item:hover { - color: var(--cru-key-t-color); + color: var(--cru-key-on-color); background-color: var(--cru-key-color); } @@ -20,5 +20,6 @@ } .cru-menu-divider { - border-top: 1px solid #e9ecef; -} + border-width: 0; + border-top: 1px solid var(--cru-key-color); +} \ No newline at end of file diff --git a/FrontEnd/src/views/common/menu/Menu.tsx b/FrontEnd/src/views/common/menu/Menu.tsx index de3b1664..a9ebfedf 100644 --- a/FrontEnd/src/views/common/menu/Menu.tsx +++ b/FrontEnd/src/views/common/menu/Menu.tsx @@ -1,11 +1,10 @@ -import * as React from "react"; -import classnames from "classnames"; -import { useTranslation } from "react-i18next"; +import { CSSProperties } from "react"; +import classNames from "classnames"; -import { convertI18nText, I18nText } from "@/common"; -import { PaletteColorType } from "@/palette"; +import { useC, Text, ThemeColor } from "../common"; import "./Menu.css"; +import Icon from "../Icon"; export type MenuItem = | { @@ -13,9 +12,9 @@ export type MenuItem = } | { type: "button"; - text: I18nText; - iconClassName?: string; - color?: PaletteColorType; + text: Text; + icon?: string; + color?: ThemeColor; onClick: () => void; }; @@ -25,44 +24,38 @@ export type MenuProps = { items: MenuItems; onItemClicked?: () => void; className?: string; - style?: React.CSSProperties; + style?: CSSProperties; }; -export default function _Menu({ +export default function Menu({ items, onItemClicked, className, style, -}: MenuProps): React.ReactElement | null { - const { t } = useTranslation(); +}: MenuProps) { + const c = useC(); return ( -
+
{items.map((item, index) => { if (item.type === "divider") { - return
; + return
; } else { + const { text, color, icon, onClick } = item; return (
{ - item.onClick(); + onClick(); onItemClicked?.(); }} > - {item.iconClassName != null ? ( - - ) : null} - {convertI18nText(item.text, t)} + {icon != null && } + {c(text)}
); } diff --git a/FrontEnd/src/views/common/menu/PopupMenu.css b/FrontEnd/src/views/common/menu/PopupMenu.css index f6654f68..38171ffd 100644 --- a/FrontEnd/src/views/common/menu/PopupMenu.css +++ b/FrontEnd/src/views/common/menu/PopupMenu.css @@ -2,5 +2,5 @@ z-index: 1040; border-radius: 5px; border: var(--cru-primary-color) 1px solid; - background-color: white; + background-color: var(--cru-surface-color); } diff --git a/FrontEnd/src/views/common/menu/PopupMenu.tsx b/FrontEnd/src/views/common/menu/PopupMenu.tsx index 74ca7aba..7ac12755 100644 --- a/FrontEnd/src/views/common/menu/PopupMenu.tsx +++ b/FrontEnd/src/views/common/menu/PopupMenu.tsx @@ -1,5 +1,5 @@ +import { useState, CSSProperties, ReactNode } from "react"; import classNames from "classnames"; -import * as React from "react"; import { createPortal } from "react-dom"; import { usePopper } from "react-popper"; @@ -11,61 +11,57 @@ import "./PopupMenu.css"; export interface PopupMenuProps { items: MenuItems; - children?: React.ReactNode; + children?: ReactNode; containerClassName?: string; - containerStyle?: React.CSSProperties; + containerStyle?: CSSProperties; } -const PopupMenu: React.FC = ({ +export default function PopupMenu({ items, children, containerClassName, containerStyle, -}) => { - const [show, setShow] = React.useState(false); +}: PopupMenuProps) { + const [show, setShow] = useState(false); const [referenceElement, setReferenceElement] = - React.useState(null); - const [popperElement, setPopperElement] = - React.useState(null); + useState(null); + const [popperElement, setPopperElement] = useState( + null, + ); const { styles, attributes } = usePopper(referenceElement, popperElement); useClickOutside(popperElement, () => setShow(false), true); return ( - <> -
setShow(true)} + > + {children} + {show && + createPortal( +
+ { + setShow(false); + }} + /> +
, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + document.getElementById("portal")!, )} - style={containerStyle} - onClick={() => setShow(true)} - > - {children} -
- {show - ? createPortal( -
- { - setShow(false); - }} - /> -
, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - document.getElementById("portal")! - ) - : null} - +
); -}; - -export default PopupMenu; +} -- cgit v1.2.3