MTShop/code/web/themes/contrib/gin/js/accent.js

177 lines
6.5 KiB
JavaScript

/* eslint-disable no-bitwise, no-nested-ternary, no-mutable-exports, comma-dangle, strict */
((Drupal, drupalSettings, once) => {
Drupal.behaviors.ginAccent = {
attach: function attach(context) {
once('ginAccent', 'body', context).forEach(() => {
// Check Darkmode.
Drupal.ginAccent.checkDarkmode();
// Set accent color.
Drupal.ginAccent.setAccentColor();
// Set focus color.
Drupal.ginAccent.setFocusColor();
});
},
};
Drupal.ginAccent = {
setAccentColor: function setAccentColor(preset = null, color = null) {
const accentColorPreset = preset != null ? preset : drupalSettings.gin.preset_accent_color;
document.body.setAttribute('data-gin-accent', accentColorPreset);
if (accentColorPreset === 'custom') {
this.setCustomAccentColor(color);
}
},
setCustomAccentColor: function setCustomAccentColor(color = null, element = document.body) {
// If custom color is set, generate colors through JS.
const accentColor = color != null ? color : drupalSettings.gin.accent_color;
if (accentColor) {
this.clearAccentColor(element);
const strippedAccentColor = accentColor.replace('#', '');
const darkAccentColor = this.mixColor('ffffff', strippedAccentColor, 65).replace('#', '');
const style = document.createElement('style');
style.className = 'gin-custom-colors';
style.innerHTML = `
[data-gin-accent="custom"] {\n\
--gin-color-primary-rgb: ${this.hexToRgb(accentColor)};\n\
--gin-color-primary-hover: ${this.shadeColor(accentColor, -10)};\n\
--gin-color-primary-active: ${this.shadeColor(accentColor, -15)};\n\
--gin-bg-app-rgb: ${this.hexToRgb(this.mixColor('ffffff', strippedAccentColor, 97))};\n\
--gin-bg-header: ${this.mixColor('ffffff', strippedAccentColor, 85)};\n\
--gin-color-sticky-rgb: ${this.hexToRgb(this.mixColor('ffffff', strippedAccentColor, 92))};\n\
}\n\
.gin--dark-mode[data-gin-accent="custom"],\n\
.gin--dark-mode [data-gin-accent="custom"] {\n\
--gin-color-primary-rgb: ${this.hexToRgb(darkAccentColor)};\n\
--gin-color-primary-hover: ${this.mixColor('ffffff', strippedAccentColor, 55)};\n\
--gin-color-primary-active: ${this.mixColor('ffffff', strippedAccentColor, 50)};\n\
--gin-bg-header: ${this.mixColor('2A2A2D', darkAccentColor, 88)};\n\
}\n\
`;
element.append(style);
}
},
clearAccentColor: (element = document.body) => {
if (element.querySelectorAll('.gin-custom-colors').length > 0) {
const removeElement = element.querySelector('.gin-custom-colors');
removeElement.parentNode.removeChild(removeElement);
}
},
setFocusColor: function setFocusColor(preset = null, color = null) {
const focusColorPreset = preset != null ? preset : drupalSettings.gin.preset_focus_color;
document.body.setAttribute('data-gin-focus', focusColorPreset);
if (focusColorPreset === 'custom') {
this.setCustomFocusColor(color);
}
},
setCustomFocusColor: function setCustomFocusColor(color = null, element = document.body) {
const accentColor = color != null ? color : drupalSettings.gin.focus_color;
// Set preset color.
if (accentColor) {
this.clearFocusColor(element);
const strippedAccentColor = accentColor.replace('#', '');
const darkAccentColor = this.mixColor('ffffff', strippedAccentColor, 65);
const style = document.createElement('style');
style.className = 'gin-custom-focus';
style.innerHTML = `
[data-gin-focus="custom"] {\n\
--gin-color-focus: ${accentColor};\n\
}\n\
.gin--dark-mode[data-gin-focus="custom"],\n\
.gin--dark-mode [data-gin-focus="custom"] {\n\
--gin-color-focus: ${darkAccentColor};\n\
}`;
element.append(style);
}
},
clearFocusColor: (element = document.body) => {
if (element.querySelectorAll('.gin-custom-focus').length > 0) {
const removeElement = element.querySelector('.gin-custom-focus');
removeElement.parentNode.removeChild(removeElement);
}
},
checkDarkmode: () => {
const darkmodeClass = drupalSettings.gin.darkmode_class;
// Change to Darkmode.
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
if (e.matches && localStorage.getItem('Drupal.gin.darkmode') === 'auto') {
document.querySelector('html').classList.add(darkmodeClass);
}
});
// Change to Lightmode.
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', e => {
if (e.matches && localStorage.getItem('Drupal.gin.darkmode') === 'auto') {
document.querySelector('html').classList.remove(darkmodeClass);
}
});
},
// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
hexToRgb: (hex) => {
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}` : null;
},
// https://gist.github.com/jedfoster/7939513
mixColor: (color_1, color_2, weight) => {
function d2h(d) { return d.toString(16); }
function h2d(h) { return parseInt(h, 16); }
weight = (typeof(weight) !== 'undefined') ? weight : 50;
var color = "#";
for (var i = 0; i <= 5; i += 2) {
var v1 = h2d(color_1.substr(i, 2)),
v2 = h2d(color_2.substr(i, 2)),
val = d2h(Math.floor(v2 + (v1 - v2) * (weight / 100.0)));
while(val.length < 2) { val = '0' + val; }
color += val;
}
return color;
},
shadeColor: (color, percent) => {
const num = parseInt(color.replace('#', ''), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) + amt;
const B = ((num >> 8) & 0x00ff) + amt;
const G = (num & 0x0000ff) + amt;
return `#${(
0x1000000
+ (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000
+ (B < 255 ? (B < 1 ? 0 : B) : 255) * 0x100
+ (G < 255 ? (G < 1 ? 0 : G) : 255)
)
.toString(16)
.slice(1)}`;
},
};
})(Drupal, drupalSettings, once);