Новые изменения в компоенты

This commit is contained in:
Web-serfer 2026-04-26 22:45:19 +05:00
parent a14c18542e
commit faf02848ed
3 changed files with 33 additions and 19 deletions

View file

@ -27,7 +27,7 @@ const { items } = Astro.props;
</aside> </aside>
)} )}
<style> <style is:global>
.toc-container { width: 100%; } .toc-container { width: 100%; }
.toc-nav { .toc-nav {
background: #ffffff; background: #ffffff;
@ -43,6 +43,7 @@ const { items } = Astro.props;
margin: 0 0 1.25rem; margin: 0 0 1.25rem;
padding-bottom: 0.75rem; padding-bottom: 0.75rem;
border-bottom: 2px solid #eac26e; border-bottom: 2px solid #eac26e;
text-align: center;
} }
.toc-list { .toc-list {
@ -55,10 +56,19 @@ const { items } = Astro.props;
gap: 0.25rem; gap: 0.25rem;
} }
/* ЧЕРНАЯ НУМЕРАЦИЯ */ /* Поддержка level=1 (из HTML h2) и level=2/3 */
.toc-item.level-2 { counter-reset: toc-h3; counter-increment: toc-h2; } .toc-item.level-1, .toc-item.level-2 { counter-reset: toc-h3; counter-increment: toc-h2; }
.toc-item.level-3 { counter-increment: toc-h3; padding-left: 1.25rem; } .toc-item.level-3 { counter-increment: toc-h3; padding-left: 1.25rem; }
/* h2 = level 1 в HTML */
.toc-item.level-1, .toc-item.level-2 {
font-weight: 600;
}
.toc-item.level-1 .toc-link, .toc-item.level-2 .toc-link {
font-size: 0.95rem;
padding: 0.6rem 0.75rem;
}
.toc-link { .toc-link {
display: flex; display: flex;
padding: 0.5rem 0.75rem; padding: 0.5rem 0.75rem;
@ -70,19 +80,21 @@ const { items } = Astro.props;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
/* Номера в оглавлении */
.toc-link::before { .toc-link::before {
content: "";
display: inline-block;
width: 1.5rem;
color: #1e3050; color: #1e3050;
font-weight: 700; font-weight: 700;
margin-right: 0.6rem; margin-right: 0.6rem;
flex-shrink: 0; flex-shrink: 0;
text-align: center;
} }
.level-2 .toc-link::before { content: counter(toc-h2) "."; } .toc-item.level-1 .toc-link::before, .toc-item.level-2 .toc-link::before { content: counter(toc-h2) "."; }
.level-3 .toc-link::before { content: counter(toc-h2) "." counter(toc-h3) "."; font-size: 0.85em; opacity: 0.7; } .toc-item.level-3 .toc-link::before { content: counter(toc-h2) "." counter(toc-h3) "."; font-size: 0.85em; opacity: 0.7; }
.toc-link:hover { color: #1e3050; background: #f1f5f9; } .toc-link:hover { color: #1e3050; background: #f1f5f9; }
/* АКТИВНЫЙ ПУНКТ (При скролле) */
.toc-item.active .toc-link { .toc-item.active .toc-link {
color: #eac26e; color: #eac26e;
font-weight: 700; font-weight: 700;

View file

@ -147,14 +147,17 @@ export async function getPostBySlug(slug: string): Promise<Post | null> {
return result.items[0] as unknown as Post; return result.items[0] as unknown as Post;
} }
export async function getAllCategories(): Promise<string[]> { export const FIXED_BLOG_CATEGORIES = [
const result = await pb.collection('posts').getFullList({ 'ДТП',
filter: 'draft = false', 'Лишение прав',
fields: 'category', 'Страховые споры',
}); 'Штрафы ГИБДД',
'Возмещение ущерба',
'Судебные дела',
];
const categories = (result || []).map((post) => post.category as string).filter(Boolean); export async function getAllCategories(): Promise<string[]> {
return ['Все', ...new Set(categories)]; return ['Все', ...FIXED_BLOG_CATEGORIES];
} }
export function getPostImageUrl(post: { image?: string }): string { export function getPostImageUrl(post: { image?: string }): string {

View file

@ -26,18 +26,17 @@ const { likes = 0, dislikes = 0 } = await getPostVotesStats(post.id).catch(() =>
// Конвертируем markdown в HTML // Конвертируем markdown в HTML
const contentHtml = marked(post.content || ''); const contentHtml = marked(post.content || '');
// Извлекаем заголовки для оглавления // Извлекаем заголовки для оглавления (поддержка HTML и Markdown)
const headingRegex = /^(#{2,3})\s+(.+)$/gm; const headingRegex = /<h([2-3])[^>]*>([^<]+)<\/?h[2-3]>/gi;
const tocItems: { id: string; text: string; level: number }[] = []; const tocItems: { id: string; text: string; level: number }[] = [];
const body = post.content || ''; const body = post.content || '';
let match; let match;
let headingIndex = 0; let headingIndex = 0;
while ((match = headingRegex.exec(body)) !== null) { while ((match = headingRegex.exec(body)) !== null) {
const level = match[1].length; const level = parseInt(match[1]); // Теперь 2 или 3
const text = match[2].trim(); const text = match[2].trim();
tocItems.push({ level, id: `heading-${headingIndex++}`, text }); tocItems.push({ level, id: `heading-${headingIndex++}`, text });
} }
console.log('[DEBUG] tocItems:', JSON.stringify(tocItems));
const formatDate = (date: string) => { const formatDate = (date: string) => {
const d = new Date(date); const d = new Date(date);
const day = d.getDate().toString().padStart(2, '0'); const day = d.getDate().toString().padStart(2, '0');
@ -90,7 +89,7 @@ const heroImage = getPostImageUrl(post);
<RelatedPosts posts={filteredRelated} currentSlug={slug} /> <RelatedPosts posts={filteredRelated} currentSlug={slug} />
*/} */}
<!-- Оглавление - пробуем без slot --> <!-- Оглавление -->
<div slot="sidebar"> <div slot="sidebar">
<ArticleTableOfContents items={tocItems} /> <ArticleTableOfContents items={tocItems} />
</div> </div>