From 8c3189b57f23c9c53845123d450f7d9052cb36ad Mon Sep 17 00:00:00 2001 From: Joxit Date: Wed, 8 Mar 2023 22:14:51 +0100 Subject: [PATCH 1/3] feat(theme): add switch to select light/dark mode when the default theme is auto --- package.json | 2 +- src/components/docker-registry-ui.riot | 11 ++++++++++- src/index.js | 2 ++ src/scripts/theme.js | 4 +++- src/style.scss | 1 + 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 62a9d57..4db87f3 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "node-sass": "^8.0.0", "prettier": "^2.8.1", "riot": "^7.1.0", - "riot-mui": "github:joxit/riot-5-mui#a9b0ce4", + "riot-mui": "github:joxit/riot-5-mui#b892806", "rollup": "^3.9.0", "rollup-plugin-app-utils": "^1.0.6", "rollup-plugin-copy": "^3.4.0", diff --git a/src/components/docker-registry-ui.riot b/src/components/docker-registry-ui.riot index d7c065d..9268bd2 100644 --- a/src/components/docker-registry-ui.riot +++ b/src/components/docker-registry-ui.riot @@ -101,6 +101,9 @@ along with this program. If not, see .
  • License AGPL-3.0
  • +
  • + +
  • @@ -156,7 +159,8 @@ along with this program. If not, see . this.state.catalogElementsLimit = props.catalogElementsLimit || 100000; this.state.pullUrl = this.pullUrl(this.state.registryUrl, props.pullUrl); this.state.useControlCacheHeader = props.useControlCacheHeader; - loadTheme(props, this.root.parentNode.style); + const theme = loadTheme(props, this.root.parentNode.style); + this.state.themeSwitch = theme === 'dark'; }, onServerChange(registryUrl) { this.update({ @@ -216,6 +220,11 @@ along with this program. If not, see . filter: value, }); }, + onThemeChange(e) { + const theme = e.target.checked ? 'dark' : 'light'; + loadTheme({ ...this.props, theme }, this.root.parentNode.style); + this.update({ themeSwitch: e.target.checked }); + }, baseRoute: '([^#]*?)/(\\?[^#]*?)?(#!)?(/?)', router, version, diff --git a/src/index.js b/src/index.js index 60ac3ac..a76338c 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,7 @@ import { MaterialDropdown, MaterialPopup, MaterialInput, + MaterialSwitch, } from 'riot-mui'; import DockerRegistryUI from './components/docker-registry-ui.riot'; @@ -31,6 +32,7 @@ register('material-tabs', MaterialTabs); register('material-dropdown', MaterialDropdown); register('material-popup', MaterialPopup); register('material-input', MaterialInput); +register('material-switch', MaterialSwitch); const createApp = component(DockerRegistryUI); const tags = document.getElementsByTagName('docker-registry-ui'); diff --git a/src/scripts/theme.js b/src/scripts/theme.js index b919c74..000936b 100644 --- a/src/scripts/theme.js +++ b/src/scripts/theme.js @@ -42,10 +42,12 @@ const preferDarkMode = ({ theme }) => { }; export const loadTheme = (props, style) => { - THEME = preferDarkMode(props) ? DARK_THEME : LIGHT_THEME; + const isDarkMode = preferDarkMode(props); + THEME = isDarkMode ? { ...DARK_THEME } : { ...LIGHT_THEME }; Object.entries(props) .filter(([k, v]) => v && /^theme[A-Z]/.test(k)) .map(([k, v]) => [normalizeKey(k), v]) .forEach(([k, v]) => (THEME[k] = v)); Object.entries(THEME).forEach(([k, v]) => style.setProperty(`--${k}`, v)); + return isDarkMode ? 'dark' : 'light'; }; diff --git a/src/style.scss b/src/style.scss index 3c7631c..20d6838 100644 --- a/src/style.scss +++ b/src/style.scss @@ -26,6 +26,7 @@ @import 'riot-mui/src/material-elements/material-dropdown/material-dropdown.scss'; @import 'riot-mui/src/material-elements/material-popup/material-popup.scss'; @import 'riot-mui/src/material-elements/material-input/material-input.scss'; +@import 'riot-mui/src/material-elements/material-switch/material-switch.scss'; @import './roboto.scss'; @import './material-icons.scss'; From 8b377aee7939ac5c14347e86194382f897314ee3 Mon Sep 17 00:00:00 2001 From: Joxit Date: Fri, 10 Mar 2023 04:02:38 +0100 Subject: [PATCH 2/3] feat(theme): add icons to the switch (sun and moon) and use accent-text color --- src/components/docker-registry-ui.riot | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/components/docker-registry-ui.riot b/src/components/docker-registry-ui.riot index 9268bd2..c051977 100644 --- a/src/components/docker-registry-ui.riot +++ b/src/components/docker-registry-ui.riot @@ -102,7 +102,17 @@ along with this program. If not, see . License AGPL-3.0
  • - + + wb_sunny + + brightness_2 + +
  • @@ -254,5 +264,9 @@ along with this program. If not, see . material-footer .material-footer-logo { color: var(--footer-text); } + + material-switch i { + user-select: none; + } From a9fd1a2a236af20dbba41e5577df33d28b5d3d71 Mon Sep 17 00:00:00 2001 From: Joxit Date: Mon, 13 Mar 2023 08:09:38 +0100 Subject: [PATCH 3/3] feat(theme): use localstorage to save the switch state at refresh --- package.json | 2 +- src/scripts/theme.js | 19 +++++++++++++++---- src/style.scss | 3 +++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4db87f3..8cf96b3 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "node-sass": "^8.0.0", "prettier": "^2.8.1", "riot": "^7.1.0", - "riot-mui": "github:joxit/riot-5-mui#b892806", + "riot-mui": "github:joxit/riot-5-mui#a97f2d3", "rollup": "^3.9.0", "rollup-plugin-app-utils": "^1.0.6", "rollup-plugin-copy": "^3.4.0", diff --git a/src/scripts/theme.js b/src/scripts/theme.js index 000936b..d1be707 100644 --- a/src/scripts/theme.js +++ b/src/scripts/theme.js @@ -23,6 +23,8 @@ const DARK_THEME = { 'footer-background': '#555', }; +const LOCAL_STORAGE_THEME = 'registryUiTheme'; + let THEME; const normalizeKey = (k) => @@ -33,9 +35,16 @@ const normalizeKey = (k) => const preferDarkMode = ({ theme }) => { if (theme === 'auto') { - if (typeof window.matchMedia === 'function') { - const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)'); - return prefersDarkScheme && prefersDarkScheme.matches; + switch (localStorage.getItem(LOCAL_STORAGE_THEME)) { + case 'dark': + return true; + case 'light': + return false; + default: + if (typeof window.matchMedia === 'function') { + const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)'); + return prefersDarkScheme && prefersDarkScheme.matches; + } } } return theme === 'dark'; @@ -49,5 +58,7 @@ export const loadTheme = (props, style) => { .map(([k, v]) => [normalizeKey(k), v]) .forEach(([k, v]) => (THEME[k] = v)); Object.entries(THEME).forEach(([k, v]) => style.setProperty(`--${k}`, v)); - return isDarkMode ? 'dark' : 'light'; + const theme = isDarkMode ? 'dark' : 'light'; + localStorage.setItem(LOCAL_STORAGE_THEME, theme); + return theme; }; diff --git a/src/style.scss b/src/style.scss index 20d6838..aa49909 100644 --- a/src/style.scss +++ b/src/style.scss @@ -341,6 +341,9 @@ main { material-footer { padding: 0.5em 1em; + li { + align-self: center; + } } .copy-to-clipboard {