aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-07-15 17:02:00 +0800
committercrupest <crupest@outlook.com>2023-07-15 17:02:00 +0800
commit85659d977ac501a13886c1c7098763935af416e2 (patch)
tree7071c8a63f7d2492fa657d92ec21d17338ac2550 /FrontEnd
parent59c424a38809be6afb170f11eadb0e4d14f10f69 (diff)
downloadtimeline-85659d977ac501a13886c1c7098763935af416e2.tar.gz
timeline-85659d977ac501a13886c1c7098763935af416e2.tar.bz2
timeline-85659d977ac501a13886c1c7098763935af416e2.zip
...
Diffstat (limited to 'FrontEnd')
-rw-r--r--FrontEnd/src/views/common/AppBar.css15
-rw-r--r--FrontEnd/src/views/common/AppBar.tsx24
-rw-r--r--FrontEnd/src/views/common/alert/alert.css10
-rw-r--r--FrontEnd/src/views/common/button/Button.css52
-rw-r--r--FrontEnd/src/views/common/button/FlatButton.css31
-rw-r--r--FrontEnd/src/views/common/button/IconButton.css2
-rw-r--r--FrontEnd/src/views/common/index.css14
-rw-r--r--FrontEnd/src/views/common/menu/Menu.css6
-rw-r--r--FrontEnd/src/views/common/theme-color.css319
-rw-r--r--FrontEnd/src/views/common/theme.css31
-rw-r--r--FrontEnd/tools/theme-generator.ts366
11 files changed, 385 insertions, 485 deletions
diff --git a/FrontEnd/src/views/common/AppBar.css b/FrontEnd/src/views/common/AppBar.css
index 3ec4fa36..272a99ad 100644
--- a/FrontEnd/src/views/common/AppBar.css
+++ b/FrontEnd/src/views/common/AppBar.css
@@ -16,16 +16,18 @@
}
.app-bar a {
- color: var(--cru-primary-t1-color);
+ color: var(--cru-primary-on-color);
text-decoration: none;
margin: 0 1em;
transition: color 1s;
}
+
.app-bar a:hover {
- color: var(--cru-primary-t-color);
+ color: var(--cru-primary-on-color);
}
+
.app-bar a.active {
- color: var(--cru-primary-t-color);
+ color: var(--cru-primary-on-color);
}
.app-bar-brand {
@@ -65,22 +67,27 @@
background-color: var(--cru-primary-color);
flex-direction: column;
}
+
.small-screen .app-bar-main-area.app-bar-collapse {
transform: scale(1, 0);
}
+
.small-screen .app-bar-main-area a {
text-align: left;
padding: 0.5em 0.5em;
}
+
.small-screen .app-bar-link-area {
flex-direction: column;
align-items: stretch;
}
+
.small-screen .app-bar-user-area {
flex-direction: column;
align-items: stretch;
margin-left: unset;
}
+
.small-screen .app-bar-avatar {
align-self: flex-end;
}
@@ -92,4 +99,4 @@
color: var(--cru-primary-t-color);
cursor: pointer;
user-select: none;
-}
+} \ No newline at end of file
diff --git a/FrontEnd/src/views/common/AppBar.tsx b/FrontEnd/src/views/common/AppBar.tsx
index 278c70fd..444d903e 100644
--- a/FrontEnd/src/views/common/AppBar.tsx
+++ b/FrontEnd/src/views/common/AppBar.tsx
@@ -1,9 +1,9 @@
import * as React from "react";
import classnames from "classnames";
-import { useTranslation } from "react-i18next";
import { Link, NavLink } from "react-router-dom";
import { useMediaQuery } from "react-responsive";
+import { useC } from "./common";
import { useUser } from "@/services/user";
import TimelineLogo from "./TimelineLogo";
@@ -11,8 +11,8 @@ import UserAvatar from "./user/UserAvatar";
import "./AppBar.css";
-const AppBar: React.FC = () => {
- const { t } = useTranslation();
+export default function AppBar() {
+ const c = useC();
const user = useUser();
const hasAdministrationPermission = user && user.hasAdministrationPermission;
@@ -26,7 +26,7 @@ const AppBar: React.FC = () => {
const createLink = (
link: string,
label: React.ReactNode,
- className?: string
+ className?: string,
): React.ReactNode => (
<NavLink
to={link}
@@ -51,14 +51,14 @@ const AppBar: React.FC = () => {
<div
className={classnames(
"app-bar-main-area",
- !expand && "app-bar-collapse"
+ !expand && "app-bar-collapse",
)}
>
<div className="app-bar-link-area">
- {createLink("/settings", t("nav.settings"))}
- {createLink("/about", t("nav.about"))}
+ {createLink("/settings", c("nav.settings"))}
+ {createLink("/about", c("nav.about"))}
{hasAdministrationPermission &&
- createLink("/admin", t("nav.administration"))}
+ createLink("/admin", c("nav.administration"))}
</div>
<div className="app-bar-user-area">
@@ -69,13 +69,11 @@ const AppBar: React.FC = () => {
username={user.username}
className="cru-avatar small cru-round cursor-pointer ml-auto"
/>,
- "app-bar-avatar"
+ "app-bar-avatar",
)
- : createLink("/login", t("nav.login"))}
+ : createLink("/login", c("nav.login"))}
</div>
</div>
</nav>
);
-};
-
-export default AppBar;
+}
diff --git a/FrontEnd/src/views/common/alert/alert.css b/FrontEnd/src/views/common/alert/alert.css
index 83e1af28..54c2b87f 100644
--- a/FrontEnd/src/views/common/alert/alert.css
+++ b/FrontEnd/src/views/common/alert/alert.css
@@ -5,9 +5,9 @@
.cru-alert {
border-radius: 5px;
- border: var(--cru-theme-color) 1px solid;
- color: var(--cru-theme-t-color);
- background-color: var(--cru-theme-b1-color);
+ border: var(--cru-key-color) 1px solid;
+ color: var(--cru-key-t-color);
+ background-color: var(--cru-key-b1-color);
display: flex;
overflow: hidden;
@@ -25,9 +25,9 @@
display: flex;
align-items: center;
justify-content: center;
- background-color: var(--cru-theme-t-color);
+ background-color: var(--cru-key-t-color);
}
.cru-alert-close-button {
- color: var(--cru-theme-color);
+ color: var(--cru-key-color);
}
diff --git a/FrontEnd/src/views/common/button/Button.css b/FrontEnd/src/views/common/button/Button.css
index 0df22ebe..dacea3e1 100644
--- a/FrontEnd/src/views/common/button/Button.css
+++ b/FrontEnd/src/views/common/button/Button.css
@@ -1,46 +1,52 @@
-.cru-button:not(.outline) {
- color: var(--cru-light-color);
- cursor: pointer;
- padding: 0.2em 0.5em;
- border-radius: 0.2em;
- border: none;
+.cru-button {
+ font-size: 1rem;
+ padding: 0.4em 0.8em;
transition: all 0.5s;
- background-color: var(--cru-theme-color);
+ border-radius: 0.2em;
+ border: 1px solid;
+ cursor: pointer;
+}
+
+.cru-button:not(.outline) {
+ color: var(--cru-key-on-color);
+ background-color: var(--cru-key-color);
+ border-color: var(--cru-key-color);
}
.cru-button:not(.outline):hover {
- background-color: var(--cru-theme-d1-color);
+ filter: brightness(var(--cru-hover-darkness));
+}
+
+.cru-button:not(.outline):focus {
+ filter: brightness(var(--cru-focus-darkness));
}
.cru-button:not(.outline):active {
- background-color: var(--cru-theme-d2-color);
+ filter: brightness(var(--cru-press-darkness));
}
.cru-button:not(.outline):disabled {
- background-color: var(--cru-disabled-color);
+ background-color: var(--cru-surface-on-color);
cursor: auto;
}
+
.cru-button.outline {
- color: var(--cru-theme-color);
- border: var(--cru-theme-color) 1px solid;
- cursor: pointer;
- padding: 0.2em 0.5em;
- border-radius: 0.2em;
- transition: all 0.6s;
- background-color: var(--cru-background-color);
+ color: var(--cru-key-color);
+ border: var(--cru-key-color) 1px solid;
+ background-color: var(--cru-surface-color);
}
.cru-button.outline:hover {
- color: var(--cru-theme-d1-color);
- border-color: var(--cru-theme-d1-color);
- background-color: var(--cru-background-color);
+ filter: brightness(var(--cru-hover-brightness));
+}
+
+.cru-button.outline:focus {
+ filter: brightness(var(--cru-focus-brightness));
}
.cru-button.outline:active {
- color: var(--cru-theme-l2-color);
- border-color: var(--cru-theme-l2-color);
- background-color: var(--cru-background-1-color);
+ filter: brightness(var(--cru-press-brightness));
}
.cru-button.outline:disabled {
diff --git a/FrontEnd/src/views/common/button/FlatButton.css b/FrontEnd/src/views/common/button/FlatButton.css
index 01eabca9..f9a7d772 100644
--- a/FrontEnd/src/views/common/button/FlatButton.css
+++ b/FrontEnd/src/views/common/button/FlatButton.css
@@ -1,18 +1,27 @@
.cru-flat-button {
- cursor: pointer;
- padding: 0.2em 0.5em;
+ font-size: 1rem;
+ padding: 0.4em 0.8em;
+ transition: all 0.5s;
border-radius: 0.2em;
- border: none;
- background-color: transparent;
- transition: all 0.6s;
- color: var(--cru-theme-color);
+ background-color: var(--cru-surface-color);
+ border: 1px none;
+ color: var(--cru-key-color);
+ cursor: pointer;
}
-.cru-flat-button.disabled {
- color: var(--cru-disabled-color);
- cursor: default;
+.cru-flat-button:hover {
+ filter: brightness(var(--cru-hover-darkness));
}
-.cru-flat-button:hover:not(.disabled) {
- background-color: #e9ecef;
+.cru-flat-button:focus {
+ filter: brightness(var(--cru-focus-darkness));
}
+
+.cru-flat-button:active {
+ filter: brightness(var(--cru-press-darkness));
+}
+
+.cru-flat-button.disabled {
+ color: var(--cru-disabled-color);
+ cursor: auto;
+} \ No newline at end of file
diff --git a/FrontEnd/src/views/common/button/IconButton.css b/FrontEnd/src/views/common/button/IconButton.css
index 45fb103c..25c5f84c 100644
--- a/FrontEnd/src/views/common/button/IconButton.css
+++ b/FrontEnd/src/views/common/button/IconButton.css
@@ -1,5 +1,5 @@
.cru-icon-button {
- color: var(--cru-theme-color);
+ color: var(--cru-key-color);
font-size: 1.4rem;
background: none;
border: none;
diff --git a/FrontEnd/src/views/common/index.css b/FrontEnd/src/views/common/index.css
index 9d69997b..bd556a81 100644
--- a/FrontEnd/src/views/common/index.css
+++ b/FrontEnd/src/views/common/index.css
@@ -6,10 +6,18 @@
margin-block: 0;
}
+*::before {
+ box-sizing: border-box;
+}
+
+*::after {
+ box-sizing: border-box;
+}
+
body {
- background: var(--cru-bg-color);
- color: var(--cru-text-color);
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ font-family: var(--cru-default-font-family);
+ background: var(--cru-surface-color);
+ color: var(--cru-surface-on-color);
}
diff --git a/FrontEnd/src/views/common/menu/Menu.css b/FrontEnd/src/views/common/menu/Menu.css
index c3fa82c4..93c229f0 100644
--- a/FrontEnd/src/views/common/menu/Menu.css
+++ b/FrontEnd/src/views/common/menu/Menu.css
@@ -7,12 +7,12 @@
padding: 0.5em 1.5em;
cursor: pointer;
transition: all 0.5s;
- color: var(--cru-theme-color);
+ color: var(--cru-key-color);
}
.cru-menu-item:hover {
- color: var(--cru-theme-t-color);
- background-color: var(--cru-theme-color);
+ color: var(--cru-key-t-color);
+ background-color: var(--cru-key-color);
}
.cru-menu-item-icon {
diff --git a/FrontEnd/src/views/common/theme-color.css b/FrontEnd/src/views/common/theme-color.css
index 9dfa1d9a..7cb9a8f8 100644
--- a/FrontEnd/src/views/common/theme-color.css
+++ b/FrontEnd/src/views/common/theme-color.css
@@ -1,260 +1,109 @@
/* Generated by theme-generator.ts */
:root {
- --cru-primary-color: hsl(210 100% 50%);
- --cru-primary-l1-color: hsl(210 100% 55%);
- --cru-primary-l2-color: hsl(210 100% 60%);
- --cru-primary-l3-color: hsl(210 100% 65%);
- --cru-primary-d1-color: hsl(210 100% 45%);
- --cru-primary-d2-color: hsl(210 100% 40%);
- --cru-primary-d3-color: hsl(210 100% 35%);
- --cru-primary-f1-color: hsl(210 100% 55%);
- --cru-primary-f2-color: hsl(210 100% 60%);
- --cru-primary-f3-color: hsl(210 100% 65%);
- --cru-primary-b1-color: hsl(210 100% 45%);
- --cru-primary-b2-color: hsl(210 100% 40%);
- --cru-primary-b3-color: hsl(210 100% 35%);
- --cru-secondary-color: hsl(40 100% 50%);
- --cru-secondary-l1-color: hsl(40 100% 55%);
- --cru-secondary-l2-color: hsl(40 100% 60%);
- --cru-secondary-l3-color: hsl(40 100% 65%);
- --cru-secondary-d1-color: hsl(40 100% 45%);
- --cru-secondary-d2-color: hsl(40 100% 40%);
- --cru-secondary-d3-color: hsl(40 100% 35%);
- --cru-secondary-f1-color: hsl(40 100% 55%);
- --cru-secondary-f2-color: hsl(40 100% 60%);
- --cru-secondary-f3-color: hsl(40 100% 65%);
- --cru-secondary-b1-color: hsl(40 100% 45%);
- --cru-secondary-b2-color: hsl(40 100% 40%);
- --cru-secondary-b3-color: hsl(40 100% 35%);
- --cru-tertiary-color: hsl(160 100% 50%);
- --cru-tertiary-l1-color: hsl(160 100% 55%);
- --cru-tertiary-l2-color: hsl(160 100% 60%);
- --cru-tertiary-l3-color: hsl(160 100% 65%);
- --cru-tertiary-d1-color: hsl(160 100% 45%);
- --cru-tertiary-d2-color: hsl(160 100% 40%);
- --cru-tertiary-d3-color: hsl(160 100% 35%);
- --cru-tertiary-f1-color: hsl(160 100% 55%);
- --cru-tertiary-f2-color: hsl(160 100% 60%);
- --cru-tertiary-f3-color: hsl(160 100% 65%);
- --cru-tertiary-b1-color: hsl(160 100% 45%);
- --cru-tertiary-b2-color: hsl(160 100% 40%);
- --cru-tertiary-b3-color: hsl(160 100% 35%);
- --cru-danger-color: hsl(0 100% 50%);
- --cru-danger-l1-color: hsl(0 100% 55%);
- --cru-danger-l2-color: hsl(0 100% 60%);
- --cru-danger-l3-color: hsl(0 100% 65%);
- --cru-danger-d1-color: hsl(0 100% 45%);
- --cru-danger-d2-color: hsl(0 100% 40%);
- --cru-danger-d3-color: hsl(0 100% 35%);
- --cru-danger-f1-color: hsl(0 100% 55%);
- --cru-danger-f2-color: hsl(0 100% 60%);
- --cru-danger-f3-color: hsl(0 100% 65%);
- --cru-danger-b1-color: hsl(0 100% 45%);
- --cru-danger-b2-color: hsl(0 100% 40%);
- --cru-danger-b3-color: hsl(0 100% 35%);
- --cru-success-color: hsl(120 60% 50%);
- --cru-success-l1-color: hsl(120 60% 55%);
- --cru-success-l2-color: hsl(120 60% 60%);
- --cru-success-l3-color: hsl(120 60% 65%);
- --cru-success-d1-color: hsl(120 60% 45%);
- --cru-success-d2-color: hsl(120 60% 40%);
- --cru-success-d3-color: hsl(120 60% 35%);
- --cru-success-f1-color: hsl(120 60% 55%);
- --cru-success-f2-color: hsl(120 60% 60%);
- --cru-success-f3-color: hsl(120 60% 65%);
- --cru-success-b1-color: hsl(120 60% 45%);
- --cru-success-b2-color: hsl(120 60% 40%);
- --cru-success-b3-color: hsl(120 60% 35%);
- --cru-text-color: hsl(0 0% 0%);
- --cru-text-1-color: hsl(0 0% 5%);
- --cru-text-2-color: hsl(0 0% 10%);
- --cru-text-3-color: hsl(0 0% 15%);
- --cru-bg-color: hsl(0 0% 100%);
- --cru-bg-1-color: hsl(0 0% 95%);
- --cru-bg-2-color: hsl(0 0% 90%);
- --cru-bg-3-color: hsl(0 0% 85%);
- --cru-light-color: hsl(0 0% 100%);
- --cru-light-1-color: hsl(0 0% 95%);
- --cru-light-2-color: hsl(0 0% 90%);
- --cru-light-3-color: hsl(0 0% 85%);
- --cru-dark-color: hsl(0 0% 0%);
- --cru-dark-1-color: hsl(0 0% 5%);
- --cru-dark-2-color: hsl(0 0% 10%);
- --cru-dark-3-color: hsl(0 0% 15%);
- --cru-disabled-color: hsl(0 0% 75%);
- --cru-disabled-1-color: hsl(0 0% 70%);
- --cru-disabled-2-color: hsl(0 0% 65%);
- --cru-disabled-3-color: hsl(0 0% 60%);
+ --cru-primary-color: hsl(210 100% 40%);
+ --cru-primary-on-color: hsl(210 100% 100%);
+ --cru-primary-container-color: hsl(210 100% 90%);
+ --cru-primary-on-container-color: hsl(210 100% 10%);
+ --cru-secondary-color: hsl(40 100% 40%);
+ --cru-secondary-on-color: hsl(40 100% 100%);
+ --cru-secondary-container-color: hsl(40 100% 90%);
+ --cru-secondary-on-container-color: hsl(40 100% 10%);
+ --cru-tertiary-color: hsl(160 100% 40%);
+ --cru-tertiary-on-color: hsl(160 100% 100%);
+ --cru-tertiary-container-color: hsl(160 100% 90%);
+ --cru-tertiary-on-container-color: hsl(160 100% 10%);
+ --cru-danger-color: hsl(0 100% 40%);
+ --cru-danger-on-color: hsl(0 100% 100%);
+ --cru-danger-container-color: hsl(0 100% 90%);
+ --cru-danger-on-container-color: hsl(0 100% 10%);
+ --cru-success-color: hsl(120 60% 40%);
+ --cru-success-on-color: hsl(120 60% 100%);
+ --cru-success-container-color: hsl(120 60% 90%);
+ --cru-success-on-container-color: hsl(120 60% 10%);
+ --cru-surface-dim-color: hsl(0 0% 87%);
+ --cru-surface-color: hsl(0 0% 98%);
+ --cru-surface-bright-color: hsl(0 0% 98%);
+ --cru-surface-container-lowest-color: hsl(0 0% 100%);
+ --cru-surface-container-low-color: hsl(0 0% 96%);
+ --cru-surface-container-color: hsl(0 0% 94%);
+ --cru-surface-container-high-color: hsl(0 0% 92%);
+ --cru-surface-container-highest-color: hsl(0 0% 90%);
+ --cru-surface-on-color: hsl(0 0% 10%);
+ --cru-surface-on-variant-color: hsl(0 0% 30%);
+ --cru-surface-outline-color: hsl(0 0% 50%);
+ --cru-surface-outline-variant-color: hsl(0 0% 80%);
}
@media (prefers-color-scheme: dark) {
:root {
- --cru-primary-color: hsl(210 100% 50%);
- --cru-primary-l1-color: hsl(210 100% 55%);
- --cru-primary-l2-color: hsl(210 100% 60%);
- --cru-primary-l3-color: hsl(210 100% 65%);
- --cru-primary-d1-color: hsl(210 100% 45%);
- --cru-primary-d2-color: hsl(210 100% 40%);
- --cru-primary-d3-color: hsl(210 100% 35%);
- --cru-primary-f1-color: hsl(210 100% 45%);
- --cru-primary-f2-color: hsl(210 100% 40%);
- --cru-primary-f3-color: hsl(210 100% 35%);
- --cru-primary-b1-color: hsl(210 100% 55%);
- --cru-primary-b2-color: hsl(210 100% 60%);
- --cru-primary-b3-color: hsl(210 100% 65%);
- --cru-secondary-color: hsl(40 100% 50%);
- --cru-secondary-l1-color: hsl(40 100% 55%);
- --cru-secondary-l2-color: hsl(40 100% 60%);
- --cru-secondary-l3-color: hsl(40 100% 65%);
- --cru-secondary-d1-color: hsl(40 100% 45%);
- --cru-secondary-d2-color: hsl(40 100% 40%);
- --cru-secondary-d3-color: hsl(40 100% 35%);
- --cru-secondary-f1-color: hsl(40 100% 45%);
- --cru-secondary-f2-color: hsl(40 100% 40%);
- --cru-secondary-f3-color: hsl(40 100% 35%);
- --cru-secondary-b1-color: hsl(40 100% 55%);
- --cru-secondary-b2-color: hsl(40 100% 60%);
- --cru-secondary-b3-color: hsl(40 100% 65%);
- --cru-tertiary-color: hsl(160 100% 50%);
- --cru-tertiary-l1-color: hsl(160 100% 55%);
- --cru-tertiary-l2-color: hsl(160 100% 60%);
- --cru-tertiary-l3-color: hsl(160 100% 65%);
- --cru-tertiary-d1-color: hsl(160 100% 45%);
- --cru-tertiary-d2-color: hsl(160 100% 40%);
- --cru-tertiary-d3-color: hsl(160 100% 35%);
- --cru-tertiary-f1-color: hsl(160 100% 45%);
- --cru-tertiary-f2-color: hsl(160 100% 40%);
- --cru-tertiary-f3-color: hsl(160 100% 35%);
- --cru-tertiary-b1-color: hsl(160 100% 55%);
- --cru-tertiary-b2-color: hsl(160 100% 60%);
- --cru-tertiary-b3-color: hsl(160 100% 65%);
- --cru-danger-color: hsl(0 100% 50%);
- --cru-danger-l1-color: hsl(0 100% 55%);
- --cru-danger-l2-color: hsl(0 100% 60%);
- --cru-danger-l3-color: hsl(0 100% 65%);
- --cru-danger-d1-color: hsl(0 100% 45%);
- --cru-danger-d2-color: hsl(0 100% 40%);
- --cru-danger-d3-color: hsl(0 100% 35%);
- --cru-danger-f1-color: hsl(0 100% 45%);
- --cru-danger-f2-color: hsl(0 100% 40%);
- --cru-danger-f3-color: hsl(0 100% 35%);
- --cru-danger-b1-color: hsl(0 100% 55%);
- --cru-danger-b2-color: hsl(0 100% 60%);
- --cru-danger-b3-color: hsl(0 100% 65%);
- --cru-success-color: hsl(120 60% 50%);
- --cru-success-l1-color: hsl(120 60% 55%);
- --cru-success-l2-color: hsl(120 60% 60%);
- --cru-success-l3-color: hsl(120 60% 65%);
- --cru-success-d1-color: hsl(120 60% 45%);
- --cru-success-d2-color: hsl(120 60% 40%);
- --cru-success-d3-color: hsl(120 60% 35%);
- --cru-success-f1-color: hsl(120 60% 45%);
- --cru-success-f2-color: hsl(120 60% 40%);
- --cru-success-f3-color: hsl(120 60% 35%);
- --cru-success-b1-color: hsl(120 60% 55%);
- --cru-success-b2-color: hsl(120 60% 60%);
- --cru-success-b3-color: hsl(120 60% 65%);
- --cru-text-color: hsl(0 0% 100%);
- --cru-text-1-color: hsl(0 0% 95%);
- --cru-text-2-color: hsl(0 0% 90%);
- --cru-text-3-color: hsl(0 0% 85%);
- --cru-bg-color: hsl(0 0% 0%);
- --cru-bg-1-color: hsl(0 0% 5%);
- --cru-bg-2-color: hsl(0 0% 10%);
- --cru-bg-3-color: hsl(0 0% 15%);
- --cru-light-color: hsl(0 0% 100%);
- --cru-light-1-color: hsl(0 0% 95%);
- --cru-light-2-color: hsl(0 0% 90%);
- --cru-light-3-color: hsl(0 0% 85%);
- --cru-dark-color: hsl(0 0% 0%);
- --cru-dark-1-color: hsl(0 0% 5%);
- --cru-dark-2-color: hsl(0 0% 10%);
- --cru-dark-3-color: hsl(0 0% 15%);
- --cru-disabled-color: hsl(0 0% 25%);
- --cru-disabled-1-color: hsl(0 0% 30%);
- --cru-disabled-2-color: hsl(0 0% 35%);
- --cru-disabled-3-color: hsl(0 0% 40%);
+ --cru-primary-color: hsl(210 100% 80%);
+ --cru-primary-on-color: hsl(210 100% 20%);
+ --cru-primary-container-color: hsl(210 100% 30%);
+ --cru-primary-on-container-color: hsl(210 100% 90%);
+ --cru-secondary-color: hsl(40 100% 80%);
+ --cru-secondary-on-color: hsl(40 100% 20%);
+ --cru-secondary-container-color: hsl(40 100% 30%);
+ --cru-secondary-on-container-color: hsl(40 100% 90%);
+ --cru-tertiary-color: hsl(160 100% 80%);
+ --cru-tertiary-on-color: hsl(160 100% 20%);
+ --cru-tertiary-container-color: hsl(160 100% 30%);
+ --cru-tertiary-on-container-color: hsl(160 100% 90%);
+ --cru-danger-color: hsl(0 100% 80%);
+ --cru-danger-on-color: hsl(0 100% 20%);
+ --cru-danger-container-color: hsl(0 100% 30%);
+ --cru-danger-on-container-color: hsl(0 100% 90%);
+ --cru-success-color: hsl(120 60% 80%);
+ --cru-success-on-color: hsl(120 60% 20%);
+ --cru-success-container-color: hsl(120 60% 30%);
+ --cru-success-on-container-color: hsl(120 60% 90%);
+ --cru-surface-dim-color: hsl(0 0% 6%);
+ --cru-surface-color: hsl(0 0% 6%);
+ --cru-surface-bright-color: hsl(0 0% 24%);
+ --cru-surface-container-lowest-color: hsl(0 0% 4%);
+ --cru-surface-container-low-color: hsl(0 0% 10%);
+ --cru-surface-container-color: hsl(0 0% 12%);
+ --cru-surface-container-high-color: hsl(0 0% 17%);
+ --cru-surface-container-highest-color: hsl(0 0% 22%);
+ --cru-surface-on-color: hsl(0 0% 90%);
+ --cru-surface-on-variant-color: hsl(0 0% 80%);
+ --cru-surface-outline-color: hsl(0 0% 60%);
+ --cru-surface-outline-variant-color: hsl(0 0% 30%);
}
}
.cru-primary {
- --cru-theme-color: var(--cru-primary-color);
- --cru-theme-l1-color: var(--cru-primary-l1-color);
- --cru-theme-l2-color: var(--cru-primary-l2-color);
- --cru-theme-l3-color: var(--cru-primary-l3-color);
- --cru-theme-d1-color: var(--cru-primary-d1-color);
- --cru-theme-d2-color: var(--cru-primary-d2-color);
- --cru-theme-d3-color: var(--cru-primary-d3-color);
- --cru-theme-f1-color: var(--cru-primary-f1-color);
- --cru-theme-f2-color: var(--cru-primary-f2-color);
- --cru-theme-f3-color: var(--cru-primary-f3-color);
- --cru-theme-b1-color: var(--cru-primary-b1-color);
- --cru-theme-b2-color: var(--cru-primary-b2-color);
- --cru-theme-b3-color: var(--cru-primary-b3-color);
+ --cru-key-color: var(--cru-primary-color);
+ --cru-key-on-color: var(--cru-primary-on-color);
+ --cru-key-container-color: var(--cru-primary-container-color);
+ --cru-key-on-container-color: var(--cru-primary-on-container-color);
}
.cru-secondary {
- --cru-theme-color: var(--cru-secondary-color);
- --cru-theme-l1-color: var(--cru-secondary-l1-color);
- --cru-theme-l2-color: var(--cru-secondary-l2-color);
- --cru-theme-l3-color: var(--cru-secondary-l3-color);
- --cru-theme-d1-color: var(--cru-secondary-d1-color);
- --cru-theme-d2-color: var(--cru-secondary-d2-color);
- --cru-theme-d3-color: var(--cru-secondary-d3-color);
- --cru-theme-f1-color: var(--cru-secondary-f1-color);
- --cru-theme-f2-color: var(--cru-secondary-f2-color);
- --cru-theme-f3-color: var(--cru-secondary-f3-color);
- --cru-theme-b1-color: var(--cru-secondary-b1-color);
- --cru-theme-b2-color: var(--cru-secondary-b2-color);
- --cru-theme-b3-color: var(--cru-secondary-b3-color);
+ --cru-key-color: var(--cru-secondary-color);
+ --cru-key-on-color: var(--cru-secondary-on-color);
+ --cru-key-container-color: var(--cru-secondary-container-color);
+ --cru-key-on-container-color: var(--cru-secondary-on-container-color);
}
.cru-tertiary {
- --cru-theme-color: var(--cru-tertiary-color);
- --cru-theme-l1-color: var(--cru-tertiary-l1-color);
- --cru-theme-l2-color: var(--cru-tertiary-l2-color);
- --cru-theme-l3-color: var(--cru-tertiary-l3-color);
- --cru-theme-d1-color: var(--cru-tertiary-d1-color);
- --cru-theme-d2-color: var(--cru-tertiary-d2-color);
- --cru-theme-d3-color: var(--cru-tertiary-d3-color);
- --cru-theme-f1-color: var(--cru-tertiary-f1-color);
- --cru-theme-f2-color: var(--cru-tertiary-f2-color);
- --cru-theme-f3-color: var(--cru-tertiary-f3-color);
- --cru-theme-b1-color: var(--cru-tertiary-b1-color);
- --cru-theme-b2-color: var(--cru-tertiary-b2-color);
- --cru-theme-b3-color: var(--cru-tertiary-b3-color);
+ --cru-key-color: var(--cru-tertiary-color);
+ --cru-key-on-color: var(--cru-tertiary-on-color);
+ --cru-key-container-color: var(--cru-tertiary-container-color);
+ --cru-key-on-container-color: var(--cru-tertiary-on-container-color);
}
.cru-danger {
- --cru-theme-color: var(--cru-danger-color);
- --cru-theme-l1-color: var(--cru-danger-l1-color);
- --cru-theme-l2-color: var(--cru-danger-l2-color);
- --cru-theme-l3-color: var(--cru-danger-l3-color);
- --cru-theme-d1-color: var(--cru-danger-d1-color);
- --cru-theme-d2-color: var(--cru-danger-d2-color);
- --cru-theme-d3-color: var(--cru-danger-d3-color);
- --cru-theme-f1-color: var(--cru-danger-f1-color);
- --cru-theme-f2-color: var(--cru-danger-f2-color);
- --cru-theme-f3-color: var(--cru-danger-f3-color);
- --cru-theme-b1-color: var(--cru-danger-b1-color);
- --cru-theme-b2-color: var(--cru-danger-b2-color);
- --cru-theme-b3-color: var(--cru-danger-b3-color);
+ --cru-key-color: var(--cru-danger-color);
+ --cru-key-on-color: var(--cru-danger-on-color);
+ --cru-key-container-color: var(--cru-danger-container-color);
+ --cru-key-on-container-color: var(--cru-danger-on-container-color);
}
.cru-success {
- --cru-theme-color: var(--cru-success-color);
- --cru-theme-l1-color: var(--cru-success-l1-color);
- --cru-theme-l2-color: var(--cru-success-l2-color);
- --cru-theme-l3-color: var(--cru-success-l3-color);
- --cru-theme-d1-color: var(--cru-success-d1-color);
- --cru-theme-d2-color: var(--cru-success-d2-color);
- --cru-theme-d3-color: var(--cru-success-d3-color);
- --cru-theme-f1-color: var(--cru-success-f1-color);
- --cru-theme-f2-color: var(--cru-success-f2-color);
- --cru-theme-f3-color: var(--cru-success-f3-color);
- --cru-theme-b1-color: var(--cru-success-b1-color);
- --cru-theme-b2-color: var(--cru-success-b2-color);
- --cru-theme-b3-color: var(--cru-success-b3-color);
+ --cru-key-color: var(--cru-success-color);
+ --cru-key-on-color: var(--cru-success-on-color);
+ --cru-key-container-color: var(--cru-success-container-color);
+ --cru-key-on-container-color: var(--cru-success-on-container-color);
}
diff --git a/FrontEnd/src/views/common/theme.css b/FrontEnd/src/views/common/theme.css
index 28c16627..6cbc06b4 100644
--- a/FrontEnd/src/views/common/theme.css
+++ b/FrontEnd/src/views/common/theme.css
@@ -1,5 +1,36 @@
@import "./theme-color.css";
:root {
+ --cru-hover-lightness-change: 4%;
+ --cru-focus-lightness-change: 10%;
+ --cru-press-lightness-change: 10%;
+ --cru-drag-lightness-change: 15%;
+
+ --cru-hover-darkness: calc(100% - var(--cru-hover-lightness-change));
+ --cru-focus-darkness: calc(100% - var(--cru-focus-lightness-change));
+ --cru-press-darkness: calc(100% - var(--cru-press-lightness-change));
+ --cru-drag-darkness: calc(100% - var(--cru-drag-lightness-change));
+ --cru-hover-brightness: calc(100% + var(--cru-hover-lightness-change));
+ --cru-focus-brightness: calc(100% + var(--cru-focus-lightness-change));
+ --cru-press-brightness: calc(100% + var(--cru-press-lightness-change));
+ --cru-drag-brightness: calc(100% + var(--cru-drag-lightness-change));
+}
+
+/*
+:hover {
+ filter: brightness(var(--cru-hover-darkness));
+}
+
+:focus {
+ filter: brightness(var(--cru-focus-darkness));
+}
+
+:active {
+ filter: brightness(var(--cru-press-darkness));
+}
+*/
+
+:root {
+ --cru-default-font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--cru-card-border-radius: 8px;
} \ No newline at end of file
diff --git a/FrontEnd/tools/theme-generator.ts b/FrontEnd/tools/theme-generator.ts
index 704a1052..c1036d80 100644
--- a/FrontEnd/tools/theme-generator.ts
+++ b/FrontEnd/tools/theme-generator.ts
@@ -2,11 +2,10 @@
/**
* Color variable name scheme:
- * has variant: --[prefix]-[name]-[variant]-color: [color];
* no variant: --[prefix]-[name]-color: [color];
- * Variant scheme:
- * [variant-prefix][level]
- * eg. --cru-primary-color: [color]; --cru-primary-l1-color: [color];
+ * with variant: --[prefix]-[name]-[variant]-color: [color];
+ *
+ * Lightness variants come from material design (https://m3.material.io/styles/color/the-color-system/tokens)
*/
import { stdout } from "process";
@@ -29,12 +28,8 @@ class HslColor implements Color {
public l: number,
) {}
- lighter(level: number): HslColor {
- return new HslColor(this.h, this.s, this.l + level * 5);
- }
-
- darker(level: number): HslColor {
- return new HslColor(this.h, this.s, this.l - level * 5);
+ withLightness(lightness: number): HslColor {
+ return new HslColor(this.h, this.s, lightness);
}
toCssString(): string {
@@ -53,11 +48,11 @@ class ColorVariable implements CssSegment {
constructor(
public prefix: string,
public name: string,
- public variant?: string | null,
+ public variant: string,
) {}
toString(): string {
- const variantPart = this.variant == null ? "" : `-${this.variant}`;
+ const variantPart = this.variant !== "" ? `-${this.variant}` : "";
return `--${this.prefix}-${this.name}${variantPart}-color`;
}
@@ -82,23 +77,15 @@ class CssVarColor implements Color {
class ColorVariableDefinition implements CssSegment {
constructor(
- public name: ColorVariable,
+ public variable: ColorVariable,
public color: Color,
) {}
toCssString(): string {
- return `${this.name.toCssString()}: ${this.color.toCssString()};`;
+ return `${this.variable.toCssString()}: ${this.color.toCssString()};`;
}
}
-type LightnessVariantType = "lighter" | "darker";
-
-interface LightnessVariantInfo {
- prefix: string;
- type: LightnessVariantType;
- levels: number;
-}
-
abstract class ColorGroup implements CssSegment {
abstract getColorVariables(): ColorVariableDefinition[];
toCssString(): string {
@@ -108,6 +95,11 @@ abstract class ColorGroup implements CssSegment {
}
}
+interface LightnessVariantInfo {
+ variant: string;
+ lightness: number;
+}
+
class LightnessVariantColorGroup extends ColorGroup {
constructor(
public prefix: string,
@@ -119,27 +111,16 @@ class LightnessVariantColorGroup extends ColorGroup {
}
getColorVariables(): ColorVariableDefinition[] {
- const result: ColorVariableDefinition[] = [
- new ColorVariableDefinition(
- new ColorVariable(this.prefix, this.name),
- this.baseColor,
- ),
- ];
+ const result: ColorVariableDefinition[] = [];
for (const lightnessVariant of this.lightnessVariants) {
- for (let i = 1; i <= lightnessVariant.levels; i++) {
- const color =
- lightnessVariant.type === "lighter"
- ? this.baseColor.lighter(i)
- : this.baseColor.darker(i);
- const colorVariant = `${lightnessVariant.prefix}${i}`;
- result.push(
- new ColorVariableDefinition(
- new ColorVariable(this.prefix, this.name, colorVariant),
- color,
- ),
- );
- }
+ const color = this.baseColor.withLightness(lightnessVariant.lightness);
+ result.push(
+ new ColorVariableDefinition(
+ new ColorVariable(this.prefix, this.name, lightnessVariant.variant),
+ color,
+ ),
+ );
}
return result;
@@ -157,12 +138,7 @@ class VarAliasColorGroup extends ColorGroup {
}
getColorVariables(): ColorVariableDefinition[] {
- const result = [
- new ColorVariableDefinition(
- new ColorVariable(this.prefix, this.newName),
- new CssVarColor(new ColorVariable(this.prefix, this.oldName)),
- ),
- ];
+ const result = [];
for (const variant of this.variants) {
result.push(
new ColorVariableDefinition(
@@ -177,51 +153,6 @@ class VarAliasColorGroup extends ColorGroup {
}
}
-class GrayscaleColorGroup extends ColorGroup {
- _delegate: LightnessVariantColorGroup;
-
- constructor(
- public prefix: string,
- public name: string,
- public baseColor: HslColor,
- public type: LightnessVariantType,
- public levels = 3,
- ) {
- super();
-
- this._delegate = new LightnessVariantColorGroup(
- prefix,
- name,
- this.baseColor,
- [{ prefix: "", type: this.type, levels }],
- );
- }
-
- getColorVariables(): ColorVariableDefinition[] {
- return this._delegate.getColorVariables();
- }
-
- static white(prefix: string, name: string, levels = 3): GrayscaleColorGroup {
- return new GrayscaleColorGroup(
- prefix,
- name,
- HslColor.white,
- "darker",
- levels,
- );
- }
-
- static black(prefix: string, name: string, levels = 3): GrayscaleColorGroup {
- return new GrayscaleColorGroup(
- prefix,
- name,
- HslColor.black,
- "lighter",
- levels,
- );
- }
-}
-
class CompositeColorGroup extends ColorGroup {
constructor(public groups: ColorGroup[]) {
super();
@@ -234,49 +165,145 @@ class CompositeColorGroup extends ColorGroup {
}
}
-type ThemeColors = { name: string; color: HslColor }[];
+interface ThemeColors {
+ keyColors: { name: string; color: HslColor }[];
+ neutralColor: HslColor;
+}
type ColorMode = "light" | "dark";
+interface ColorModeColorVariant {
+ variant: string;
+ lightness: { light: number; dark: number };
+}
+
class Theme {
- static getDefaultThemeColorLightnessVariants(
- mode: ColorMode,
- levels = 3,
- ): LightnessVariantInfo[] {
- return [
- {
- prefix: "l",
- type: "lighter",
- levels,
+ static keyColorVariants: ColorModeColorVariant[] = [
+ {
+ variant: "",
+ lightness: {
+ light: 40,
+ dark: 80,
},
- {
- prefix: "d",
- type: "darker",
- levels,
+ },
+ {
+ variant: "on",
+ lightness: {
+ light: 100,
+ dark: 20,
},
- {
- prefix: "f",
- type: mode === "light" ? "lighter" : "darker",
- levels,
+ },
+ {
+ variant: "container",
+ lightness: {
+ light: 90,
+ dark: 30,
},
- {
- prefix: "b",
- type: mode === "light" ? "darker" : "lighter",
- levels,
+ },
+ {
+ variant: "on-container",
+ lightness: {
+ light: 10,
+ dark: 90,
},
- ];
- }
+ },
+ ];
- static getThemeColorAllVariants(): string[] {
- const lightnessVariantInfos =
- Theme.getDefaultThemeColorLightnessVariants("light");
- const result: string[] = [];
- for (const { prefix, levels } of lightnessVariantInfos) {
- for (let i = 1; i <= levels; i++) {
- result.push(`${prefix}${i}`);
- }
- }
- return result;
+ static surfaceColorVariants: ColorModeColorVariant[] = [
+ {
+ variant: "dim",
+ lightness: {
+ light: 87,
+ dark: 6,
+ },
+ },
+ {
+ variant: "",
+ lightness: {
+ light: 98,
+ dark: 6,
+ },
+ },
+ {
+ variant: "bright",
+ lightness: {
+ light: 98,
+ dark: 24,
+ },
+ },
+ {
+ variant: "container-lowest",
+ lightness: {
+ light: 100,
+ dark: 4,
+ },
+ },
+ {
+ variant: "container-low",
+ lightness: {
+ light: 96,
+ dark: 10,
+ },
+ },
+ {
+ variant: "container",
+ lightness: {
+ light: 94,
+ dark: 12,
+ },
+ },
+ {
+ variant: "container-high",
+ lightness: {
+ light: 92,
+ dark: 17,
+ },
+ },
+ {
+ variant: "container-highest",
+ lightness: {
+ light: 90,
+ dark: 22,
+ },
+ },
+ {
+ variant: "on",
+ lightness: {
+ light: 10,
+ dark: 90,
+ },
+ },
+ {
+ variant: "on-variant",
+ lightness: {
+ light: 30,
+ dark: 80,
+ },
+ },
+ {
+ variant: "outline",
+ lightness: {
+ light: 50,
+ dark: 60,
+ },
+ },
+ {
+ variant: "outline-variant",
+ lightness: {
+ light: 80,
+ dark: 30,
+ },
+ },
+ ];
+
+ static getLightnessVariants(
+ mode: ColorMode,
+ colorModeColorVariants: ColorModeColorVariant[],
+ ): LightnessVariantInfo[] {
+ return colorModeColorVariants.map((v) => ({
+ variant: v.variant,
+ lightness: v.lightness[mode],
+ }));
}
constructor(
@@ -285,91 +312,53 @@ class Theme {
public levels = 3,
) {}
- getThemeColorDefinitions(mode: ColorMode): ColorGroup {
+ getColorModeColorDefinitions(mode: ColorMode): ColorGroup {
const groups: ColorGroup[] = [];
- for (const { name, color } of this.themeColors) {
+ for (const { name, color } of this.themeColors.keyColors) {
const colorGroup = new LightnessVariantColorGroup(
this.prefix,
name,
color,
- Theme.getDefaultThemeColorLightnessVariants(mode, this.levels),
+ Theme.getLightnessVariants(mode, Theme.keyColorVariants),
);
groups.push(colorGroup);
}
+ groups.push(
+ new LightnessVariantColorGroup(
+ this.prefix,
+ "surface",
+ this.themeColors.neutralColor,
+ Theme.getLightnessVariants(mode, Theme.surfaceColorVariants),
+ ),
+ );
return new CompositeColorGroup(groups);
}
getAliasColorDefinitions(name: string): ColorGroup {
return new VarAliasColorGroup(
this.prefix,
- "theme",
+ "key",
name,
- Theme.getThemeColorAllVariants(),
+ Theme.keyColorVariants.map((v) => v.variant),
);
}
- getGrayscaleDefinitions(mode: ColorMode): ColorGroup {
- const textGroup =
- mode === "light"
- ? GrayscaleColorGroup.black(this.prefix, "text", this.levels)
- : GrayscaleColorGroup.white(this.prefix, "text", this.levels);
- const bgGroup =
- mode === "light"
- ? GrayscaleColorGroup.white(this.prefix, "bg", this.levels)
- : GrayscaleColorGroup.black(this.prefix, "bg", this.levels);
- const lightGroup = GrayscaleColorGroup.white(
- this.prefix,
- "light",
- this.levels,
- );
- const darkGroup = GrayscaleColorGroup.black(
- this.prefix,
- "dark",
- this.levels,
- );
- const disabledGroup =
- mode == "light"
- ? new GrayscaleColorGroup(
- this.prefix,
- "disabled",
- new HslColor(0, 0, 75),
- "darker",
- this.levels,
- )
- : new GrayscaleColorGroup(
- this.prefix,
- "disabled",
- new HslColor(0, 0, 25),
- "lighter",
- this.levels,
- );
- return new CompositeColorGroup([
- textGroup,
- bgGroup,
- lightGroup,
- darkGroup,
- disabledGroup,
- ]);
- }
-
generateCss(print: (text: string, indent: number) => void): void {
print(":root {", 0);
- print(this.getThemeColorDefinitions("light").toCssString(), 1);
- print(this.getGrayscaleDefinitions("light").toCssString(), 1);
+ print(this.getColorModeColorDefinitions("light").toCssString(), 1);
print("}", 0);
print("", 0);
print("@media (prefers-color-scheme: dark) {", 0);
print(":root {", 1);
- print(this.getThemeColorDefinitions("dark").toCssString(), 2);
- print(this.getGrayscaleDefinitions("dark").toCssString(), 2);
+ print(this.getColorModeColorDefinitions("dark").toCssString(), 2);
print("}", 1);
print("}", 0);
print("", 0);
- for (const { name } of this.themeColors) {
+ for (const { name } of this.themeColors.keyColors) {
print(`.${this.prefix}-${name} {`, 0);
print(this.getAliasColorDefinitions(name).toCssString(), 1);
print("}", 0);
@@ -381,13 +370,16 @@ class Theme {
(function main() {
const prefix = "cru";
- const themeColors: ThemeColors = [
- { name: "primary", color: new HslColor(210, 100, 50) },
- { name: "secondary", color: new HslColor(40, 100, 50) },
- { name: "tertiary", color: new HslColor(160, 100, 50) },
- { name: "danger", color: new HslColor(0, 100, 50) },
- { name: "success", color: new HslColor(120, 60, 50) },
- ];
+ const themeColors: ThemeColors = {
+ keyColors: [
+ { name: "primary", color: new HslColor(210, 100, 50) },
+ { name: "secondary", color: new HslColor(40, 100, 50) },
+ { name: "tertiary", color: new HslColor(160, 100, 50) },
+ { name: "danger", color: new HslColor(0, 100, 50) },
+ { name: "success", color: new HslColor(120, 60, 50) },
+ ],
+ neutralColor: new HslColor(0, 0, 50),
+ };
const theme = new Theme(prefix, themeColors);