chore: format codebase and move SectionAccordion to entities/Section
This commit is contained in:
@@ -1,50 +1,50 @@
|
||||
'use client'
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import { cn } from '$shared/lib'
|
||||
import type { NavItem } from '../model/types'
|
||||
import { useState, useEffect } from 'react';
|
||||
import { cn } from '$shared/lib';
|
||||
import type { NavItem } from '../model/types';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* Navigation items to render
|
||||
*/
|
||||
items: NavItem[]
|
||||
items: NavItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixed sidebar navigation, visible on lg+ screens.
|
||||
*/
|
||||
export function SidebarNav({ items }: Props) {
|
||||
const [activeSection, setActiveSection] = useState('bio')
|
||||
const [activeSection, setActiveSection] = useState('bio');
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
entries => {
|
||||
entries.forEach(entry => {
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
setActiveSection(entry.target.id)
|
||||
setActiveSection(entry.target.id);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
{ rootMargin: '-20% 0px -70% 0px', threshold: 0 },
|
||||
)
|
||||
);
|
||||
|
||||
items.forEach(item => {
|
||||
const el = document.getElementById(item.id)
|
||||
if (el) observer.observe(el)
|
||||
})
|
||||
items.forEach((item) => {
|
||||
const el = document.getElementById(item.id);
|
||||
if (el) observer.observe(el);
|
||||
});
|
||||
|
||||
return () => observer.disconnect()
|
||||
}, [items])
|
||||
return () => observer.disconnect();
|
||||
}, [items]);
|
||||
|
||||
/**
|
||||
* Scrolls to the section by id with a 40px offset.
|
||||
*/
|
||||
function scrollToSection(id: string) {
|
||||
const el = document.getElementById(id)
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
const top = el.getBoundingClientRect().top + window.scrollY - 40
|
||||
window.scrollTo({ top, behavior: 'smooth' })
|
||||
const top = el.getBoundingClientRect().top + window.scrollY - 40;
|
||||
window.scrollTo({ top, behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ export function SidebarNav({ items }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{items.map(item => {
|
||||
const isActive = activeSection === item.id
|
||||
{items.map((item) => {
|
||||
const isActive = activeSection === item.id;
|
||||
return (
|
||||
<button
|
||||
key={item.id}
|
||||
@@ -76,19 +76,27 @@ export function SidebarNav({ items }: Props) {
|
||||
<span className="font-heading text-xl font-black">{item.label}</span>
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
);
|
||||
})}
|
||||
|
||||
<div className="mt-12 pt-12 brutal-border-top">
|
||||
<p className="text-sm uppercase tracking-wider mb-4 opacity-60">Quick Links</p>
|
||||
<div className="space-y-3">
|
||||
<a href="mailto:hello@allmy.work" className="block">Email</a>
|
||||
<a href="https://linkedin.com" className="block">LinkedIn</a>
|
||||
<a href="https://instagram.com" className="block">Instagram</a>
|
||||
<a href="https://are.na" className="block">Are.na</a>
|
||||
<a href="mailto:hello@allmy.work" className="block">
|
||||
Email
|
||||
</a>
|
||||
<a href="https://linkedin.com" className="block">
|
||||
LinkedIn
|
||||
</a>
|
||||
<a href="https://instagram.com" className="block">
|
||||
Instagram
|
||||
</a>
|
||||
<a href="https://are.na" className="block">
|
||||
Are.na
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user