add light theme and theme toggle
This commit is contained in:
parent
80d9f7146a
commit
d7f49a55e8
33
src/ThemeLoader.tsx
Normal file
33
src/ThemeLoader.tsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { Component } from "preact";
|
||||||
|
import { settings } from "./globalSettings";
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
import style_dark from "./scss/main-dark.scss" assert {type: "css"};
|
||||||
|
// @ts-ignore
|
||||||
|
import style_light from "./scss/main-light.scss" assert {type: "css"};
|
||||||
|
|
||||||
|
export const default_theme = "dark";
|
||||||
|
|
||||||
|
const themes: { [key: string]: string } = {
|
||||||
|
"dark": style_dark,
|
||||||
|
"light": style_light,
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ThemeLoader extends Component<{}, { sheet: string }> {
|
||||||
|
componentDidMount() {
|
||||||
|
this.setCorrectStyle(settings.theme);
|
||||||
|
settings.registerListener((key: string) => {
|
||||||
|
if (key != "theme") return;
|
||||||
|
this.setCorrectStyle(settings.theme);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setCorrectStyle(theme: string) {
|
||||||
|
this.setState({ sheet: themes[theme] })
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.state.sheet) return;
|
||||||
|
return <style>{this.state.sheet}</style>
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@
|
||||||
// JS & CSS
|
// JS & CSS
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import "./scss/main.scss";
|
|
||||||
import UIkit from "uikit";
|
import UIkit from "uikit";
|
||||||
// Don't Sort These!
|
// Don't Sort These!
|
||||||
import Icons from "uikit/dist/js/uikit-icons";
|
import Icons from "uikit/dist/js/uikit-icons";
|
||||||
|
@ -32,12 +31,14 @@ import { playground } from "./playground";
|
||||||
import { render } from "preact";
|
import { render } from "preact";
|
||||||
import { settings } from "./globalSettings";
|
import { settings } from "./globalSettings";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { ThemeLoader } from "./ThemeLoader";
|
||||||
|
|
||||||
async function onLoad(): Promise<void> {
|
async function onLoad(): Promise<void> {
|
||||||
document.documentElement.dir = settings.pageDirection;
|
document.documentElement.dir = settings.pageDirection;
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<>
|
<>
|
||||||
|
<ThemeLoader />
|
||||||
<NavBar />
|
<NavBar />
|
||||||
<div class="uk-container uk-container-medium uk-align-center">
|
<div class="uk-container uk-container-medium uk-align-center">
|
||||||
<div class="uk-card uk-card-body">
|
<div class="uk-card uk-card-body">
|
||||||
|
@ -52,8 +53,6 @@ async function onLoad(): Promise<void> {
|
||||||
await playground();
|
await playground();
|
||||||
}
|
}
|
||||||
|
|
||||||
//await pageRouter.changePage(pageState.currentPage);
|
|
||||||
|
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
console.log(getCurrentUrl());
|
console.log(getCurrentUrl());
|
||||||
if (getCurrentUrl() != "/unseal") {
|
if (getCurrentUrl() != "/unseal") {
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
|
import { settings } from "./globalSettings";
|
||||||
|
import { Settings } from "./settings/Settings";
|
||||||
|
|
||||||
// Playground is a way to debug and test things.
|
// Playground is a way to debug and test things.
|
||||||
// Anything you put in here is gonna be run on page initial load
|
// Anything you put in here is gonna be run on page initial load
|
||||||
// before rendering.
|
// before rendering.
|
||||||
// Also it only runs when process.env.NODE_ENV == "development"
|
// Also it only runs when process.env.NODE_ENV == "development"
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
settings: Settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Please empty this function before committing.
|
// Please empty this function before committing.
|
||||||
export async function playground(): Promise<void> {
|
export async function playground(): Promise<void> {
|
||||||
console.log("Welcome to Playground!");
|
console.log("Welcome to Playground!");
|
||||||
|
|
||||||
|
window.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
.editor {
|
.editor {
|
||||||
background-color: #3b4252;
|
color: #f8f8f2;
|
||||||
padding: 1em;
|
background-color: #3b4252;
|
||||||
margin: 0.5em 0;
|
padding: 1em;
|
||||||
overflow: auto;
|
margin: 0.5em 0;
|
||||||
}
|
overflow: auto;
|
||||||
.code-block {
|
}
|
||||||
padding-top: 10px !important;
|
.code-block {
|
||||||
padding-right: 10px !important;
|
padding-top: 10px !important;
|
||||||
padding-bottom: 10px !important;
|
padding-right: 10px !important;
|
||||||
padding-left: 10px !important;
|
padding-bottom: 10px !important;
|
||||||
}
|
padding-left: 10px !important;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
@import "normalize.css/normalize.css";
|
@import "normalize.css/normalize.css";
|
||||||
@import "./code.scss";
|
@import "./code.scss";
|
||||||
@import "./prism-nord.scss";
|
@import "./prism-nord.scss";
|
||||||
@import "./uikit.scss";
|
@import "./uikit/uikit-dark.scss";
|
4
src/scss/main-light.scss
Normal file
4
src/scss/main-light.scss
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@import "normalize.css/normalize.css";
|
||||||
|
@import "./code.scss";
|
||||||
|
@import "./prism-nord.scss";
|
||||||
|
@import "./uikit/uikit-light.scss";
|
|
@ -1,28 +1,3 @@
|
||||||
$global-color: #d8dee9;
|
|
||||||
$global-emphasis-color: #e5e9f0;
|
|
||||||
$global-muted-color: #e5e9f0;
|
|
||||||
|
|
||||||
$global-link-color: #5e81ac;
|
|
||||||
$global-link-hover-color: #88c0d0;
|
|
||||||
|
|
||||||
$global-background: #2e3440;
|
|
||||||
$global-muted-background: #3b4252;
|
|
||||||
$global-primary-background: #5e81ac;
|
|
||||||
$global-secondary-background: #4c566a;
|
|
||||||
|
|
||||||
$global-success-background: #a3be8c;
|
|
||||||
$global-warning-background: #d08770;
|
|
||||||
$global-danger-background: #bf616a;
|
|
||||||
|
|
||||||
$button-primary-background: #5e81ac;
|
|
||||||
$progress-bar-background: #5e81ac;
|
|
||||||
|
|
||||||
$form-radio-background: $global-secondary-background;
|
|
||||||
|
|
||||||
$form-select-option-color: $global-muted-color;
|
|
||||||
|
|
||||||
$form-range-track-background: $global-link-color;
|
|
||||||
$form-range-track-focus-background: $global-link-hover-color;
|
|
||||||
|
|
||||||
// Keep these in same order as https://github.com/uikit/uikit/blob/develop/src/scss/components/_import.scss
|
// Keep these in same order as https://github.com/uikit/uikit/blob/develop/src/scss/components/_import.scss
|
||||||
@import "uikit/src/scss/variables.scss";
|
@import "uikit/src/scss/variables.scss";
|
27
src/scss/uikit/uikit-dark.scss
Normal file
27
src/scss/uikit/uikit-dark.scss
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
$global-color: #d8dee9;
|
||||||
|
$global-emphasis-color: #e5e9f0;
|
||||||
|
$global-muted-color: #e5e9f0;
|
||||||
|
|
||||||
|
$global-link-color: #5e81ac;
|
||||||
|
$global-link-hover-color: #88c0d0;
|
||||||
|
|
||||||
|
$global-background: #2e3440;
|
||||||
|
$global-muted-background: #3b4252;
|
||||||
|
$global-primary-background: #5e81ac;
|
||||||
|
$global-secondary-background: #4c566a;
|
||||||
|
|
||||||
|
$global-success-background: #a3be8c;
|
||||||
|
$global-warning-background: #d08770;
|
||||||
|
$global-danger-background: #bf616a;
|
||||||
|
|
||||||
|
$button-primary-background: #5e81ac;
|
||||||
|
$progress-bar-background: #5e81ac;
|
||||||
|
|
||||||
|
$form-radio-background: $global-secondary-background;
|
||||||
|
|
||||||
|
$form-select-option-color: $global-muted-color;
|
||||||
|
|
||||||
|
$form-range-track-background: $global-link-color;
|
||||||
|
$form-range-track-focus-background: $global-link-hover-color;
|
||||||
|
|
||||||
|
@import "./uikit-base.scss";
|
24
src/scss/uikit/uikit-light.scss
Normal file
24
src/scss/uikit/uikit-light.scss
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
$global-color: #4C566A;
|
||||||
|
$global-emphasis-color: #434C5E;
|
||||||
|
$global-muted-color: #434C5E;
|
||||||
|
|
||||||
|
$global-link-color: #5e81ac;
|
||||||
|
$global-link-hover-color: #88c0d0;
|
||||||
|
|
||||||
|
$global-background: #f7f8f9;
|
||||||
|
$global-muted-background: #D8DEE9;
|
||||||
|
$global-primary-background: #88C0D0;
|
||||||
|
$global-secondary-background: #D8DEE9;
|
||||||
|
|
||||||
|
$global-success-background: #a3be8c;
|
||||||
|
$global-warning-background: #d08770;
|
||||||
|
$global-danger-background: #bf616a;
|
||||||
|
|
||||||
|
$button-primary-background: #5e81ac;
|
||||||
|
$progress-bar-background: #5e81ac;
|
||||||
|
|
||||||
|
$form-select-option-color: $global-muted-color;
|
||||||
|
$form-range-track-background: $global-link-color;
|
||||||
|
$form-range-track-focus-background: $global-link-hover-color;
|
||||||
|
|
||||||
|
@import "./uikit-base.scss";
|
|
@ -1,11 +1,26 @@
|
||||||
|
import { default_theme } from "../ThemeLoader";
|
||||||
import { StorageType } from "./storage/StorageType";
|
import { StorageType } from "./storage/StorageType";
|
||||||
|
|
||||||
|
type OnChangeListener = (key: string) => void;
|
||||||
|
|
||||||
export class Settings {
|
export class Settings {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.storage = localStorage;
|
this.storage = localStorage;
|
||||||
|
this.listeners = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private storage: StorageType;
|
private storage: StorageType;
|
||||||
|
private listeners: OnChangeListener[];
|
||||||
|
|
||||||
|
registerListener(listener: OnChangeListener) {
|
||||||
|
this.listeners.push(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
alertChange(key: string) {
|
||||||
|
for (let listener of this.listeners) {
|
||||||
|
listener(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get apiURL(): string | null {
|
get apiURL(): string | null {
|
||||||
const apiurl = this.storage.getItem("apiURL") || "";
|
const apiurl = this.storage.getItem("apiURL") || "";
|
||||||
|
@ -13,6 +28,7 @@ export class Settings {
|
||||||
}
|
}
|
||||||
set apiURL(value: string) {
|
set apiURL(value: string) {
|
||||||
this.storage.setItem("apiURL", value);
|
this.storage.setItem("apiURL", value);
|
||||||
|
this.alertChange("apiURL");
|
||||||
}
|
}
|
||||||
|
|
||||||
get token(): string | null {
|
get token(): string | null {
|
||||||
|
@ -21,6 +37,7 @@ export class Settings {
|
||||||
}
|
}
|
||||||
set token(value: string) {
|
set token(value: string) {
|
||||||
this.storage.setItem("token", value);
|
this.storage.setItem("token", value);
|
||||||
|
this.alertChange("token");
|
||||||
}
|
}
|
||||||
|
|
||||||
get pageDirection(): string {
|
get pageDirection(): string {
|
||||||
|
@ -28,6 +45,7 @@ export class Settings {
|
||||||
}
|
}
|
||||||
set pageDirection(value: string) {
|
set pageDirection(value: string) {
|
||||||
this.storage.setItem("pageDirection", value);
|
this.storage.setItem("pageDirection", value);
|
||||||
|
this.alertChange("pageDirection");
|
||||||
}
|
}
|
||||||
|
|
||||||
get language(): string {
|
get language(): string {
|
||||||
|
@ -35,5 +53,15 @@ export class Settings {
|
||||||
}
|
}
|
||||||
set language(value: string) {
|
set language(value: string) {
|
||||||
this.storage.setItem("language", value);
|
this.storage.setItem("language", value);
|
||||||
|
this.alertChange("language");
|
||||||
|
}
|
||||||
|
|
||||||
|
get theme(): string {
|
||||||
|
return this.storage.getItem("theme") || default_theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
set theme(value: string) {
|
||||||
|
this.storage.setItem("theme", value);
|
||||||
|
this.alertChange("theme");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { addClipboardNotifications, setErrorText } from "../../pageUtils";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { InputWithTitle } from "../elements/InputWithTitle";
|
||||||
|
|
||||||
export class CopyLink extends Component<{ text: string; data: string }, unknown> {
|
export class CopyLink extends Component<{ text: string; data: string }, unknown> {
|
||||||
linkRef = createRef<HTMLAnchorElement>();
|
linkRef = createRef<HTMLAnchorElement>();
|
||||||
|
@ -54,6 +55,8 @@ export class Me extends Component<DefaultPageProps, MeState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
themeSelectRef = createRef<HTMLSelectElement>()
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
this.state.loaded && (
|
this.state.loaded && (
|
||||||
|
@ -106,6 +109,16 @@ export class Me extends Component<DefaultPageProps, MeState> {
|
||||||
<li>
|
<li>
|
||||||
<a href="/set_vault_url">{i18next.t("me_set_vault_url_btn")}</a>
|
<a href="/set_vault_url">{i18next.t("me_set_vault_url_btn")}</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<InputWithTitle title="Theme">
|
||||||
|
<select ref={this.themeSelectRef} class="uk-select uk-form-width-medium" onChange={() => {
|
||||||
|
let newTheme = this.themeSelectRef.current.value;
|
||||||
|
this.props.settings.theme = newTheme;
|
||||||
|
}}>
|
||||||
|
<option label="Dark" value="dark" selected={this.props.settings.theme == "dark"} />
|
||||||
|
<option label="Light" value="light" selected={this.props.settings.theme == "light"} />
|
||||||
|
</select>
|
||||||
|
</InputWithTitle>
|
||||||
</ul>
|
</ul>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,6 @@ const { GitRevisionPlugin } = require('git-revision-webpack-plugin');
|
||||||
const gitRevisionPlugin = new GitRevisionPlugin();
|
const gitRevisionPlugin = new GitRevisionPlugin();
|
||||||
let commitHash = gitRevisionPlugin.commithash();
|
let commitHash = gitRevisionPlugin.commithash();
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "development",
|
mode: "development",
|
||||||
cache: true,
|
cache: true,
|
||||||
|
@ -41,11 +40,16 @@ module.exports = {
|
||||||
|
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
{
|
||||||
|
assert: { type: "css" },
|
||||||
|
loader: "css-loader",
|
||||||
|
options: {
|
||||||
|
exportType: "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.(sa|sc|c)ss$/,
|
test: /\.(sa|sc|c)ss$/,
|
||||||
use: [
|
use: [
|
||||||
MiniCssExtractPlugin.loader,
|
|
||||||
"css-loader",
|
|
||||||
"sass-loader"
|
"sass-loader"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -70,7 +70,7 @@ module.exports = {
|
||||||
test: /\.(sa|sc|c)ss$/,
|
test: /\.(sa|sc|c)ss$/,
|
||||||
use: [
|
use: [
|
||||||
MiniCssExtractPlugin.loader,
|
MiniCssExtractPlugin.loader,
|
||||||
"css-loader",
|
{loader: "css-loader", options: {exportType: "string"}},
|
||||||
"sass-loader"
|
"sass-loader"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue