refactor(devtools): extract and organize colors into themes (#60374)

Extract all colors from the stylesheets, reduce their number by merging the similar ones and organize them into themes represented by CSS variables.

PR Close #60374
This commit is contained in:
hawkgs 2025-02-28 16:16:46 +02:00 committed by Jessica Janiuk
parent c65259c8a5
commit 77b5eed024
50 changed files with 362 additions and 623 deletions

View file

@ -8,7 +8,6 @@ package(default_visibility = ["//visibility:public"])
sass_binary(
name = "devtools_component_styles",
src = "devtools.component.scss",
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -35,8 +35,8 @@ export class ThemeService {
toggleDarkMode(isDark: boolean): void {
const removeClass = isDark ? LIGHT_THEME_CLASS : DARK_THEME_CLASS;
const addClass = !isDark ? LIGHT_THEME_CLASS : DARK_THEME_CLASS;
this.renderer.removeClass(this.doc.body, removeClass);
this.renderer.addClass(this.doc.body, addClass);
this.renderer.removeClass(this.doc.documentElement, removeClass);
this.renderer.addClass(this.doc.documentElement, addClass);
this.currentTheme.set(addClass);
}

View file

@ -57,7 +57,7 @@ describe('ThemeService', () => {
const doc = TestBed.inject(DOCUMENT);
expect(service.currentTheme()).toEqual('light-theme');
expect(doc.body.classList.contains('light-theme')).toBeTrue();
expect(doc.documentElement.classList.contains('light-theme')).toBeTrue();
});
it(`should enable dark mode, if it's the preferred/system one`, () => {
@ -69,7 +69,7 @@ describe('ThemeService', () => {
const doc = TestBed.inject(DOCUMENT);
expect(service.currentTheme()).toEqual('dark-theme');
expect(doc.body.classList.contains('dark-theme')).toBeTrue();
expect(doc.documentElement.classList.contains('dark-theme')).toBeTrue();
});
it('should toggle dark mode', () => {
@ -84,7 +84,7 @@ describe('ThemeService', () => {
const doc = TestBed.inject(DOCUMENT);
expect(service.currentTheme()).toEqual('dark-theme');
expect(doc.body.classList.contains('dark-theme')).toBeTrue();
expect(doc.documentElement.classList.contains('dark-theme')).toBeTrue();
});
it('should update the theme automatically, if the system one changes', () => {
@ -95,7 +95,7 @@ describe('ThemeService', () => {
// Initialize the watcher.
service.initializeThemeWatcher();
const docClassList = TestBed.inject(DOCUMENT).body.classList;
const docClassList = TestBed.inject(DOCUMENT).documentElement.classList;
expect(service.currentTheme()).toEqual('light-theme');
expect(docClassList.contains('light-theme')).toBeTrue();

View file

@ -8,7 +8,6 @@ package(default_visibility = ["//visibility:public"])
sass_binary(
name = "devtools_tabs_component_styles",
src = "devtools-tabs.component.scss",
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -9,7 +9,6 @@ sass_binary(
name = "resolution_path_styles",
src = "resolution-path.component.scss",
visibility = ["//visibility:private"],
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -1,20 +1,14 @@
@use '../../../../styles/theme' as theme;
/* TODO: Extract */
$darkBg: #1a1a1a;
$lightBg: #f3f3f3;
:host {
display: flex;
flex-wrap: wrap;
background: $lightBg;
border-top: 1px solid black;
background: var(--octonary-contrast);
padding: 0.5rem 0.5rem 0.25rem 0.5rem;
border-top: 1px solid var(--senary-contrast);
.node {
position: relative;
border-radius: 5px;
background: #c4c4c4;
background: var(--octonary-contrast);
color: black;
padding: 4px 25px 4px 15px;
margin-bottom: 0.25rem;
@ -23,15 +17,15 @@ $lightBg: #f3f3f3;
box-sizing: border-box;
&.type-env {
background: #f9c2c5;
background: var(--red-06);
}
&.type-element {
background: #a6d5a9;
background: var(--green-03);
}
&.type-imported {
background: #c79eff;
background: var(--purple-03);
}
&.type-hidden {
@ -60,7 +54,7 @@ $lightBg: #f3f3f3;
&:not(:last-of-type)::before {
content: '';
background: $lightBg;
background: var(--octonary-contrast);
width: 21px;
height: 21px;
top: calc(50% - 6px);
@ -76,10 +70,3 @@ $lightBg: #f3f3f3;
}
}
}
@include theme.dark-theme {
:host,
.node:not(:last-of-type)::before {
background: #1a1a1a;
}
}

View file

@ -1,5 +1,3 @@
@use '../../styles/theme' as theme;
:host {
position: relative;
width: 100%;
@ -23,6 +21,10 @@ ng-injector-tree.hidden {
height: calc(100% - 31px);
}
nav {
border-bottom: 1px solid var(--color-separator);
}
#nav-buttons {
display: flex;
@ -31,6 +33,7 @@ ng-injector-tree.hidden {
border: none;
cursor: pointer;
opacity: 0.8;
color: var(--secondary-contrast);
&:active {
opacity: 1;
@ -39,7 +42,7 @@ ng-injector-tree.hidden {
}
.inspector-active {
color: #1a73e8 !important;
color: var(--blue-02) !important;
}
#app-angular-version {
@ -54,7 +57,7 @@ ng-injector-tree.hidden {
}
#version-number {
color: #1b1aa5;
color: var(--blue-02);
cursor: text;
-moz-user-select: text;
-khtml-user-select: text;
@ -63,7 +66,7 @@ ng-injector-tree.hidden {
user-select: text;
&.unsupported-version {
color: red;
color: var(--red-04);
}
}
@ -109,9 +112,7 @@ mat-icon {
}
.frame-selector {
background-color: #e2e2e2;
border-radius: 2px;
color: #474747;
border: none;
margin: 4px 4px 2px 4px;
padding: 2px;
@ -119,32 +120,3 @@ mat-icon {
width: 100px;
font-size: 12px;
}
@include theme.dark-theme {
.frame-selector {
background-color: #464646;
color: #fff;
}
#app-angular-version {
color: #fff;
}
#nav-buttons {
button {
color: #fff;
}
}
#version-number {
color: #5caace;
&.unsupported-version {
color: red;
}
}
.inspector-active {
color: #4688f1 !important;
}
}

View file

@ -6,7 +6,6 @@ package(default_visibility = ["//visibility:public"])
sass_binary(
name = "directive_forest_component_styles",
src = "directive-forest.component.scss",
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -6,7 +6,6 @@ package(default_visibility = ["//visibility:public"])
sass_binary(
name = "breadcrumbs_component_styles",
src = "breadcrumbs.component.scss",
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
.mdc-card.breadcrumb-card {
padding: 0;
width: 100%;
@ -9,7 +7,7 @@
.scroll-button {
height: 100%;
background-color: rgb(243, 243, 243);
background-color: var(--septenary-contrast);
border: none;
cursor: pointer;
@ -34,7 +32,7 @@
height: 24px;
&.selected {
background-color: rgb(243, 243, 243);
background-color: var(--color-tree-node-highlighted);
}
}
}
@ -45,36 +43,10 @@
font-size: 11px;
margin-right: 5px;
width: fit-content;
color: #8a1882;
color: var(--color-tree-node-element-name);
&:hover {
background-color: #ebf1fb;
}
}
}
@include theme.dark-theme {
.mdc-card {
&.breadcrumb-card {
.scroll-button {
background-color: rgb(41, 42, 45);
color: #ffffff;
}
.breadcrumbs {
button {
&.selected {
background-color: rgb(41, 42, 45);
}
}
}
.mdc-button {
color: #5caace;
&:hover {
background-color: #093e69;
}
}
background-color: var(--color-tree-node-hovered);
}
}
}

View file

@ -1,5 +1,3 @@
@use '../../../../styles/theme' as theme;
:host {
width: 100%;
height: 100%;
@ -7,7 +5,7 @@
.tree-node {
position: relative;
color: #8a1882;
color: var(--color-tree-node-element-name);
cursor: default;
font-family: Menlo, monospace;
@ -35,50 +33,47 @@
width: 16px;
height: 13px;
display: inline-block;
color: var(--primary-contrast);
}
.dir-names {
color: #9b4807;
color: var(--color-tree-node-dir-name);
}
.console-reference,
.on-push {
color: #748591;
color: var(--color-tree-node-console-ref);
padding-left: 8px;
font-style: italic;
}
&:hover {
background-color: #ebf1fb;
background-color: var(--color-tree-node-hovered);
}
&.matched {
background-color: #ebf1fb;
&:hover {
background-color: #cfe8fc;
}
background-color: var(--color-tree-node-matched);
}
&.selected,
&.highlighted {
background-color: #cfe8fc;
background-color: var(--color-tree-node-highlighted);
}
.hydration {
margin: auto 8px auto auto;
font-size: 14px;
color: #60a6fc;
color: var(--blue-02);
position: sticky;
right: 0;
&.skipped {
color: #9a9a9a;
color: var(--senary-contrast);
}
&.mismatched {
color: #ff0040;
color: var(--red-04);
}
}
}
@ -89,7 +84,7 @@
background-color: transparent;
}
50% {
background-color: #cfe8fc;
background-color: var(--blue-04);
}
100% {
background-color: transparent;
@ -100,29 +95,6 @@
animation: appear 1.5s;
}
.filter {
display: flex;
.icon {
width: 20px;
height: 20px;
margin: auto 12px;
opacity: 0.7;
}
.filter-input {
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
width: 100%;
font-size: 2em;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
padding: 12px 6px;
}
}
.up-down-buttons {
width: 20%;
display: flex;
@ -135,7 +107,7 @@
.angular-element {
content: '';
color: #1b1aa5;
color: var(--color-tree-node-ng-element);
&::before {
content: '<';
@ -147,13 +119,13 @@
}
.hydration-error {
color: #e62222;
color: var(--dynamic-red-01);
margin-left: 16px;
padding: 0 8px 8px 0px;
pre {
margin: 0;
background: rgba(1, 1, 1, 0.05);
background: var(--dynamic-transparent-01);
padding: 8px;
border-radius: 8px;
@ -162,57 +134,3 @@
}
}
}
@include theme.dark-theme {
.tree-node {
color: #5cadd3;
.mat-icon {
color: #bcc5ce;
}
.dir-names {
color: #91adcb;
}
.angular-element {
color: #dc8c61;
}
&:hover {
background-color: #262d36;
}
&.matched {
background-color: #262d36;
&:hover {
background-color: #073d69;
}
}
&.selected,
&.highlighted {
background-color: #073d69;
}
.hydration {
color: #60a6fc;
&.skipped {
color: #9a9a9a;
}
&.mismatched {
color: #ff0040;
}
}
.hydration-error {
color: #ea7171;
pre {
background: rgb(1, 1, 1, 0.2);
}
}
}
}

View file

@ -6,7 +6,6 @@ package(default_visibility = ["//visibility:public"])
sass_binary(
name = "filter_component_styles",
src = "filter.component.scss",
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -1,11 +1,9 @@
@use '../../../../../styles/theme' as theme;
.filter {
display: flex;
padding: 0px;
border-radius: 0px;
box-shadow: none !important;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
border-bottom: 1px solid var(--color-separator);
label {
display: flex;
@ -25,7 +23,6 @@
.filter-input {
border: none;
border-left: 1px solid rgba(0, 0, 0, 0.12);
padding-left: 5px;
width: 100%;
font-size: 11px;
@ -33,7 +30,7 @@
font-weight: inherit;
height: 30px;
outline: none;
color: rgba(0, 0, 0, 0.87);
background: var(--color-background);
}
}
}
@ -64,18 +61,3 @@
}
}
}
@include theme.dark-theme {
.filter {
label {
.filter-input {
background-color: #202124;
color: #ffffff;
}
}
}
mat-icon {
color: #fff;
}
}

View file

@ -18,7 +18,6 @@ _STYLE_LABELS = [
sass_binary(
name = label,
src = src,
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
for label, src in zip(_STYLE_LABELS, _STYLE_SRCS)
]

View file

@ -1,5 +1,3 @@
@use '../../../../styles/theme' as theme;
.element-header {
display: flex;
justify-content: space-between;
@ -45,9 +43,3 @@
}
}
}
@include theme.dark-theme {
.element-name {
color: #ffffff;
}
}

View file

@ -22,7 +22,6 @@ _STYLE_LABELS = [
sass_binary(
name = label,
src = src,
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
for label, src in zip(_STYLE_LABELS, _STYLE_SRCS)
]

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
.editor {
cursor: text;
border: none;
@ -10,8 +8,7 @@
}
.editor-input {
background-color: #bbddfb;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05);
box-shadow: 0 0 0 1px var(--dynamic-transparent-01);
}
input {
@ -22,15 +19,3 @@ input {
border: none;
outline: none;
}
@include theme.dark-theme {
input {
color: #bcc5ce;
background-color: #202124;
}
.editor-input {
background-color: #454546;
box-shadow: 0 0 0 1px rgba(165, 165, 165, 0.05);
}
}

View file

@ -1,7 +1,7 @@
.function {
&:hover {
background: #4da1ff;
color: #fff;
background: var(--blue-02);
color: white;
cursor: pointer;
}
}

View file

@ -1,11 +1,15 @@
@use '../../../../../styles/theme' as theme;
:host {
::ng-deep {
mat-expansion-panel {
border-radius: unset !important;
}
.mat-expansion-panel {
box-shadow:
0 -2px 5px -2px var(--dynamic-transparent-02),
0 2px 5px 0 var(--dynamic-transparent-02);
}
.mat-expansion-panel-body {
padding: 0;
}
@ -24,14 +28,13 @@
}
.docs-link {
color: #000000de;
height: inherit;
width: fit-content;
font-size: initial;
padding-left: 0.1rem;
&:active {
color: #1b1aa5;
color: var(--blue-02);
}
}
}
@ -47,15 +50,5 @@
margin-bottom: 4.5px;
}
}
@include theme.dark-theme {
.docs-link {
color: #bcc5ce;
&:active {
color: #5caace;
}
}
}
}
}

View file

@ -152,7 +152,6 @@ export class DependencyViewerComponent {
styles: [
`
ng-dependency-viewer {
border-bottom: 1px solid color-mix(in srgb, currentColor, #bdbdbd 85%);
display: block;
}
`,

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
mat-toolbar {
padding-left: 10px;
justify-content: space-between;
@ -33,9 +31,3 @@ button {
opacity: 1;
}
}
@include theme.dark-theme {
button {
color: #fff;
}
}

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
:host {
width: 100%;
display: block;
@ -38,29 +36,21 @@
margin: 5px 5px 5px 15px;
mat-tree-node {
.name {
color: #ce271e;
color: var(--color-tree-node-element-name);
font-weight: 500;
}
}
}
@include theme.dark-theme {
.property-list {
.name {
color: #54c9bd !important;
}
}
}
.property-list mat-tree-node.disabled .name,
.disabled {
color: #333;
color: var(--secondary-contrast);
}
.arrow {
font-family: monospace;
font-size: 0.5em;
color: #6e6e6e;
color: var(--quaternary-contrast);
}
:host ::ng-deep .mat-tree-node,

View file

@ -8,7 +8,6 @@ package(default_visibility = ["//:__subpackages__"])
sass_binary(
name = "injector_tree_styles",
src = "injector-tree.component.scss",
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -11,7 +11,6 @@ sass_binary(
],
deps = [
"//devtools/projects/ng-devtools/src/styles:material_sass_deps",
"//devtools/projects/ng-devtools/src/styles:theme",
],
)

View file

@ -1,5 +1,4 @@
@use '@angular/material' as mat;
@use '../../../../styles/theme' as theme;
h2 {
font-size: 0.875rem;
@ -108,13 +107,3 @@ tr.example-detail-row {
padding: 0.5rem 0;
text-align: center;
}
@include theme.dark-theme {
.providers-title {
color: #ffffff;
}
.no-providers-label {
color: #bcc5ce;
}
}

View file

@ -1,5 +1,3 @@
@use '../../../styles/theme' as theme;
:host {
width: 100%;
height: 100%;
@ -56,14 +54,14 @@ svg {
}
.docs-link {
color: #000000de;
color: black;
height: inherit;
width: fit-content;
font-size: initial;
padding-left: 0.1rem;
&:active {
color: #1b1aa5;
color: var(--blue-02);
}
}
}
@ -89,7 +87,7 @@ svg {
height: 90px;
flex-shrink: 0;
align-items: center;
border-right: 1px solid #e8e8e8;
border-right: 1px solid var(--septenary-contrast);
}
.parameter {
@ -113,20 +111,20 @@ svg {
}
.parameter-name {
color: #d23a32;
color: var(--dynamic-red-01);
}
.parameter-flag {
a {
display: inline-block;
padding: 0px 6px;
background: #dddddd;
background: var(--senary-contrast);
border-radius: 10px;
color: inherit;
text-decoration: none;
&:hover {
background: #c6c6c6;
background: var(--senary-contrast);
}
}
}
@ -162,16 +160,16 @@ svg {
display: flex;
overflow: auto;
background: #f5f5f5;
background: var(--septenary-contrast);
.dep {
border-top: 1px solid #e8e8e8;
border-bottom: 1px solid #e8e8e8;
border-left: 1px solid #e8e8e8;
border-top: 1px solid var(--septenary-contrast);
border-bottom: 1px solid var(--septenary-contrast);
border-left: 1px solid var(--septenary-contrast);
padding: 1rem;
&:last-of-type {
border-right: 1px solid #e8e8e8;
border-right: 1px solid var(--septenary-contrast);
}
.dep-header {
@ -195,7 +193,7 @@ svg {
font-size: 11px;
font-weight: 500;
height: auto;
background: #f5f5f5;
background: var(--septenary-contrast);
}
.injector-hierarchy {
@ -207,7 +205,7 @@ svg {
margin: 0;
display: flex;
align-items: center;
border-bottom: 1px solid #777777;
border-bottom: 1px solid var(--quaternary-contrast);
font-size: 0.875rem;
display: flex;
align-items: center;
@ -224,7 +222,7 @@ svg {
.injector-graph {
overflow: auto;
background: #f3f3f3;
background: var(--octonary-contrast);
height: calc(100% - 50px);
}
@ -232,19 +230,3 @@ svg {
color: currentColor;
text-decoration: none;
}
@include theme.dark-theme {
.injector-hierarchy {
h2 {
color: #ffffff;
}
}
.deps {
background: #161515;
}
.injector-graph {
background: #1a1a1a;
}
}

View file

@ -17,7 +17,6 @@ _STYLE_LABELS = [
sass_binary(
name = label,
src = src,
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
for label, src in zip(_STYLE_LABELS, _STYLE_SRCS)
]

View file

@ -4,10 +4,10 @@
}
.profiler-version {
color: #388e3c;
color: var(--green-01);
}
.imported-version,
.error {
color: #d32f2f;
color: var(--dynamic-red-01);
}

View file

@ -32,7 +32,7 @@
}
<p class="instructions" [class.hidden]="state() !== 'idle'">
<span>
Click the record button to start a new recording, or upload a json file containing profiler
Click the record button to start a new recording, or upload a JSON file containing profiler
data.
</span>
<br />

View file

@ -1,5 +1,3 @@
@use '../../../styles/theme' as theme;
:host,
.profiler-wrapper {
font-size: 1em;
@ -21,7 +19,7 @@
cursor: pointer;
&.recording-button {
color: #d83c34;
color: var(--dynamic-red-01);
}
}
@ -38,12 +36,6 @@
}
}
@include theme.dark-theme {
.instructions {
color: #ffffff;
}
}
#profiler-content-wrapper {
margin: 0;
height: calc(100% - 30px);
@ -55,14 +47,6 @@
height: 100%;
}
@include theme.dark-theme {
.profiler-control {
&.recording-button {
color: #ff625a;
}
}
}
.mdc-card {
flex-direction: row;
align-items: center;

View file

@ -21,7 +21,6 @@ _STYLE_LABELS = [
sass_binary(
name = label,
src = src,
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
for label, src in zip(_STYLE_LABELS, _STYLE_SRCS)
]

View file

@ -1,5 +1,3 @@
@use '../../../../styles/theme' as theme;
.bar-graph-container {
padding: 2px;
height: 54px;
@ -43,7 +41,7 @@
margin-top: 2px;
&:hover {
background-color: #ebf1fb;
background-color: var(--septenary-contrast);
}
&.selected {
@ -53,8 +51,8 @@
padding-left: 0.5px;
padding-right: 0.5px;
background-color: #cfe8fc;
border: 2px solid #cfe8fc;
background-color: var(--dynamic-blue-01);
border: 2px solid var(--dynamic-blue-01);
}
}
}
@ -64,23 +62,6 @@
}
}
@include theme.dark-theme {
.bar-graph-container .bar-container .frame-bar {
&:hover {
background-color: #262d36;
}
&.selected {
background-color: #073d69;
border: 2px solid #073d69;
}
}
.txt-frames {
color: #ffffff;
}
}
cdk-virtual-scroll-viewport {
height: 50px;
}

View file

@ -21,7 +21,6 @@ _STYLE_LABELS = [
sass_binary(
name = label,
src = src,
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
for label, src in zip(_STYLE_LABELS, _STYLE_SRCS)
]

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
.bar {
width: 0%;
margin-bottom: 7px;
@ -22,6 +20,7 @@
text-overflow: ellipsis;
overflow: hidden;
opacity: 1;
color: var(--color-text);
}
.bar:hover {
@ -34,9 +33,3 @@
height: 100%;
display: block;
}
@include theme.dark-theme {
.bar span {
color: #bcc5ce;
}
}

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
table {
border-collapse: collapse;
width: 100%;
@ -10,13 +8,5 @@ table {
th,
td {
border-bottom: 1px solid #ddd;
}
@include theme.dark-theme {
.name,
.method,
.value {
color: #ffffff;
}
border-bottom: 1px solid var(--senary-contrast);
}

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
:host {
width: 100%;
height: 100%;
@ -17,32 +15,18 @@
::ng-deep {
.ngx-fg-label {
color: #000000de;
font-weight: 500;
font-size: 1em;
}
}
@include theme.dark-theme {
.entry-statistics {
span {
color: #54c9bd;
}
color: var(--senary-contrast);
}
::ng-deep {
.ngx-fg-rect {
stroke: #303030;
transition: none;
}
.ngx-fg-rect {
stroke: var(--secondary-contrast);
transition: none;
}
.ngx-fg-label {
color: #bcc5ce;
}
.ngx-fg-svg-g {
transition: none;
}
.ngx-fg-svg-g {
transition: none;
}
}
}

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
:host {
display: block;
overflow: auto;
@ -47,7 +45,7 @@
}
span {
color: #8a1882;
color: var(--purple-01);
}
}
@ -60,15 +58,3 @@ ul {
margin-block-start: 0px;
padding-inline-start: 20px;
}
@include theme.dark-theme {
.entry-statistics {
span {
color: #5cadd3;
}
}
.txt-total-time {
color: #ffffff;
}
}

View file

@ -1,5 +1,3 @@
@use '../../../../../styles/theme' as theme;
.web-tree {
height: calc(100% - 25px);
width: calc(100% - 25px);
@ -8,25 +6,15 @@
:host {
::ng-deep {
.webtreemap-node {
background: var(--primary-contrast);
}
.webtreemap-caption {
font-size: 0.9em;
// color: white;
}
.webtreemap-node:hover {
background: #ebf1fb;
}
}
}
@include theme.dark-theme {
::ng-deep {
.webtreemap-node {
background: #202124;
}
.webtreemap-node:hover {
background: #262d36;
}
.webtreemap-caption {
color: #ffffff;
background: var(--septenary-contrast);
}
}
}

View file

@ -1,5 +1,3 @@
@use '../../../../styles/theme' as theme;
.visual-controls {
display: flex;
flex-direction: column;
@ -49,12 +47,12 @@
text-overflow: ellipsis;
&.warning-label {
color: #d83c34;
color: var(--dynamic-red-01);
}
}
.value {
color: #8a1882;
color: var(--dynamic-purple-01);
}
}
@ -66,16 +64,3 @@
min-height: 85px;
}
}
@include theme.dark-theme {
.details .value {
color: #5cadd3;
}
.warning-label {
color: #ff625a;
}
.details {
color: #ffffff;
}
}

View file

@ -1,5 +1,3 @@
@use '../../../../styles/theme' as theme;
:host {
font-size: 11px;
width: 100%;
@ -28,9 +26,3 @@
height: 100%;
margin: 0 10px;
}
@include theme.dark-theme {
.info {
color: #ffffff;
}
}

View file

@ -6,7 +6,6 @@ package(default_visibility = ["//:__subpackages__"])
sass_binary(
name = "router_tree_styles",
src = "router-tree.component.scss",
deps = ["//devtools/projects/ng-devtools/src/styles:theme"],
)
ng_module(

View file

@ -105,8 +105,8 @@ export class RouterTreeVisualizer {
.attr('y', 10)
.attr('width', size)
.attr('height', size)
.style('stroke', '#ff7a7e')
.style('fill', '#f9c2c5');
.style('stroke', 'var(--red-05)')
.style('fill', 'var(--red-06)');
svg
.append('rect')
@ -114,8 +114,8 @@ export class RouterTreeVisualizer {
.attr('y', 45)
.attr('width', size)
.attr('height', size)
.style('stroke', 'oklch(0.65 0.25 266/1)')
.style('fill', '#8bc1ff');
.style('stroke', 'var(--blue-02)')
.style('fill', 'var(--blue-03)');
svg
.append('rect')
@ -123,8 +123,8 @@ export class RouterTreeVisualizer {
.attr('y', 80)
.attr('width', size)
.attr('height', size)
.style('stroke', '#28ab2c')
.style('fill', '#a7d5a9');
.style('stroke', 'var(--green-02)')
.style('fill', 'var(--green-03)');
svg
.append('text')

View file

@ -1,5 +1,3 @@
@use '../../../styles/theme' as theme;
.router-tree-wrapper {
font-size: 1em;
width: 100%;
@ -9,7 +7,7 @@
}
.filter-input {
border: 1px solid rgba(0, 0, 0, 0.12);
border: 1px solid var(--senary-contrast);
border-radius: 3px;
padding-left: 5px;
margin: 0 5px 0 10px;
@ -17,12 +15,5 @@
font-size: 11px;
height: 28px;
outline: none;
color: rgba(0, 0, 0, 0.87);
}
@include theme.dark-theme {
.filter-input {
border: 1px solid rgba(255, 255, 255, 0.12);
color: rgba(255, 255, 255, 0.87);
}
color: black;
}

View file

@ -15,23 +15,54 @@
display: none;
}
.legend {
background: var(--primary-contrast);
}
.arrow {
fill: var(--full-contrast);
}
.legend-router-tree {
fill: var(--full-contrast) !important;
}
.link {
stroke: #9b9b9b;
stroke: var(--quaternary-contrast);
stroke-width: 3px;
fill: none;
&.highlighted {
stroke: #4da1ff;
stroke: var(--blue-02);
}
}
.node {
cursor: pointer;
.node-container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
color: black;
font-size: 16px;
box-sizing: border-box;
border-radius: 2px;
border-style: solid;
border-width: 2px;
font-weight: 300;
&:hover {
color: white;
}
}
&.highlighted {
.node-container,
.node-container:hover {
background: oklch(0.65 0.25 266 / 1);
background: var(--blue-02);
border-color: white;
color: white;
font-weight: 400;
@ -40,30 +71,15 @@
&.selected {
.node-container,
.node-container:hover {
color: oklch(0.65 0.25 266 / 1);
color: var(--blue-02);
background: white;
border-width: 3px;
border-color: oklch(0.65 0.25 266 / 1);
border-color: var(--blue-02);
font-weight: 800;
}
}
}
.node-container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
color: #000;
font-size: 16px;
box-sizing: border-box;
border-radius: 2px;
border-style: solid;
border-width: 2px;
font-weight: 300;
}
.node-search {
border-width: 4px !important;
border-style: groove !important;
@ -72,44 +88,48 @@
}
.node-environment {
border: 1px solid #ff7a7e;
background: #f9c2c5;
border: 1px solid var(--red-05);
background: var(--red-06);
&:hover {
background: #ff7a7e;
background: var(--red-05);
}
}
.node-imported-module {
border-color: #8838f7;
background: #c79eff;
border-color: var(--purple-02);
background: var(--purple-03);
&:hover {
background: #8838f7;
background: var(--purple-02);
}
}
.node-lazy {
border-color: oklch(0.65 0.25 266/1);
background: #8bc1ff;
border-color: var(--blue-02);
background: var(--blue-03);
&:hover {
background: #8bc1ff;
background: var(--blue-02);
}
}
.node-element {
border-color: #28ab2c;
background: #a7d5a9;
border-color: var(--green-02);
background: var(--green-03);
&:hover {
background: #28ab2c;
background: var(--green-02);
}
}
.node-null {
border: 1px solid #8b8b8b;
border: 1px solid var(--quaternary-contrast);
background: white;
&:hover {
color: black;
}
}
.node-label {
@ -122,32 +142,3 @@
}
}
}
:host-context(.dark-theme) {
svg ::ng-deep {
.legend {
background: #2f2c2c;
}
.link {
stroke: #bcc5ce;
fill: none;
&.highlighted {
stroke: #4da1ff;
}
}
.arrow {
fill: white;
}
.node-label {
color: #000;
}
.legend-router-tree {
fill: #ffffff !important;
}
}
}

View file

@ -1,20 +1,9 @@
@use '../styles/theme' as theme;
@keyframes pulse {
0% {
box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 0 0px var(--dynamic-red-02);
}
100% {
box-shadow: 0 0 0 35px rgba(0, 0, 0, 0);
}
}
@keyframes darkmode-pulse {
0% {
box-shadow: 0 0 0 0px rgb(126, 40, 40);
}
100% {
box-shadow: 0 0 0 35px rgba(0, 0, 0, 0);
box-shadow: 0 0 0 35px var(--dynamic-transparent-01);
}
}
@ -30,18 +19,6 @@
display: block;
}
@include theme.dark-theme {
.devtools-wrapper {
background: #202124;
}
.initializing {
.loading {
animation: darkmode-pulse 1s infinite;
}
}
}
.noselect {
user-select: none;
}
@ -74,7 +51,7 @@
display: inline-block;
font-size: 0.8em;
border-radius: 50%;
border: solid 2px rgb(17, 17, 17);
border: solid 2px var(--primary-contrast);
cursor: pointer;
width: 16px;
height: 16px;
@ -83,29 +60,19 @@
}
}
@include theme.dark-theme {
.info-icon {
border: solid 2px #bcc5ce;
}
a {
color: #bcc5ce;
}
}
.ng-dev-mode-causes {
font-weight: 500;
font-size: 1.2em;
padding: 1rem;
width: 80%;
margin: auto;
border: 1px solid;
border: 1px solid var(--quinary-contrast);
border-radius: 16px;
code {
padding: 2px;
color: lightgreen;
background: #3e3e3e;
color: var(--dynamic-green-01);
background: var(--senary-contrast);
border-radius: 5px;
}

View file

@ -63,7 +63,7 @@
}
&:not(:first-of-type) {
border-left: 1px solid #eeeeee;
border-left: 1px solid var(--color-separator);
}
}
}
@ -91,7 +91,7 @@
}
&:not(:first-of-type) {
border-top: 1px solid #eeeeee;
border-top: 1px solid var(--color-separator);
}
&.as-hidden {
@ -117,21 +117,3 @@
}
}
}
:host-context(.dark-theme) {
&.as-horizontal {
::ng-deep > .as-split-area {
&:not(:first-of-type) {
border-left: 1px solid #3f3f3f;
}
}
}
&.as-vertical {
::ng-deep > .as-split-area {
&:not(:first-of-type) {
border-top: 1px solid #3f3f3f;
}
}
}
}

View file

@ -13,7 +13,10 @@ npm_sass_library(
sass_library(
name = "global",
srcs = ["_global.scss"],
deps = [":material_sass_deps"],
deps = [
":colors",
":material_sass_deps",
],
)
sass_library(
@ -29,6 +32,9 @@ sass_library(
sass_library(
name = "colors",
srcs = ["_colors.scss"],
deps = [
":theme",
],
)
sass_binary(

View file

@ -1 +1,171 @@
$dummy: #f00;
@use 'sass:color';
@use 'sass:map';
@use './theme' as theme;
/* A map with all available solid colors (excl. Special). Available as CSS vars as well. */
/* prettier-ignore */
$_colors: (
/* Reds */
red-01: oklch(40% 0.1 26),
red-02: oklch(49.3% 0.2 26),
red-03: oklch(55% 0.2 26),
red-04: oklch(63% 0.2 26),
red-05: oklch(68.8% 0.2 26),
red-06: oklch(86% 0.06 15),
/* Greens */
green-01: oklch(58% 0.13 145),
green-02: oklch(65% 0.13 145),
green-03: oklch(83% 0.13 145),
/* Blues */
blue-01: oklch(36% 0.1 258),
blue-02: oklch(57% 0.2 258),
blue-03: oklch(72% 0.2 258),
blue-04: oklch(83% 0.2 258),
blue-05: oklch(91% 0.04 258),
blue-06: oklch(96% 0.01 258),
/* Purples */
purple-01: oklch(47.5% 0.26 295),
purple-02: oklch(57.9% 0.26 295),
purple-03: oklch(76% 0.15 305),
/* Grayscale */
gray-1000: oklch(16.93% 0 0),
gray-900: oklch(19.37% 0 0),
gray-800: oklch(27.68% 0 0),
gray-700: oklch(36.98% 0 0),
gray-600: oklch(47% 0 0),
gray-500: oklch(54.84% 0 0),
gray-400: oklch(70.9% 0 0),
gray-300: oklch(84.01% 0 0),
gray-200: oklch(91.75% 0 0),
gray-100: oklch(97.12% 0 0),
gray-50: oklch(98.81% 0 0),
/* Transparent */
transparent-01: oklch(0% 0 0 / 0.8),
transparent-02: oklch(0% 0 0 / 0.35),
transparent-03: oklch(0% 0 0 / 0.2),
transparent-04: oklch(0% 0 0 / 0.05),
);
@mixin _light-colors {
/* Dynamic general purpose colors */
--full-contrast: black;
--primary-contrast: var(--gray-900);
--secondary-contrast: var(--gray-800);
--tertiary-contrast: var(--gray-700);
--quaternary-contrast: var(--gray-500);
--quinary-contrast: var(--gray-300);
--senary-contrast: var(--gray-200);
--septenary-contrast: var(--gray-100);
--octonary-contrast: var(--gray-50);
--dynamic-red-01: var(--red-03);
--dynamic-red-02: var(--red-06);
--dynamic-green-01: var(--green-01);
--dynamic-blue-01: var(--blue-05);
--dynamic-purple-01: var(--purple-01);
--dynamic-transparent-01: var(--transparent-04);
--dynamic-transparent-02: var(--transparent-02);
/* Main colors general UI colors like background and text color */
--color-background: white;
--color-foreground: var(--blue-06);
--color-text: black;
--color-separator: var(--blue-05);
/* Special colors usually a single-use colors meant for specific elements */
--color-tree-node-element-name: #830042;
--color-tree-node-dir-name: #953b13;
--color-tree-node-ng-element: #0c3a96;
--color-tree-node-console-ref: #146129;
--color-tree-node-hovered: #f2f2f2;
--color-tree-node-highlighted: #cddffd;
--color-tree-node-matched: #f3ce49;
--color-property-list-name: #71a2f7;
}
@mixin _dark-colors {
/* Dynamic general purpose colors */
--full-contrast: white;
--primary-contrast: var(--gray-50);
--secondary-contrast: var(--gray-300);
--tertiary-contrast: var(--gray-300);
--quaternary-contrast: var(--gray-400);
--quinary-contrast: var(--gray-500);
--senary-contrast: var(--gray-700);
--septenary-contrast: var(--gray-800);
--octonary-contrast: var(--gray-900);
--dynamic-red-01: var(--red-05);
--dynamic-red-02: var(--red-01);
--dynamic-green-01: var(--green-03);
--dynamic-blue-01: var(--blue-01);
--dynamic-purple-01: var(--purple-03);
--dynamic-transparent-01: var(--transparent-03);
--dynamic-transparent-02: var(--transparent-01);
/* Main colors general UI colors like background and text color */
--color-background: var(--gray-800);
--color-foreground: var(--gray-700);
--color-text: white;
--color-separator: var(--gray-600);
/* Special colors usually a single-use colors meant for specific elements */
--color-tree-node-element-name: #71a2f7;
--color-tree-node-dir-name: #9ec0f9;
--color-tree-node-ng-element: #fe824f;
--color-tree-node-console-ref: #a1a1a1;
--color-tree-node-hovered: #393939;
--color-tree-node-highlighted: #00416c;
--color-tree-node-matched: #906921;
--color-property-list-name: #0c3a96;
}
/* Utilities */
@function convert-to-rgb($map) {
$rgb-map: ();
@each $name, $color in $map {
$rgb-map: map-merge(
$rgb-map,
(
$name: color.to-space($color, rgb),
)
);
}
@return $rgb-map;
}
@mixin convert-color-map-to-vars($colors) {
@each $name, $color in $colors {
--#{$name}: #{$color};
}
}
/* Main */
/* Since Oklch global browser support is ~93%, we are converting colors to RGB. */
$colors: convert-to-rgb($_colors); /* Main color map */
@mixin root-colors {
:root {
@include convert-color-map-to-vars($colors);
@include _light-colors();
&.#{theme.$dark-theme-class} {
@include _dark-colors();
}
}
}

View file

@ -2,13 +2,24 @@
@use 'sass:map';
@use 'external/npm/node_modules/@angular/material/index' as mat;
@use './colors' as clr;
@include mat.all-component-typographies();
@include mat.core();
@include clr.root-colors();
html,
body {
padding: 0;
margin: 0;
background: var(--color-background);
color: var(--color-text);
}
input,
select {
color: var(--primary-contrast);
background: var(--color-foreground);
}
// Light theme
@ -24,19 +35,19 @@ $dark-theme: map.deep-merge(
(
'color': (
'background': (
background: #202124,
card: #202124,
background: map.get(clr.$colors, gray-800),
card: map.get(clr.$colors, gray-800),
),
'foreground': (
text: #bcc5ce,
text: map.get(clr.$colors, gray-200),
),
),
'background': (
background: #202124,
card: #202124,
background: map.get(clr.$colors, gray-800),
card: map.get(clr.$colors, gray-800),
),
'foreground': (
'text': #bcc5ce,
'text': map.get(clr.$colors, gray-200),
),
)
);
@ -53,7 +64,6 @@ $dark-theme: map.deep-merge(
/* Keep class name in sync with ThemeService */
.dark-theme {
color-scheme: dark;
background: #202124;
@include mat.all-component-themes($dark-theme);
.mat-mdc-chip.mat-mdc-standard-chip {

View file

@ -1,30 +1,30 @@
/* Keep class names in sync with ThemeService */
$_dark-theme-class: 'dark-theme';
$_light-theme-class: 'light-theme';
$dark-theme-class: 'dark-theme';
$light-theme-class: 'light-theme';
/* $browser expects 'chrome', 'firefox' or 'safari' */
@mixin _theme($theme, $browser: '') {
@if $browser == '' {
:host-context(body.#{$theme}) {
:host-context(:root.#{$theme}) {
@content;
}
} @else {
/* Keep browser class name in sync with BrowserService. */
$browser-class: $browser + '-ui';
:host-context(body.#{$theme}.#{$browser-class}) {
:host-context(:root.#{$theme}.#{$browser-class}) {
@content;
}
}
}
@mixin dark-theme($browser: '') {
@include _theme($_dark-theme-class, $browser) {
@include _theme($dark-theme-class, $browser) {
@content;
}
}
@mixin light-theme($browser: '') {
@include _theme($_light-theme-class, $browser) {
@include _theme($light-theme-class, $browser) {
@content;
}
}