Новые изменения в компоенты
This commit is contained in:
parent
a14c18542e
commit
faf02848ed
3 changed files with 33 additions and 19 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue