From f5dfd52f6efece2f4cad227044ecf4dd66301bbc Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 26 Aug 2023 21:36:58 +0800 Subject: ... --- FrontEnd/src/components/button/Button.css | 64 ++++++++++ FrontEnd/src/components/button/Button.tsx | 46 ++++++++ FrontEnd/src/components/button/ButtonRow.css | 0 FrontEnd/src/components/button/ButtonRow.tsx | 62 ++++++++++ FrontEnd/src/components/button/ButtonRowV2.tsx | 143 +++++++++++++++++++++++ FrontEnd/src/components/button/FlatButton.css | 27 +++++ FrontEnd/src/components/button/FlatButton.tsx | 36 ++++++ FrontEnd/src/components/button/IconButton.css | 30 +++++ FrontEnd/src/components/button/IconButton.tsx | 30 +++++ FrontEnd/src/components/button/LoadingButton.css | 13 +++ FrontEnd/src/components/button/LoadingButton.tsx | 40 +++++++ FrontEnd/src/components/button/index.tsx | 15 +++ 12 files changed, 506 insertions(+) create mode 100644 FrontEnd/src/components/button/Button.css create mode 100644 FrontEnd/src/components/button/Button.tsx create mode 100644 FrontEnd/src/components/button/ButtonRow.css create mode 100644 FrontEnd/src/components/button/ButtonRow.tsx create mode 100644 FrontEnd/src/components/button/ButtonRowV2.tsx create mode 100644 FrontEnd/src/components/button/FlatButton.css create mode 100644 FrontEnd/src/components/button/FlatButton.tsx create mode 100644 FrontEnd/src/components/button/IconButton.css create mode 100644 FrontEnd/src/components/button/IconButton.tsx create mode 100644 FrontEnd/src/components/button/LoadingButton.css create mode 100644 FrontEnd/src/components/button/LoadingButton.tsx create mode 100644 FrontEnd/src/components/button/index.tsx (limited to 'FrontEnd/src/components/button') diff --git a/FrontEnd/src/components/button/Button.css b/FrontEnd/src/components/button/Button.css new file mode 100644 index 00000000..1da70f0e --- /dev/null +++ b/FrontEnd/src/components/button/Button.css @@ -0,0 +1,64 @@ +.cru-button { + font-size: 1rem; + padding: 0.4em 0.8em; + transition: all 0.3s; + border-radius: 0.2em; + border: 1px solid; + cursor: pointer; +} + +.cru-button:not(.outline) { + color: var(--cru-push-button-text-color); + background-color: var(--cru-clickable-normal-color); + border-color: var(--cru-clickable-normal-color); +} + +.cru-button:not(.outline):hover { + background-color: var(--cru-clickable-hover-color); + border-color: var(--cru-clickable-hover-color); +} + +.cru-button:not(.outline):focus { + background-color: var(--cru-clickable-focus-color); + border-color: var(--cru-clickable-focus-color); +} + +.cru-button:not(.outline):active { + background-color: var(--cru-clickable-active-color); + border-color: var(--cru-clickable-active-color); +} + +.cru-button:not(.outline):disabled { + color: var(--cru-push-button-disabled-text-color); + background-color: var(--cru-push-button-disabled-color); + border-color: var(--cru-push-button-disabled-color); + cursor: auto; +} + + +.cru-button.outline { + color: var(--cru-clickable-normal-color); + border-color: var(--cru-clickable-normal-color); + background-color: transparent; +} + +.cru-button.outline:hover { + color: var(--cru-clickable-hover-color); + border-color: var(--cru-clickable-hover-color); +} + +.cru-button.outline:focus { + color: var(--cru-clickable-focus-color); + border-color: var(--cru-clickable-focus-color); +} + +.cru-button.outline:active { + color: var(--cru-clickable-active-color); + border-color: var(--cru-clickable-active-color); +} + +.cru-button.outline:disabled { + color: var(--cru-clickable-disabled-color); + border-color: var(--cru-clickable-disabled-color); + cursor: auto; +} diff --git a/FrontEnd/src/components/button/Button.tsx b/FrontEnd/src/components/button/Button.tsx new file mode 100644 index 00000000..6c38e130 --- /dev/null +++ b/FrontEnd/src/components/button/Button.tsx @@ -0,0 +1,46 @@ +import { ComponentPropsWithoutRef, Ref } from "react"; +import classNames from "classnames"; + +import { Text, useC, ThemeColor } from "../common"; + +import "./Button.css"; + +interface ButtonProps extends ComponentPropsWithoutRef<"button"> { + color?: ThemeColor; + text?: Text; + outline?: boolean; + buttonRef?: Ref | null; +} + +export default function Button(props: ButtonProps) { + const { + buttonRef, + color, + text, + outline, + className, + children, + ...otherProps + } = props; + + if (text != null && children != null) { + console.warn("You can't set both text and children props."); + } + + const c = useC(); + + return ( + + ); +} diff --git a/FrontEnd/src/components/button/ButtonRow.css b/FrontEnd/src/components/button/ButtonRow.css new file mode 100644 index 00000000..e69de29b diff --git a/FrontEnd/src/components/button/ButtonRow.tsx b/FrontEnd/src/components/button/ButtonRow.tsx new file mode 100644 index 00000000..eea60cc4 --- /dev/null +++ b/FrontEnd/src/components/button/ButtonRow.tsx @@ -0,0 +1,62 @@ +import { ComponentPropsWithoutRef, Ref } from "react"; +import classNames from "classnames"; + +import Button from "./Button"; +import FlatButton from "./FlatButton"; +import IconButton from "./IconButton"; +import LoadingButton from "./LoadingButton"; + +import "./ButtonRow.css"; + +type ButtonRowButton = ( + | { + type: "normal"; + props: ComponentPropsWithoutRef; + } + | { + type: "flat"; + props: ComponentPropsWithoutRef; + } + | { + type: "icon"; + props: ComponentPropsWithoutRef; + } + | { type: "loading"; props: ComponentPropsWithoutRef } +) & { key: string | number }; + +interface ButtonRowProps { + className?: string; + containerRef?: Ref; + buttons: ButtonRowButton[]; + buttonsClassName?: string; +} + +export default function ButtonRow({ + className, + containerRef, + buttons, + buttonsClassName, +}: ButtonRowProps) { + return ( +
+ {buttons.map((button) => { + const { type, key, props } = button; + const newClassName = classNames(props.className, buttonsClassName); + switch (type) { + case "normal": + return
+ ); +} diff --git a/FrontEnd/src/components/button/ButtonRowV2.tsx b/FrontEnd/src/components/button/ButtonRowV2.tsx new file mode 100644 index 00000000..3467ad52 --- /dev/null +++ b/FrontEnd/src/components/button/ButtonRowV2.tsx @@ -0,0 +1,143 @@ +import { ComponentPropsWithoutRef, Ref } from "react"; +import classNames from "classnames"; + +import Button from "./Button"; +import FlatButton from "./FlatButton"; +import IconButton from "./IconButton"; +import LoadingButton from "./LoadingButton"; + +import "./ButtonRow.css"; +import { Text, ThemeColor } from "../common"; + +interface ButtonRowV2ButtonBase { + key: string | number; + action?: "primary" | "secondary"; + color?: ThemeColor; + disabled?: boolean; + onClick?: () => void; +} + +interface ButtonRowV2ButtonWithNoType extends ButtonRowV2ButtonBase { + type?: undefined | null; + text: Text; + outline?: boolean; + props?: ComponentPropsWithoutRef; +} + +interface ButtonRowV2NormalButton extends ButtonRowV2ButtonBase { + type: "normal"; + text: Text; + outline?: boolean; + props?: ComponentPropsWithoutRef; +} + +interface ButtonRowV2FlatButton extends ButtonRowV2ButtonBase { + type: "flat"; + text: Text; + props?: ComponentPropsWithoutRef; +} + +interface ButtonRowV2IconButton extends ButtonRowV2ButtonBase { + type: "icon"; + icon: string; + props?: ComponentPropsWithoutRef; +} + +interface ButtonRowV2LoadingButton extends ButtonRowV2ButtonBase { + type: "loading"; + text: Text; + loading?: boolean; + props?: ComponentPropsWithoutRef; +} + +type ButtonRowV2Button = + | ButtonRowV2ButtonWithNoType + | ButtonRowV2NormalButton + | ButtonRowV2FlatButton + | ButtonRowV2IconButton + | ButtonRowV2LoadingButton; + +interface ButtonRowV2Props { + className?: string; + containerRef?: Ref; + buttons: ButtonRowV2Button[]; + buttonsClassName?: string; +} + +export default function ButtonRowV2({ + className, + containerRef, + buttons, + buttonsClassName, +}: ButtonRowV2Props) { + return ( +
+ {buttons.map((button) => { + const { key, action, color, disabled, onClick } = button; + + const realAction = action ?? "primary"; + const realColor = + color ?? (realAction === "primary" ? "primary" : "secondary"); + + const commonProps = { key, color: realColor, disabled, onClick }; + const newClassName = classNames( + button.props?.className, + buttonsClassName, + ); + + switch (button.type) { + case null: + case undefined: + case "normal": { + const { text, outline, props } = button; + return ( +
+ ); +} diff --git a/FrontEnd/src/components/button/FlatButton.css b/FrontEnd/src/components/button/FlatButton.css new file mode 100644 index 00000000..2050946c --- /dev/null +++ b/FrontEnd/src/components/button/FlatButton.css @@ -0,0 +1,27 @@ +.cru-flat-button { + font-size: 1rem; + padding: 0.4em 0.8em; + transition: all 0.5s; + border-radius: 0.2em; + background-color: var(--cru-clickable-grayscale-normal-color); + border: 1px none; + color: var(--cru-clickable-normal-color); + cursor: pointer; +} + +.cru-flat-button:hover { + background-color: var(--cru-clickable-grayscale-hover-color); +} + +.cru-flat-button:focus { + background-color: var(--cru-clickable-grayscale-focus-color); +} + +.cru-flat-button:active { + background-color: var(--cru-clickable-grayscale-active-color); +} + +.cru-flat-button:disabled { + color: var(--cru-clickable-disabled-color); + cursor: auto; +} \ No newline at end of file diff --git a/FrontEnd/src/components/button/FlatButton.tsx b/FrontEnd/src/components/button/FlatButton.tsx new file mode 100644 index 00000000..9f074dd6 --- /dev/null +++ b/FrontEnd/src/components/button/FlatButton.tsx @@ -0,0 +1,36 @@ +import { ComponentPropsWithoutRef, Ref } from "react"; +import classNames from "classnames"; + +import { Text, useC, ThemeColor } from "../common"; + +import "./FlatButton.css"; + +interface FlatButtonProps extends ComponentPropsWithoutRef<"button"> { + color?: ThemeColor; + text?: Text; + buttonRef?: Ref | null; +} + +export default function FlatButton(props: FlatButtonProps) { + const { color, text, className, children, buttonRef, ...otherProps } = props; + + if (text != null && children != null) { + console.warn("You can't set both text and children props."); + } + + const c = useC(); + + return ( + + ); +} diff --git a/FrontEnd/src/components/button/IconButton.css b/FrontEnd/src/components/button/IconButton.css new file mode 100644 index 00000000..a3747201 --- /dev/null +++ b/FrontEnd/src/components/button/IconButton.css @@ -0,0 +1,30 @@ +.cru-icon-button { + color: var(--cru-clickable-normal-color); + font-size: 1.4rem; + background: none; + border: none; + transition: all 0.5s; + cursor: pointer; + user-select: none; +} + +.cru-icon-button:hover { + color: var(--cru-clickable-hover-color); +} + +.cru-icon-button:focus { + color: var(--cru-clickable-focus-color); +} + +.cru-icon-button:active { + color: var(--cru-clickable-active-color); +} + +.cru-flat-button:disabled { + color: var(--cru-clickable-disabled-color); + cursor: auto; +} + +.cru-icon-button.large { + font-size: 1.6rem; +} diff --git a/FrontEnd/src/components/button/IconButton.tsx b/FrontEnd/src/components/button/IconButton.tsx new file mode 100644 index 00000000..95c58887 --- /dev/null +++ b/FrontEnd/src/components/button/IconButton.tsx @@ -0,0 +1,30 @@ +import { ComponentPropsWithoutRef } from "react"; +import classNames from "classnames"; + +import { ThemeColor } from "../common"; + +import "./IconButton.css"; + +interface IconButtonProps extends ComponentPropsWithoutRef<"i"> { + icon: string; + color?: ThemeColor | "grayscale"; + large?: boolean; + disabled?: boolean; // TODO: Not implemented +} + +export default function IconButton(props: IconButtonProps) { + const { icon, color, className, large, ...otherProps } = props; + + return ( + + ); +} diff --git a/FrontEnd/src/components/button/index.tsx b/FrontEnd/src/components/button/index.tsx new file mode 100644 index 00000000..b5aa5470 --- /dev/null +++ b/FrontEnd/src/components/button/index.tsx @@ -0,0 +1,15 @@ +import Button from "./Button"; +import FlatButton from "./FlatButton"; +import IconButton from "./IconButton"; +import LoadingButton from "./LoadingButton"; +import ButtonRow from "./ButtonRow"; +import ButtonRowV2 from "./ButtonRowV2"; + +export { + Button, + FlatButton, + IconButton, + LoadingButton, + ButtonRow, + ButtonRowV2, +}; -- cgit v1.2.3