feat(theme): add support for custom themes

This commit is contained in:
Joxit 2023-01-05 22:29:37 +01:00
parent 5983935f84
commit 367ca0380c
No known key found for this signature in database
GPG key ID: F526592B8E012263
8 changed files with 67 additions and 31 deletions

View file

@ -41,7 +41,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
filter-results="{ state.filter }" filter-results="{ state.filter }"
on-authentication="{ onAuthentication }" on-authentication="{ onAuthentication }"
show-catalog-nb-tags="{ truthy(props.showCatalogNbTags) }" show-catalog-nb-tags="{ truthy(props.showCatalogNbTags) }"
/> ></catalog>
</route> </route>
<route path="{baseRoute}taglist/(.*)"> <route path="{baseRoute}taglist/(.*)">
<tag-list <tag-list
@ -84,7 +84,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</main> </main>
<footer> <footer>
<material-footer mini="true"> <material-footer mini="true">
<a class="material-footer-logo" href="https://joxit.github.io/docker-registry-ui/">Docker Registry UI { version }</a> <a class="material-footer-logo" href="https://joxit.github.io/docker-registry-ui/">
Docker Registry UI { version }
</a>
<ul> <ul>
<li> <li>
<a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a> <a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a>
@ -105,6 +107,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import SearchBar from './search-bar.riot'; import SearchBar from './search-bar.riot';
import { stripHttps, getRegistryServers, setRegistryServers, truthy, stringToArray } from '../scripts/utils'; import { stripHttps, getRegistryServers, setRegistryServers, truthy, stringToArray } from '../scripts/utils';
import router from '../scripts/router'; import router from '../scripts/router';
import { loadTheme } from '../scripts/theme';
export default { export default {
components: { components: {
@ -138,6 +141,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
this.state.catalogElementsLimit = props.catalogElementsLimit || 100000; this.state.catalogElementsLimit = props.catalogElementsLimit || 100000;
this.state.pullUrl = this.pullUrl(this.state.registryUrl, props.pullUrl); this.state.pullUrl = this.pullUrl(this.state.registryUrl, props.pullUrl);
this.state.useControlCacheHeader = props.useControlCacheHeader; this.state.useControlCacheHeader = props.useControlCacheHeader;
loadTheme(props, this.root.style);
}, },
onServerChange(registryUrl) { onServerChange(registryUrl) {
this.update({ this.update({
@ -200,10 +204,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
}; };
</script> </script>
<style> <style>
:host {
display: block;
background-color: var(--background);
color: var(--primary-text);
}
material-navbar { material-navbar {
height: 64px; height: 64px;
} }
material-navbar .menu { material-navbar .menu {
display: flex; display: flex;
} }

View file

@ -18,12 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<material-card> <material-card>
<div class="material-card-title-action"> <div class="material-card-title-action">
<material-button <material-button
color="#777" text-color="var(--neutral-text)"
color="inherit"
waves-color="var(--hover-background)"
waves-center="true" waves-center="true"
rounded="true" rounded="true"
waves-color="#ddd" waves-color="#ddd"
href="{ toTaglist() }" href="{ toTaglist() }"
inverted
icon icon
> >
<i class="material-icons">arrow_back</i> <i class="material-icons">arrow_back</i>

View file

@ -18,9 +18,9 @@
<div class="copy-to-clipboard"> <div class="copy-to-clipboard">
<input style="display: none; width: 1px; height: 1px" value="{ getDockerCmd(props) }" /> <input style="display: none; width: 1px; height: 1px" value="{ getDockerCmd(props) }" />
<material-button <material-button
color="rgba(0,0,0,0)" text-color="var(--neutral-text)"
text-color="#777" color="var(--background)"
waves-color="#ddd" waves-color="var(--hover-background)"
waves-center="true" waves-center="true"
onClick="{ copy }" onClick="{ copy }"
title="Copy pull command." title="Copy pull command."

View file

@ -16,9 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<remove-image> <remove-image>
<material-button <material-button
color="rgba(0,0,0,0)" text-color="var(--neutral-text)"
text-color="#777" color="var(--background)"
waves-color="#ddd" waves-color="var(--hover-background)"
waves-center="true" waves-center="true"
title="This will delete the image." title="This will delete the image."
if="{ !props.multiDelete }" if="{ !props.multiDelete }"

View file

@ -17,9 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<tag-history-button> <tag-history-button>
<material-button <material-button
title="{ buttonTittle() }" title="{ buttonTittle() }"
color="rgba(0,0,0,0)" text-color="var(--neutral-text)"
text-color="#777" color="var(--background)"
waves-color="#ddd" waves-color="var(--hover-background)"
waves-center="true" waves-center="true"
href="{ routeToHistory() }" href="{ routeToHistory() }"
disabled="{ props.image.ociImage }" disabled="{ props.image.ociImage }"

View file

@ -18,12 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<material-card class="header"> <material-card class="header">
<div class="material-card-title-action"> <div class="material-card-title-action">
<material-button <material-button
color="#777" text-color="var(--neutral-text)"
waves-color="#ddd" color="var(--background)"
waves-color="var(--hover-background)"
waves-center="true" waves-center="true"
href="{ router.home() }" href="{ router.home() }"
icon icon
inverted
> >
<i class="material-icons">arrow_back</i> <i class="material-icons">arrow_back</i>
</material-button> </material-button>

29
src/scripts/theme.js Normal file
View file

@ -0,0 +1,29 @@
const LIGHT_THEME = {
'primary-text': '#25313b',
'neutral-text': '#777',
'background': '#fff',
'hover-background': '#eee',
};
const DARK_THEME = {
'primary-text': '#8A9EBA',
'neutral-text': '#36527A',
'background': '#22272e',
'hover-background': '#30404D',
};
let THEME;
const normalizeKey = (k) =>
k
.replace(/([A-Z])/g, '-$1')
.toLowerCase()
.replace(/^theme-/, '');
export const loadTheme = (props, style) => {
THEME = props.theme == 'dark' ? 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));
};

View file

@ -60,7 +60,9 @@ body {
text-decoration: none; text-decoration: none;
font-weight: inherit; font-weight: inherit;
} }
material-card {
background-color: var(--background);
}
material-card, material-card,
material-tabs, material-tabs,
pagination .container { pagination .container {
@ -141,7 +143,7 @@ h2 {
} }
.list.highlight:hover { .list.highlight:hover {
background-color: #eee; background-color: var(--hover-background);
cursor: pointer; cursor: pointer;
} }
@ -165,7 +167,7 @@ docker-registry-ui material-button > :first-child .content i.material-icons.mate
height: 24px; height: 24px;
width: 24px; width: 24px;
box-sizing: border-box; box-sizing: border-box;
color: #757575; color: var(--neutral-text);
} }
.list > span .right i.material-icons.animated { .list > span .right i.material-icons.animated {
@ -230,7 +232,6 @@ material-card table {
border-collapse: collapse; border-collapse: collapse;
white-space: nowrap; white-space: nowrap;
font-size: 13px; font-size: 13px;
background-color: #fff;
border: none; border: none;
} }
@ -239,7 +240,7 @@ material-card table th {
vertical-align: bottom; vertical-align: bottom;
line-height: 24px; line-height: 24px;
height: 48px; height: 48px;
color: rgba(0, 0, 0, 0.54); color: var(--neutral-text);
box-sizing: border-box; box-sizing: border-box;
padding: 0 18px 12px 18px; padding: 0 18px 12px 18px;
text-align: right; text-align: right;
@ -249,10 +250,10 @@ material-card table th {
text-align: left; text-align: left;
} }
material-button:hover > :first-child[inverted='true'], material-button:hover > :first-child,
material-card .material-card-title-action material-button:hover button, material-card .material-card-title-action material-button:hover button,
material-card table tbody tr:hover { material-card table tbody tr:hover {
background-color: #eee !important; background-color: rgba(0, 0, 0, 0.12) !important;
} }
material-button > :first-child[inverted='true'], material-button > :first-child[inverted='true'],
@ -308,7 +309,7 @@ material-card table th.material-card-th-sorted-descending:before {
material-button .content i.material-icons, material-button .content i.material-icons,
.material-icons { .material-icons {
color: #777; color: var(--neutral-text);
} }
material-button[disabled] .content i.material-icons, material-button[disabled] .content i.material-icons,
@ -320,10 +321,6 @@ material-snackbar .toast {
height: auto; height: auto;
} }
material-popup material-button:hover material-waves {
background-color: hsla(0, 0%, 75%, 0.2);
}
material-popup .popup > .content { material-popup .popup > .content {
padding: 1em; padding: 1em;
max-width: 450px; max-width: 450px;
@ -452,9 +449,9 @@ material-checkbox.indeterminate .checkbox.checked .checkmark {
} }
material-checkbox .checkbox { material-checkbox .checkbox {
border-color: #777; border-color: var(--neutral-text);
} }
material-checkbox .checkbox.checked { material-checkbox .checkbox.checked {
background-color: #777; background-color: var(--neutral-text);
} }