Настройки внешнего вида
Сделай экран настроек внешнего вида: сегментированный переключатель темы на три варианта, ползунок масштаба интерфейса от 80 до 140 процентов с показом текущего значения, переключатель плотной вёрстки и раздел «Ещё» под разделителем с выбором шрифта. Справа от заголовка экрана метка с текущей темой. Состояние храни в компоненте и отдавай наружу через колбэк onChange.
appearance-settings__docs-rules__claude-code__claude-opus-5__1 · 23.09.2026, 21:58:24 мск
Первый вызов модели получил 49 104 токена входа, включая системный промпт Claude Code. Контекст до задачи — оценка по длине текста, для русского текста она занижает число токенов в полтора-два раза.
Компилятор
Ошибок нет: все компоненты и пропсы существуют.
Линтер и покрытие
- inline-styleСтроки 57, 71, 80, 94, 95Инлайновые стили вместо классов и токенов библиотеки
JxBadge, JxDivider, JxSelect, JxSlider, JxSwitch, JxToggle
Ожидались JxToggle, JxSlider, JxSwitch, JxDivider, JxBadge · покрытие 100%
Доки (llms-full.txt, ~22548) · Правила (jinx-ui, ~1083)
Вход 2 · выход 1 368 · из кэша 8 233 · в кэш 40 869 · 14 с
Рендер
Код компонента
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
import { useState } from 'react';
import {
JxBadge,
JxDivider,
JxSelect,
JxSlider,
JxSwitch,
JxToggle,
} from '@jinx-ui/react';
export interface AppearanceSettings {
theme: string;
scale: number;
compact: boolean;
fontFamily: string;
}
const THEMES = [
{ value: 'light', label: 'Светлая' },
{ value: 'dark', label: 'Тёмная' },
{ value: 'system', label: 'Системная' },
];
const FONTS = [
{ value: 'sans', label: 'Inter Tight', meta: 'по умолчанию' },
{ value: 'display', label: 'Fraunces' },
{ value: 'mono', label: 'JetBrains Mono' },
];
export default function AppearanceSettingsScreen({
defaultValue,
onChange,
}: {
defaultValue?: Partial<AppearanceSettings>;
onChange?: (settings: AppearanceSettings) => void;
}) {
const [settings, setSettings] = useState<AppearanceSettings>({
theme: defaultValue?.theme ?? 'system',
scale: defaultValue?.scale ?? 100,
compact: defaultValue?.compact ?? false,
fontFamily: defaultValue?.fontFamily ?? 'sans',
});
const update = (patch: Partial<AppearanceSettings>) => {
setSettings((prev) => {
const next = { ...prev, ...patch };
onChange?.(next);
return next;
});
};
const themeLabel =
THEMES.find((item) => item.value === settings.theme)?.label ?? settings.theme;
return (
<section
style={{
display: 'flex',
flexDirection: 'column',
gap: 24,
maxWidth: 560,
padding: 24,
background: 'var(--jx-surface)',
border: '1px solid var(--jx-border)',
borderRadius: 'var(--jx-r-lg)',
color: 'var(--jx-text)',
fontFamily: 'var(--jx-font-sans)',
}}
>
<header
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: 12,
flexWrap: 'wrap',
}}
>
<h2
style={{
margin: 0,
fontFamily: 'var(--jx-font-display)',
fontSize: 20,
color: 'var(--jx-text)',
}}
>
Внешний вид
</h2>
<JxBadge tone="accent" dot>
{themeLabel}
</JxBadge>
</header>
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
<span style={{ color: 'var(--jx-text-2)', fontSize: 14 }}>Тема</span>
<JxToggle
aria-label="Тема оформления"
items={THEMES}
value={settings.theme}
onValueChange={(theme) => update({ theme })}
/>
</div>
<JxSlider
label="Масштаб интерфейса"
min={80}
max={140}
step={10}
unit="%"
showOutput
value={settings.scale}
onValueChange={(scale) => update({ scale })}
/>
<JxSwitch
label="Плотная вёрстка"
checked={settings.compact}
onChange={(event) => update({ compact: event.target.checked })}
/>
<JxDivider label="Ещё" />
<JxSelect
label="Шрифт"
placeholder="Выберите шрифт"
options={FONTS}
value={settings.fontFamily}
onValueChange={(fontFamily) => update({ fontFamily })}
/>
</section>
);
}