aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FrontEnd/src/index.css53
-rw-r--r--FrontEnd/src/palette.ts43
-rw-r--r--FrontEnd/src/views/admin/UserAdmin.tsx20
-rw-r--r--FrontEnd/src/views/center/TimelineBoard.tsx3
-rw-r--r--FrontEnd/src/views/common/button/FlatButton.tsx2
-rw-r--r--FrontEnd/src/views/common/button/TextButton.css36
-rw-r--r--FrontEnd/src/views/common/button/TextButton.tsx36
7 files changed, 105 insertions, 88 deletions
diff --git a/FrontEnd/src/index.css b/FrontEnd/src/index.css
index ca0d4829..ff8c1866 100644
--- a/FrontEnd/src/index.css
+++ b/FrontEnd/src/index.css
@@ -81,59 +81,6 @@ textarea {
color: #ffc107;
}
-.text-button {
- background: transparent;
- border: none;
-}
-.text-button.primary {
- color: #0d6efd;
-}
-.text-button.primary:hover {
- color: #599bfe;
-}
-.text-button.secondary {
- color: #6c757d;
-}
-.text-button.secondary:hover {
- color: #939ba2;
-}
-.text-button.success {
- color: #198754;
-}
-.text-button.success:hover {
- color: #25c87c;
-}
-.text-button.info {
- color: #0dcaf0;
-}
-.text-button.info:hover {
- color: #54dbf6;
-}
-.text-button.warning {
- color: #ffc107;
-}
-.text-button.warning:hover {
- color: #ffd454;
-}
-.text-button.danger {
- color: #dc3545;
-}
-.text-button.danger:hover {
- color: #e77681;
-}
-.text-button.light {
- color: #f8f9fa;
-}
-.text-button.light:hover {
- color: white;
-}
-.text-button.dark {
- color: #212529;
-}
-.text-button.dark:hover {
- color: #434b53;
-}
-
.touch-action-none {
touch-action: none;
}
diff --git a/FrontEnd/src/palette.ts b/FrontEnd/src/palette.ts
index 11b3de85..6385df66 100644
--- a/FrontEnd/src/palette.ts
+++ b/FrontEnd/src/palette.ts
@@ -19,18 +19,19 @@ export interface PaletteColor {
[key: string]: string;
}
-export interface Palette {
- primary: PaletteColor;
- primaryEnhance: PaletteColor;
- secondary: PaletteColor;
- textPrimary: PaletteColor;
- textOnPrimary: PaletteColor;
- danger: PaletteColor;
- success: PaletteColor;
- [key: string]: PaletteColor;
-}
+const paletteColorList = [
+ "primary",
+ "primary-enhance",
+ "secondary",
+ "text-primary",
+ "text-on-primary",
+ "danger",
+ "success",
+] as const;
+
+export type PaletteColorType = typeof paletteColorList[number];
-export type PaletteColorType = keyof Palette;
+export type Palette = Record<PaletteColorType, PaletteColor>;
export function generatePaletteColor(color: string): PaletteColor {
const c = Color(color);
@@ -60,26 +61,24 @@ export function generatePalette(options: {
return {
primary: generatePaletteColor(p.toString()),
- primaryEnhance: generatePaletteColor(pe.toString()),
+ "primary-enhance": generatePaletteColor(pe.toString()),
secondary: generatePaletteColor(s.toString()),
- textPrimary: generatePaletteColor("#111111"),
- textOnPrimary: generatePaletteColor(p.lightness() > 60 ? "black" : "white"),
+ "text-primary": generatePaletteColor("#111111"),
+ "text-on-primary": generatePaletteColor(
+ p.lightness() > 60 ? "black" : "white"
+ ),
danger: generatePaletteColor("red"),
success: generatePaletteColor("green"),
};
}
export function generatePaletteCSS(palette: Palette): string {
- function toSnakeCase(s: string): string {
- return s.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
- }
-
const colors: [string, string][] = [];
- for (const paletteColorName in palette) {
- const paletteColor = palette[paletteColorName];
+ for (const colorType of paletteColorList) {
+ const paletteColor = palette[colorType];
for (const variant in paletteColor) {
- let key = `--tl-${toSnakeCase(paletteColorName)}`;
- if (variant !== "color") key += `-${toSnakeCase(variant)}`;
+ let key = `--tl-${colorType}`;
+ if (variant !== "color") key += `-${variant}`;
key += "-color";
colors.push([key, paletteColor[variant]]);
}
diff --git a/FrontEnd/src/views/admin/UserAdmin.tsx b/FrontEnd/src/views/admin/UserAdmin.tsx
index 558d3aee..eb141520 100644
--- a/FrontEnd/src/views/admin/UserAdmin.tsx
+++ b/FrontEnd/src/views/admin/UserAdmin.tsx
@@ -14,6 +14,7 @@ import {
UserPermission,
} from "@/http/user";
import { Trans, useTranslation } from "react-i18next";
+import TextButton from "../common/button/TextButton";
interface DialogProps<TData = undefined, TReturn = undefined> {
open: boolean;
@@ -230,15 +231,16 @@ const UserItem: React.FC<UserItemProps> = ({ user, on }) => {
className={classnames("edit-mask", !editMaskVisible && "d-none")}
onClick={() => setEditMaskVisible(false)}
>
- <button className="text-button primary" onClick={on[kModify]}>
- {t("admin:user.modify")}
- </button>
- <button className="text-button primary" onClick={on[kModifyPermission]}>
- {t("admin:user.modifyPermissions")}
- </button>
- <button className="text-button danger" onClick={on[kDelete]}>
- {t("admin:user.delete")}
- </button>
+ <TextButton text="admin:user.modify" onClick={on[kModify]} />
+ <TextButton
+ text="admin:user.modifyPermissions"
+ onClick={on[kModifyPermission]}
+ />
+ <TextButton
+ text="admin:user.delete"
+ color="danger"
+ onClick={on[kDelete]}
+ />
</div>
</ListGroup.Item>
);
diff --git a/FrontEnd/src/views/center/TimelineBoard.tsx b/FrontEnd/src/views/center/TimelineBoard.tsx
index a6a60b3d..e0a2d80e 100644
--- a/FrontEnd/src/views/center/TimelineBoard.tsx
+++ b/FrontEnd/src/views/center/TimelineBoard.tsx
@@ -1,7 +1,6 @@
import React from "react";
import classnames from "classnames";
import { Link } from "react-router-dom";
-import { useTranslation } from "react-i18next";
import { Spinner } from "react-bootstrap";
import { HttpTimelineInfo } from "@/http/timeline";
@@ -220,8 +219,6 @@ interface TimelineBoardUIProps {
const TimelineBoardUI: React.FC<TimelineBoardUIProps> = (props) => {
const { title, timelines, className, editHandler } = props;
- const { t } = useTranslation();
-
const editable = editHandler != null;
const [editing, setEditing] = React.useState<boolean>(false);
diff --git a/FrontEnd/src/views/common/button/FlatButton.tsx b/FrontEnd/src/views/common/button/FlatButton.tsx
index 0727eb88..24f47785 100644
--- a/FrontEnd/src/views/common/button/FlatButton.tsx
+++ b/FrontEnd/src/views/common/button/FlatButton.tsx
@@ -1,11 +1,11 @@
import React from "react";
import { useTranslation } from "react-i18next";
+import classNames from "classnames";
import { convertI18nText, I18nText } from "@/common";
import { PaletteColorType } from "@/palette";
import "./FlatButton.css";
-import classNames from "classnames";
function _FlatButton(
{
diff --git a/FrontEnd/src/views/common/button/TextButton.css b/FrontEnd/src/views/common/button/TextButton.css
new file mode 100644
index 00000000..dc5abaaa
--- /dev/null
+++ b/FrontEnd/src/views/common/button/TextButton.css
@@ -0,0 +1,36 @@
+.cru-text-button {
+ background: transparent;
+ border: none;
+}
+
+.cru-text-button.primary {
+ color: var(--tl-primary-color);
+}
+
+.cru-text-button.primary:hover {
+ color: var(--tl-primary-lighter-color);
+}
+
+.cru-text-button.secondary {
+ color: var(--tl-secondary-color);
+}
+
+.cru-text-button.secondary:hover {
+ color: var(--tl-secondary-lighter-color);
+}
+
+.cru-text-button.success {
+ color: var(--tl-success-color);
+}
+
+.cru-text-button.success:hover {
+ color: var(--tl-success-lighter-color);
+}
+
+.cru-text-button.danger {
+ color: var(--tl-danger-color);
+}
+
+.cru-text-button.danger:hover {
+ color: var(--tl-danger-lighter-color);
+}
diff --git a/FrontEnd/src/views/common/button/TextButton.tsx b/FrontEnd/src/views/common/button/TextButton.tsx
new file mode 100644
index 00000000..2014158a
--- /dev/null
+++ b/FrontEnd/src/views/common/button/TextButton.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+import { useTranslation } from "react-i18next";
+import classNames from "classnames";
+
+import { convertI18nText, I18nText } from "@/common";
+import { PaletteColorType } from "@/palette";
+
+import "./TextButton.css";
+
+function _TextButton(
+ {
+ text,
+ color,
+ onClick,
+ }: {
+ text: I18nText;
+ color?: PaletteColorType;
+ onClick?: () => void;
+ },
+ ref: React.ForwardedRef<HTMLButtonElement>
+): React.ReactElement | null {
+ const { t } = useTranslation();
+
+ return (
+ <button
+ ref={ref}
+ className={classNames("cru-text-button", color ?? "primary")}
+ onClick={onClick}
+ >
+ {convertI18nText(text, t)}
+ </button>
+ );
+}
+
+const TextButton = React.forwardRef(_TextButton);
+export default TextButton;