mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Switching color theme globally (#728)
* Adding cluster menu colors Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Adding theme class name flag into #app Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Cleaning up mixins Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Tuning up Wizard Layout styles Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Using theme-light global flag Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Minor style fixes Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Using .theme-light flag across components Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Set theme as @computed value Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Preventing Drawer slide-in scroll flickering Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Setting background for settings views Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Minor layout fixes Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Switching AceEditor theme reactively Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Cleaning up Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
parent
c7b11f86af
commit
0f11b03692
@ -1,13 +1,6 @@
|
||||
@import "release.mixins";
|
||||
|
||||
.ReleaseDetails {
|
||||
&.light {
|
||||
.AceEditor {
|
||||
border: 1px solid gainsboro;
|
||||
border-radius: $radius;
|
||||
}
|
||||
}
|
||||
|
||||
.DrawerItem {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
.content-col {
|
||||
margin: 0;
|
||||
padding-top: $padding * 3;
|
||||
background-color: transparent;
|
||||
background-color: $clusterSettingsBackground;
|
||||
|
||||
.SubTitle {
|
||||
text-transform: none;
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
padding: 0;
|
||||
|
||||
.content-col {
|
||||
background-color: transparent;
|
||||
padding: $padding * 8 0;
|
||||
background-color: $clusterSettingsBackground;
|
||||
|
||||
h2 {
|
||||
margin-bottom: $margin * 2;
|
||||
@ -40,6 +40,10 @@
|
||||
.WizardLayout .head-col {
|
||||
padding-top: 32px;
|
||||
overflow: hidden;
|
||||
|
||||
.Icon {
|
||||
margin-top: -$margin * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,13 +5,12 @@
|
||||
flex: 1;
|
||||
z-index: 10;
|
||||
|
||||
&.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
.theme-light & {
|
||||
border: 1px solid gainsboro;
|
||||
border-radius: $radius;
|
||||
|
||||
&.light {
|
||||
.ace_scrollbar {
|
||||
@include custom-scrollbar($theme: dark);
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,10 +3,11 @@
|
||||
import "./ace-editor.scss"
|
||||
|
||||
import React from "react"
|
||||
import { observer } from "mobx-react";
|
||||
import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import AceBuild, { Ace } from "ace-builds"
|
||||
import { autobind, cssNames } from "../../utils";
|
||||
import { themeStore } from "../../theme.store";
|
||||
import { reaction } from "mobx";
|
||||
|
||||
interface Props extends Partial<Ace.EditorOptions> {
|
||||
className?: string;
|
||||
@ -46,6 +47,11 @@ export class AceEditor extends React.Component<Props, State> {
|
||||
require("ace-builds/src-noconflict/ext-searchbox")
|
||||
}
|
||||
|
||||
@disposeOnUnmount
|
||||
themeSwitcher = reaction(() => themeStore.activeTheme, () => {
|
||||
this.setTheme(this.theme);
|
||||
});
|
||||
|
||||
get theme() {
|
||||
switch (themeStore.activeTheme.type) {
|
||||
case "light":
|
||||
@ -148,9 +154,8 @@ export class AceEditor extends React.Component<Props, State> {
|
||||
|
||||
render() {
|
||||
const { className, hidden } = this.props;
|
||||
const themeType = themeStore.activeTheme.type;
|
||||
return (
|
||||
<div className={cssNames("AceEditor", className, { hidden }, themeType)}>
|
||||
<div className={cssNames("AceEditor", className, { hidden })}>
|
||||
<div className="editor" ref={e => this.elem = e}/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -12,8 +12,6 @@
|
||||
|
||||
:root {
|
||||
--mainBackground: #1e2124;
|
||||
--textColorPrimary: #87909c;
|
||||
--clusters-menu-bgc: #252729;
|
||||
--main-layout-header: 40px;
|
||||
}
|
||||
|
||||
@ -31,6 +29,7 @@ html {
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#app {
|
||||
@ -79,7 +78,7 @@ hr {
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
color: $textColorPrimary;
|
||||
font-size: 28px;
|
||||
font-weight: normal;
|
||||
letter-spacing: -.010em;
|
||||
@ -142,10 +141,6 @@ a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:not([href]) {
|
||||
border-bottom: 1px dotted;
|
||||
text-decoration: none;
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: $spacing;
|
||||
background: var(--clusters-menu-bgc);
|
||||
background: $clusterMenuBackground;
|
||||
border-right: 1px solid $clusterMenuBorderColor;
|
||||
|
||||
.is-mac & {
|
||||
padding-top: $spacing * 2;
|
||||
@ -47,11 +48,9 @@
|
||||
.Icon {
|
||||
border-radius: $radius;
|
||||
padding: $padding / 3;
|
||||
color: var(--clusters-menu-bgc) !important;
|
||||
background: white !important;
|
||||
font-weight: bold;
|
||||
color: $addClusterIconColor;
|
||||
background: #ffffff66;
|
||||
cursor: pointer;
|
||||
opacity: 0.4;
|
||||
|
||||
&.active {
|
||||
opacity: 1;
|
||||
@ -59,7 +58,7 @@
|
||||
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
opacity: .75;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,4 +15,8 @@
|
||||
&.modal {
|
||||
background: transparentize(#222, .5);
|
||||
}
|
||||
|
||||
h5 {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
@ -77,4 +77,8 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.AceEditor {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
margin-left: $padding * 2;
|
||||
margin-top: $padding * 2;
|
||||
|
||||
&.light {
|
||||
.theme-light & {
|
||||
.xterm-viewport {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
box-shadow: 0 0 $unit * 2 $boxShadow;
|
||||
z-index: $zIndex-drawer;
|
||||
|
||||
&.light {
|
||||
.theme-light & {
|
||||
.drawer-content {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import { cssNames, noop } from "../../utils";
|
||||
import { Icon } from "../icon";
|
||||
import { Animate, AnimateName } from "../animate";
|
||||
import { history } from "../../navigation";
|
||||
import { themeStore } from "../../theme.store";
|
||||
|
||||
export interface DrawerProps {
|
||||
open: boolean;
|
||||
@ -101,7 +100,7 @@ export class Drawer extends React.Component<DrawerProps> {
|
||||
render() {
|
||||
const { open, position, title, animation, children, toolbar, size, usePortal } = this.props
|
||||
let { className, contentClass } = this.props;
|
||||
className = cssNames("Drawer", className, position, themeStore.activeTheme.type);
|
||||
className = cssNames("Drawer", className, position);
|
||||
contentClass = cssNames("drawer-content flex column box grow", contentClass);
|
||||
const style = size ? { "--size": size } as React.CSSProperties : undefined;
|
||||
const drawer = (
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
.KubeConfigDialog {
|
||||
&.light {
|
||||
.theme-light & {
|
||||
.AceEditor {
|
||||
border: 1px solid gainsboro;
|
||||
border-radius: $radius;
|
||||
|
||||
@ -13,7 +13,6 @@ import { Dialog, DialogProps } from "../dialog";
|
||||
import { Icon } from "../icon";
|
||||
import { Notifications } from "../notifications";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
import { themeStore } from "../../theme.store";
|
||||
import { apiBase } from "../../api";
|
||||
|
||||
interface IKubeconfigDialogData {
|
||||
@ -92,7 +91,7 @@ export class KubeConfigDialog extends React.Component<Props> {
|
||||
return (
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className={cssNames("KubeConfigDialog", themeStore.activeTheme.type)}
|
||||
className={cssNames("KubeConfigDialog")}
|
||||
isOpen={isOpen}
|
||||
onOpen={this.onOpen}
|
||||
close={this.close}
|
||||
|
||||
@ -8,13 +8,6 @@
|
||||
grid-template-columns: [sidebar] minmax(var(--main-layout-header), min-content) [main] 1fr;
|
||||
height: 100%;
|
||||
|
||||
&.light {
|
||||
main {
|
||||
@include custom-scrollbar(dark);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
> .Tabs {
|
||||
grid-area: tabs;
|
||||
background: $layoutTabsBackground;
|
||||
@ -69,6 +62,10 @@
|
||||
@include custom-scrollbar;
|
||||
$spacing: $margin * 2;
|
||||
|
||||
.theme-light & {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
|
||||
grid-area: main;
|
||||
overflow-y: scroll; // always reserve space for scrollbar (17px)
|
||||
overflow-x: auto;
|
||||
|
||||
@ -11,7 +11,6 @@ import { ErrorBoundary } from "../error-boundary";
|
||||
import { Dock } from "../dock";
|
||||
import { navigate, navigation } from "../../navigation";
|
||||
import { getHostedCluster } from "../../../common/cluster-store";
|
||||
import { themeStore } from "../../theme.store";
|
||||
|
||||
export interface TabRoute extends RouteProps {
|
||||
title: React.ReactNode;
|
||||
@ -50,7 +49,7 @@ export class MainLayout extends React.Component<Props> {
|
||||
const routePath = navigation.location.pathname;
|
||||
const cluster = getHostedCluster();
|
||||
return (
|
||||
<div className={cssNames("MainLayout", className, themeStore.activeTheme.type)}>
|
||||
<div className={cssNames("MainLayout", className)}>
|
||||
<header className={cssNames("flex gaps align-center", headerClass)}>
|
||||
<span className="cluster">
|
||||
{cluster.preferences?.clusterName || cluster.contextName}
|
||||
|
||||
@ -20,6 +20,10 @@
|
||||
&.pinned {
|
||||
.sidebar-nav {
|
||||
@include custom-scrollbar;
|
||||
|
||||
.theme-light & {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
$spacing: $padding * 2;
|
||||
|
||||
position: relative;
|
||||
padding: $padding * 3;
|
||||
padding: $padding * 2;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 40%;
|
||||
@ -11,17 +11,21 @@
|
||||
@include custom-scrollbar;
|
||||
--flex-gap: #{$spacing};
|
||||
padding: $spacing;
|
||||
|
||||
.theme-light & {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
}
|
||||
|
||||
> .head-col {
|
||||
position: sticky;
|
||||
border-bottom: 1px solid $grey-800;
|
||||
justify-content: space-between;
|
||||
background-color: $clusterMenuBackground;
|
||||
}
|
||||
|
||||
> .content-col {
|
||||
margin-right: $spacing;
|
||||
background-color: var(--clusters-menu-bgc);
|
||||
background-color: $contentColor;
|
||||
border-radius: $radius;
|
||||
|
||||
> div {
|
||||
@ -36,7 +40,7 @@
|
||||
}
|
||||
|
||||
> .info-col {
|
||||
border-left: 1px solid #353a3e;
|
||||
background-color: $contentColor;
|
||||
}
|
||||
|
||||
p {
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
|
||||
@mixin custom-scrollbar($theme: light, $size: 7px, $borderSpacing: 5px) {
|
||||
$themes: (
|
||||
light: rgba(255, 255, 255, .25),
|
||||
dark: rgba(0, 0, 0, .25),
|
||||
light: #5f6064,
|
||||
dark: #bbb,
|
||||
);
|
||||
|
||||
$scrollBarColor: if(map_has_key($themes, $theme), map_get($themes, $theme), none);
|
||||
@ -34,10 +34,6 @@
|
||||
&::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
// Firefox
|
||||
scrollbar-color: $scrollBarColor transparent;
|
||||
//scrollbar-width: thin;
|
||||
}
|
||||
|
||||
// Hide scrollbar but keep the element scrollable
|
||||
@ -49,27 +45,6 @@
|
||||
height: 0;
|
||||
background: transparent;
|
||||
}
|
||||
scrollbar-width: none; // Firefox 65+
|
||||
-ms-overflow-style: none; // IE (10,11?), Edge(?)
|
||||
}
|
||||
|
||||
// Cross-browser hacks
|
||||
@mixin safariOnly {
|
||||
@media not all and (min-resolution: .001dpcm) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin firefoxOnly {
|
||||
@-moz-document url-prefix() {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin edgeOnly {
|
||||
@supports (-ms-accelerator: true) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin stripeLinesAnimation($color1: #ccc, $color2: transparent, $spacing: 1rem) {
|
||||
|
||||
@ -38,7 +38,9 @@ export class Select extends React.Component<SelectProps> {
|
||||
menuPortalTarget: document.body,
|
||||
}
|
||||
|
||||
private theme = this.props.themeName || themeStore.activeTheme.type;
|
||||
@computed get theme() {
|
||||
return this.props.themeName || themeStore.activeTheme.type;
|
||||
}
|
||||
|
||||
private styles: Styles = {
|
||||
menuPortal: styles => ({
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
.Table {
|
||||
&.scrollable {
|
||||
&.light {
|
||||
.theme-light & {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
.VirtualList {
|
||||
overflow: hidden;
|
||||
|
||||
&.light {
|
||||
.list {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
}
|
||||
|
||||
> .list {
|
||||
@include custom-scrollbar;
|
||||
|
||||
.theme-light & {
|
||||
@include custom-scrollbar(dark);
|
||||
}
|
||||
|
||||
overflow-y: overlay !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
@ -93,6 +93,9 @@ export class ThemeStore {
|
||||
return `--${cssName}: ${color} !important;`
|
||||
});
|
||||
this.styles.textContent = `:root {\n${cssVars.join("\n")}}`;
|
||||
// Adding universal theme flag which can be used in component styles
|
||||
const body = document.querySelector("body");
|
||||
body.classList.toggle("theme-light", theme.type === ThemeType.LIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -90,6 +90,10 @@
|
||||
"drawerSubtitleBackground": "#373a3e",
|
||||
"drawerItemNameColor": "#87909c",
|
||||
"drawerItemValueColor": "#a0a0a0",
|
||||
"clusterMenuBackground": "#252729",
|
||||
"clusterMenuBorderColor": "#252729",
|
||||
"clusterSettingsBackground": "#1e2124",
|
||||
"addClusterIconColor": "#252729",
|
||||
"boxShadow": "#0000003a",
|
||||
"iconActiveColor": "#ffffff",
|
||||
"iconActiveBackground": "#ffffff22",
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
"sidebarBackground": "#e8e8e8",
|
||||
"buttonPrimaryBackground": "#3d90ce",
|
||||
"buttonDefaultBackground": "#414448",
|
||||
"buttonAccentBackground": "#3b4148",
|
||||
"buttonAccentBackground": "#e85555",
|
||||
"buttonDisabledBackground": "#808080",
|
||||
"tableBgcStripe": "#f8f8f8",
|
||||
"tableBgcSelected": "#f4f5f5",
|
||||
@ -91,6 +91,10 @@
|
||||
"drawerSubtitleBackground": "#f1f1f1",
|
||||
"drawerItemNameColor": "#727272",
|
||||
"drawerItemValueColor": "#555555",
|
||||
"clusterMenuBackground": "#e8e8e8",
|
||||
"clusterMenuBorderColor": "#c9cfd3",
|
||||
"clusterSettingsBackground": "#ffffff",
|
||||
"addClusterIconColor": "#8d8d8d",
|
||||
"boxShadow": "#0000003a",
|
||||
"iconActiveColor": "#ffffff",
|
||||
"iconActiveBackground": "#a6a6a694",
|
||||
|
||||
@ -110,6 +110,12 @@ $chartStripesColor: var(--chartStripesColor);
|
||||
$chartCapacityColor: var(--chartCapacityColor);
|
||||
$pieChartDefaultColor: var(--pieChartDefaultColor);
|
||||
|
||||
// Cluster Menu
|
||||
$clusterMenuBackground: var(--clusterMenuBackground);
|
||||
$clusterMenuBorderColor: var(--clusterMenuBorderColor);
|
||||
$clusterSettingsBackground: var(--clusterSettingsBackground);
|
||||
$addClusterIconColor: var(--addClusterIconColor);
|
||||
|
||||
// Misc
|
||||
$boxShadow: var(--boxShadow);
|
||||
$iconActiveColor: var(--iconActiveColor);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user