Skip to content

Commit

Permalink
Add transitions to Sections bg and line
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorrenkema committed Sep 25, 2024
1 parent e09f747 commit eab8feb
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 10 deletions.
17 changes: 17 additions & 0 deletions packages/gitbook/src/components/PageAside/AnimatedBackground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import { Transition, motion, useReducedMotion } from 'framer-motion';
import React from 'react';

export function AnimatedBackground({ transition }: { transition?: Transition }) {
const prefersReducedMotion = useReducedMotion();

return (
<motion.div
layout
layoutId="sections-item"
className="absolute left-0 top-0 z-0 h-full w-full bg-primary-50 dark:bg-dark-3"
transition={prefersReducedMotion ? { duration: 0 } : transition}
/>
);
}
26 changes: 26 additions & 0 deletions packages/gitbook/src/components/PageAside/AnimatedLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client';

import { Transition, motion, useReducedMotion } from 'framer-motion';
import React from 'react';

import { tcls } from '@/lib/tailwind';

export function AnimatedLine({ transition }: { transition?: Transition }) {
const prefersReducedMotion = useReducedMotion();

return (
<motion.div
layout
layoutId="sections-line"
className={tcls([
'border-primary',
'border-l',
'dark:border-primary-400',
'h-full',
'absolute',
'z-20',
])}
transition={prefersReducedMotion ? { duration: 0 } : transition}
/>
);
}
36 changes: 26 additions & 10 deletions packages/gitbook/src/components/PageAside/ScrollSectionsList.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
'use client';

import { motion, useReducedMotion } from 'framer-motion';
import React from 'react';

import { useScrollActiveId } from '@/components/hooks';
import { DocumentSection } from '@/lib/document';
import { tcls } from '@/lib/tailwind';

import { AnimatedBackground } from './AnimatedBackground';
import { AnimatedLine } from './AnimatedLine';
import { HEADER_HEIGHT_DESKTOP } from '../layout';

/**
* The threshold at which we consider a section as intersecting the viewport.
*/
const SECTION_INTERSECTING_THRESHOLD = 0.9;

const springCurve = {
type: 'spring',
stiffness: 700,
damping: 50,
mass: 0.8,
};

export function ScrollSectionsList(props: { sections: DocumentSection[] }) {
const [hoveredId, setHoveredId] = React.useState<null | string>(null);

const { sections } = props;

const ids = React.useMemo(() => {
Expand All @@ -28,31 +39,36 @@ export function ScrollSectionsList(props: { sections: DocumentSection[] }) {
});

return (
<ul className={tcls('border-l', 'border-dark/2', 'dark:border-light/1', 'space-y-1')}>
<ul className={tcls('border-l', 'border-dark/2', 'dark:border-light/1')}>
{sections.map((section) => (
<li key={section.id} className={tcls('flex', 'flex-row')}>
<motion.li
key={section.id}
className={tcls('flex', 'flex-row', 'relative', 'h-fit')}
onMouseEnter={() => setHoveredId(section.id)}
onMouseLeave={() => setHoveredId(activeId)}
>
{activeId === section.id ? <AnimatedLine transition={springCurve} /> : null}
{activeId === section.id || hoveredId === section.id ? (
<AnimatedBackground transition={springCurve} />
) : null}
<a
href={`#${section.id}`}
className={tcls(
'flex',
'flex-row',
'z-10',
'w-full',
'items-baseline',
'left-[-1px]',
'relative',
'text-sm',
'py-1',
'ps-3',
'hover:text-primary',
'transition-all',
'border-l',
'border-transparent',
section.depth > 1 ? ['ps-6', 'opacity-8'] : null,
activeId === section.id
? [
'text-primary',
'border-primary',
'dark:text-primary-400',
'dark:border-primary-400',
'opacity-[1]',
'[&>span]:bg-primary-400',
'dark:[&>span]:bg-primary-600',
Expand All @@ -71,7 +87,7 @@ export function ScrollSectionsList(props: { sections: DocumentSection[] }) {

{section.title}
</a>
</li>
</motion.li>
))}
</ul>
);
Expand Down

0 comments on commit eab8feb

Please sign in to comment.