Skip to content

Commit d16de25

Browse files
Merge pull request #4 from jonathanperis/copilot/sub-pr-3
Apply PR review feedback: perf, accessibility, and React key stability
2 parents 44f6a59 + 327013c commit d16de25

2 files changed

Lines changed: 57 additions & 23 deletions

File tree

app/page.tsx

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,28 @@ export default function Home() {
147147
const mainRef = useRef<HTMLDivElement>(null);
148148

149149
useEffect(() => {
150+
let animationFrameId: number | null = null;
151+
const latestPositionRef = { x: 0, y: 0 };
152+
150153
const handleMouseMove = (e: MouseEvent) => {
151-
setMousePosition({ x: e.clientX, y: e.clientY });
154+
latestPositionRef.x = e.clientX;
155+
latestPositionRef.y = e.clientY;
156+
157+
if (animationFrameId === null) {
158+
animationFrameId = window.requestAnimationFrame(() => {
159+
setMousePosition({ x: latestPositionRef.x, y: latestPositionRef.y });
160+
animationFrameId = null;
161+
});
162+
}
152163
};
153164

154165
window.addEventListener("mousemove", handleMouseMove);
155-
return () => window.removeEventListener("mousemove", handleMouseMove);
166+
return () => {
167+
window.removeEventListener("mousemove", handleMouseMove);
168+
if (animationFrameId !== null) {
169+
window.cancelAnimationFrame(animationFrameId);
170+
}
171+
};
156172
}, []);
157173

158174
useEffect(() => {
@@ -209,7 +225,11 @@ export default function Home() {
209225
href={`#${item.id}`}
210226
onClick={(e) => {
211227
e.preventDefault();
212-
document.getElementById(item.id)?.scrollIntoView({ behavior: "smooth" });
228+
const section = document.getElementById(item.id);
229+
if (section) {
230+
section.scrollIntoView({ behavior: "smooth" });
231+
history.pushState(null, "", `#${item.id}`);
232+
}
213233
}}
214234
>
215235
<span
@@ -363,8 +383,8 @@ export default function Home() {
363383
</div>
364384
<div>
365385
<ol className="group/list">
366-
{EXPERIENCES.map((exp, i) => (
367-
<li key={i} className="mb-12">
386+
{EXPERIENCES.map((exp) => (
387+
<li key={`${exp.company}-${exp.period}`} className="mb-12">
368388
<div className="group relative grid pb-1 transition-all sm:grid-cols-8 sm:gap-8 md:gap-4 lg:hover:!opacity-100 lg:group-hover/list:opacity-50">
369389
<div className="absolute -inset-x-4 -inset-y-4 z-0 hidden rounded-md transition motion-reduce:transition-none lg:-inset-x-6 lg:block lg:group-hover:bg-navy-light/50 lg:group-hover:shadow-[inset_0_1px_0_0_rgba(148,163,184,0.1)] lg:group-hover:drop-shadow-lg" />
370390

@@ -377,22 +397,36 @@ export default function Home() {
377397
<div className="z-10 sm:col-span-6">
378398
<h3 className="font-medium leading-snug text-slate-lightest">
379399
<div>
380-
<a
381-
className="group/link inline-flex items-baseline text-base font-medium leading-tight text-slate-lightest hover:text-green focus-visible:text-green"
382-
href={exp.url}
383-
target="_blank"
384-
rel="noreferrer noopener"
385-
aria-label={`${exp.title} at ${exp.company} (opens in a new tab)`}
386-
>
387-
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded md:-inset-x-6 md:-inset-y-4 lg:block" />
388-
<span>
389-
{exp.title} ·{" "}
390-
<span className="inline-block">
391-
{exp.company}
392-
<ArrowIcon />
400+
{exp.url && exp.url !== "#" ? (
401+
<a
402+
className="group/link inline-flex items-baseline text-base font-medium leading-tight text-slate-lightest hover:text-green focus-visible:text-green"
403+
href={exp.url}
404+
target="_blank"
405+
rel="noreferrer noopener"
406+
aria-label={`${exp.title} at ${exp.company} (opens in a new tab)`}
407+
>
408+
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded md:-inset-x-6 md:-inset-y-4 lg:block" />
409+
<span>
410+
{exp.title} ·{" "}
411+
<span className="inline-block">
412+
{exp.company}
413+
<ArrowIcon />
414+
</span>
415+
</span>
416+
</a>
417+
) : (
418+
<span
419+
className="group/link inline-flex items-baseline text-base font-medium leading-tight text-slate-lightest"
420+
>
421+
<span className="absolute -inset-x-4 -inset-y-2.5 hidden rounded md:-inset-x-6 md:-inset-y-4 lg:block" />
422+
<span>
423+
{exp.title} ·{" "}
424+
<span className="inline-block">
425+
{exp.company}
426+
</span>
393427
</span>
394428
</span>
395-
</a>
429+
)}
396430
</div>
397431
</h3>
398432
<p className="mt-2 text-sm leading-normal">
@@ -439,8 +473,8 @@ export default function Home() {
439473
</div>
440474
<div>
441475
<ul className="group/list">
442-
{PROJECTS.map((project, i) => (
443-
<li key={i} className="mb-12">
476+
{PROJECTS.map((project) => (
477+
<li key={project.title} className="mb-12">
444478
<div className="group relative grid gap-4 pb-1 transition-all sm:grid-cols-8 sm:gap-8 md:gap-4 lg:hover:!opacity-100 lg:group-hover/list:opacity-50">
445479
<div className="absolute -inset-x-4 -inset-y-4 z-0 hidden rounded-md transition motion-reduce:transition-none lg:-inset-x-6 lg:block lg:group-hover:bg-navy-light/50 lg:group-hover:shadow-[inset_0_1px_0_0_rgba(148,163,184,0.1)] lg:group-hover:drop-shadow-lg" />
446480

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)