- add dark mode support for UI components

- fix https://github.com/HeyPuter/puter/issues/3098
This commit is contained in:
Miika Kuisma
2026-05-13 08:54:23 +03:00
parent b0dc9c7f1b
commit 238ed12e28
5 changed files with 219 additions and 4 deletions
@@ -176,6 +176,48 @@ class PuterColorPicker extends PuterWebComponent {
flex: 1;
}
}
@media (prefers-color-scheme: dark) {
.picker-body {
background-color: rgba(40, 44, 52, .95);
color: #e6e6e6;
box-shadow: 0px 0px 15px #000000aa;
}
.preview {
border-color: #555;
}
.header-label {
color: #aaa;
}
.hex-input {
background-color: #1f1f1f;
border-color: #555;
color: #e6e6e6;
}
.native-color-row {
background: rgba(255, 255, 255, 0.05);
border-color: #555;
}
.native-color-row label {
color: #aaa;
}
input[type="color"] {
border-color: #555;
}
.swatch {
border-color: rgba(255, 255, 255, 0.1);
}
.btn {
color: #e6e6e6;
border-color: #555;
background: linear-gradient(#4a4a4a, #3a3a3a);
box-shadow: inset 0px 1px 0px rgb(255 255 255 / 8%), 0 1px 2px rgb(0 0 0 / 25%);
}
.btn:active {
background-color: #333;
border-color: #444;
color: #999;
}
}
`;
}
@@ -47,15 +47,16 @@ class PuterContextMenu extends PuterWebComponent {
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 2px;
border-radius: 4px;
padding: 3px 0;
min-width: 200px;
background-color: rgb(255 255 255 / 92%);
backdrop-filter: blur(3px);
border: 1px solid #e6e4e466;
box-shadow: 0px 0px 15px #00000066;
padding-left: 6px;
padding-right: 6px;
box-shadow: 0px 3px 10px #00000044;
margin-top: 5px;
padding-left: 4px;
padding-right: 4px;
padding-top: 4px;
padding-bottom: 4px;
user-select: none;
@@ -335,6 +336,94 @@ class PuterContextMenu extends PuterWebComponent {
width: 20px;
height: 20px;
}
@media (prefers-color-scheme: dark) {
.context-menu {
background: #2d2d2d;
background-color: rgb(45 45 45 / 94%);
color: #e6e6e6;
border-color: #00000080;
box-shadow: 0px 0px 15px #000000aa;
}
.menu-item {
color: #e6e6e6;
}
/* Inactive items: icon/check/shortcut/arrow tones */
.icon,
.check {
color: #e6e6e6;
}
.submenu-arrow {
color: #b0b0b0;
}
.shortcut {
color: #888;
}
.icon img {
filter: drop-shadow(0px 0px 0.3px rgb(230, 230, 230));
}
/* Inactive icon SVGs use currentColor already; nothing to invert */
/* Safe-triangle: non-active hover restored colors should match dark */
.context-menu.safe-traverse .menu-item:hover:not(.has-open-submenu):not(.focused):not(.disabled):not(.divider) {
color: #e6e6e6;
}
.context-menu.safe-traverse .menu-item:hover:not(.has-open-submenu):not(.focused):not(.disabled):not(.divider) .icon,
.context-menu.safe-traverse .menu-item:hover:not(.has-open-submenu):not(.focused):not(.disabled):not(.divider) .check,
.context-menu.safe-traverse .menu-item:hover:not(.has-open-submenu):not(.focused):not(.disabled):not(.divider) .submenu-arrow,
.context-menu.safe-traverse .menu-item:hover:not(.has-open-submenu):not(.focused):not(.disabled):not(.divider) .label {
color: #e6e6e6;
}
.context-menu.safe-traverse .menu-item:hover:not(.has-open-submenu):not(.focused):not(.disabled):not(.divider) .shortcut {
color: #888;
}
.context-menu.safe-traverse .menu-item:hover:not(.has-open-submenu):not(.focused):not(.disabled):not(.divider) .icon img {
filter: drop-shadow(0px 0px 0.3px rgb(230, 230, 230));
}
/* Submenu-open parent (no hover): subtle dark highlight */
.menu-item.has-open-submenu:not(:hover) {
background-color: #3f3f3f;
color: #e6e6e6;
}
.menu-item.has-open-submenu:not(:hover) .icon,
.menu-item.has-open-submenu:not(:hover) .icon svg,
.menu-item.has-open-submenu:not(:hover) .icon img {
color: #e6e6e6;
}
/* Danger items */
.menu-item.danger,
.menu-item.danger .icon {
color: #ff7b72;
}
/* Divider */
.divider hr {
background: #444;
}
/* Sheet mode (mobile) */
:host(.sheet-mode) .context-menu {
background-color: rgb(40 40 40 / 96%);
box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.45);
}
:host(.sheet-mode) .menu-item:hover:not(.disabled):not(.divider) {
background-color: rgba(0, 122, 255, 0.22);
}
:host(.sheet-mode) .menu-item:active:not(.disabled):not(.divider) {
background-color: rgba(0, 122, 255, 0.35);
}
:host(.sheet-mode) .menu-item:hover:not(.disabled):not(.divider) .label,
:host(.sheet-mode) .menu-item:hover:not(.disabled):not(.divider) .icon,
:host(.sheet-mode) .menu-item:active:not(.disabled):not(.divider) .label,
:host(.sheet-mode) .menu-item:active:not(.disabled):not(.divider) .icon {
color: #e6e6e6;
}
:host(.sheet-mode) .divider hr {
background: rgba(255, 255, 255, 0.15);
}
}
`;
}
@@ -185,6 +185,51 @@ class PuterFontPicker extends PuterWebComponent {
flex: 1;
}
}
@media (prefers-color-scheme: dark) {
.picker-body {
background-color: rgba(40, 44, 52, .95);
color: #e6e6e6;
box-shadow: 0px 0px 15px #000000aa;
}
.title {
color: #e6e6e6;
text-shadow: none;
}
.search {
background-color: #1f1f1f;
border-color: #555;
color: #e6e6e6;
}
.font-list {
background-color: #1f1f1f;
border-color: #555;
}
.font-item {
color: #e6e6e6;
}
.font-item:hover {
background: rgba(255, 255, 255, 0.06);
}
.font-name-label {
color: #888;
}
.preview {
background: #1f1f1f;
border-color: #555;
color: #e6e6e6;
}
.btn {
color: #e6e6e6;
border-color: #555;
background: linear-gradient(#4a4a4a, #3a3a3a);
box-shadow: inset 0px 1px 0px rgb(255 255 255 / 8%), 0 1px 2px rgb(0 0 0 / 25%);
}
.btn:active {
background-color: #333;
border-color: #444;
color: #999;
}
}
`;
}
@@ -86,6 +86,20 @@ class PuterMenubar extends PuterWebComponent {
flex-shrink: 0;
}
}
@media (prefers-color-scheme: dark) {
.menubar {
background-color: #2a2a2a;
border-bottom-color: #3a3a3a;
}
.menu-button {
color: #e6e6e6;
}
.menu-button:hover,
.menu-button.active,
.menu-button.focused {
background-color: #3a3a3a;
}
}
`;
}
@@ -175,6 +175,31 @@ class PuterNotification extends PuterWebComponent {
width: auto;
}
}
@media (prefers-color-scheme: dark) {
.notification {
background: #2d2d2dcd;
border-color: #3a3a3a;
box-shadow: 0px 0px 17px -6px #000;
}
.close-btn {
background: #3a3a3a;
color: #ccc;
filter: drop-shadow(0px 0px 0.5px rgb(230, 230, 230));
}
.close-btn:hover {
background: #4a4a4a;
color: #fff;
}
.icon-area {
filter: drop-shadow(0px 0px 0.5px rgb(230, 230, 230));
}
.title {
color: #e6e6e6;
}
.text {
color: #b0b0b0;
}
}
`;
}