From f5dfd52f6efece2f4cad227044ecf4dd66301bbc Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Sat, 26 Aug 2023 21:36:58 +0800
Subject: ...

---
 FrontEnd/src/components/button/FlatButton.tsx | 36 +++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 FrontEnd/src/components/button/FlatButton.tsx

(limited to 'FrontEnd/src/components/button/FlatButton.tsx')

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<HTMLButtonElement> | 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 (
+    <button
+      ref={buttonRef}
+      className={classNames(
+        "cru-flat-button",
+        `cru-clickable-${color ?? "primary"}`,
+        className,
+      )}
+      {...otherProps}
+    >
+      {text != null ? c(text) : children}
+    </button>
+  );
+}
-- 
cgit v1.2.3


From 9c69024cf5961c3c71fb58e4237f09a513d195b1 Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Thu, 31 Aug 2023 00:30:35 +0800
Subject: Minor buttons

---
 FrontEnd/src/components/button/Button.tsx          |  4 +--
 FrontEnd/src/components/button/ButtonRowV2.tsx     | 14 ++++----
 FrontEnd/src/components/button/FlatButton.tsx      |  4 +--
 FrontEnd/src/components/button/IconButton.tsx      |  4 +--
 FrontEnd/src/components/button/LoadingButton.tsx   |  4 +--
 FrontEnd/src/components/common.ts                  |  2 ++
 FrontEnd/src/components/dialog/FullPageDialog.tsx  |  4 +--
 FrontEnd/src/components/dialog/OperationDialog.tsx | 39 +++++++++-------------
 FrontEnd/src/components/index.css                  |  2 +-
 FrontEnd/src/components/theme.css                  | 23 ++++++++++---
 FrontEnd/src/pages/setting/index.css               |  4 +--
 FrontEnd/src/pages/timeline/TimelineCard.css       |  4 +--
 .../src/pages/timeline/TimelinePostCreateView.css  |  4 +--
 13 files changed, 62 insertions(+), 50 deletions(-)

(limited to 'FrontEnd/src/components/button/FlatButton.tsx')

diff --git a/FrontEnd/src/components/button/Button.tsx b/FrontEnd/src/components/button/Button.tsx
index 6c38e130..30ea8c11 100644
--- a/FrontEnd/src/components/button/Button.tsx
+++ b/FrontEnd/src/components/button/Button.tsx
@@ -1,12 +1,12 @@
 import { ComponentPropsWithoutRef, Ref } from "react";
 import classNames from "classnames";
 
-import { Text, useC, ThemeColor } from "../common";
+import { Text, useC, ClickableColor } from "../common";
 
 import "./Button.css";
 
 interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
-  color?: ThemeColor;
+  color?: ClickableColor;
   text?: Text;
   outline?: boolean;
   buttonRef?: Ref<HTMLButtonElement> | null;
diff --git a/FrontEnd/src/components/button/ButtonRowV2.tsx b/FrontEnd/src/components/button/ButtonRowV2.tsx
index 5129e7f1..a54425cc 100644
--- a/FrontEnd/src/components/button/ButtonRowV2.tsx
+++ b/FrontEnd/src/components/button/ButtonRowV2.tsx
@@ -1,7 +1,7 @@
 import { ComponentPropsWithoutRef, Ref } from "react";
 import classNames from "classnames";
 
-import { Text, ThemeColor } from "../common";
+import { Text, ClickableColor } from "../common";
 
 import Button from "./Button";
 import FlatButton from "./FlatButton";
@@ -10,10 +10,12 @@ import LoadingButton from "./LoadingButton";
 
 import "./ButtonRow.css";
 
+type ButtonAction = "major" | "minor";
+
 interface ButtonRowV2ButtonBase {
   key: string | number;
-  action?: "primary" | "secondary";
-  color?: ThemeColor;
+  action?: ButtonAction;
+  color?: ClickableColor;
   disabled?: boolean;
   onClick?: () => void;
 }
