diff --git a/qortal-ui-core/assets/js/svg.js b/qortal-ui-core/assets/js/svg.js
new file mode 100644
index 00000000..bf4e4288
--- /dev/null
+++ b/qortal-ui-core/assets/js/svg.js
@@ -0,0 +1,4 @@
+import { html } from 'lit'
+
+export const svgSun = html``;
+export const svgMoon = html ``;
diff --git a/qortal-ui-core/font/switch-theme.css b/qortal-ui-core/font/switch-theme.css
new file mode 100644
index 00000000..91510dd2
--- /dev/null
+++ b/qortal-ui-core/font/switch-theme.css
@@ -0,0 +1,39 @@
+html {
+ --white: #ffffff;
+ --black: #080808;
+ --gray: #c8c8c8;
+ --plugback: #ffffff;
+ --border: #d0d6de;
+ --border2: #dde2e8;
+ --copybutton: #707584;
+ --sectxt: #576374;
+ --vdicon: #707b8a;
+ --tradehead: #6a6c75;
+ --tradeborder: #666666;
+ --tradehave: #555555;
+ --txtfieldborder: #666666;
+ --txtfieldhoverborder: #00000;
+ --relaynodetxt: #646464;
+ --chatmenuhover: #eeeeee;
+ --chatmenuactive: #ebebeb;
+}
+
+html[theme="dark"] {
+ --white: #36393f;
+ --black: #f8f8f8;
+ --gray: #d8d8d8;
+ --plugback: #36393f;
+ --border: #fcfcfc;
+ --border2: #fdfdfd;
+ --copybutton: #d0d6de;
+ --sectxt: #bbc3cd;
+ --vdicon: #d0d6de;
+ --tradehead: #e8ebf0;
+ --tradeborder: #cccccc;
+ --tradehave: #dddddd;
+ --txtfieldborder: #cccccc;
+ --txtfieldhoverborder: #ffffff;
+ --relaynodetxt: #d4d4d4;
+ --chatmenuhover: #666666;
+ --chatmenuactive: #6b6b6b;
+}
\ No newline at end of file
diff --git a/qortal-ui-core/package.json b/qortal-ui-core/package.json
index b1ddc710..a281a663 100644
--- a/qortal-ui-core/package.json
+++ b/qortal-ui-core/package.json
@@ -58,8 +58,8 @@
"@rollup/plugin-commonjs": "^21.0.2",
"@rollup/plugin-node-resolve": "^13.1.3",
"@rollup/plugin-replace": "^4.0.0",
- "@vaadin/grid": "^23.0.0",
- "@vaadin/password-field": "^23.0.0",
+ "@vaadin/grid": "^23.0.1",
+ "@vaadin/password-field": "^23.0.1",
"asmcrypto.js": "^2.3.2",
"bcryptjs": "^2.4.3",
"epml": "^0.3.3",
diff --git a/qortal-ui-core/public/index.html b/qortal-ui-core/public/index.html
index a171e51f..345e19a6 100644
--- a/qortal-ui-core/public/index.html
+++ b/qortal-ui-core/public/index.html
@@ -21,9 +21,9 @@
-
+
-
+
+
Qortal
diff --git a/qortal-ui-core/src/components/app-info.js b/qortal-ui-core/src/components/app-info.js
index 34b6fb1e..92c98a4b 100644
--- a/qortal-ui-core/src/components/app-info.js
+++ b/qortal-ui-core/src/components/app-info.js
@@ -27,10 +27,12 @@ class AppInfo extends connect(store)(LitElement) {
.normal {
--mdc-theme-primary: rgb(3, 169, 244);
}
+
.normal-button {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-on-primary: white;
}
+
mwc-button.normal-button {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-on-primary: white;
@@ -38,10 +40,12 @@ class AppInfo extends connect(store)(LitElement) {
.test-net {
--mdc-theme-primary: black;
}
+
.test-net-button {
--mdc-theme-primary: black;
--mdc-theme-on-primary: white;
}
+
mwc-button.test-net-button {
--mdc-theme-primary: black;
--mdc-theme-on-primary: white;
@@ -50,6 +54,7 @@ class AppInfo extends connect(store)(LitElement) {
flex: 0 0 100px;
padding:12px;
border-top: 1px solid #eee;
+ background: var(--white);
}
.info {
margin: 0;
@@ -58,6 +63,7 @@ class AppInfo extends connect(store)(LitElement) {
display: inline-block;
width:100%;
padding-bottom:8px;
+ color: var(--black);
}
.blue {
color: #03a9f4;
@@ -67,7 +73,7 @@ class AppInfo extends connect(store)(LitElement) {
display: inline;
}
.black {
- color: black;
+ color: var(--black);
margin: 0;
font-size: 14px;
font-weight:200;
diff --git a/qortal-ui-core/src/components/app-view.js b/qortal-ui-core/src/components/app-view.js
index e15170a6..792b15cf 100644
--- a/qortal-ui-core/src/components/app-view.js
+++ b/qortal-ui-core/src/components/app-view.js
@@ -9,6 +9,7 @@ import './wallet-profile.js'
import './app-info.js'
import './sidenav-menu.js'
import './show-plugin.js'
+import './qort-theme-toggle.js'
import '@material/mwc-drawer'
@@ -27,47 +28,56 @@ class AppView extends connect(store)(LitElement) {
static get styles() {
return [
css`
- :host {
- --app-drawer-width: 260px;
- }
- app-drawer-layout:not([narrow]) [drawer-toggle]:not(sidenav-menu) {
- display: none;
- }
- app-drawer {
- box-shadow: var(--shadow-2);
- background: var(--mdc-theme-surface);
- }
- app-header {
- box-shadow: var(--shadow-2);
- }
- app-toolbar {
- background: var(--mdc-theme-surface);
- color: var(--mdc-theme-on-surface);
- }
- #sideBar {
- height: 100vh;
- display: flex;
- flex-direction: column;
- }
- .sideBarMenu{
- overflow-y: auto;
- flex: 1 1;
- }
- #sideBar::-webkit-scrollbar {
- width: 7px;
- background-color: transparent;
- }
+ :host {
+ --app-drawer-width: 260px;
+ }
- #sideBar::-webkit-scrollbar-track {
- background-color: transparent;
- }
+ app-drawer-layout:not([narrow]) [drawer-toggle]:not(sidenav-menu) {
+ display: none;
+ }
- #sideBar::-webkit-scrollbar-thumb {
- background-color: #333;
- border-radius: 6px;
- border: 3px solid #333;
- }
- `
+ app-drawer {
+ box-shadow: var(--shadow-2);
+ background: var(--white);
+ }
+
+ app-header {
+ box-shadow: var(--shadow-2);
+ }
+
+ app-toolbar {
+ background: var(--white);
+ color: var(--black);
+ border-top: 1px solid rgb(238, 238, 238);
+ }
+
+ #sideBar {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background: var(--white);
+ }
+
+ .sideBarMenu{
+ overflow-y: auto;
+ flex: 1 1;
+ }
+
+ #sideBar::-webkit-scrollbar {
+ width: 7px;
+ background-color: transparent;
+ }
+
+ #sideBar::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ #sideBar::-webkit-scrollbar-thumb {
+ background-color: #333;
+ border-radius: 6px;
+ border: 3px solid #333;
+ }
+ `
]
}
@@ -94,6 +104,8 @@ class AppView extends connect(store)(LitElement) {
+
+
this.openSettings()} title="Settings" >
diff --git a/qortal-ui-core/src/components/qort-theme-toggle.js b/qortal-ui-core/src/components/qort-theme-toggle.js
new file mode 100644
index 00000000..ba4d4e22
--- /dev/null
+++ b/qortal-ui-core/src/components/qort-theme-toggle.js
@@ -0,0 +1,134 @@
+import { LitElement, html, css } from 'lit'
+import { svgSun, svgMoon } from '../../assets/js/svg.js'
+
+class QortThemeToggle extends LitElement {
+ static get properties() {
+ return {
+ theme: {
+ type: String,
+ reflect: true
+ }
+ }
+ }
+
+ constructor() {
+ super();
+ this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
+ }
+
+ static styles = [
+ css`
+ :host {
+ display: inline-block;
+ position: relative;
+ width: 54px;
+ height: 32px;
+ transform: translateY(-2px);
+ }
+
+ svg {
+ width: 32px;
+ height: 32px;
+ }
+
+ input {
+ cursor: pointer;
+ position: absolute;
+ z-index: 1;
+ opacity: 0;
+ width: 100%;
+ height: 100%;
+ }
+
+ .slider {
+ position: absolute;
+ cursor: pointer;
+ width: 100%;
+ height: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ border-radius: 1rem;
+ background-color: var(--graylight);
+ transition: all .4s ease;
+ }
+
+ .icon {
+ width: 32px;
+ height: 32px;
+ display: inline-block;
+ position: absolute;
+ top: 50%;
+ background: var(--graylight);
+ border: 2px solid var(--gray);
+ border-radius: 50%;
+ transition: transform 300ms ease;
+ }
+
+ :host([theme="light"]) .icon {
+ transform: translate(0, -50%);
+ }
+
+ input:checked ~ .icon,
+ :host([theme="dark"]) .icon {
+ transform: translate(calc(100% - 18px), -50%);
+ }
+
+ .moon {
+ display: none;
+ }
+
+ .moon svg {
+ transform: scale(0.6);
+ }
+
+ :host([theme="dark"]) .sun {
+ display: none;
+ }
+
+ :host([theme="dark"]) .moon {
+ display: inline-block;
+ }
+ `
+ ];
+
+ render() {
+ return html`
+ this.toggleTheme()}/>
+
+
+ ${svgSun}
+ ${svgMoon}
+
+ `;
+ }
+
+ firstUpdated() {
+ this.initTheme();
+ }
+
+
+ toggleTheme() {
+ if (this.theme === 'light') {
+ this.theme = 'dark';
+ } else {
+ this.theme = 'light';
+ }
+
+ this.dispatchEvent(
+ new CustomEvent('qort-theme-change', {
+ bubbles: true,
+ composed: true,
+ detail: this.theme,
+ }),
+ );
+
+ window.localStorage.setItem('qortalTheme', this.theme);
+ this.initTheme();
+ }
+
+ initTheme() {
+ document.querySelector('html').setAttribute('theme', this.theme);
+ }
+}
+
+window.customElements.define('qort-theme-toggle', QortThemeToggle);
\ No newline at end of file
diff --git a/qortal-ui-core/src/components/sidenav-menu.js b/qortal-ui-core/src/components/sidenav-menu.js
index 76ed6b18..55a4367e 100644
--- a/qortal-ui-core/src/components/sidenav-menu.js
+++ b/qortal-ui-core/src/components/sidenav-menu.js
@@ -20,11 +20,12 @@ class SidenavMenu extends connect(store)(LitElement) {
.mcd-menu {
list-style: none;
padding: 0px 0px;
- background: rgb(255, 255, 255);
+ background: var(--white);
border-radius: 2px;
width: 100%;
outline: none;
}
+
.mcd-menu li {
position: relative;
line-height: 48px;
@@ -32,17 +33,19 @@ class SidenavMenu extends connect(store)(LitElement) {
padding: 2px;
list-style: none;
}
+
.mcd-menu li a {
display: block;
text-decoration: none;
padding-left: 20px;
- color: var(--mdc-theme-on-surface);
+ color: var(--black);
text-align: left;
height: 48px;
position: relative;
border-bottom: 1px solid #EEE;
outline: none;
}
+
.mcd-menu li a mwc-icon {
float: left;
margin: 0 10px 0 0;
@@ -65,6 +68,7 @@ class SidenavMenu extends connect(store)(LitElement) {
.mcd-menu li:hover > a mwc-icon {
opacity: 1;
}
+
.mcd-menu li:hover a span {
opacity: 1;
outline: none;
@@ -74,12 +78,14 @@ class SidenavMenu extends connect(store)(LitElement) {
background: #f8f8f8;
color: #515151;
}
+
.mcd-menu li a.active {
position: relative;
color: #515151;
background-color: #eee;
outline: none;
}
+
.mcd-menu li a.active:before {
content: "";
position: absolute;
@@ -123,6 +129,7 @@ class SidenavMenu extends connect(store)(LitElement) {
border-left: 4px solid #515151;
outline: none;
}
+
.mcd-menu li ul:before {
content: "";
position: absolute;
@@ -133,6 +140,7 @@ class SidenavMenu extends connect(store)(LitElement) {
border-top: 5px solid transparent;
outline: none;
}
+
.mcd-menu li:hover > ul,
.mcd-menu li ul li:hover > ul {
display: block;
@@ -149,17 +157,20 @@ class SidenavMenu extends connect(store)(LitElement) {
height: auto;
outline: none;
}
+
.mcd-menu li ul li a mwc-icon {
display: inline-block;
margin: 0 10px 0 0;
}
+
.mcd-menu li ul li ul {
left: 230px;
top: 0;
border: 0;
border-left: 4px solid #515151;
outline: none;
- }
+ }
+
.mcd-menu li ul li ul:before {
content: "";
position: absolute;
@@ -170,6 +181,7 @@ class SidenavMenu extends connect(store)(LitElement) {
border-top: 5px solid transparent;
outline: none;
}
+
.mcd-menu li ul li:hover > ul {
top: 0px;
left: 200px;
@@ -186,10 +198,6 @@ class SidenavMenu extends connect(store)(LitElement) {
render() {
return html`
-
-