From 3f9ab07a5efe50a2e1336e696406ab93fa630e79 Mon Sep 17 00:00:00 2001 From: ajnart Date: Sat, 22 Aug 2026 12:40:11 +0200 Subject: [PATCH] fix: restore translucent dashboard styling --- .../layout/scaled-board-canvas.module.css | 2 + .../board/sections/grid/grid-editor.css | 42 ++++------ .../sections/grid/section-grid.module.css | 4 +- .../beszel-system-grid/component.module.css | 4 + .../src/beszel-system-grid/component.tsx | 1 + .../src/beszel/_shared/disk-usage.module.css | 4 + .../widgets/src/beszel/_shared/disk-usage.tsx | 22 +++++- .../widgets/src/calendar/component.module.css | 8 ++ packages/widgets/src/calendar/component.tsx | 18 +++-- .../src/dns-hole/summary/component.tsx | 7 +- packages/widgets/src/docker/component.tsx | 8 +- packages/widgets/src/docker/styles.css | 24 ++++++ packages/widgets/src/downloads/component.tsx | 10 +-- packages/widgets/src/downloads/styles.css | 22 +++++- .../immich/server-stats/component.module.css | 21 +++-- .../src/immich/server-stats/component.tsx | 79 ++++++++++--------- .../src/indexer-manager/component.module.css | 11 +-- .../media-requests/list/component.module.css | 7 +- .../src/media-requests/list/component.tsx | 8 +- .../widgets/src/rssFeed/component.module.scss | 15 +++- packages/widgets/src/rssFeed/component.tsx | 2 +- .../src/speedtest-tracker/speed-stat-card.tsx | 21 +++-- .../widgets/src/system-disks/component.tsx | 12 +-- .../system-resources/chart/common-chart.tsx | 17 ++-- .../src/system-resources/component.tsx | 4 +- .../widgets/src/umami/component.module.css | 21 +++++ packages/widgets/src/umami/umami-content.tsx | 15 ++-- packages/widgets/src/umami/umami-top-list.tsx | 3 +- .../widgets/src/weather/component.module.css | 10 +-- 29 files changed, 277 insertions(+), 145 deletions(-) create mode 100644 packages/widgets/src/docker/styles.css create mode 100644 packages/widgets/src/umami/component.module.css diff --git a/apps/nextjs/src/components/board/layout/scaled-board-canvas.module.css b/apps/nextjs/src/components/board/layout/scaled-board-canvas.module.css index feb2a8ac5..014c503b6 100644 --- a/apps/nextjs/src/components/board/layout/scaled-board-canvas.module.css +++ b/apps/nextjs/src/components/board/layout/scaled-board-canvas.module.css @@ -23,6 +23,8 @@ * zoom and enlarges everything together. */ --mantine-scale: var(--board-canvas-ui-scale, 1); + /* Keep the legacy card inset visually stable while the fixed canvas is zoomed. */ + --board-grid-item-inset: calc(10px * var(--board-canvas-inverse-scale, 1) - 12px); --mantine-spacing-xs: calc(0.625rem * var(--board-canvas-ui-scale, 1)); --mantine-spacing-sm: calc(0.75rem * var(--board-canvas-ui-scale, 1)); --mantine-spacing-md: calc(1rem * var(--board-canvas-ui-scale, 1)); diff --git a/apps/nextjs/src/components/board/sections/grid/grid-editor.css b/apps/nextjs/src/components/board/sections/grid/grid-editor.css index abc2139e2..798a2c970 100644 --- a/apps/nextjs/src/components/board/sections/grid/grid-editor.css +++ b/apps/nextjs/src/components/board/sections/grid/grid-editor.css @@ -51,7 +51,7 @@ .board-grid-entry[data-board-item-selected="true"]::after { position: absolute; - inset: 0; + inset: var(--board-grid-item-inset, 0px); z-index: 100; content: ""; background: color-mix(in srgb, var(--mantine-primary-color-filled) 12%, transparent); @@ -121,6 +121,7 @@ body[data-board-grid-interacting="resize"] .board-grid-entry[data-dnd-active="tr .board-grid-placeholder { z-index: 0; + clip-path: inset(var(--board-grid-item-inset, 0px)); background: color-mix(in srgb, var(--mantine-primary-color-filled) 16%, transparent); border: 2px dashed var(--mantine-primary-color-filled); border-radius: var(--mantine-radius-md); @@ -139,6 +140,7 @@ body[data-board-grid-interacting="resize"] .board-grid-entry[data-dnd-active="tr .board-grid-resize-outline { z-index: 1002; + clip-path: inset(var(--board-grid-item-inset, 0px)); background: color-mix(in srgb, var(--mantine-primary-color-filled) 6%, transparent); border: 2px solid var(--mantine-primary-color-filled); border-radius: var(--mantine-radius-md); @@ -240,11 +242,11 @@ body[data-board-grid-interacting="resize"] .board-grid-entry[data-dnd-active="tr } .board-grid-resize-handle[data-grid-resize-handle="n"] { - top: -0.25rem; + top: calc(var(--board-grid-item-inset, 0px) - 0.25rem); } .board-grid-resize-handle[data-grid-resize-handle="s"] { - bottom: -0.25rem; + bottom: calc(var(--board-grid-item-inset, 0px) - 0.25rem); } .board-grid-resize-handle[data-grid-resize-handle="e"], @@ -258,11 +260,11 @@ body[data-board-grid-interacting="resize"] .board-grid-entry[data-dnd-active="tr } .board-grid-resize-handle[data-grid-resize-handle="e"] { - right: -0.25rem; + right: calc(var(--board-grid-item-inset, 0px) - 0.25rem); } .board-grid-resize-handle[data-grid-resize-handle="w"] { - left: -0.25rem; + left: calc(var(--board-grid-item-inset, 0px) - 0.25rem); } .board-grid-resize-handle[data-grid-resize-handle="ne"], @@ -275,42 +277,30 @@ body[data-board-grid-interacting="resize"] .board-grid-entry[data-dnd-active="tr } .board-grid-resize-handle[data-grid-resize-handle="ne"] { - top: -0.625rem; - right: -0.625rem; + top: calc(var(--board-grid-item-inset, 0px) - 0.625rem); + right: calc(var(--board-grid-item-inset, 0px) - 0.625rem); cursor: nesw-resize; } .board-grid-resize-handle[data-grid-resize-handle="se"] { - right: -0.625rem; - bottom: -0.625rem; + right: calc(var(--board-grid-item-inset, 0px) - 0.625rem); + bottom: calc(var(--board-grid-item-inset, 0px) - 0.625rem); cursor: nwse-resize; } .board-grid-resize-handle[data-grid-resize-handle="sw"] { - bottom: -0.625rem; - left: -0.625rem; + bottom: calc(var(--board-grid-item-inset, 0px) - 0.625rem); + left: calc(var(--board-grid-item-inset, 0px) - 0.625rem); cursor: nesw-resize; } .board-grid-resize-handle[data-grid-resize-handle="nw"] { - top: -0.625rem; - left: -0.625rem; + top: calc(var(--board-grid-item-inset, 0px) - 0.625rem); + left: calc(var(--board-grid-item-inset, 0px) - 0.625rem); cursor: nwse-resize; /* Leaves a thin draggable border around the corner instead of a solid 44x44 hit area, so it doesn't sit on top of the container menu button anchored in this same corner. */ - clip-path: polygon( - evenodd, - 0 0, - 100% 0, - 100% 100%, - 0 100%, - 0 0, - 4px 4px, - 4px 40px, - 40px 40px, - 40px 4px, - 4px 4px - ); + clip-path: polygon(evenodd, 0 0, 100% 0, 100% 100%, 0 100%, 0 0, 4px 4px, 4px 40px, 40px 40px, 40px 4px, 4px 4px); } @media (prefers-reduced-motion: reduce) { diff --git a/apps/nextjs/src/components/board/sections/grid/section-grid.module.css b/apps/nextjs/src/components/board/sections/grid/section-grid.module.css index 250634810..12a8904d9 100644 --- a/apps/nextjs/src/components/board/sections/grid/section-grid.module.css +++ b/apps/nextjs/src/components/board/sections/grid/section-grid.module.css @@ -46,9 +46,7 @@ .contentMount { position: absolute; - inset: 0; - width: 100%; - height: 100%; + inset: var(--board-grid-item-inset, 0px); overflow: visible; } diff --git a/packages/widgets/src/beszel-system-grid/component.module.css b/packages/widgets/src/beszel-system-grid/component.module.css index 41bc5efed..b4854aa30 100644 --- a/packages/widgets/src/beszel-system-grid/component.module.css +++ b/packages/widgets/src/beszel-system-grid/component.module.css @@ -1,3 +1,7 @@ +.progress { + opacity: max(0.6, var(--opacity, 1)); +} + .clickableCard { position: relative; transition: background-color 150ms; diff --git a/packages/widgets/src/beszel-system-grid/component.tsx b/packages/widgets/src/beszel-system-grid/component.tsx index 260e33ed7..ae04f9ffb 100644 --- a/packages/widgets/src/beszel-system-grid/component.tsx +++ b/packages/widgets/src/beszel-system-grid/component.tsx @@ -159,6 +159,7 @@ const MetricValue = ({ value, progress, size }: Pick {progress && ( - + {formatPercent(value)} - + ))} @@ -111,7 +122,12 @@ export const DiskUsage = ({ system, fontSize, progressSize, valueMiw, valueGap = ) : ( - + )} diff --git a/packages/widgets/src/calendar/component.module.css b/packages/widgets/src/calendar/component.module.css index b3863ab63..f9ff6ab2d 100644 --- a/packages/widgets/src/calendar/component.module.css +++ b/packages/widgets/src/calendar/component.module.css @@ -3,3 +3,11 @@ display: flex; flex-direction: column; } + +.errorIndicator { + z-index: 1; + padding: 2px; + border: 1px solid rgb(from var(--mantine-primary-color-filled) r g b / calc(var(--opacity, 1) * 0.45)); + border-radius: var(--mantine-radius-sm); + background-color: rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.18)); +} diff --git a/packages/widgets/src/calendar/component.tsx b/packages/widgets/src/calendar/component.tsx index 8805b1932..6291f8a4a 100644 --- a/packages/widgets/src/calendar/component.tsx +++ b/packages/widgets/src/calendar/component.tsx @@ -180,14 +180,10 @@ const CalendarBase = ({ ); } + const hasErrors = failedIntegrations.length > 0 || Boolean(queryError); + return ( - - {(failedIntegrations.length > 0 || Boolean(queryError)) && ( - - - - - )} + setMonth(new Date(previousMonth))} @@ -260,7 +256,13 @@ const CalendarBase = ({ ); }} /> - + {hasErrors && ( + + + + + )} + ); }; diff --git a/packages/widgets/src/dns-hole/summary/component.tsx b/packages/widgets/src/dns-hole/summary/component.tsx index 2e2151506..b3f7e1426 100644 --- a/packages/widgets/src/dns-hole/summary/component.tsx +++ b/packages/widgets/src/dns-hole/summary/component.tsx @@ -195,6 +195,9 @@ const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => { const board = useRequiredBoard(); const label = translateIfNecessary(t, item.label); const value = item.value(data, width <= 64 ? "sm" : "md"); + const backgroundColor = usePiHoleColors + ? `rgb(from ${item.color} r g b / calc(var(--opacity, 1) * 0.4))` + : "rgb(from var(--mantine-color-primaryColor-filled) r g b / calc(var(--opacity, 1) * 0.12))"; return ( @@ -206,9 +209,11 @@ const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => { className="summary-card" p="sm" radius={board.itemRadius} - bg={usePiHoleColors ? item.color : "var(--mantine-color-default-hover)"} + bg={backgroundColor} style={{ flex: 1, + border: + "1px solid rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.45))", }} > {inlineState && } = { unknown: "gray", }; -const rowBgAlpha: Partial> = { - failed: "var(--mantine-color-red-light)", - paused: "var(--mantine-color-yellow-light)", -}; - const columnVisibilityChecks: Partial boolean>> = { upSpeed: (ctx) => ctx.hasTorrents && ctx.size.showSpeedColumns, ratio: (ctx) => ctx.hasTorrents, @@ -606,7 +601,7 @@ export default function DownloadClientsWidget({ title: t("items.state.columnTitle"), width: 90, render: (record) => ( - + {t(`states.${record.state}`)} ), @@ -784,7 +779,6 @@ export default function DownloadClientsWidget({ className="downloads-table" customRowAttributes={(_, index) => ({ "data-row-index": index })} onRowContextMenu={rowContextMenuHandler} - rowBackgroundColor={(record) => rowBgAlpha[record.state]} rowExpansion={{ trigger: "click", allowMultiple: true, @@ -900,7 +894,7 @@ function ExpandedRow({ item, collapse }: { item: ExtendedDownloadClientItem; col {item.name} - + {t(`states.${item.state}`)} diff --git a/packages/widgets/src/downloads/styles.css b/packages/widgets/src/downloads/styles.css index 0caffa099..66c8d44bc 100644 --- a/packages/widgets/src/downloads/styles.css +++ b/packages/widgets/src/downloads/styles.css @@ -1,4 +1,20 @@ -/* Row expansion styling */ -.downloads-table .mantine-datatable-row-expansion-cell { - background-color: color-mix(in srgb, var(--mantine-color-body) 40%, transparent) !important; +/* Keep the downloads table translucent so the board wallpaper and opacity remain visible. */ +.homarr-data-table.downloads-table, +.homarr-data-table.downloads-table .mantine-datatable-table, +.homarr-data-table.downloads-table .mantine-datatable-table thead, +.homarr-data-table.downloads-table .mantine-datatable-table tbody, +.homarr-data-table.downloads-table .mantine-datatable-table tfoot, +.homarr-data-table.downloads-table .mantine-datatable-table tr, +.homarr-data-table.downloads-table th, +.homarr-data-table.downloads-table td, +.homarr-data-table.downloads-table .mantine-datatable-row-expansion-cell { + background-color: transparent !important; +} + +.homarr-data-table.downloads-table .mantine-datatable-table tbody tr:hover { + background-color: transparent !important; +} + +.homarr-data-table.downloads-table th { + backdrop-filter: none; } diff --git a/packages/widgets/src/immich/server-stats/component.module.css b/packages/widgets/src/immich/server-stats/component.module.css index 6ef6260c4..e7ece8d6b 100644 --- a/packages/widgets/src/immich/server-stats/component.module.css +++ b/packages/widgets/src/immich/server-stats/component.module.css @@ -1,13 +1,22 @@ .statItem { - padding: 12px; - border-radius: var(--mantine-radius-md); - background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); + padding: 8px 10px; + border: 0.0625rem solid rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.38)); + border-radius: var(--mantine-radius-sm); + background-color: transparent; } .statItemDense { min-width: 0; - min-height: 44px; - padding: 4px 6px; + min-height: 40px; + padding: 3px 6px; + border: 0.0625rem solid rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.32)); border-radius: var(--mantine-radius-sm); - background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); + background-color: transparent; +} + +@media (forced-colors: active) { + .statItem, + .statItemDense { + border-color: CanvasText; + } } diff --git a/packages/widgets/src/immich/server-stats/component.tsx b/packages/widgets/src/immich/server-stats/component.tsx index 71443d1b2..a0f7e8720 100644 --- a/packages/widgets/src/immich/server-stats/component.tsx +++ b/packages/widgets/src/immich/server-stats/component.tsx @@ -55,42 +55,49 @@ export default function ImmichServerStatsWidget({ Number(statVisibility.showStorage); const statsLayout = getImmichStatsLayout(width, height, statCount, isAdvanced); - const statsContent = ( - - {statVisibility.showUsers && ( - } - label={t("users")} - value={stats.userCount.toLocaleString(locale)} - dense={statsLayout.dense} - /> - )} - {statVisibility.showPhotos && ( - } - label={t("photos")} - value={stats.photoCount.toLocaleString(locale)} - dense={statsLayout.dense} - /> - )} - {statVisibility.showVideos && ( - } - label={t("videos")} - value={stats.videoCount.toLocaleString(locale)} - dense={statsLayout.dense} - /> - )} - {statVisibility.showStorage && ( - } - label={t("storage")} - value={formatBytes(stats.totalLibraryUsageInBytes)} - dense={statsLayout.dense} - /> - )} - - ); + const statItems = [ + { + key: "users", + enabled: statVisibility.showUsers, + icon: , + label: t("users"), + value: stats.userCount.toLocaleString(locale), + }, + { + key: "photos", + enabled: statVisibility.showPhotos, + icon: , + label: t("photos"), + value: stats.photoCount.toLocaleString(locale), + }, + { + key: "videos", + enabled: statVisibility.showVideos, + icon: , + label: t("videos"), + value: stats.videoCount.toLocaleString(locale), + }, + { + key: "storage", + enabled: statVisibility.showStorage, + icon: , + label: t("storage"), + value: formatBytes(stats.totalLibraryUsageInBytes), + }, + ] + .filter((item) => item.enabled) + .map(({ key, icon, label, value }) => ( + + )); + + const statsContent = + isAdvanced || statsLayout.dense ? ( + + {statItems} + + ) : ( + {statItems} + ); if (!isAdvanced) { return ( diff --git a/packages/widgets/src/indexer-manager/component.module.css b/packages/widgets/src/indexer-manager/component.module.css index a2ffdd407..81c9e2d4c 100644 --- a/packages/widgets/src/indexer-manager/component.module.css +++ b/packages/widgets/src/indexer-manager/component.module.css @@ -1,9 +1,6 @@ -[data-mantine-color-scheme="light"] .card { - background-color: var(--mantine-color-gray-1); -} - -[data-mantine-color-scheme="dark"] .card { - background-color: var(--mantine-color-dark-7); +.card { + background-color: transparent; + border: 1px solid rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.38)); } .root { @@ -31,7 +28,7 @@ &:hover, &:focus-within { - background-color: var(--mantine-color-default-hover); + background-color: transparent; } } diff --git a/packages/widgets/src/media-requests/list/component.module.css b/packages/widgets/src/media-requests/list/component.module.css index ee7dfd344..05c7c6ef4 100644 --- a/packages/widgets/src/media-requests/list/component.module.css +++ b/packages/widgets/src/media-requests/list/component.module.css @@ -1,14 +1,15 @@ .card { min-width: 0; - background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7)); + background-color: transparent; + border-color: rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.38)); transition: background-color 120ms ease, border-color 120ms ease; &:hover, &:focus-within { - border-color: var(--mantine-primary-color-filled); - background-color: var(--mantine-color-default-hover); + border-color: rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.62)); + background-color: transparent; } } diff --git a/packages/widgets/src/media-requests/list/component.tsx b/packages/widgets/src/media-requests/list/component.tsx index 40315d6ba..f0526aa65 100644 --- a/packages/widgets/src/media-requests/list/component.tsx +++ b/packages/widgets/src/media-requests/list/component.tsx @@ -149,7 +149,7 @@ const MediaRequestCard = ({ )} - + { @@ -289,7 +289,7 @@ const DecisionButtons = ({ requestId, integrationId, canInteract, alwaysVisible className={`mediaRequests-list-item-pending-button-decline ${actionTargetClasses.root}`} variant="light" color="red" - size="sm" + size="xs" disabled={!canInteract || isPending} aria-label={t("pending.decline")} onClick={() => { diff --git a/packages/widgets/src/rssFeed/component.module.scss b/packages/widgets/src/rssFeed/component.module.scss index 7d68fd7de..60fe1a072 100644 --- a/packages/widgets/src/rssFeed/component.module.scss +++ b/packages/widgets/src/rssFeed/component.module.scss @@ -2,11 +2,16 @@ min-width: 0; color: inherit; text-decoration: none; - transition: background-color 120ms ease; + background-color: transparent; + border: 1px solid rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.38)); + transition: + background-color 120ms ease, + border-color 120ms ease; &:hover, &:focus-visible { - background-color: var(--mantine-color-default-hover); + background-color: transparent; + border-color: rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.62)); } &:focus-visible { @@ -24,3 +29,9 @@ transition: none; } } + +@media (forced-colors: active) { + .entry { + border-color: CanvasText; + } +} diff --git a/packages/widgets/src/rssFeed/component.tsx b/packages/widgets/src/rssFeed/component.tsx index 2d2cb92bf..e84e8f2c3 100644 --- a/packages/widgets/src/rssFeed/component.tsx +++ b/packages/widgets/src/rssFeed/component.tsx @@ -219,7 +219,7 @@ export const getRssEntryDisplay = ({ descriptionLines, }: RssEntryDisplayInput) => ({ showDescription: isAdvanced || (!hideDescription && !isTiny), - showImage: isAdvanced || (showPosterImage && !isTiny), + showImage: isAdvanced || (showPosterImage && !isDense), showSource: isAdvanced || !isDense, descriptionLineClamp: isAdvanced ? undefined : descriptionLines, }); diff --git a/packages/widgets/src/speedtest-tracker/speed-stat-card.tsx b/packages/widgets/src/speedtest-tracker/speed-stat-card.tsx index 844093417..6bd9801b4 100644 --- a/packages/widgets/src/speedtest-tracker/speed-stat-card.tsx +++ b/packages/widgets/src/speedtest-tracker/speed-stat-card.tsx @@ -1,6 +1,6 @@ "use client"; -import { Box, Flex, Text, Tooltip, VisuallyHidden } from "@mantine/core"; +import { Card, Flex, Text, Tooltip, VisuallyHidden } from "@mantine/core"; import { useElementSize } from "@mantine/hooks"; import { useRequiredBoard } from "@homarr/boards/context"; @@ -8,7 +8,7 @@ import type { TablerIcon } from "@homarr/ui"; export interface SpeedStatCardProps { icon: TablerIcon; - color: string; + color: "blue" | "teal" | "orange" | "green" | "red"; value: string; label: string; compact?: boolean; @@ -19,15 +19,22 @@ export function SpeedStatCard({ icon: Icon, color, value, label, compact = false const board = useRequiredBoard(); const isWide = width > height + 20; const hideLabel = height > 0 && height <= 38; + const surfaceColor = `var(--mantine-color-${color}-filled)`; + const accentColor = `var(--mantine-color-${color}-5)`; + const surfaceAlpha = compact ? 0.1 : 0.14; + const surfaceBackground = `rgb(from ${surfaceColor} r g b / calc(var(--opacity, 1) * ${surfaceAlpha}))`; + const surfaceBorder = "rgb(from var(--mantine-color-default-border) r g b / calc(var(--opacity, 1) * 0.45))"; return ( - - + {value} @@ -51,7 +58,7 @@ export function SpeedStatCard({ icon: Icon, color, value, label, compact = false {hideLabel && {label}} - + ); } diff --git a/packages/widgets/src/system-disks/component.tsx b/packages/widgets/src/system-disks/component.tsx index cfc59dfe1..9313cc602 100644 --- a/packages/widgets/src/system-disks/component.tsx +++ b/packages/widgets/src/system-disks/component.tsx @@ -1,7 +1,7 @@ "use client"; import { useEffect, useRef, useState } from "react"; -import { Box, Card, Group, ScrollArea, SimpleGrid, Text, Tooltip, useMantineColorScheme } from "@mantine/core"; +import { Box, Card, Group, ScrollArea, SimpleGrid, Text, Tooltip } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; import { useRequiredBoard } from "@homarr/boards/context"; @@ -85,7 +85,6 @@ const SystemDiskCard = ({ showTemperature, }: SystemDiskCardProps) => { const board = useRequiredBoard(); - const scheme = useMantineColorScheme(); const t = useI18n("widget.systemDisks"); const valueRef = useRef(null); const [valueFits, setValueFits] = useState(true); @@ -120,6 +119,8 @@ const SystemDiskCard = ({ ] .filter(Boolean) .join(" ยท "); + const backgroundColor = "rgb(from var(--mantine-color-primaryColor-filled) r g b / calc(var(--opacity, 1) * 0.12))"; + const borderColor = "rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.45))"; return (
@@ -241,7 +243,7 @@ export default function SystemResources({ const isAdvanced = displayMode === "advanced"; const minimumCardWidth = 260; - const columns = Math.max(1, Math.min(disks.length, Math.floor(width / minimumCardWidth))); + const columns = isAdvanced ? Math.max(1, Math.min(disks.length, Math.floor(width / minimumCardWidth))) : 1; const cellWidth = width / columns; return ( diff --git a/packages/widgets/src/system-resources/chart/common-chart.tsx b/packages/widgets/src/system-resources/chart/common-chart.tsx index ffc10a45f..2c96818a5 100644 --- a/packages/widgets/src/system-resources/chart/common-chart.tsx +++ b/packages/widgets/src/system-resources/chart/common-chart.tsx @@ -2,7 +2,7 @@ import type { ReactNode } from "react"; import type { AreaChartSeries } from "@mantine/charts"; import { AreaChart, LineChart } from "@mantine/charts"; -import { Card, Center, Group, Stack, Text, useComputedColorScheme, useMantineTheme } from "@mantine/core"; +import { Card, Center, Group, Stack, Text, useMantineTheme } from "@mantine/core"; import { useElementSize, useHover, useMergedRef } from "@mantine/hooks"; import type { TooltipProps, YAxisProps } from "recharts"; @@ -36,13 +36,12 @@ export const CommonChart = ({ }) => { const { ref: elementSizeRef, height } = useElementSize(); const theme = useMantineTheme(); - const colorScheme = useComputedColorScheme("light"); const board = useRequiredBoard(); const { hovered, ref: hoverRef } = useHover(); const ref = useMergedRef(elementSizeRef, hoverRef); - const opacity = board.opacity / 100; - const backgroundColor = colorScheme === "dark" ? `rgba(57, 57, 57, ${opacity})` : `rgba(246, 247, 248, ${opacity})`; + const backgroundColor = "rgb(from var(--mantine-color-primaryColor-filled) r g b / calc(var(--opacity, 1) * 0.12))"; + const borderColor = "rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.45))"; const ChartComponent = chartType === "line" ? LineChart : AreaChart; const showIcon = labelDisplayMode === "icon" || labelDisplayMode === "textWithIcon"; @@ -53,7 +52,7 @@ export const CommonChart = ({ ref={ref} h={"100%"} pos={"relative"} - style={{ overflow: "visible" }} + style={{ overflow: "visible", border: `1px solid ${borderColor}` }} p={0} bg={backgroundColor} radius={board.itemRadius} @@ -119,7 +118,13 @@ export const CommonChart = ({ withYAxis={false} withDots={false} bg={backgroundColor} - styles={{ root: { padding: 5, borderRadius: theme.radius[board.itemRadius] } }} + styles={{ + root: { + padding: 5, + borderRadius: theme.radius[board.itemRadius], + backgroundColor, + }, + }} tooltipAnimationDuration={200} tooltipProps={tooltipProps} withTooltip={height >= 64} diff --git a/packages/widgets/src/system-resources/component.tsx b/packages/widgets/src/system-resources/component.tsx index 0aed6076a..ec665d306 100644 --- a/packages/widgets/src/system-resources/component.tsx +++ b/packages/widgets/src/system-resources/component.tsx @@ -232,10 +232,10 @@ const SystemCharts = ({ const chartColumns = isAdvanced && width >= 560 ? 2 : 1; const chartHeight = isAdvanced ? 180 - : `calc((100% - ${Math.max(0, chartCount - 1) * 10}px) / ${Math.max(1, chartCount)})`; + : `calc((100% - ${Math.max(0, chartCount - 1) * 8}px) / ${Math.max(1, chartCount)})`; return ( - + {showTitle && ( {integrationName} diff --git a/packages/widgets/src/umami/component.module.css b/packages/widgets/src/umami/component.module.css new file mode 100644 index 000000000..6d5fa12b7 --- /dev/null +++ b/packages/widgets/src/umami/component.module.css @@ -0,0 +1,21 @@ +.chartSurface { + min-width: 0; + min-height: 0; + background-color: transparent !important; +} + +.chartSurface :global(.mantine-ScrollArea-viewport), +.chartSurface :global(.mantine-ScrollArea-scrollbar), +.chartSurface :global(.recharts-wrapper), +.chartSurface :global(.recharts-surface) { + background-color: transparent !important; +} + +.listSurface { + min-width: 0; + min-height: 0; + padding: 4px 6px; + border: 1px solid rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.32)); + border-radius: var(--mantine-radius-sm); + background-color: transparent; +} diff --git a/packages/widgets/src/umami/umami-content.tsx b/packages/widgets/src/umami/umami-content.tsx index 39e622742..bde67ad7b 100644 --- a/packages/widgets/src/umami/umami-content.tsx +++ b/packages/widgets/src/umami/umami-content.tsx @@ -7,6 +7,7 @@ import { clientApi } from "@homarr/api/client"; import { formatDuration } from "@homarr/common"; import type { UmamiVisitorStats } from "@homarr/integrations/types"; import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; +import classes from "./component.module.css"; import { UmamiEventsContent } from "./umami-events-content"; import { getUmamiLayout } from "./umami-layout"; @@ -161,7 +162,7 @@ export function UmamiContent({ ); const advancedLists = ( - + {viewMode !== "topPages" && ( + {selectedView} {advancedLists} @@ -190,15 +191,17 @@ export function UmamiContent({ ) : ( - + {selectedView} - {advancedLists} + + {advancedLists} + ); return ( - + {visitorStats.domain} ({formatTimeFrameLabel(timeFrame, t)}) @@ -264,7 +267,7 @@ export function UmamiContent({ )} )} - + {displayMode === "advanced" ? advancedContent : selectedView} {(statsQuery.error || activeVisitorsQuery.error || multiEventQuery.error) && ( diff --git a/packages/widgets/src/umami/umami-top-list.tsx b/packages/widgets/src/umami/umami-top-list.tsx index a9e86461b..ffb060134 100644 --- a/packages/widgets/src/umami/umami-top-list.tsx +++ b/packages/widgets/src/umami/umami-top-list.tsx @@ -5,6 +5,7 @@ import { Group, ScrollArea, Stack, Text } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; import type { UmamiMetricItem } from "@homarr/integrations/types"; import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; +import classes from "./component.module.css"; import { umamiQueryOptions } from "./umami-utils"; import { getUsableWidgetQueryData } from "../common/query-state"; @@ -52,7 +53,7 @@ function UmamiTopList({ const locale = useCurrentIntlLocale(); return ( - + {heading} diff --git a/packages/widgets/src/weather/component.module.css b/packages/widgets/src/weather/component.module.css index 2e2c76a7f..0b5645767 100644 --- a/packages/widgets/src/weather/component.module.css +++ b/packages/widgets/src/weather/component.module.css @@ -31,8 +31,8 @@ .dailyCard, .detailMetric, .solarDetails { - background: color-mix(in srgb, var(--mantine-color-body) 72%, transparent); - border: 0.0625rem solid color-mix(in srgb, var(--mantine-color-default-border) 72%, transparent); + background-color: transparent; + border: 0.0625rem solid rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.45)); } .dailyCard { @@ -43,8 +43,8 @@ .dailyCardButton:hover .dailyCard, .dailyCardButton:focus-visible .dailyCard { - background: color-mix(in srgb, var(--mantine-primary-color-light) 30%, var(--mantine-color-body)); - border-color: color-mix(in srgb, var(--mantine-primary-color-filled) 45%, var(--mantine-color-default-border)); + background-color: transparent; + border-color: rgb(from var(--mantine-color-secondaryColor-filled) r g b / calc(var(--opacity, 1) * 0.72)); } .dailyDetailsDropdown { @@ -74,7 +74,7 @@ } .solarDetails { - background: color-mix(in srgb, var(--mantine-color-yellow-light) 24%, var(--mantine-color-body)); + background-color: transparent; } .detailsButton,