diff --git a/package.json b/package.json
index 62a9d57..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#a9b0ce4",
+ "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/components/docker-registry-ui.riot b/src/components/docker-registry-ui.riot
index d7c065d..c051977 100644
--- a/src/components/docker-registry-ui.riot
+++ b/src/components/docker-registry-ui.riot
@@ -101,6 +101,19 @@ along with this program. If not, see .
License AGPL-3.0
+
+
+ wb_sunny
+
+ brightness_2
+
+
+
@@ -156,7 +169,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 +230,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,
@@ -245,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;
+ }
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..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,19 +35,30 @@ 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';
};
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));
+ const theme = isDarkMode ? 'dark' : 'light';
+ localStorage.setItem(LOCAL_STORAGE_THEME, theme);
+ return theme;
};
diff --git a/src/style.scss b/src/style.scss
index 3c7631c..aa49909 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';
@@ -340,6 +341,9 @@ main {
material-footer {
padding: 0.5em 1em;
+ li {
+ align-self: center;
+ }
}
.copy-to-clipboard {