Chore/remove usage of mantine color scheme (#6108)

Remove instances of `colorScheme === "dark" ?` in the app and rely on
the theme.css' light and dark variables instead.
This commit is contained in:
EthanHealy01
2026-04-17 14:29:37 +01:00
committed by GitHub
parent a7a5bb2057
commit bad92a9eae
18 changed files with 218 additions and 176 deletions

View File

@@ -1,4 +1,6 @@
dist/
# Tauri/Cargo build output (binary assets named *.js etc. confuse Prettier)
src-tauri/target/
node_modules/
public/vendor/
public/pdfjs*/

View File

@@ -1,10 +1,10 @@
import React, { useRef, useState } from "react";
import { Button, Group, useMantineColorScheme } from "@mantine/core";
import { Button, Group } from "@mantine/core";
import { useTranslation } from "react-i18next";
import AddIcon from "@mui/icons-material/Add";
import { useFilesModalContext } from "@app/contexts/FilesModalContext";
import LocalIcon from "@app/components/shared/LocalIcon";
import { useLogoAssets } from "@app/hooks/useLogoAssets";
import { Wordmark } from "@app/components/shared/Wordmark";
import styles from "@app/components/fileEditor/FileEditor.module.css";
import { useFileActionTerminology } from "@app/hooks/useFileActionTerminology";
import { useFileActionIcons } from "@app/hooks/useFileActionIcons";
@@ -24,9 +24,7 @@ const AddFileCard = ({
const { t } = useTranslation();
const fileInputRef = useRef<HTMLInputElement>(null);
const { openFilesModal } = useFilesModalContext();
const { colorScheme } = useMantineColorScheme();
const [isUploadHover, setIsUploadHover] = useState(false);
const { wordmark } = useLogoAssets();
const terminology = useFileActionTerminology();
const icons = useFileActionIcons();
@@ -98,9 +96,9 @@ const AddFileCard = ({
<div className={styles.addFileContent}>
{/* Stirling PDF Branding */}
<Group gap="xs" align="center">
<img
src={colorScheme === "dark" ? wordmark.white : wordmark.grey}
<Wordmark
alt="Stirling PDF"
muted
style={{ height: "2.2rem", width: "auto" }}
/>
</Group>

View File

@@ -1,25 +1,17 @@
import React, { useState } from "react";
import {
Button,
Group,
Text,
Stack,
useMantineColorScheme,
} from "@mantine/core";
import { Button, Group, Text, Stack } from "@mantine/core";
import HistoryIcon from "@mui/icons-material/History";
import { useTranslation } from "react-i18next";
import { useFileManagerContext } from "@app/contexts/FileManagerContext";
import LocalIcon from "@app/components/shared/LocalIcon";
import { useLogoAssets } from "@app/hooks/useLogoAssets";
import { Wordmark } from "@app/components/shared/Wordmark";
import { useFileActionTerminology } from "@app/hooks/useFileActionTerminology";
import { useFileActionIcons } from "@app/hooks/useFileActionIcons";
const EmptyFilesState: React.FC = () => {
const { t } = useTranslation();
const { colorScheme } = useMantineColorScheme();
const { onLocalFileClick } = useFileManagerContext();
const [isUploadHover, setIsUploadHover] = useState(false);
const { wordmark } = useLogoAssets();
const terminology = useFileActionTerminology();
const icons = useFileActionIcons();
@@ -65,9 +57,9 @@ const EmptyFilesState: React.FC = () => {
{/* Stirling PDF Logo */}
<Group gap="xs" align="center">
<img
src={colorScheme === "dark" ? wordmark.white : wordmark.grey}
<Wordmark
alt="Stirling PDF"
muted
style={{ height: "2.2rem", width: "auto" }}
/>
</Group>

View File

@@ -0,0 +1,14 @@
import React from "react";
import { useMantineColorScheme } from "@mantine/core";
import { useLogoPath } from "@app/hooks/useLogoPath";
interface LogoIconProps extends React.ImgHTMLAttributes<HTMLImageElement> {
alt?: string;
}
export function LogoIcon({ alt = "", ...props }: LogoIconProps) {
const { colorScheme } = useMantineColorScheme();
const logoPaths = useLogoPath();
const src = colorScheme === "dark" ? logoPaths.dark : logoPaths.light;
return <img src={src} alt={alt} {...props} />;
}

View File

@@ -1,5 +1,4 @@
import React, { forwardRef } from "react";
import { useMantineColorScheme } from "@mantine/core";
import LocalIcon from "@app/components/shared/LocalIcon";
import styles from "@app/components/shared/textInput/TextInput.module.css";
@@ -61,8 +60,6 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
},
ref,
) => {
const { colorScheme } = useMantineColorScheme();
const handleClear = () => {
if (onClear) {
onClear();
@@ -79,7 +76,7 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
{icon && (
<span
className={styles.icon}
style={{ color: colorScheme === "dark" ? "#FFFFFF" : "#6B7382" }}
style={{ color: "var(--search-text-and-icon-color)" }}
>
{icon}
</span>
@@ -99,8 +96,8 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
aria-label={ariaLabel}
onFocus={onFocus}
style={{
backgroundColor: colorScheme === "dark" ? "#4B525A" : "#FFFFFF",
color: colorScheme === "dark" ? "#FFFFFF" : "#6B7382",
backgroundColor: "var(--input-bg)",
color: "var(--search-text-and-icon-color)",
paddingRight: shouldShowClearButton ? "40px" : "12px",
paddingLeft: icon ? "40px" : "12px",
}}
@@ -111,7 +108,7 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
type="button"
className={styles.clearButton}
onClick={handleClear}
style={{ color: colorScheme === "dark" ? "#FFFFFF" : "#6B7382" }}
style={{ color: "var(--search-text-and-icon-color)" }}
aria-label="Clear input"
>
<LocalIcon icon="close-rounded" width="1.25rem" height="1.25rem" />

View File

@@ -0,0 +1,20 @@
import React from "react";
import { useMantineColorScheme } from "@mantine/core";
import { useLogoAssets } from "@app/hooks/useLogoAssets";
interface WordmarkProps extends React.ImgHTMLAttributes<HTMLImageElement> {
alt?: string;
muted?: boolean;
}
export function Wordmark({ alt = "", muted = false, ...props }: WordmarkProps) {
const { colorScheme } = useMantineColorScheme();
const isDark = colorScheme === "dark";
const { wordmark } = useLogoAssets();
// light: black text (standard) or grey text (muted)
// dark: white text for both variants
const src = isDark ? wordmark.white : muted ? wordmark.grey : wordmark.black;
return <img src={src} alt={alt} {...props} />;
}

View File

@@ -1,10 +1,5 @@
import { useState, useRef } from "react";
import {
ActionIcon,
ScrollArea,
Switch,
useMantineColorScheme,
} from "@mantine/core";
import { ActionIcon, ScrollArea, Switch } from "@mantine/core";
import DoubleArrowIcon from "@mui/icons-material/DoubleArrow";
import { useTranslation } from "react-i18next";
import ToolSearch from "@app/components/tools/toolPicker/ToolSearch";
@@ -12,8 +7,8 @@ import FullscreenToolList from "@app/components/tools/FullscreenToolList";
import { ToolRegistryEntry } from "@app/data/toolsTaxonomy";
import { ToolId } from "@app/types/toolId";
import { useFocusTrap } from "@app/hooks/useFocusTrap";
import { useLogoPath } from "@app/hooks/useLogoPath";
import { useLogoAssets } from "@app/hooks/useLogoAssets";
import { LogoIcon } from "@app/components/shared/LogoIcon";
import { Wordmark } from "@app/components/shared/Wordmark";
import { Tooltip } from "@app/components/shared/Tooltip";
import "@app/components/tools/ToolPanel.css";
import { ToolPanelGeometry } from "@app/hooks/tools/useToolPanelGeometry";
@@ -52,7 +47,6 @@ const FullscreenToolSurface = ({
geometry,
}: FullscreenToolSurfaceProps) => {
const { t } = useTranslation();
const { colorScheme } = useMantineColorScheme();
const [isExiting, setIsExiting] = useState(false);
const surfaceRef = useRef<HTMLDivElement>(null);
const isRTL =
@@ -62,9 +56,6 @@ const FullscreenToolSurface = ({
useFocusTrap(surfaceRef, !isExiting);
const brandAltText = t("home.mobile.brandAlt", "Stirling PDF logo");
const brandIconSrc = useLogoPath();
const { wordmark } = useLogoAssets();
const brandTextSrc = colorScheme === "dark" ? wordmark.white : wordmark.black;
const handleExit = () => {
const prefersReducedMotion = window.matchMedia(
@@ -118,13 +109,8 @@ const FullscreenToolSurface = ({
>
<header className="tool-panel__fullscreen-header">
<div className="tool-panel__fullscreen-brand">
<img
src={brandIconSrc}
alt=""
className="tool-panel__fullscreen-brand-icon"
/>
<img
src={brandTextSrc}
<LogoIcon className="tool-panel__fullscreen-brand-icon" />
<Wordmark
alt={brandAltText}
className="tool-panel__fullscreen-brand-text"
/>

View File

@@ -6,7 +6,6 @@ import {
Divider,
UnstyledButton,
useMantineTheme,
useMantineColorScheme,
} from "@mantine/core";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import { useTranslation } from "react-i18next";
@@ -64,7 +63,6 @@ const ConvertSettings = ({
}: ConvertSettingsProps) => {
const { t } = useTranslation();
const theme = useMantineTheme();
const { colorScheme } = useMantineColorScheme();
const { setSelectedFiles } = useFileSelection();
const { state, selectors } = useFileState();
const activeFiles = state.files.ids;
@@ -339,14 +337,8 @@ const ConvertSettings = ({
padding: "0.5rem 0.75rem",
border: `0.0625rem solid ${theme.colors.gray[4]}`,
borderRadius: theme.radius.sm,
backgroundColor:
colorScheme === "dark"
? theme.colors.dark[5]
: theme.colors.gray[1],
color:
colorScheme === "dark"
? theme.colors.dark[2]
: theme.colors.gray[6],
backgroundColor: "var(--select-placeholder-bg)",
color: "var(--select-placeholder-text)",
cursor: "not-allowed",
}}
>
@@ -360,10 +352,7 @@ const ConvertSettings = ({
<KeyboardArrowDownIcon
style={{
fontSize: "1rem",
color:
colorScheme === "dark"
? theme.colors.dark[2]
: theme.colors.gray[6],
color: "var(--select-placeholder-text)",
}}
/>
</Group>

View File

@@ -8,7 +8,6 @@ import {
Popover,
UnstyledButton,
useMantineTheme,
useMantineColorScheme,
} from "@mantine/core";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import CloudOutlinedIcon from "@mui/icons-material/CloudOutlined";
@@ -47,7 +46,6 @@ const GroupedFormatDropdown = ({
}: GroupedFormatDropdownProps) => {
const [dropdownOpened, setDropdownOpened] = useState(false);
const theme = useMantineTheme();
const { colorScheme } = useMantineColorScheme();
const groupedOptions = useMemo(() => {
const groups: Record<string, FormatOption[]> = {};
@@ -100,18 +98,12 @@ const GroupedFormatDropdown = ({
borderRadius: theme.radius.sm,
backgroundColor: disabled
? theme.colors.gray[1]
: colorScheme === "dark"
? theme.colors.dark[6]
: theme.white,
: "var(--dropdown-trigger-bg)",
cursor: disabled ? "not-allowed" : "pointer",
width: "100%",
color: disabled
? colorScheme === "dark"
? theme.colors.dark[1]
: theme.colors.dark[7]
: colorScheme === "dark"
? theme.colors.dark[0]
: theme.colors.dark[9],
? "var(--dropdown-trigger-text-disabled)"
: "var(--dropdown-trigger-text)",
}}
>
<Group justify="space-between">
@@ -123,10 +115,7 @@ const GroupedFormatDropdown = ({
fontSize: "1rem",
transform: dropdownOpened ? "rotate(180deg)" : "rotate(0deg)",
transition: "transform 0.2s ease",
color:
colorScheme === "dark"
? theme.colors.dark[2]
: theme.colors.gray[6],
color: "var(--dropdown-trigger-icon)",
}}
/>
</Group>
@@ -138,9 +127,8 @@ const GroupedFormatDropdown = ({
maxWidth: "90vw",
maxHeight: "40vh",
overflow: "auto",
backgroundColor:
colorScheme === "dark" ? theme.colors.dark[7] : theme.white,
border: `0.0625rem solid ${colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[4]}`,
backgroundColor: "var(--dropdown-panel-bg)",
border: `0.0625rem solid var(--dropdown-panel-border)`,
}}
>
<Stack gap="md">
@@ -149,8 +137,8 @@ const GroupedFormatDropdown = ({
<Text
size="sm"
fw={600}
c={colorScheme === "dark" ? "dark.2" : "gray.6"}
mb="xs"
style={{ color: "var(--dropdown-group-label)" }}
>
{groupName}
</Text>

View File

@@ -15,16 +15,16 @@ export function useLogoAssets() {
folder,
folderPath,
getAssetPath: (name: string) => `${folderPath}/${name}`,
wordmark: {
black: `${folderPath}/StirlingPDFLogoBlackText.svg`,
grey: `${folderPath}/StirlingPDFLogoGreyText.svg`,
white: `${folderPath}/StirlingPDFLogoWhiteText.svg`,
},
tooltipLogo: `${folderPath}/logo-tooltip.svg`,
firstPage: `${folderPath}/Firstpage.png`,
favicon: `${folderPath}/favicon.ico`,
logo192: `${folderPath}/logo192.png`,
logo512: `${folderPath}/logo512.png`,
wordmark: {
white: `${folderPath}/StirlingPDFLogoWhiteText.svg`,
black: `${folderPath}/StirlingPDFLogoBlackText.svg`,
grey: `${folderPath}/StirlingPDFLogoGreyText.svg`,
},
manifestHref:
logoVariant === "classic"
? `${BASE_PATH}/manifest-classic.json`

View File

@@ -1,22 +1,15 @@
import { useMemo } from "react";
import { useMantineColorScheme } from "@mantine/core";
import { useLogoAssets } from "@app/hooks/useLogoAssets";
/**
* Hook to get the correct logo path based on app config (logo style) and theme (light/dark)
*
* Logo styles:
* - classic: classic S logo stored in /classic-logo
* - modern: minimalist logo stored in /modern-logo
*
* @returns The path to the appropriate logo SVG file
*/
export function useLogoPath(): string {
const { colorScheme } = useMantineColorScheme();
/** Theme-specific no-text logo SVG URLs under the active variant folder (`modern-logo` / `classic-logo`). */
export function useLogoPath(): { dark: string; light: string } {
const { folderPath } = useLogoAssets();
return useMemo(() => {
const themeSuffix = colorScheme === "dark" ? "Dark" : "Light";
return `${folderPath}/StirlingPDFLogoNoText${themeSuffix}.svg`;
}, [colorScheme, folderPath]);
return useMemo(
() => ({
dark: `${folderPath}/StirlingPDFLogoNoTextDark.svg`,
light: `${folderPath}/StirlingPDFLogoNoTextLight.svg`,
}),
[folderPath],
);
}

View File

@@ -1,14 +1,14 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useToolWorkflow } from "@app/contexts/ToolWorkflowContext";
import { Group, useMantineColorScheme } from "@mantine/core";
import { Group } from "@mantine/core";
import { useSidebarContext } from "@app/contexts/SidebarContext";
import { useDocumentMeta } from "@app/hooks/useDocumentMeta";
import { useBaseUrl } from "@app/hooks/useBaseUrl";
import { useIsMobile } from "@app/hooks/useIsMobile";
import { useAppConfig } from "@app/contexts/AppConfigContext";
import { useLogoPath } from "@app/hooks/useLogoPath";
import { useLogoAssets } from "@app/hooks/useLogoAssets";
import { LogoIcon } from "@app/components/shared/LogoIcon";
import { Wordmark } from "@app/components/shared/Wordmark";
import { useFileContext } from "@app/contexts/file/fileHooks";
import {
useNavigationState,
@@ -50,7 +50,6 @@ export default function HomePage() {
} = useToolWorkflow();
const { openFilesModal } = useFilesModalContext();
const { colorScheme } = useMantineColorScheme();
const { config } = useAppConfig();
const isMobile = useIsMobile();
const sliderRef = useRef<HTMLDivElement | null>(null);
@@ -112,9 +111,6 @@ export default function HomePage() {
)?.hideToolPanel ?? false;
const brandAltText = t("home.mobile.brandAlt", "Stirling PDF logo");
const brandIconSrc = useLogoPath();
const { wordmark } = useLogoAssets();
const brandTextSrc = colorScheme === "dark" ? wordmark.white : wordmark.black;
const handleSelectMobileView = useCallback((view: MobileView) => {
setActiveMobileView(view);
@@ -241,17 +237,8 @@ export default function HomePage() {
<div className="mobile-toggle">
<div className="mobile-header">
<div className="mobile-brand">
<img
src={brandIconSrc}
alt=""
aria-hidden="true"
className="mobile-brand-icon"
/>
<img
src={brandTextSrc}
alt={brandAltText}
className="mobile-brand-text"
/>
<LogoIcon className="mobile-brand-icon" />
<Wordmark alt={brandAltText} className="mobile-brand-text" />
</div>
</div>
<div

View File

@@ -10,11 +10,10 @@ import {
Progress,
Switch,
Card,
useMantineColorScheme,
} from "@mantine/core";
import { useTranslation } from "react-i18next";
import { useLogoPath } from "@app/hooks/useLogoPath";
import { useLogoAssets } from "@app/hooks/useLogoAssets";
import { LogoIcon } from "@app/components/shared/LogoIcon";
import { Wordmark } from "@app/components/shared/Wordmark";
import ErrorRoundedIcon from "@mui/icons-material/ErrorRounded";
import InfoRoundedIcon from "@mui/icons-material/InfoRounded";
import PhotoCameraRoundedIcon from "@mui/icons-material/PhotoCameraRounded";
@@ -41,10 +40,6 @@ export default function MobileScannerPage() {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const sessionId = searchParams.get("session");
const { colorScheme } = useMantineColorScheme();
const brandIconSrc = useLogoPath();
const { wordmark } = useLogoAssets();
const brandTextSrc = colorScheme === "dark" ? wordmark.white : wordmark.black;
const [mode, setMode] = useState<"choice" | "camera" | "file" | null>(
"choice",
@@ -1024,16 +1019,11 @@ export default function MobileScannerPage() {
}}
>
<Group gap="sm" align="center">
<img
src={brandIconSrc}
<LogoIcon
alt={t("home.mobile.brandAlt", "Stirling PDF logo")}
style={{ height: "32px", width: "32px" }}
/>
<img
src={brandTextSrc}
alt="Stirling PDF"
style={{ height: "24px" }}
/>
<Wordmark alt="Stirling PDF" style={{ height: "24px" }} />
</Group>
</Box>

View File

@@ -391,6 +391,25 @@
/* Compare page label chip (light mode): slightly lighter than surrounding rows */
--compare-page-label-bg: var(--bg-muted);
--compare-page-label-fg: var(--text-secondary);
/* Status indicator dot ring shadow */
--status-dot-ring: 0 0 0 2px rgba(0, 0, 0, 0.08);
/* Input element styling */
--input-bg: #ffffff;
/* Select/dropdown placeholder state */
--select-placeholder-bg: var(--mantine-color-gray-1);
--select-placeholder-text: var(--mantine-color-gray-6);
/* Grouped format dropdown */
--dropdown-trigger-bg: var(--mantine-color-white);
--dropdown-trigger-text: var(--mantine-color-dark-9);
--dropdown-trigger-text-disabled: var(--mantine-color-dark-7);
--dropdown-trigger-icon: var(--mantine-color-gray-6);
--dropdown-panel-bg: var(--mantine-color-white);
--dropdown-panel-border: var(--mantine-color-gray-4);
--dropdown-group-label: var(--mantine-color-gray-6);
}
/* Onboarding (light mode) */
@@ -681,6 +700,25 @@
/* Compare page label chip (dark mode): slightly darker than surrounding rows */
--compare-page-label-bg: #1f2329;
--compare-page-label-fg: var(--text-secondary);
/* Status indicator dot ring shadow (dark) */
--status-dot-ring: 0 0 0 2px rgba(255, 255, 255, 0.18);
/* Input element styling (dark) */
--input-bg: #4b525a;
/* Select/dropdown placeholder state (dark) */
--select-placeholder-bg: var(--mantine-color-dark-5);
--select-placeholder-text: var(--mantine-color-dark-2);
/* Grouped format dropdown (dark) */
--dropdown-trigger-bg: var(--mantine-color-dark-6);
--dropdown-trigger-text: var(--mantine-color-dark-0);
--dropdown-trigger-text-disabled: var(--mantine-color-dark-1);
--dropdown-trigger-icon: var(--mantine-color-dark-2);
--dropdown-panel-bg: var(--mantine-color-dark-7);
--dropdown-panel-border: var(--mantine-color-dark-4);
--dropdown-group-label: var(--mantine-color-dark-2);
}
/* Dropzone drop state styling */
@@ -969,3 +1007,87 @@
[data-theme="dark"] {
--shadow-color: rgba(0, 0, 0, 0.75);
}
/* Theme-aware image display utilities */
/* Use .theme-img-light-only for images to show in light mode only */
/* Use .theme-img-dark-only for images to show in dark mode only */
.theme-img-light-only {
display: inline;
}
.theme-img-dark-only {
display: none;
}
[data-mantine-color-scheme="dark"] .theme-img-light-only {
display: none;
}
[data-mantine-color-scheme="dark"] .theme-img-dark-only {
display: inline;
}
/* Modern logo icon */
.logo-icon-modern__path1 {
fill: #acacac;
fill-opacity: 0.3;
}
.logo-icon-modern__path2 {
fill: #fc9999;
fill-opacity: 0.5;
}
[data-mantine-color-scheme="dark"] .logo-icon-modern__path1 {
fill: #e6e6e6;
fill-opacity: 0.4;
}
[data-mantine-color-scheme="dark"] .logo-icon-modern__path2 {
fill: #e6e6e6;
fill-opacity: 0.7;
}
/* Classic logo icon — single path structure, colors change per theme */
.logo-icon-classic__group {
opacity: 0.2;
}
.logo-icon-classic__body {
fill: #ff4b4b;
}
.logo-icon-classic__flap {
fill: #545454;
}
.logo-icon-classic__triangle {
fill: #d0dbdc;
}
.logo-icon-classic__s {
fill: white;
}
[data-mantine-color-scheme="dark"] .logo-icon-classic__group {
opacity: 1;
}
[data-mantine-color-scheme="dark"] .logo-icon-classic__body {
fill: white;
}
[data-mantine-color-scheme="dark"] .logo-icon-classic__flap {
fill: #d3d3d3;
}
[data-mantine-color-scheme="dark"] .logo-icon-classic__triangle {
fill: #d0dbdc;
}
[data-mantine-color-scheme="dark"] .logo-icon-classic__s {
fill: var(--mantine-color-body);
}
/* Wordmark muted variant (used in empty/placeholder states) */
/* Stirling text: 30% opacity in light mode, full opacity in dark */
.wordmark__text--muted {
fill-opacity: 0.3;
}
[data-mantine-color-scheme="dark"] .wordmark__text--muted {
fill-opacity: 1;
}
/* PDF text: dimmed red in light mode, standard red in dark */
.wordmark__pdf--muted {
fill: #d62626;
fill-opacity: 0.7;
}
[data-mantine-color-scheme="dark"] .wordmark__pdf--muted {
fill: #c56565;
fill-opacity: 1;
}

View File

@@ -1,12 +1,6 @@
import React, { useMemo, useCallback } from "react";
import { useTranslation } from "react-i18next";
import {
Box,
Tooltip,
useMantineTheme,
useComputedColorScheme,
rem,
} from "@mantine/core";
import { Box, Tooltip, useMantineTheme, rem } from "@mantine/core";
import { useBackendHealth } from "@app/hooks/useBackendHealth";
interface BackendHealthIndicatorProps {
@@ -18,7 +12,6 @@ export const BackendHealthIndicator: React.FC<BackendHealthIndicatorProps> = ({
}) => {
const { t } = useTranslation();
const theme = useMantineTheme();
const colorScheme = useComputedColorScheme("light");
const { status, isOnline, checkHealth } = useBackendHealth();
const label = useMemo(() => {
@@ -60,14 +53,7 @@ export const BackendHealthIndicator: React.FC<BackendHealthIndicatorProps> = ({
);
return (
<Tooltip
label={label}
position="left"
offset={12}
withArrow
withinPortal
color={colorScheme === "dark" ? undefined : "dark"}
>
<Tooltip label={label} position="left" offset={12} withArrow withinPortal>
<Box
component="span"
className={className ? `${className}` : undefined}
@@ -82,10 +68,7 @@ export const BackendHealthIndicator: React.FC<BackendHealthIndicatorProps> = ({
height: rem(12),
borderRadius: "50%",
backgroundColor: dotColor,
boxShadow:
colorScheme === "dark"
? "0 0 0 2px rgba(255, 255, 255, 0.18)"
: "0 0 0 2px rgba(0, 0, 0, 0.08)",
boxShadow: "var(--status-dot-ring)",
cursor: "pointer",
display: "inline-block",
outline: "none",

View File

@@ -1,5 +1,5 @@
import { useState, useEffect, useMemo } from "react";
import { Box, Tooltip, rem, useComputedColorScheme } from "@mantine/core";
import { Box, Tooltip, rem } from "@mantine/core";
import { useTranslation } from "react-i18next";
import {
connectionModeService,
@@ -18,7 +18,6 @@ interface RightRailFooterExtensionsProps {
function ConnectionStatusDot() {
const { t } = useTranslation();
const colorScheme = useComputedColorScheme("light");
const [connectionMode, setConnectionMode] = useState<ConnectionMode | null>(
null,
);
@@ -84,14 +83,7 @@ function ConnectionStatusDot() {
}, [connectionMode, selfHostedState, isOnline, t]);
return (
<Tooltip
label={label}
position="left"
offset={12}
withArrow
withinPortal
color={colorScheme === "dark" ? undefined : "dark"}
>
<Tooltip label={label} position="left" offset={12} withArrow withinPortal>
<Box
component="span"
role="status"
@@ -109,10 +101,7 @@ function ConnectionStatusDot() {
height: rem(10),
borderRadius: "50%",
backgroundColor: color,
boxShadow:
colorScheme === "dark"
? "0 0 0 2px rgba(255, 255, 255, 0.15)"
: "0 0 0 2px rgba(0, 0, 0, 0.07)",
boxShadow: "var(--status-dot-ring)",
display: "inline-block",
cursor: "pointer",
outline: "none",

View File

@@ -2,13 +2,12 @@ import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "@app/auth/UseSession";
import { useTranslation } from "react-i18next";
import { useLogoPath } from "@app/hooks/useLogoPath";
import { LogoIcon } from "@app/components/shared/LogoIcon";
export default function LoggedInState() {
const navigate = useNavigate();
const { user } = useAuth();
const { t } = useTranslation();
const logoPath = useLogoPath();
useEffect(() => {
const timer = setTimeout(() => {
@@ -47,8 +46,7 @@ export default function LoggedInState() {
justifyContent: "center",
}}
>
<img
src={logoPath}
<LogoIcon
alt="Stirling PDF Logo"
style={{ width: "64px", height: "64px", objectFit: "contain" }}
/>

View File

@@ -1,4 +1,4 @@
import { useLogoAssets } from "@app/hooks/useLogoAssets";
import { Wordmark } from "@app/components/shared/Wordmark";
interface LoginHeaderProps {
title: string;
@@ -11,18 +11,12 @@ export default function LoginHeader({
subtitle,
centerOnly = false,
}: LoginHeaderProps) {
const { wordmark } = useLogoAssets();
return (
<div
className={`login-header${centerOnly ? " login-header-centered" : ""}`}
>
<div className="login-header-logos">
<img
src={wordmark.black}
alt="Stirling PDF"
className="login-logo-text"
/>
<Wordmark alt="Stirling PDF" className="login-logo-text" />
</div>
{title && <h1 className="login-title">{title}</h1>}
{subtitle && <p className="login-subtitle">{subtitle}</p>}