mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 09:16:10 -06:00
simplify color mode selection
This commit is contained in:
parent
aba00ca01d
commit
01d1e7adbc
BIN
netbox/project-static/dist/config.js
vendored
BIN
netbox/project-static/dist/config.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/config.js.map
vendored
BIN
netbox/project-static/dist/config.js.map
vendored
Binary file not shown.
BIN
netbox/project-static/dist/lldp.js
vendored
BIN
netbox/project-static/dist/lldp.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/lldp.js.map
vendored
BIN
netbox/project-static/dist/lldp.js.map
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js.map
vendored
BIN
netbox/project-static/dist/netbox.js.map
vendored
Binary file not shown.
BIN
netbox/project-static/dist/status.js
vendored
BIN
netbox/project-static/dist/status.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/status.js.map
vendored
BIN
netbox/project-static/dist/status.js.map
vendored
Binary file not shown.
@ -1,72 +1,42 @@
|
||||
/**
|
||||
* Set the color mode on the `<html/>` element and in local storage.
|
||||
* Set the color mode on the `<html/>` element.
|
||||
*
|
||||
* @param mode {"dark" | "light"} NetBox Color Mode.
|
||||
* @param inferred {boolean} Value is inferred from browser/system preference.
|
||||
* @param mode {"dark" | "light" | "system"} NetBox Color Mode.
|
||||
*/
|
||||
function setMode(mode, inferred) {
|
||||
document.documentElement.setAttribute("data-netbox-color-mode", mode);
|
||||
localStorage.setItem("netbox-color-mode", mode);
|
||||
localStorage.setItem("netbox-color-mode-inferred", inferred);
|
||||
function setMode(mode) {
|
||||
if (mode === 'system') {
|
||||
mode = getSystemColorMode();
|
||||
}
|
||||
document.documentElement.setAttribute('data-netbox-color-mode', mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the system color mode (light or dark).
|
||||
*
|
||||
* @return {string} "dark" or "light" based on system preference.
|
||||
*/
|
||||
function getSystemColorMode() {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the best initial color mode to use prior to rendering.
|
||||
*/
|
||||
function initMode() {
|
||||
try {
|
||||
// Browser prefers dark color scheme.
|
||||
var preferDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
// Browser prefers light color scheme.
|
||||
var preferLight = window.matchMedia("(prefers-color-scheme: light)").matches;
|
||||
// Client NetBox color-mode override.
|
||||
var clientMode = localStorage.getItem("netbox-color-mode");
|
||||
// NetBox server-rendered value.
|
||||
var serverMode = document.documentElement.getAttribute("data-netbox-color-mode");
|
||||
// Color mode is inferred from browser/system preference and not deterministically set by
|
||||
// the client or server.
|
||||
var inferred = JSON.parse(localStorage.getItem("netbox-color-mode-inferred"));
|
||||
try {
|
||||
// NetBox server-rendered value.
|
||||
const serverMode = document.documentElement.getAttribute('data-netbox-color-mode');
|
||||
|
||||
if (inferred === true && (serverMode === "light" || serverMode === "dark")) {
|
||||
// The color mode was previously inferred from browser/system preference, but
|
||||
// the server now has a value, so we should use the server's value.
|
||||
return setMode(serverMode, false);
|
||||
}
|
||||
if (clientMode === null && (serverMode === "light" || serverMode === "dark")) {
|
||||
// If the client mode is not set but the server mode is, use the server mode.
|
||||
return setMode(serverMode, false);
|
||||
}
|
||||
if (clientMode !== null && serverMode === "unset") {
|
||||
// The color mode has been set, deterministically or otherwise, and the server
|
||||
// has no preference or has not been set. Use the client mode, but allow it to
|
||||
/// be overridden by the server if/when a server value exists.
|
||||
return setMode(clientMode, true);
|
||||
}
|
||||
if (
|
||||
clientMode !== null &&
|
||||
(serverMode === "light" || serverMode === "dark") &&
|
||||
clientMode !== serverMode
|
||||
) {
|
||||
// If the client mode is set and is different than the server mode (which is also set),
|
||||
// use the client mode over the server mode, as it should be more recent.
|
||||
return setMode(clientMode, false);
|
||||
}
|
||||
if (clientMode === serverMode) {
|
||||
// If the client and server modes match, use that value.
|
||||
return setMode(clientMode, false);
|
||||
}
|
||||
if (preferDark && serverMode === "unset") {
|
||||
// If the server mode is not set but the browser prefers dark mode, use dark mode, but
|
||||
// allow it to be overridden by an explicit preference.
|
||||
return setMode("dark", true);
|
||||
}
|
||||
if (preferLight && serverMode === "unset") {
|
||||
// If the server mode is not set but the browser prefers light mode, use light mode,
|
||||
// but allow it to be overridden by an explicit preference.
|
||||
return setMode("light", true);
|
||||
}
|
||||
} catch (error) {
|
||||
// In the event of an error, log it to the console and set the mode to light mode.
|
||||
console.error(error);
|
||||
if (serverMode === 'light' || serverMode === 'dark' || serverMode === 'system') {
|
||||
// If the server mode is set (light, dark, or system), use the server mode.
|
||||
return setMode(serverMode);
|
||||
}
|
||||
return setMode("light", true);
|
||||
};
|
||||
|
||||
// If server mode is not set, use the system color mode.
|
||||
return setMode('system');
|
||||
} catch (error) {
|
||||
// In the event of an error, log it to the console and set the mode to system mode.
|
||||
console.error(error);
|
||||
return setMode('system');
|
||||
}
|
||||
}
|
||||
|
@ -1,134 +0,0 @@
|
||||
import { getElements, isTruthy } from './util';
|
||||
|
||||
const COLOR_MODE_KEY = 'netbox-color-mode';
|
||||
const TEXT_WHEN_DARK = 'Light Mode';
|
||||
const TEXT_WHEN_LIGHT = 'Dark Mode';
|
||||
const ICON_WHEN_DARK = 'mdi-lightbulb-on';
|
||||
const ICON_WHEN_LIGHT = 'mdi-lightbulb';
|
||||
|
||||
/**
|
||||
* Determine if a value is a supported color mode string value.
|
||||
*/
|
||||
function isColorMode(value: unknown): value is ColorMode {
|
||||
return value === 'dark' || value === 'light';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color mode to light or dark.
|
||||
*
|
||||
* @param mode `'light'` or `'dark'`
|
||||
* @returns `true` if the color mode was successfully set, `false` if not.
|
||||
*/
|
||||
function storeColorMode(mode: ColorMode): void {
|
||||
return localStorage.setItem(COLOR_MODE_KEY, mode);
|
||||
}
|
||||
|
||||
function updateElements(targetMode: ColorMode): void {
|
||||
document.documentElement.setAttribute(`data-${COLOR_MODE_KEY}`, targetMode);
|
||||
|
||||
for (const text of getElements<HTMLSpanElement>('span.color-mode-text')) {
|
||||
if (targetMode === 'light') {
|
||||
text.innerText = TEXT_WHEN_LIGHT;
|
||||
} else if (targetMode === 'dark') {
|
||||
text.innerText = TEXT_WHEN_DARK;
|
||||
}
|
||||
}
|
||||
for (const icon of getElements<HTMLSpanElement>('i.color-mode-icon', 'span.color-mode-icon')) {
|
||||
if (targetMode === 'light') {
|
||||
icon.classList.remove(ICON_WHEN_DARK);
|
||||
icon.classList.add(ICON_WHEN_LIGHT);
|
||||
} else if (targetMode === 'dark') {
|
||||
icon.classList.remove(ICON_WHEN_LIGHT);
|
||||
icon.classList.add(ICON_WHEN_DARK);
|
||||
}
|
||||
}
|
||||
|
||||
for (const elevation of getElements<HTMLObjectElement>('.rack_elevation')) {
|
||||
const svg = elevation.contentDocument?.querySelector('svg') ?? null;
|
||||
if (svg !== null) {
|
||||
svg.setAttribute(`data-${COLOR_MODE_KEY}`, targetMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call all functions necessary to update the color mode across the UI.
|
||||
*
|
||||
* @param mode Target color mode.
|
||||
*/
|
||||
export function setColorMode(mode: ColorMode): void {
|
||||
for (const func of [storeColorMode, updateElements]) {
|
||||
func(mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the color mode when a color mode toggle is clicked.
|
||||
*/
|
||||
function handleColorModeToggle(): void {
|
||||
const currentValue = localStorage.getItem(COLOR_MODE_KEY);
|
||||
if (currentValue === 'light') {
|
||||
setColorMode('dark');
|
||||
} else if (currentValue === 'dark') {
|
||||
setColorMode('light');
|
||||
} else {
|
||||
console.warn('Unable to determine the current color mode');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the user's preference and set it as the color mode.
|
||||
*/
|
||||
function defaultColorMode(): void {
|
||||
// Get the current color mode value from local storage.
|
||||
const currentValue = localStorage.getItem(COLOR_MODE_KEY) as Nullable<ColorMode>;
|
||||
const serverValue = document.documentElement.getAttribute(`data-${COLOR_MODE_KEY}`);
|
||||
|
||||
if (isTruthy(serverValue) && isTruthy(currentValue)) {
|
||||
return setColorMode(currentValue);
|
||||
}
|
||||
|
||||
let preference: ColorModePreference = 'none';
|
||||
|
||||
// Determine if the user prefers dark or light mode.
|
||||
for (const mode of ['dark', 'light']) {
|
||||
if (window.matchMedia(`(prefers-color-scheme: ${mode})`).matches) {
|
||||
preference = mode as ColorModePreference;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isTruthy(currentValue) && !isTruthy(serverValue) && isColorMode(currentValue)) {
|
||||
return setColorMode(currentValue);
|
||||
}
|
||||
|
||||
switch (preference) {
|
||||
case 'dark':
|
||||
return setColorMode('dark');
|
||||
case 'light':
|
||||
return setColorMode('light');
|
||||
case 'none':
|
||||
return setColorMode('light');
|
||||
default:
|
||||
return setColorMode('light');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize color mode toggle buttons and set the default color mode.
|
||||
*/
|
||||
function initColorModeToggle(): void {
|
||||
for (const element of getElements<HTMLButtonElement>('button.color-mode-toggle')) {
|
||||
element.addEventListener('click', handleColorModeToggle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all color mode elements.
|
||||
*/
|
||||
export function initColorMode(): void {
|
||||
window.addEventListener('load', defaultColorMode);
|
||||
for (const func of [initColorModeToggle]) {
|
||||
func();
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ import { initBootstrap } from './bs';
|
||||
import { initQuickSearch } from './search';
|
||||
import { initSelect } from './select';
|
||||
import { initButtons } from './buttons';
|
||||
import { initColorMode } from './colorMode';
|
||||
import { initMessages } from './messages';
|
||||
import { initClipboard } from './clipboard';
|
||||
import { initDateSelector } from './dateSelector';
|
||||
@ -18,7 +17,6 @@ import { initHtmx } from './htmx';
|
||||
function initDocument(): void {
|
||||
for (const init of [
|
||||
initBootstrap,
|
||||
initColorMode,
|
||||
initMessages,
|
||||
initForms,
|
||||
initQuickSearch,
|
||||
|
@ -7,13 +7,7 @@
|
||||
data-netbox-url-name="{{ request.resolver_match.url_name }}"
|
||||
data-netbox-base-path="{{ settings.BASE_PATH }}"
|
||||
{% with preferences|get_key:'ui.colormode' as color_mode %}
|
||||
{% if color_mode == 'dark'%}
|
||||
data-netbox-color-mode="dark"
|
||||
{% elif color_mode == 'light' %}
|
||||
data-netbox-color-mode="light"
|
||||
{% else %}
|
||||
data-netbox-color-mode="unset"
|
||||
{% endif %}
|
||||
data-netbox-color-mode={{ color_mode }}
|
||||
{% endwith %}
|
||||
>
|
||||
<head>
|
||||
|
Loading…
Reference in New Issue
Block a user