Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/components/settings/hooks/useSettingsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import type {
type ThemeContextValue = {
isDarkMode: boolean;
toggleDarkMode: () => void;
useSystemFont: boolean;
setUseSystemFont: (value: boolean) => void;
};

type UseSettingsControllerArgs = {
Expand Down Expand Up @@ -138,7 +140,12 @@ const normalizeNotificationPreferences = (
};

export function useSettingsController({ isOpen, initialTab }: UseSettingsControllerArgs) {
const { isDarkMode, toggleDarkMode } = useTheme() as ThemeContextValue;
const {
isDarkMode,
toggleDarkMode,
useSystemFont,
setUseSystemFont,
} = useTheme() as ThemeContextValue;
const closeTimerRef = useRef<number | null>(null);

const [activeTab, setActiveTab] = useState<SettingsMainTab>(() => normalizeMainTab(initialTab));
Expand Down Expand Up @@ -381,6 +388,8 @@ export function useSettingsController({ isOpen, initialTab }: UseSettingsControl
setActiveTab,
isDarkMode,
toggleDarkMode,
useSystemFont,
setUseSystemFont,
saveStatus,
projectSortOrder,
setProjectSortOrder,
Expand Down
4 changes: 4 additions & 0 deletions src/components/settings/view/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: Set
activeTab,
setActiveTab,
saveStatus,
useSystemFont,
setUseSystemFont,
projectSortOrder,
setProjectSortOrder,
codeEditorSettings,
Expand Down Expand Up @@ -163,6 +165,8 @@ function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: Set
<div key={activeTab} className="settings-content-enter min-w-0 space-y-6 overflow-x-hidden p-4 pb-safe-area-inset-bottom md:space-y-8 md:p-6">
{activeTab === 'appearance' && (
<AppearanceSettingsTab
useSystemFont={useSystemFont}
onUseSystemFontChange={setUseSystemFont}
projectSortOrder={projectSortOrder}
onProjectSortOrderChange={setProjectSortOrder}
codeEditorSettings={codeEditorSettings}
Expand Down
19 changes: 19 additions & 0 deletions src/components/settings/view/tabs/AppearanceSettingsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import SettingsSection from '../SettingsSection';
import SettingsToggle from '../SettingsToggle';

type AppearanceSettingsTabProps = {
useSystemFont: boolean;
onUseSystemFontChange: (value: boolean) => void;
projectSortOrder: ProjectSortOrder;
onProjectSortOrderChange: (value: ProjectSortOrder) => void;
codeEditorSettings: CodeEditorSettingsState;
Expand All @@ -18,6 +20,8 @@ type AppearanceSettingsTabProps = {
};

export default function AppearanceSettingsTab({
useSystemFont,
onUseSystemFontChange,
projectSortOrder,
onProjectSortOrderChange,
codeEditorSettings,
Expand Down Expand Up @@ -65,6 +69,21 @@ export default function AppearanceSettingsTab({
</SettingsCard>
</SettingsSection>

<SettingsSection title={t('appearanceSettings.typography.title')}>
<SettingsCard>
<SettingsRow
label={t('appearanceSettings.typography.systemFont.label')}
description={t('appearanceSettings.typography.systemFont.description')}
>
<SettingsToggle
checked={useSystemFont}
onChange={onUseSystemFontChange}
ariaLabel={t('appearanceSettings.typography.systemFont.label')}
/>
</SettingsRow>
</SettingsCard>
</SettingsSection>

<SettingsSection title={t('appearanceSettings.codeEditor.title')}>
<SettingsCard divided>
<SettingsRow
Expand Down
11 changes: 11 additions & 0 deletions src/contexts/ThemeContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export const ThemeProvider = ({ children }) => {
return false;
});

const [useSystemFont, setUseSystemFont] = useState(
() => localStorage.getItem('useSystemFont') === 'true',
);

// Update document class and localStorage when theme changes
useEffect(() => {
if (isDarkMode) {
Expand Down Expand Up @@ -60,6 +64,11 @@ export const ThemeProvider = ({ children }) => {
}
}, [isDarkMode]);

useEffect(() => {
document.documentElement.classList.toggle('system-font', useSystemFont);
localStorage.setItem('useSystemFont', String(useSystemFont));
}, [useSystemFont]);

Comment on lines +69 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check for inline theme initialization scripts in HTML files.

rg "localStorage\.getItem" -g "*.html" -C 2

Repository: siteboon/claudecodeui

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- files ---'
git ls-files | rg '(^|/)(index\.html|ThemeContext\.jsx|ThemeContext\.[jt]sx|main\.[jt]sx|App\.[jt]sx)$'

echo
echo '--- search for theme bootstrap/localStorage in html/jsx ---'
rg -n "localStorage\.getItem|system-font|ThemeContext|document\.documentElement\.classList\.toggle|classList\.add|classList\.remove" src . -g '*.html' -g '*.js' -g '*.jsx' -g '*.ts' -g '*.tsx'

echo
echo '--- candidate html files ---'
fd -a -t f 'index.html|*.html' .

Repository: siteboon/claudecodeui

Length of output: 18963


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the theme context around the relevant effect.
FILE='src/contexts/ThemeContext.jsx'
wc -l "$FILE"
sed -n '1,140p' "$FILE"

# If there is an index.html, inspect it for inline scripts.
if git ls-files | rg -q '(^|/)index\.html$'; then
  HTML=$(git ls-files | rg '(^|/)index\.html$' | head -n 1)
  echo
  echo "--- $HTML ---"
  cat -n "$HTML"
fi

Repository: siteboon/claudecodeui

Length of output: 4049


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- tracked html and theme files ---'
git ls-files | rg '(^|/)(index\.html|.*ThemeContext\.jsx|main\.[jt]sx|App\.[jt]sx)$' || true

echo
echo '--- ThemeContext.jsx ---'
sed -n '1,120p' src/contexts/ThemeContext.jsx

echo
echo '--- html files containing theme/bootstrap terms ---'
rg -n "localStorage\.getItem|system-font|theme" --glob '*.html' . || true

Repository: siteboon/claudecodeui

Length of output: 3946


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- root index.html ---'
cat -n index.html | sed -n '1,220p'

echo
echo '--- any inline scripts in HTML files ---'
rg -n "<script|localStorage|getItem|matchMedia|theme|system-font" index.html electron/launcher/index.html public/api-docs.html -C 3

Repository: siteboon/claudecodeui

Length of output: 6308


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
for p in [Path('index.html'), Path('electron/launcher/index.html')]:
    if p.exists():
        text = p.read_text()
        print(f'--- {p} script tags ---')
        for i, line in enumerate(text.splitlines(), 1):
            if '<script' in line or 'theme' in line.lower() or 'system-font' in line.lower():
                print(f'{i}: {line}')
PY

Repository: siteboon/claudecodeui

Length of output: 441


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- root index.html ---'
cat -n index.html | sed -n '1,220p'

echo
echo '--- root and launcher HTML theme-related lines ---'
rg -n "<script|localStorage|getItem|matchMedia|theme|system-font" index.html electron/launcher/index.html -C 3

Repository: siteboon/claudecodeui

Length of output: 3930


Apply system-font before first paint.
useEffect runs after hydration, so users who prefer the system font can see a brief font flash on load. Initialize this class in the bootstrap/initial render path instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/contexts/ThemeContext.jsx` around lines 67 - 71, Move the `system-font`
class initialization from the `useEffect` in `ThemeContext` to the bootstrap or
initial render path so it is applied before first paint, while preserving the
existing `useSystemFont` preference and localStorage behavior. Keep the effect
only for subsequent preference changes if needed.

// Listen for system theme changes
useEffect(() => {
if (!window.matchMedia) return;
Expand All @@ -84,6 +93,8 @@ export const ThemeProvider = ({ children }) => {
const value = {
isDarkMode,
toggleDarkMode,
useSystemFont,
setUseSystemFont,
};

return (
Expand Down
7 changes: 7 additions & 0 deletions src/i18n/locales/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@
"alphabetical": "Alphabetical",
"recentActivity": "Recent Activity"
},
"typography": {
"title": "Typography",
"systemFont": {
"label": "Use system font",
"description": "Use your device's default font throughout the interface"
}
},
"codeEditor": {
"title": "Code Editor",
"theme": {
Expand Down
9 changes: 8 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
--input: 44 14% 87%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
--font-sans: "Encode Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-serif: "Merriweather", Georgia, Cambria, "Times New Roman", serif;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

/* Nav design tokens */
--nav-glass-bg: 44 22% 96% / 0.7;
Expand Down Expand Up @@ -73,6 +75,11 @@
--header-base-padding: 8px;
--header-total-padding: calc(var(--header-safe-area-top) + var(--header-base-padding));
}

:root.system-font {
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* Fallback for older iOS versions */
@supports (padding-top: constant(safe-area-inset-top)) {
Expand Down Expand Up @@ -129,7 +136,7 @@
body {
@apply bg-background text-foreground;

font-family: "Encode Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-family: var(--font-sans);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin: 0;
Expand Down
6 changes: 3 additions & 3 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export default {
},
extend: {
fontFamily: {
sans: ['"Encode Sans"', '-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', '"Helvetica Neue"', 'Arial', 'sans-serif'],
serif: ['Merriweather', 'Georgia', 'Cambria', '"Times New Roman"', 'serif'],
sans: ['var(--font-sans)'],
serif: ['var(--font-serif)'],
},
colors: {
border: "hsl(var(--border))",
Expand Down Expand Up @@ -84,4 +84,4 @@ export default {
},
},
plugins: [require('@tailwindcss/typography')],
}
}