Компоненты интерфейса и доработка
Интерфейс EpoCanvas Docs написан не с нуля, а построен на нативных компонентах Starlight с помощью точечного переопределения: сохранены каркас страниц и обработка контента Starlight, а отображаемые компоненты — верхняя панель, боковая панель, оглавление, поиск и т.д. — заменены, чтобы получить нужную трёхколоночную раскладку и поведение. На этой странице описана структура этой системы компонентов и способы её изменения.
Механизм переопределения компонентов
Starlight позволяет заменить любой нативный компонент собственной реализацией через поле components в astro.config.mjs. В этом проекте переопределено 7 компонентов:
// astro.config.mjs (фрагмент)components: { Header: './src/components/starlight/Header.astro', Sidebar: './src/components/starlight/Sidebar.astro', TableOfContents: './src/components/starlight/TableOfContents.astro', PageTitle: './src/components/starlight/PageTitle.astro', TwoColumnContent: './src/components/starlight/TwoColumnContent.astro', Search: './src/components/starlight/Search.astro', Pagination: './src/components/starlight/Pagination.astro',},При сборке для каждой позиции рендеринга страницы Starlight сначала использует файлы, указанные здесь. Непереопределённые компоненты (например, Footer в подвале или мобильное меню) продолжают использовать нативную реализацию.
Назначение семи кастомных компонентов
Весь исходный код находится в src/components/starlight/; их объём и назначение перечислены ниже:
| Файл компонента | Объём | Назначение |
|---|---|---|
Header.astro | около 646 строк | Всё содержимое верхней панели: логотип, поле поиска, основная навигация, значок версии, переключатель языка, переключатель темы, ссылки на GitHub и Telegram |
Search.astro | около 837 строк | Поиск с двумя режимами: поиск по странице в верхней панели (подсветка и счётчик) + всплывающее окно поиска по всему сайту на Ctrl+K (Pagefind UI) |
Pagination.astro | около 123 строк | Карточки «Предыдущая / Следующая страница» внизу: плоская тонкая рамка, заголовок фирменного цвета, косые стрелки ↙/↘, указывающие направление перехода |
TwoColumnContent.astro | около 77 строк | Двухколоночный каркас из основного текста и оглавления справа; управляет фиксированной шириной правой колонки и её прокруткой |
TableOfContents.astro | около 64 строк | Заголовок «Содержание страницы», значок и список оглавления; отфильтровывает заголовок самой страницы |
PageTitle.astro | около 62 строк | Крупный заголовок страницы (берётся из title во Frontmatter) и отметка времени «последнее обновление» |
Sidebar.astro | около 22 строк | Тонкая обёртка: переиспользует нативный компонент Starlight SidebarPersister, благодаря чему позиция прокрутки боковой панели сохраняется при переходе между страницами |
Поток данных: три конфигурационных файла управляют всем интерфейсом
Кастомные компоненты сами по себе не содержат бизнес-данных; содержимое интерфейса управляется тремя конфигурационными файлами:
astro.config.mjs ──→ массивы locales + sidebar ──→ Sidebar.astro рендерит каталог слева (для каждого языка берётся соответствующий перевод)src/config/navigation.ts ──→ navigationConfig ──→ Header.astro рендерит верхнюю навигацию и подсветку (ссылки автоматически получают языковой префикс)src/utils/i18n.ts ──→ словарь UI_TRANSLATIONS ──→ компоненты получают строки на текущем языке на этапе сборки- Каталог слева распознаёт только объявления
sidebarизastro.config.mjs, и новые документы обязательно нужно регистрировать здесь; полеtranslationsкаждого пункта содержит тексты меню на 10 языках; - Верхняя навигация: отображаемый текст каждого пункта берётся из словаря
i18n.tsпо ключуlabelKey, а функцияmatchопределяет, какая кнопка подсвечивается на текущей странице (перед сопоставлением языковой префикс удаляется); - Тексты интерфейса (плейсхолдер поля поиска, заголовок «Содержание страницы», подсказка переключателя темы и т.п.) каждый компонент выводит на нужном языке напрямую на этапе сборки через
getTranslation(key, lang); скриптов подмены в рантайме на странице нет.
Иными словами: чтобы изменить содержимое интерфейса, сначала найдите соответствующий конфигурационный файл; исходный код компонентов нужно трогать только при изменении внешнего вида (отступов, цветов, значков).
Ключевые детали реализации компонентов
PageTitle: заголовок страницы и фактическое время обновления
Крупный заголовок страницы читается напрямую из title во Frontmatter, поэтому не пишите заголовок первого уровня # в самом тексте. Отметка времени «последнее обновление» берётся из истории коммитов Git на этапе сборки (в astro.config.mjs включён lastUpdated: true); она обновляется автоматически при каждом коммите и не требует ручного ведения.
Sidebar: как реализовано запоминание позиции прокрутки
Sidebar.astro занимает всего около 20 строк; главное — переиспользование официального компонента Starlight SidebarPersister: при переключении страниц DOM боковой панели не пересоздаётся, благодаря чему сохраняется позиция прокрутки. В этом и состоит принцип «непрыгающего» каталога слева при переходах между страницами.
TableOfContents: генерация содержания страницы
Данные оглавления Starlight генерирует на этапе сборки, разбирая заголовки в тексте (## и ###); компонент лишь отфильтровывает сам заголовок страницы и выполняет рендеринг. Подсветку при прокрутке выполняет в браузере пользовательский элемент starlight-toc, без использования каких-либо фреймворков.
TwoColumnContent: единственный источник ширины правой колонки
Ширина колонки оглавления справа зафиксирована на 20rem при @media (min-width: 72rem) (и 21rem на сверхшироких экранах от 90rem); максимальная ширина области основного текста соответственно уменьшается на ширину правой колонки. Чтобы изменить ширину правой колонки, правьте только этот файл — не переопределяйте её кусками в других таблицах стилей.
Header: навигация, тема и язык
- Кнопки навигации рендерятся в цикле по
navigationConfig; стиль активного состояния определяется значением, возвращаемым функциейmatch, а ссылки черезlocalizedHref()автоматически получают префикс текущего языка; - Переключатель темы записывает ключ
starlight-themeв LocalStorage; при загрузке страницы начальная тема выбирается в порядке «локальный выбор → системные настройки»; - Каждый пункт выпадающего списка языков — реальная ссылка на версию текущей страницы на соответствующем языке: клик сразу выполняет переход, дополнительного хранения состояния нет;
- Оба значка справа в верхней панели — GitHub и Telegram — жёстко прописаны в
src/components/starlight/Header.astro, поэтому адрес меняют правкой этого файла. Telegram указывает на страницу аккаунта@epocanvas, а всплывающая подсказка берётся из строкиsocial.telegram. Записьsocialвastro.config.mjsуправляет отдельной группой значков внизу боковой панели; они друг на друга не влияют.
Search: поиск в двух режимах
В одном компоненте реализованы две системы поиска (подробнее — в разделе Полнотекстовый поиск и горячие клавиши):
- Поиск по странице: поле в верхней панели; Enter перемещает между совпадениями на текущей странице, подсветка реализована скриптом, который расставляет отметки;
- Поиск по всему сайту: всплывающее окно
<dialog>со стандартным интерфейсом Pagefind; индекс генерируется на этапеpnpm run build.
Pagination: карточки перехода между страницами
Данные «предыдущая / следующая страница» Starlight вычисляет на этапе сборки в соответствии с порядком sidebar (Astro.locals.starlightRoute.pagination); компонент только рендерит: две равные по ширине карточки, тонкая рамка без тени, заголовок фирменного цвета, косые стрелки ↙ / ↘ при наведении сдвигаются в направлении перехода. Стрелки представляют собой инлайновые SVG-пути, и если сайт используется на языке с письмом RTL, их направление зеркалится автоматически.
Важные замечания по доработке
- Для изменения стилей в первую очередь используйте CSS-переменные: цвета, шрифты и размеры макета собраны в переменных
:rootвsrc/styles/custom.css, см. Конфигурация сайта и настройка стилей; большинство кастомизаций не требуют изменения компонентов; - Компоненты трогайте только при изменении поведения: добавляя кнопки или меняя структуру, получайте тексты интерфейса через
getTranslation(key, lang)и дополняйте словарь вi18n.tsстроками на всех 10 языках — для пропущенных языков будет использоваться резервный механизм с отображением на китайском; - После изменений обязательно проверяйте локально:
pnpm run devдля проверки поведения,pnpm run buildдля подтверждения успешного прохождения проверки типов и сборки (локальные команды описаны в Частых вопросах и устранении неполадок).
Конкретные типовые операции по кастомизации смотрите прямо в Шпаргалке по типовым доработкам.