@@ -76,9 +78,9 @@ export default function ButtonRowV2({
       {buttons.map((button) => {
         const { key, action, color, disabled, onClick } = button;
 
-        const realAction = action ?? "primary";
+        const realAction: ButtonAction = action ?? "minor";
         const realColor =
-          color ?? (realAction === "primary" ? "primary" : "secondary");
+          color ?? (realAction === "major" ? "primary" : "minor");
 
         const commonProps = { key, color: realColor, disabled, onClick };
         const newClassName = classNames(
@@ -95,7 +97,7 @@ export default function ButtonRowV2({
               <Button
                 {...commonProps}
                 text={text}
-                outline={outline ?? realAction !== "primary"}
+                outline={outline ?? realAction !== "major"}
                 {...props}
                 className={newClassName}
               />
diff --git a/FrontEnd/src/components/button/FlatButton.tsx b/FrontEnd/src/components/button/FlatButton.tsx
index 9f074dd6..aad02e76 100644
--- a/FrontEnd/src/components/button/FlatButton.tsx
+++ b/FrontEnd/src/components/button/FlatButton.tsx
@@ -1,12 +1,12 @@
 import { ComponentPropsWithoutRef, Ref } from "react";
 import classNames from "classnames";
 
-import { Text, useC, ThemeColor } from "../common";
+import { Text, useC, ClickableColor } from "../common";
 
 import "./FlatButton.css";
 
 interface FlatButtonProps extends ComponentPropsWithoutRef<"button"> {
-  color?: ThemeColor;
+  color?: ClickableColor;
   text?: Text;
   buttonRef?: Ref<HTMLButtonElement> | null;
 }
diff --git a/FrontEnd/src/components/button/IconButton.tsx b/FrontEnd/src/components/button/IconButton.tsx
index 95c58887..e0862167 100644
--- a/FrontEnd/src/components/button/IconButton.tsx
+++ b/FrontEnd/src/components/button/IconButton.tsx
@@ -1,13 +1,13 @@
 import { ComponentPropsWithoutRef } from "react";
 import classNames from "classnames";
 
-import { ThemeColor } from "../common";
+import { ClickableColor } from "../common";
 
 import "./IconButton.css";
 
 interface IconButtonProps extends ComponentPropsWithoutRef<"i"> {
   icon: string;
-  color?: ThemeColor | "grayscale";
+  color?: ClickableColor;
   large?: boolean;
   disabled?: boolean; // TODO: Not implemented
 }
diff --git a/FrontEnd/src/components/button/LoadingButton.tsx b/FrontEnd/src/components/button/LoadingButton.tsx
index d9d41ddb..9d65a2b3 100644
--- a/FrontEnd/src/components/button/LoadingButton.tsx
+++ b/FrontEnd/src/components/button/LoadingButton.tsx
@@ -1,12 +1,12 @@
 import classNames from "classnames";
 
-import { I18nText, ThemeColor, useC } from "../common";
+import { I18nText, ClickableColor, useC } from "../common";
 import Spinner from "../Spinner";
 
 import "./LoadingButton.css";
 
 interface LoadingButtonProps extends React.ComponentPropsWithoutRef<"button"> {
-  color?: ThemeColor;
+  color?: ClickableColor;
   text?: I18nText;
   loading?: boolean;
 }
diff --git a/FrontEnd/src/components/common.ts b/FrontEnd/src/components/common.ts
index 835a8b4a..48473269 100644
--- a/FrontEnd/src/components/common.ts
+++ b/FrontEnd/src/components/common.ts
@@ -12,6 +12,8 @@ export const themeColors = [
 
 export type ThemeColor = (typeof themeColors)[number];
 
+export type ClickableColor = ThemeColor | "grayscale" | "minor";
+
 export { breakpoints } from "./breakpoints";
 
 export * as geometry from "~src/utilities/geometry";
diff --git a/FrontEnd/src/components/dialog/FullPageDialog.tsx b/FrontEnd/src/components/dialog/FullPageDialog.tsx
index 6368fc0a..cba57e21 100644
--- a/FrontEnd/src/components/dialog/FullPageDialog.tsx
+++ b/FrontEnd/src/components/dialog/FullPageDialog.tsx
@@ -38,7 +38,7 @@ const FullPageDialog: React.FC<FullPageDialogProps> = ({
         <div
           className={classnames(
             "cru-full-page-content-container",
-            contentContainerClassName
+            contentContainerClassName,
           )}
         >
           {children}
@@ -46,7 +46,7 @@ const FullPageDialog: React.FC<FullPageDialogProps> = ({
       </div>
     </CSSTransition>,
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    document.getElementById("portal")!
+    document.getElementById("portal")!,
   );
 };
 
diff --git a/FrontEnd/src/components/dialog/OperationDialog.tsx b/FrontEnd/src/components/dialog/OperationDialog.tsx
index 4b4ceb36..6ca4d0a0 100644
--- a/FrontEnd/src/components/dialog/OperationDialog.tsx
+++ b/FrontEnd/src/components/dialog/OperationDialog.tsx
@@ -8,7 +8,7 @@ import {
   Initializer as InputInitializer,
   InputConfirmValueDict,
 } from "../input";
-import { ButtonRow } from "../button";
+import { ButtonRowV2 } from "../button";
 import Dialog from "./Dialog";
 import DialogContainer from "./DialogContainer";
 import { useDialogController } from "./DialogProvider";
@@ -140,7 +140,7 @@ function OperationDialog<TData>(props: OperationDialogProps<TData>) {
   }
 
   let body: ReactNode;
-  let buttons: ComponentProps<typeof ButtonRow>["buttons"];
+  let buttons: ComponentProps<typeof ButtonRowV2>["buttons"];
 
   if (step.type === "input" || step.type === "process") {
     const isProcessing = step.type === "process";
@@ -161,25 +161,19 @@ function OperationDialog<TData>(props: OperationDialogProps<TData>) {
     buttons = [
       {
         key: "cancel",
-        type: "normal",
-        props: {
-          text: "operationDialog.cancel",
-          color: "secondary",
-          outline: true,
-          onClick: close,
-          disabled: isProcessing,
-        },
+        text: "operationDialog.cancel",
+        onClick: close,
+        disabled: isProcessing,
       },
       {
         key: "confirm",
         type: "loading",
-        props: {
-          text: "operationDialog.confirm",
-          color,
-          loading: isProcessing,
-          disabled: hasErrorAndDirty,
-          onClick: onConfirm,
-        },
+        action: "major",
+        text: "operationDialog.confirm",
+        color,
+        loading: isProcessing,
+        disabled: hasErrorAndDirty,
+        onClick: onConfirm,
       },
     ];
   } else {
@@ -207,18 +201,17 @@ function OperationDialog<TData>(props: OperationDialogProps<TData>) {
       {
         key: "ok",
         type: "normal",
-        props: {
-          text: "operationDialog.ok",
-          color: "primary",
-          onClick: close,
-        },
+        action: "major",
+        color: "create",
+        text: "operationDialog.ok",
+        onClick: close,
       },
     ];
   }
 
   return (
     <Dialog color={color}>
-      <DialogContainer title={title} titleColor={color} buttons={buttons}>
+      <DialogContainer title={title} titleColor={color} buttonsV2={buttons}>
         {body}
       </DialogContainer>
     </Dialog>
diff --git a/FrontEnd/src/components/index.css b/FrontEnd/src/components/index.css
index a8f5e9a5..eb1f5b46 100644
--- a/FrontEnd/src/components/index.css
+++ b/FrontEnd/src/components/index.css
@@ -9,7 +9,7 @@
 body {
   font-family: var(--cru-default-font-family);
   background: var(--cru-body-background-color);
-  color: var(--cru-text-primary-color);
+  color: var(--cru-text-major-color);
   line-height: 1.2;
 }
 
diff --git a/FrontEnd/src/components/theme.css b/FrontEnd/src/components/theme.css
index 67340b6f..bd7805cf 100644
--- a/FrontEnd/src/components/theme.css
+++ b/FrontEnd/src/components/theme.css
@@ -34,16 +34,16 @@
 :root {
   --cru-background-color: hsl(0 0% 100%);
   --cru-container-background-color: hsl(0 0% 97%);
-  --cru-text-primary-color: hsl(0 0% 0%);
-  --cru-text-secondary-color: hsl(0 0% 38%);
+  --cru-text-major-color: hsl(0 0% 0%);
+  --cru-text-minor-color: hsl(0 0% 38%);
 }
 
 @media (prefers-color-scheme: dark) {
   :root {
     --cru-background-color: hsl(0 0% 0%);
     --cru-container-background-color: hsl(0 0% 2%);
-    --cru-text-primary-color: hsl(0 0% 100%);
-    --cru-text-secondary-color: hsl(0 0% 85%);
+    --cru-text-major-color: hsl(0 0% 100%);
+    --cru-text-minor-color: hsl(0 0% 85%);
   }
 }
 
@@ -87,11 +87,19 @@
   --cru-clickable-grayscale-hover-color: hsl(0 0% 92%);
   --cru-clickable-grayscale-focus-color: hsl(0 0% 92%);
   --cru-clickable-grayscale-active-color: hsl(0 0% 88%);
+  --cru-clickable-minor-normal-color: hsl(0 0% 30%);
+  --cru-clickable-minor-hover-color: hsl(0 0% 40%);
+  --cru-clickable-minor-focus-color: hsl(0 0% 40%);
+  --cru-clickable-minor-active-color: hsl(0 0% 45%);
   --cru-clickable-disabled-color: hsl(0 0% 50%);
 }
 
 @media (prefers-color-scheme: dark) {
   :root {
+    --cru-clickable-minor-normal-color: hsl(0 0% 74%);
+    --cru-clickable-minor-hover-color: hsl(0 0% 82%);
+    --cru-clickable-minor-focus-color: hsl(0 0% 82%);
+    --cru-clickable-minor-active-color: hsl(0 0% 90%);
     --cru-clickable-grayscale-normal-color: hsl(0 0% 0%);
     --cru-clickable-grayscale-hover-color: hsl(0 0% 10%);
     --cru-clickable-grayscale-focus-color: hsl(0 0% 10%);
@@ -134,6 +142,13 @@
   --cru-clickable-active-color: var(--cru-clickable-grayscale-active-color);
 }
 
+.cru-clickable-minor {
+  --cru-clickable-normal-color: var(--cru-clickable-minor-normal-color);
+  --cru-clickable-hover-color: var(--cru-clickable-minor-hover-color);
+  --cru-clickable-focus-color: var(--cru-clickable-minor-focus-color);
+  --cru-clickable-active-color: var(--cru-clickable-minor-active-color);
+}
+
 /* button colors */
 :root {
   /* push button colors */
diff --git a/FrontEnd/src/pages/setting/index.css b/FrontEnd/src/pages/setting/index.css
index a8a44524..19e7cff4 100644
--- a/FrontEnd/src/pages/setting/index.css
+++ b/FrontEnd/src/pages/setting/index.css
@@ -38,7 +38,7 @@
 }
 
 .setting-item-label-sub {
-  color: var(--cru-text-secondary-color);
+  color: var(--cru-text-minor-color);
 }
 
 .setting-item-value-area {
@@ -50,7 +50,7 @@
 }
 
 .register-code {
-  background: var(--cru-text-primary-color);
+  background: var(--cru-text-major-color);
   color: var(--cru-background-color);
   border-radius: 3px;
   padding: 0.2em;
diff --git a/FrontEnd/src/pages/timeline/TimelineCard.css b/FrontEnd/src/pages/timeline/TimelineCard.css
index ab1a1fd0..29e59b62 100644
--- a/FrontEnd/src/pages/timeline/TimelineCard.css
+++ b/FrontEnd/src/pages/timeline/TimelineCard.css
@@ -17,13 +17,13 @@
 .timeline-card-title {
   display: inline-block;
   vertical-align: middle;
-  color: var(--cru-text-primary-color);
+  color: var(--cru-text-major-color);
   margin: 0.5em 1em;
 }
 
 .timeline-card-title-name {
   margin-inline-start: 1em;
-  color: var(--cru-text-secondary-color);
+  color: var(--cru-text-minor-color);
 }
 
 .timeline-card-user {
diff --git a/FrontEnd/src/pages/timeline/TimelinePostCreateView.css b/FrontEnd/src/pages/timeline/TimelinePostCreateView.css
index 5986e566..252340f6 100644
--- a/FrontEnd/src/pages/timeline/TimelinePostCreateView.css
+++ b/FrontEnd/src/pages/timeline/TimelinePostCreateView.css
@@ -17,8 +17,8 @@
   width: 100%;
   height: 100%;
   background-color: var(--cru-background-color);
-  color: var(--cru-text-primary-color);
-  border: 1px solid var(--cru-text-primary-color);
+  color: var(--cru-text-major-color);
+  border: 1px solid var(--cru-text-major-color);
   padding: 0.5em;
   border-radius: 5px;
 }
-- 
cgit v1.2.3

