mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-29 12:55:21 +01:00
[PS-1693] feat(browser): implement theming for notification bar (#3805)
* feat(browser): implement theming for notification bar * refactor(browser): split notification bar function * refactor(browser): use own method for getCurrentTheme * chore(browser): add close.svg file as an asset this file is embedded in apps/browser/src/notification/bar.html * feat(browser): change textContrast color on primary buttons * feat(browser): use dedicated color variable for close button * feat(browser): use textColor for close button * feat(browser): implement styling for select fields * feat(browser): improve close button styling, add hover effect
This commit is contained in:
parent
0cb5ffd6ed
commit
2ffafa1f23
@ -7,6 +7,7 @@ import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.serv
|
|||||||
import { AuthenticationStatus } from "@bitwarden/common/enums/authenticationStatus";
|
import { AuthenticationStatus } from "@bitwarden/common/enums/authenticationStatus";
|
||||||
import { CipherType } from "@bitwarden/common/enums/cipherType";
|
import { CipherType } from "@bitwarden/common/enums/cipherType";
|
||||||
import { PolicyType } from "@bitwarden/common/enums/policyType";
|
import { PolicyType } from "@bitwarden/common/enums/policyType";
|
||||||
|
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
||||||
import { Utils } from "@bitwarden/common/misc/utils";
|
import { Utils } from "@bitwarden/common/misc/utils";
|
||||||
import { CipherView } from "@bitwarden/common/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/models/view/cipher.view";
|
||||||
import { LoginUriView } from "@bitwarden/common/models/view/login-uri.view";
|
import { LoginUriView } from "@bitwarden/common/models/view/login-uri.view";
|
||||||
@ -125,13 +126,13 @@ export default class NotificationBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tab != null) {
|
if (tab != null) {
|
||||||
this.doNotificationQueueCheck(tab);
|
await this.doNotificationQueueCheck(tab);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentTab = await BrowserApi.getTabFromCurrentWindow();
|
const currentTab = await BrowserApi.getTabFromCurrentWindow();
|
||||||
if (currentTab != null) {
|
if (currentTab != null) {
|
||||||
this.doNotificationQueueCheck(currentTab);
|
await this.doNotificationQueueCheck(currentTab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ export default class NotificationBackground {
|
|||||||
setTimeout(() => this.cleanupNotificationQueue(), 2 * 60 * 1000); // check every 2 minutes
|
setTimeout(() => this.cleanupNotificationQueue(), 2 * 60 * 1000); // check every 2 minutes
|
||||||
}
|
}
|
||||||
|
|
||||||
private doNotificationQueueCheck(tab: chrome.tabs.Tab): void {
|
private async doNotificationQueueCheck(tab: chrome.tabs.Tab): Promise<void> {
|
||||||
if (tab == null) {
|
if (tab == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -167,6 +168,7 @@ export default class NotificationBackground {
|
|||||||
type: "add",
|
type: "add",
|
||||||
typeData: {
|
typeData: {
|
||||||
isVaultLocked: this.notificationQueue[i].wasVaultLocked,
|
isVaultLocked: this.notificationQueue[i].wasVaultLocked,
|
||||||
|
theme: await this.getCurrentTheme(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (this.notificationQueue[i].type === NotificationQueueMessageType.ChangePassword) {
|
} else if (this.notificationQueue[i].type === NotificationQueueMessageType.ChangePassword) {
|
||||||
@ -174,6 +176,7 @@ export default class NotificationBackground {
|
|||||||
type: "change",
|
type: "change",
|
||||||
typeData: {
|
typeData: {
|
||||||
isVaultLocked: this.notificationQueue[i].wasVaultLocked,
|
isVaultLocked: this.notificationQueue[i].wasVaultLocked,
|
||||||
|
theme: await this.getCurrentTheme(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -181,6 +184,18 @@ export default class NotificationBackground {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getCurrentTheme() {
|
||||||
|
const theme = await this.stateService.getTheme();
|
||||||
|
|
||||||
|
if (theme !== ThemeType.System) {
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
|
? ThemeType.Dark
|
||||||
|
: ThemeType.Light;
|
||||||
|
}
|
||||||
|
|
||||||
private removeTabFromNotificationQueue(tab: chrome.tabs.Tab) {
|
private removeTabFromNotificationQueue(tab: chrome.tabs.Tab) {
|
||||||
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
if (this.notificationQueue[i].tabId === tab.id) {
|
if (this.notificationQueue[i].tabId === tab.id) {
|
||||||
|
@ -498,17 +498,13 @@ document.addEventListener("DOMContentLoaded", (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function closeExistingAndOpenBar(type: string, typeData: any) {
|
function closeExistingAndOpenBar(type: string, typeData: any) {
|
||||||
let barPage = "notification/bar.html";
|
const barQueryParams = {
|
||||||
switch (type) {
|
type,
|
||||||
case "add":
|
isVaultLocked: typeData.isVaultLocked,
|
||||||
barPage = barPage + "?add=1&isVaultLocked=" + typeData.isVaultLocked;
|
theme: typeData.theme,
|
||||||
break;
|
};
|
||||||
case "change":
|
const barQueryString = new URLSearchParams(barQueryParams).toString();
|
||||||
barPage = barPage + "?change=1&isVaultLocked=" + typeData.isVaultLocked;
|
const barPage = "notification/bar.html?" + barQueryString;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const frame = document.getElementById("bit-notification-bar-iframe") as HTMLIFrameElement;
|
const frame = document.getElementById("bit-notification-bar-iframe") as HTMLIFrameElement;
|
||||||
if (frame != null && frame.src.indexOf(barPage) >= 0) {
|
if (frame != null && frame.src.indexOf(barPage) >= 0) {
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 288 B |
1
apps/browser/src/images/close.svg
Normal file
1
apps/browser/src/images/close.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" xmlns:v="https://vecta.io/nano"><path d="M497.72 429.63l-169-174.82L498.11 82.24c6.956-7.168 6.956-18.85 0-26.018L449.934 6.31C446.585 2.859 442.076 1 437.31 1s-9.275 1.991-12.624 5.31l-168.62 172.04L87.196 6.45c-3.349-3.451-7.858-5.31-12.624-5.31s-9.275 1.991-12.624 5.31L13.9 56.362c-6.956 7.168-6.956 18.85 0 26.018l169.39 172.57L14.42 429.64c-3.349 3.451-5.281 8.097-5.281 13.009s1.803 9.558 5.281 13.009l48.176 49.912c3.478 3.584 7.987 5.442 12.624 5.442 4.508 0 9.146-1.726 12.624-5.442l168.23-174.16 168.36 174.03c3.478 3.584 7.986 5.442 12.624 5.442 4.509 0 9.146-1.726 12.624-5.442l48.176-49.912c3.349-3.451 5.281-8.097 5.281-13.009a19.32 19.32 0 0 0-5.41-12.876z"/></svg>
|
After Width: | Height: | Size: 743 B |
@ -100,8 +100,7 @@
|
|||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
"notification/bar.html",
|
"notification/bar.html",
|
||||||
"images/icon38.png",
|
"images/icon38.png",
|
||||||
"images/icon38_locked.png",
|
"images/icon38_locked.png"
|
||||||
"images/close.png"
|
|
||||||
],
|
],
|
||||||
"applications": {
|
"applications": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
|
@ -106,12 +106,7 @@
|
|||||||
},
|
},
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
{
|
{
|
||||||
"resources": [
|
"resources": ["notification/bar.html", "images/icon38.png", "images/icon38_locked.png"],
|
||||||
"notification/bar.html",
|
|
||||||
"images/icon38.png",
|
|
||||||
"images/icon38_locked.png",
|
|
||||||
"images/close.png"
|
|
||||||
],
|
|
||||||
"matches": ["<all_urls>"]
|
"matches": ["<all_urls>"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -15,7 +15,16 @@
|
|||||||
<div id="content"></div>
|
<div id="content"></div>
|
||||||
<div>
|
<div>
|
||||||
<button type="button" class="neutral" id="close-button">
|
<button type="button" class="neutral" id="close-button">
|
||||||
<img id="close" alt="Close" />
|
<svg
|
||||||
|
id="close"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
xmlns:v="https://vecta.io/nano"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M497.72 429.63l-169-174.82L498.11 82.24c6.956-7.168 6.956-18.85 0-26.018L449.934 6.31C446.585 2.859 442.076 1 437.31 1s-9.275 1.991-12.624 5.31l-168.62 172.04L87.196 6.45c-3.349-3.451-7.858-5.31-12.624-5.31s-9.275 1.991-12.624 5.31L13.9 56.362c-6.956 7.168-6.956 18.85 0 26.018l169.39 172.57L14.42 429.64c-3.349 3.451-5.281 8.097-5.281 13.009s1.803 9.558 5.281 13.009l48.176 49.912c3.478 3.584 7.987 5.442 12.624 5.442 4.508 0 9.146-1.726 12.624-5.442l168.23-174.16 168.36 174.03c3.478 3.584 7.986 5.442 12.624 5.442 4.509 0 9.146-1.726 12.624-5.442l48.176-49.912c3.349-3.451 5.281-8.097 5.281-13.009a19.32 19.32 0 0 0-5.41-12.876z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
require("./bar.scss");
|
require("./bar.scss");
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const theme = getQueryVariable("theme");
|
||||||
|
document.documentElement.classList.add("theme_" + theme);
|
||||||
|
|
||||||
let i18n = {};
|
let i18n = {};
|
||||||
let lang = window.navigator.language;
|
let lang = window.navigator.language;
|
||||||
|
|
||||||
@ -39,10 +42,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
var changeButton = document.querySelector("#template-change .change-save");
|
var changeButton = document.querySelector("#template-change .change-save");
|
||||||
changeButton.textContent = i18n.notificationChangeSave;
|
changeButton.textContent = i18n.notificationChangeSave;
|
||||||
|
|
||||||
var closeIcon = document.getElementById("close");
|
|
||||||
closeIcon.src = chrome.runtime.getURL("images/close.png");
|
|
||||||
closeIcon.alt = i18n.close;
|
|
||||||
|
|
||||||
var closeButton = document.getElementById("close-button");
|
var closeButton = document.getElementById("close-button");
|
||||||
closeButton.title = i18n.close;
|
closeButton.title = i18n.close;
|
||||||
closeButton.setAttribute("aria-label", i18n.close);
|
closeButton.setAttribute("aria-label", i18n.close);
|
||||||
@ -51,7 +50,38 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
document.querySelector("#template-change .change-text").textContent =
|
document.querySelector("#template-change .change-text").textContent =
|
||||||
i18n.notificationChangeDesc;
|
i18n.notificationChangeDesc;
|
||||||
|
|
||||||
if (getQueryVariable("add")) {
|
if (getQueryVariable("type") === "add") {
|
||||||
|
handleTypeAdd(isVaultLocked);
|
||||||
|
} else if (getQueryVariable("type") === "change") {
|
||||||
|
handleTypeChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
closeButton.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
sendPlatformMessage({
|
||||||
|
command: "bgCloseNotificationBar",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("resize", adjustHeight);
|
||||||
|
adjustHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQueryVariable(variable) {
|
||||||
|
var query = window.location.search.substring(1);
|
||||||
|
var vars = query.split("&");
|
||||||
|
|
||||||
|
for (var i = 0; i < vars.length; i++) {
|
||||||
|
var pair = vars[i].split("=");
|
||||||
|
if (pair[0] === variable) {
|
||||||
|
return pair[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTypeAdd(isVaultLocked) {
|
||||||
setContent(document.getElementById("template-add"));
|
setContent(document.getElementById("template-add"));
|
||||||
|
|
||||||
var addButton = document.querySelector("#template-add-clone .add-save"), // eslint-disable-line
|
var addButton = document.querySelector("#template-add-clone .add-save"), // eslint-disable-line
|
||||||
@ -88,7 +118,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
responseCommand: responseFoldersCommand,
|
responseCommand: responseFoldersCommand,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (getQueryVariable("change")) {
|
}
|
||||||
|
|
||||||
|
function handleTypeChange() {
|
||||||
setContent(document.getElementById("template-change"));
|
setContent(document.getElementById("template-change"));
|
||||||
var changeButton = document.querySelector("#template-change-clone .change-save"); // eslint-disable-line
|
var changeButton = document.querySelector("#template-change-clone .change-save"); // eslint-disable-line
|
||||||
changeButton.addEventListener("click", (e) => {
|
changeButton.addEventListener("click", (e) => {
|
||||||
@ -101,31 +133,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
closeButton.addEventListener("click", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
sendPlatformMessage({
|
|
||||||
command: "bgCloseNotificationBar",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener("resize", adjustHeight);
|
|
||||||
adjustHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getQueryVariable(variable) {
|
|
||||||
var query = window.location.search.substring(1);
|
|
||||||
var vars = query.split("&");
|
|
||||||
|
|
||||||
for (var i = 0; i < vars.length; i++) {
|
|
||||||
var pair = vars[i].split("=");
|
|
||||||
if (pair[0] === variable) {
|
|
||||||
return pair[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setContent(element) {
|
function setContent(element) {
|
||||||
const content = document.getElementById("content");
|
const content = document.getElementById("content");
|
||||||
while (content.firstChild) {
|
while (content.firstChild) {
|
||||||
|
@ -1,22 +1,31 @@
|
|||||||
body {
|
@import "variables.scss";
|
||||||
background-color: #ffffff;
|
|
||||||
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
color: #333333;
|
font-family: $font-family-sans-serif;
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
|
@include themify($themes) {
|
||||||
|
color: themed("textColor");
|
||||||
|
background-color: themed("backgroundColor");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.outer-wrapper {
|
.outer-wrapper {
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
border-bottom: 2px solid #175ddc;
|
border-bottom: 2px solid transparent;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 24px auto 55px;
|
grid-template-columns: 24px auto 55px;
|
||||||
grid-column-gap: 10px;
|
grid-column-gap: 10px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-height: 42px;
|
min-height: 42px;
|
||||||
|
|
||||||
|
@include themify($themes) {
|
||||||
|
border-bottom-color: themed("primaryColor");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.inner-wrapper {
|
.inner-wrapper {
|
||||||
@ -41,41 +50,85 @@ img {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#close {
|
#close-button {
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
display: block;
|
|
||||||
padding: 5px 0;
|
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:not(.link),
|
#close {
|
||||||
button:not(.neutral) {
|
display: block;
|
||||||
background-color: #175ddc;
|
width: 17px;
|
||||||
padding: 5px 15px;
|
height: 17px;
|
||||||
border-radius: 3px;
|
|
||||||
color: #ffffff;
|
> path {
|
||||||
border: 0;
|
@include themify($themes) {
|
||||||
|
fill: themed("textColor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#close-button:hover {
|
||||||
|
@include themify($themes) {
|
||||||
|
border-color: rgba(themed("textColor"), 0.2);
|
||||||
|
background-color: rgba(themed("textColor"), 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 0.35rem 15px;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:not(.neutral):not(.link) {
|
||||||
|
@include themify($themes) {
|
||||||
|
background-color: themed("primaryColor");
|
||||||
|
color: themed("textContrast");
|
||||||
|
border-color: themed("primaryColor");
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
@include themify($themes) {
|
||||||
background-color: #1751bd;
|
background-color: darken(themed("primaryColor"), 1.5%);
|
||||||
|
color: darken(themed("textContrast"), 6%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button.link,
|
button.link,
|
||||||
button.neutral {
|
button.neutral {
|
||||||
background: none;
|
@include themify($themes) {
|
||||||
padding: 5px 15px;
|
background-color: transparent;
|
||||||
color: #175ddc;
|
color: themed("primaryColor");
|
||||||
border: 0;
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
|
||||||
background: none;
|
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
|
||||||
|
@include themify($themes) {
|
||||||
|
background-color: transparent;
|
||||||
|
color: darken(themed("primaryColor"), 6%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 0.35rem;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
|
||||||
|
@include themify($themes) {
|
||||||
|
color: themed("textColor");
|
||||||
|
background-color: themed("inputBackgroundColor");
|
||||||
|
border-color: themed("inputBorderColor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select,
|
||||||
|
button {
|
||||||
|
font-size: $font-size-base;
|
||||||
|
font-family: $font-family-sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
.select-folder[isVaultLocked="true"] {
|
.select-folder[isVaultLocked="true"] {
|
||||||
display: none;
|
display: none;
|
||||||
|
80
apps/browser/src/notification/variables.scss
Normal file
80
apps/browser/src/notification/variables.scss
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
@import "~nord/src/sass/nord.scss";
|
||||||
|
|
||||||
|
$font-family-sans-serif: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
$font-size-base: 14px;
|
||||||
|
$text-color: #333333;
|
||||||
|
$border-color-dark: #ddd;
|
||||||
|
$border-radius: 3px;
|
||||||
|
|
||||||
|
$brand-primary: #175ddc;
|
||||||
|
|
||||||
|
$background-color: #f0f0f0;
|
||||||
|
|
||||||
|
$solarizedDarkBase03: #002b36;
|
||||||
|
$solarizedDarkBase02: #073642;
|
||||||
|
$solarizedDarkBase01: #586e75;
|
||||||
|
$solarizedDarkBase2: #eee8d5;
|
||||||
|
$solarizedDarkCyan: #2aa198;
|
||||||
|
$solarizedDarkGreen: #859900;
|
||||||
|
|
||||||
|
$themes: (
|
||||||
|
light: (
|
||||||
|
textColor: $text-color,
|
||||||
|
backgroundColor: $background-color,
|
||||||
|
primaryColor: $brand-primary,
|
||||||
|
buttonPrimaryColor: $brand-primary,
|
||||||
|
textContrast: $background-color,
|
||||||
|
inputBorderColor: darken($border-color-dark, 7%),
|
||||||
|
inputBackgroundColor: #ffffff,
|
||||||
|
),
|
||||||
|
dark: (
|
||||||
|
textColor: #ffffff,
|
||||||
|
backgroundColor: #2f343d,
|
||||||
|
buttonPrimaryColor: #6f9df1,
|
||||||
|
primaryColor: #6f9df1,
|
||||||
|
textContrast: #2f343d,
|
||||||
|
inputBorderColor: #4c525f,
|
||||||
|
inputBackgroundColor: #2f343d,
|
||||||
|
),
|
||||||
|
nord: (
|
||||||
|
textColor: $nord5,
|
||||||
|
backgroundColor: $nord1,
|
||||||
|
buttonPrimaryColor: $nord8,
|
||||||
|
primaryColor: $nord9,
|
||||||
|
textContrast: $nord2,
|
||||||
|
inputBorderColor: $nord0,
|
||||||
|
inputBackgroundColor: $nord2,
|
||||||
|
),
|
||||||
|
solarizedDark: (
|
||||||
|
textColor: $solarizedDarkBase2,
|
||||||
|
backgroundColor: $solarizedDarkBase03,
|
||||||
|
buttonPrimaryColor: $solarizedDarkCyan,
|
||||||
|
primaryColor: $solarizedDarkGreen,
|
||||||
|
textContrast: $solarizedDarkBase02,
|
||||||
|
inputBorderColor: rgba($solarizedDarkBase2, 0.2),
|
||||||
|
inputBackgroundColor: $solarizedDarkBase01,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@mixin themify($themes: $themes) {
|
||||||
|
@each $theme, $map in $themes {
|
||||||
|
html.theme_#{$theme} & {
|
||||||
|
$theme-map: () !global;
|
||||||
|
@each $key, $submap in $map {
|
||||||
|
$value: map-get(map-get($themes, $theme), "#{$key}");
|
||||||
|
$theme-map: map-merge(
|
||||||
|
$theme-map,
|
||||||
|
(
|
||||||
|
$key: $value,
|
||||||
|
)
|
||||||
|
) !global;
|
||||||
|
}
|
||||||
|
@content;
|
||||||
|
$theme-map: null !global;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@function themed($key) {
|
||||||
|
@return map-get($theme-map, $key);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user