Add two new backlog documentation files: - ai-chat-collapse-on-page-focus.md describing auto‑collapse behavior for the AI chat window. - comments-panel-density.md outlining UI density improvements for the comments panel.
12 KiB
Панель комментариев: сделать плотнее (меньше воздуха, меньше шрифт)
Статус: план, код не менялся. Чисто UI-задача на клиенте (CSS + пропсы Mantine). Бэкенда, схемы данных и логики не касается.
Суть
Сейчас панель комментариев (правый aside, вкладка «Comments») выглядит разреженной: крупные отступы между карточками и внутри них, большой межстрочный интервал, тело комментария набрано базовым размером редактора (16px). На узкой колонке это «съедает» вертикаль — на экран помещается мало комментариев, много пустого места.
Хотим: уплотнить раскладку — уменьшить внутренние/внешние отступы карточек, зазор «аватар ↔ текст», вертикальный ритм редактора — и уменьшить шрифт тела комментария, имени автора и цитаты выделения. Цель — больше комментариев на экран без потери читабельности.
Где сейчас живёт «воздух» (точные места)
Вся вёрстка панели — в фиче apps/client/src/features/comment/.
1. Карточка комментария — comment-list-with-tabs.tsx
renderComments, обёртка каждого треда (~строки 121-129):<Paper shadow="sm" radius="md" p="sm" mb="sm" withBorder>—p="sm"(12px внутренний отступ) иmb="sm"(12px зазор между комментариями).- Разделитель перед редактором ответа (~строка 148):
<Divider my={4} />. - Вкладки (
Tabs.Panel pt="xs", строки 226 и 245) и пустое состояние (<Center py="xl">, строки 228 и 247) — второстепенные источники воздуха. - Нижнее поле ввода
PageCommentInput(строки ~361-405):paddingTop=sm,paddingBottom: 25, аватарmarginTop: 10, кнопка отправки спозиционированаbottom: 30. Эти величины связаны (плавающая кнопка над полем) — трогать осторожно.
2. Элемент комментария — comment-list-item.tsx
- Внешняя обёртка (строка 119):
<Box ref={ref} pb="xs">— 10px снизу у каждого элемента (включая вложенные ответы). - Шапка «аватар ↔ контент» (строка 120):
<Group>безgap→ дефолтныйgap="md"(16px) между аватаром и блоком с именем/телом. Это главный горизонтальный «воздух». - Имя автора (строка 129):
<Text size="sm" fw={500} lineClamp={1}>— 14px. - Время (строки 157-161): уже
<Text size="xs">(12px) — оставить. - Цитата выделения (строка 180):
<Text size="sm">{comment?.selection}</Text>— 14px, внутри блока.textSelection.
3. Стили — comment.module.css
.textSelection(строки 9-21):margin-top: 4px,padding: 8px..commentEditor .ProseMirror :global(.ProseMirror)(строки 35-44):margin-top: 10px,margin-bottom: 2px, паддинги 6px. font-size не задан — тело комментария наследует глобальный.ProseMirror { font-size: var(--mantine-font-size-md) }(16px) из core.css:10..wrapper(строки 1-3) —padding: md, в коде не используется (можно игнорировать или удалить заодно).
4. Внешняя рамка панели (ВНИМАНИЕ: общая) — aside.tsx
<Box p="md">(строка 47) и шапка<Group ... mb="md">с<Title order={2} size="h6">(строки 50-51) дают 16px отступа по краям панели и под заголовком. Этот контейнер общий для трёх вкладок aside (comments/toc/details). Менять его — значит уплотнить заодно «Содержание» и «Детали». См. «Открытые вопросы».
Шкалы Mantine в проекте без переопределений (theme.ts палитру/контраст меняет,
но не размеры): шрифт xs=12px / sm=14px / md=16px; spacing xs=10 / sm=12 / md=16.
Решение (точечное, в границах фичи comment)
Базовый объём — только компоненты features/comment/, чтобы вкладки
«Содержание»/«Детали» (общий aside.tsx) не задеть. Уплотнение рамки панели —
отдельный опциональный пункт (см. ниже).
Правки по файлам
comment-list-with-tabs.tsx
<Paper>вrenderComments:p="sm"→p="xs",mb="sm"→mb="xs"(12 → 10px).shadow="sm",radius="md",withBorder— оставить.<Divider my={4} />→my={2}.
comment-list-item.tsx
<Box ref={ref} pb="xs">→pb={6}.- Шапка
<Group>(аватар + контент, строка 120): добавитьgap="xs"(дефолтные 16px → 10px). НЕ трогать внутренние<Group justify="space-between">и<Group gap="xs">, у них зазор уже задан. - Имя:
<Text size="sm" ...>→size="xs".fw={500}иlineClamp={1}— оставить (см. «иерархия шрифта» ниже). - Цитата:
<Text size="sm">{comment?.selection}</Text>→size="xs".
comment.module.css
- В
.ProseMirror :global(.ProseMirror)добавитьfont-size: var(--mantine-font-size-sm);(16 → 14px) иline-height: 1.4;, заменитьmargin-top: 10px→margin-top: 4px. Остальные декларации (border-radius,max-width,white-space,word-break, паддинги,margin-bottom) — без изменений. .textSelection:margin-top: 4px→2px,padding: 8px→6px.
Эскиз (ключевой фрагмент CSS)
.commentEditor {
/* ... */
.ProseMirror :global(.ProseMirror) {
border-radius: var(--mantine-radius-sm);
max-width: 100%;
white-space: pre-wrap;
word-break: break-word;
padding-left: 6px;
padding-right: 6px;
/* Denser comments: shrink body text from the global 16px ProseMirror size
to 14px and tighten the rhythm vs. the comment header. */
font-size: var(--mantine-font-size-sm);
line-height: 1.4;
margin-top: 4px; /* was 10px */
margin-bottom: 2px;
}
}
.textSelection {
margin-top: 2px; /* was 4px */
padding: 6px; /* was 8px */
/* ...остальное без изменений... */
}
Тонкие моменты / edge cases
- Не трогать
aside.tsxв базовом объёме. Егоp="md"и шапка общие для вкладокtoc/details— правка уплотнит и их. Если это нежелательно, держать изменения строго внутриfeatures/comment/. - Иерархия шрифта (принято). После правок: имя —
xs(12px,fw=500), тело —sm(14px), время —xs(12px). Тело крупнее имени — это норма (имя/мета как «капс-лейбл», тело как основной текст). font-sizeставится на внутренний:global(.ProseMirror), т.к. размер приходит из глобального правилаcore.css. Класс-модуль.commentEditorскоупит переопределение только на редактор комментариев — основной редактор страницы не затрагивается.- Тёмная тема. Меняем только размеры/отступы, цвета берутся из токенов Mantine — отдельной проверки палитры не требуется, но визуально глянуть стоит.
- Вложенные ответы рендерятся тем же
CommentListItem→ уплотнениеpb,gap, шрифтов применится и к ним автоматически (так и нужно). - Markdown/код в теле.
pre/code/списки внутри комментария наследуютfont-sizeот.ProseMirrorконтейнера — послеfont-size: smони тоже станут компактнее; проверить, что код-блоки не разъезжаются. - Цитата выделения кликабельна (
role="button", переход к месту в тексте) — уменьшениеpadding/sizeне должно сломать зону клика; визуально проверить. - Нижнее поле ввода (
PageCommentInput) с плавающей кнопкой: величиныpaddingBottom: 25/bottom: 30связаны. В базовом объёме не трогаем; если захотим уплотнить и его — менять обе согласованно и проверить, что кнопка отправки не наезжает на текст.
Тесты / проверка
- Прогнать
pnpm --filter client lintиpnpm --filter client test(изменения косметические — падений быть не должно). - Ручная проверка во вкладке Comments: тред с длинным телом, тред с цитатой
выделения, вложенные ответы, режим редактирования, светлая/тёмная тема, узкая
ширина aside. Убедиться, что вкладки «Содержание»/«Детали» не изменились
(если
aside.tsxне трогали).
Опционально / расширения (вне базового объёма)
- Уплотнить рамку панели —
aside.tsx:p="md"→p="sm", шапкаmb="md"→mb="sm". Даст ощутимо меньше воздуха по краям, но затронет все вкладки aside (см. «Открытые вопросы»). - Компактные вкладки Tabs —
Tabs.Panel pt="xs"→pt={6}, бейджи счётчиков ужеsize="sm". - Удалить мёртвый
.wrapperизcomment.module.css(не используется). - Уменьшить аватары с
size="sm"доsize="xs"вCommentListItemиPageCommentInputдля ещё большей плотности (проверить, что инициалы/картинка не мельчат до нечитаемости).
Принятые решения
Решения зафиксированы — реализовать можно сразу, без доп. согласований:
- Границы правки: строго
features/comment/. Общую рамку aside (p="md", шапкаmb="md") не трогаем — она общая с вкладками «Содержание»/«Детали», и правка задела бы их (см. «Опционально», если позже захотим уплотнить и их). - Шрифт тела:
sm(14px) — не мельче. - Иерархия: имя
xs(12px,fw=500), телоsm(14px), времяxs(12px). - Нижнее поле ввода и размер аватаров: оставляем как есть.