Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
'use client'
|
|
|
|
import Link from 'next/link'
|
|
import { useEffect, useState } from 'react'
|
|
import { ArticleHeading } from '@/types/content-types'
|
|
import { cn } from '@/utils/cn'
|
|
|
|
export function HeadingsMenu({ headings }: { headings: ArticleHeading[] }) {
|
|
const [activeSlug, setActiveSlug] = useState('')
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
let current = ''
|
|
for (const { slug } of headings) {
|
|
const element = document.getElementById(slug)
|
|
if (element && element.getBoundingClientRect().top < 100) current = slug
|
|
}
|
|
setActiveSlug(current)
|
|
}
|
|
handleScroll()
|
|
window.addEventListener('scroll', handleScroll, { passive: true })
|
|
return () => window.removeEventListener('scroll', handleScroll)
|
|
}, [headings])
|
|
|
|
if (headings.length === 0) return null
|
|
|
|
return (
|
|
<div className="relative overflow-y-auto shrink mb-12">
|
|
<div className="sticky top-0">
|
|
<h4 className="block text-xs font-semibold text-black uppercase bg-white dark:bg-zinc-950 dark:text-white">
|
|
On this page
|
|
</h4>
|
|
<div className="w-full h-2 bg-gradient-to-b from-white dark:from-zinc-950" />
|
|
</div>
|
|
<ul className="flex flex-col gap-2 text-sm break-words">
|
|
{headings.map(({ title, level, slug }, index) => (
|
|
<li key={index} style={{ paddingLeft: `${(level - 2) * 0.75}rem` }}>
|
|
<Link
|
|
href={`#${slug}`}
|
|
className={cn(
|
|
slug === activeSlug
|
|
? 'text-black dark:text-white font-semibold'
|
|
: 'hover:text-zinc-800 dark:hover:text-zinc-100'
|
|
)}
|
|
>
|
|
{title}
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)
|
|
}
|