Skip to content

Commit

Permalink
UI: Add Light- and Dark-Mode (#3720)
Browse files Browse the repository at this point in the history
  • Loading branch information
naltatis committed Jun 27, 2022
1 parent 89c908b commit 06e688c
Show file tree
Hide file tree
Showing 51 changed files with 25,637 additions and 20,333 deletions.
25 changes: 9 additions & 16 deletions .storybook/main.js
@@ -1,23 +1,16 @@
const { loadConfigFromFile } = require("vite");
const path = require("path");

module.exports = {
stories: ["../assets/js/**/*.stories.mdx", "../assets/js/**/*.stories.@(js|jsx|ts|tsx)"],
addons: ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-postcss"],
stories: ["../assets/js/**/*.stories.js"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: "@storybook/vue3",
core: {
builder: "storybook-builder-vite",
builder: "@storybook/builder-vite",
},
staticDirs: ["../assets"],
async viteFinal(config, b) {
const { config: userConfig } = await loadConfigFromFile(
path.resolve(__dirname, "../vite.config.ts")
);
const vuePlugin = userConfig.plugins.find((p) => p.name === "vite:vue");

const vuePluginIndex = config.plugins.findIndex((p) => p.name === "vite:vue");
config.plugins[vuePluginIndex] = vuePlugin;

return config;
features: {
storyStoreV7: true,
},
};
9 changes: 0 additions & 9 deletions .storybook/middleware.js

This file was deleted.

3 changes: 3 additions & 0 deletions .storybook/preview-head.html
@@ -0,0 +1,3 @@
<script>
window.global = window;
</script>
16 changes: 11 additions & 5 deletions .storybook/preview.js
Expand Up @@ -10,16 +10,22 @@ app.use(i18n);

export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
backgrounds: {
default: "dark",
default: "background",
values: [
{
name: "light",
value: "#ffffff",
name: "background",
value: "var(--evcc-background)",
},
{
name: "dark",
value: "#28293e",
name: "box",
value: "var(--evcc-box)",
},
],
},
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Expand Up @@ -14,6 +14,8 @@ RUN make install-ui
COPY assets assets
COPY vite.config.js vite.config.js
COPY .eslintrc.js .eslintrc.js
COPY postcss.config.js postcss.config.js

RUN make clean ui


Expand Down
128 changes: 111 additions & 17 deletions assets/css/app.css
Expand Up @@ -11,24 +11,47 @@
font-style: normal;
}

/* Bootstrap Breakpoints as Custom Media Queries */
@custom-media --sm-and-up (min-width: 576px);
@custom-media --md-and-up (min-width: 768px);
@custom-media --lg-and-up (min-width: 992px);
@custom-media --xl-and-up (min-width: 1200px);
@custom-media --xxl-and-up (min-width: 1400px);

@custom-media --light-mode (prefers-color-scheme: light);
@custom-media --dark-mode (prefers-color-scheme: dark);

:root {
--evcc-green: #baffcb;
--evcc-dark-green: #0fde41;
--evcc-darker-green: #0ba631;
--evcc-darkest-green: #076f20;
--evcc-yellow: #faf000;
--evcc-dark-yellow: #bbb400;
--bs-gray-deep: #010322;
--bs-gray-dark: #28293e;
--bs-gray-medium: #93949e;
--bs-gray-light: #b5b6c3;
--bs-gray-bright: #f3f3f7;

--evcc-grid: var(--bs-gray-dark);
--evcc-self: var(--evcc-dark-green);
--evcc-export: var(--evcc-yellow);
--evcc-background: var(--bs-gray-bright);
--evcc-box: var(--bs-white);
--evcc-default-text: var(--bs-gray-dark);
--evcc-gray: var(--bs-gray-medium);

--evcc-accent1: var(--evcc-dark-yellow);
--evcc-accent2: var(--evcc-darker-green);
--evcc-accent3: var(--evcc-darkest-green);

--evcc-transition-slow: 1000ms;
--evcc-transition-medium: 500ms;
--evcc-transition-fast: 250ms;
--evcc-transition-very-fast: 100ms;

--bs-primary: var(--evcc-dark-green);
--bs-primary: var(--evcc-darker-green);
--bs-primary-rgb: 58, 186, 44;

--bs-body-font-size: 14px;
Expand All @@ -37,14 +60,29 @@
"Segoe UI Symbol", "Noto Color Emoji";
}

@media (--dark-mode) {
:root {
--evcc-grid: var(--bs-gray-medium);
--evcc-background: var(--bs-gray-deep);
--evcc-box: var(--bs-gray-dark);
--evcc-default-text: var(--bs-white);
--evcc-gray: var(--bs-gray-light);
--evcc-accent1: var(--evcc-yellow);
--evcc-accent2: var(--evcc-dark-green);
--evcc-accent3: var(--evcc-darker-green);
--bs-primary: var(--evcc-dark-green);
}
}

html {
/* prevents content jump when scrollbar is activate */
width: 100vw;
overflow-x: hidden;
}

body {
background-color: var(--evcc-gray-dark);
background-color: var(--evcc-background);
color: var(--evcc-default-text);
}

h1,
Expand All @@ -70,7 +108,11 @@ h4 {
}

a {
color: var(--evcc-dark-green);
color: var(--bs-primary);
}

a:hover {
color: var(--evcc-accent3);
}

/* reverse loading animation */
Expand All @@ -87,33 +129,50 @@ a {

.btn-primary,
.btn-primary:focus {
background-color: var(--bs-gray-dark);
border-color: var(--bs-gray-dark);
background-color: var(--bs-primary);
border-color: var(--bs-primary);
color: var(--evcc-background);
}

.btn-primary:hover,
.btn-primary:active {
background-color: var(--evcc-dark-green);
border-color: var(--evcc-dark-green);
background-color: var(--evcc-accent3);
border-color: var(--evcc-accent3);
}
.btn-outline-primary,
.btn-outline-primary:focus {
color: var(--bs-gray-dark);
color: var(--bs-primary);
background-color: transparent;
border-width: 2px;
border-color: var(--bs-gray-dark);
border-color: var(--bs-primary);
}
.btn-outline-primary:hover,
.btn-outline-primary:active {
color: var(--evcc-dark-green);
color: var(--evcc-accent3);
background-color: transparent;
border-width: 2px;
border-color: var(--evcc-dark-green);
border-color: var(--evcc-accent3);
}

.text-evcc {
color: var(--evcc-dark-green);
}
.text-accent1 {
color: var(--evcc-accent1);
}
.text-accent2 {
color: var(--evcc-accent2);
}
.text-accent3 {
color: var(--evcc-accent3);
}

.evcc-default-text {
color: var(--evcc-default-text) !important;
}
.evcc-gray {
color: var(--evcc-gray);
}
.text-grid {
color: var(--evcc-grid);
}
Expand Down Expand Up @@ -147,26 +206,39 @@ a {
}

.modal-header {
padding-bottom: 1.5rem;
padding: 0 0 1rem 0;
border: none;
}

.modal-title {
font-weight: bold;
font-size: 22px;
font-size: 1.25rem;
}

.modal-content {
border-radius: 1rem;
padding: 1rem;
padding: 1.25rem;
background-color: var(--evcc-box);
color: var(--evcc-default-text);
}

@media (--sm-and-up) {
.modal-content {
padding: 2rem;
}
}

.modal-body {
padding-top: 1.5rem;
padding-bottom: 1.5rem;
padding: 1rem 0 0;
}

.modal-footer {
padding-top: 1.5rem;
padding: 1rem 0 0;
border: none;
}

.modal-footer > * {
margin: 0;
}

.cursor-pointer {
Expand All @@ -186,3 +258,25 @@ small {
.btn-close {
opacity: 1;
}

@media (--dark-mode) {
.btn-close {
filter: invert(1);
}
}

.dropdown-menu {
border: none;
border-radius: 10px;
box-shadow: 0 0 8px var(--bs-gray-light);
background-color: var(--evcc-box);
}
.dropdown-item {
color: var(--evcc-default-text);
}

@media (--dark-mode) {
.dropdown-menu {
box-shadow: 0 0 8px var(--evcc-box);
}
}
4 changes: 2 additions & 2 deletions assets/index.html
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="evcc - Sonne tanken ☀️🚘" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="evcc" />
<meta name="application-name" content="evcc" />

Expand All @@ -17,7 +17,7 @@
<link rel="shortcut icon" href="meta/favicon.ico?[[.Version]]" />
<meta name="msapplication-TileColor" content="#28293e" />
<meta name="msapplication-config" content="meta/browserconfig.xml?[[.Version]]" />
<meta name="theme-color" content="#28293e" />
<meta name="theme-color" content="#020318" />

<title>evcc</title>
</head>
Expand Down
8 changes: 8 additions & 0 deletions assets/js/app.js
Expand Up @@ -73,3 +73,11 @@ window.app = app.mount("#app");
window.setInterval(function () {
api.get("health").then(window.app.setOnline).catch(window.app.setOffline);
}, 5000);

const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)");
isDarkMode.addEventListener("change", updateThemeColor);
function updateThemeColor() {
const $el = document.querySelector("meta[name=theme-color]");
$el.setAttribute("content", isDarkMode.matches ? "#020318" : "#f3f3f7");
}
updateThemeColor();
5 changes: 0 additions & 5 deletions assets/js/components/Energyflow/Energyflow.stories.js
Expand Up @@ -12,11 +12,6 @@ export default {
batteryPower: { control: { type: "range", min: -4000, max: 4000, step: 100 } },
batterySoC: { control: { type: "range", min: 0, max: 100, step: 1 } },
},
parameters: {
backgrounds: {
default: "light",
},
},
};

const Template = (args) => ({
Expand Down

0 comments on commit 06e688c

Please sign in to comment.